History

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

Pull drm updates from Dave Airlie: "This is the main drm pull request for v4.2. I've one other new driver from freescale on my radar, it's been posted and reviewed, I'd just like to get someone to give it a last look, so maybe I'll send it or maybe I'll leave it. There is no major nouveau changes in here, Ben was working on something big, and we agreed it was a bit late, there wasn't anything else he considered urgent to merge. There might be another msm pull for some bits that are waiting on arm-soc, I'll see how we time it. This touches some "of" stuff, acks are in place except for the fixes to the build in various configs,t hat I just applied. Summary: New drivers: - virtio-gpu: KMS only pieces of driver for virtio-gpu in qemu. This is just the first part of this driver, enough to run unaccelerated userspace on. As qemu merges more we'll start adding the 3D features for the virgl 3d work. - amdgpu: a new driver from AMD to driver their newer GPUs. (VI+) It contains a new cleaner userspace API, and is a clean break from radeon moving forward, that AMD are going to concentrate on. It also contains a set of register headers auto generated from AMD internal database. core: - atomic modesetting API completed, enabled by default now. - Add support for mode_id blob to atomic ioctl to complete interface. - bunch of Displayport MST fixes - lots of misc fixes. panel: - new simple panels - fix some long-standing build issues with bridge drivers radeon: - VCE1 support - add a GPU reset counter for userspace - lots of fixes. amdkfd: - H/W debugger support module - static user-mode queues - support killing all the waves when a process terminates - use standard DECLARE_BITMAP i915: - Add Broxton support - S3, rotation support for Skylake - RPS booting tuning - CPT modeset sequence fixes - ns2501 dither support - enable cmd parser on haswell - cdclk handling fixes - gen8 dynamic pte allocation - lots of atomic conversion work exynos: - Add atomic modesetting support - Add iommu support - Consolidate drm driver initialization - and MIC, DECON and MIPI-DSI support for exynos5433 omapdrm: - atomic modesetting support (fixes lots of things in rewrite) tegra: - DP aux transaction fixes - iommu support fix msm: - adreno a306 support - various dsi bits - various 64-bit fixes - NV12MT support rcar-du: - atomic and misc fixes sti: - fix HDMI timing complaince tilcdc: - use drm component API to access tda998x driver - fix module unloading qxl: - stability fixes" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (872 commits) drm/nouveau: Pause between setting gpu to D3hot and cutting the power drm/dp/mst: close deadlock in connector destruction. drm: Always enable atomic API drm/vgem: Set unique to "vgem" of: fix a build error to of_graph_get_endpoint_by_regs function drm/dp/mst: take lock around looking up the branch device on hpd irq drm/dp/mst: make sure mst_primary mstb is valid in work function of: add EXPORT_SYMBOL for of_graph_get_endpoint_by_regs ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi' drm/atomic: Don't set crtc_state->enable manually drm/exynos: dsi: do not set TE GPIO direction by input drm/exynos: dsi: add support for MIC driver as a bridge drm/exynos: dsi: add support for Exynos5433 drm/exynos: dsi: make use of array for clock access drm/exynos: dsi: make use of driver data for static values drm/exynos: dsi: add macros for register access drm/exynos: dsi: rename pll_clk to sclk_clk drm/exynos: mic: add MIC driver of: add helper for getting endpoint node of specific identifiers drm/exynos: add Exynos5433 decon driver ...

Linus Torvalds committed 11 years ago

Commit 099bfbf2 parents 22165fa c5fd936569 files · +453841 −9861Browse files

Unified · Split

208 files
  1. Documentation/DocBook/drm.tmpl +38 −26
  2. Documentation/devicetree/bindings/drm/msm/dsi.txt +120 −0
  3. Documentation/devicetree/bindings/drm/msm/edp.txt +60 −0
  4. Documentation/devicetree/bindings/drm/msm/hdmi.txt +6 −0
  5. Documentation/devicetree/bindings/drm/tilcdc/slave.txt +0 −18
  6. Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt +27 −0
  7. Documentation/devicetree/bindings/panel/hannstar,hsd100pxn1.txt +7 −0
  8. Documentation/devicetree/bindings/panel/lg,lb070wv8.txt +7 −0
  9. Documentation/devicetree/bindings/video/exynos-mic.txt +51 −0
  10. Documentation/devicetree/bindings/video/exynos5433-decon.txt +65 −0
  11. Documentation/devicetree/bindings/video/exynos_dsim.txt +25 −6
  12. MAINTAINERS +10 −1
  13. arch/arm/boot/dts/exynos4.dtsi +1 −1
  14. arch/x86/kernel/early-quirks.c +1 −0
  15. drivers/gpu/drm/Kconfig +23 −0
  16. drivers/gpu/drm/Makefile +3 −3
  17. drivers/gpu/drm/amd/amdgpu/Kconfig +17 −0
  18. drivers/gpu/drm/amd/amdgpu/Makefile +81 −0
  19. drivers/gpu/drm/amd/amdgpu/ObjectID.h +736 −0
  20. drivers/gpu/drm/amd/amdgpu/amdgpu.h +2337 −0
  21. drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +768 −0
  22. drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h +445 −0
  23. drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c +105 −0
  24. drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +1598 −0
  25. drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h +206 −0
  26. drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +572 −0
  27. drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c +221 −0
  28. drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +363 −0
  29. drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +268 −0
  30. drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +1907 −0
  31. drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h +42 −0
  32. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +796 −0
  33. drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +193 −0
  34. drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2003 −0
  35. drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +832 −0
  36. drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +955 −0
  37. drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +85 −0
  38. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +545 −0
  39. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h +48 −0
  40. drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c +245 −0
  41. drivers/gpu/drm/amd/amdgpu/amdgpu_family.h +62 −0
  42. drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +421 −0
  43. drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +1133 −0
  44. drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +371 −0
  45. drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h +72 −0
  46. drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +716 −0
  47. drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +72 −0
  48. drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +30 −0
  49. drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c +395 −0
  50. drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.h +44 −0
  51. drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +354 −0
  52. drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +216 −0
  53. drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +62 −0
  54. drivers/gpu/drm/amd/amdgpu/amdgpu_ioc32.c +47 −0
  55. drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +458 −0
  56. drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +92 −0
  57. drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +697 −0
  58. drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +322 −0
  59. drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +586 −0
  60. drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +670 −0
  61. drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +203 −0
  62. drivers/gpu/drm/amd/amdgpu/amdgpu_pll.c +350 −0
  63. drivers/gpu/drm/amd/amdgpu/amdgpu_pll.h +38 −0
  64. drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +807 −0
  65. drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h +35 −0
  66. drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +125 −0
  67. drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +561 −0
  68. drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +419 −0
  69. drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c +102 −0
  70. drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +234 −0
  71. drivers/gpu/drm/amd/amdgpu/amdgpu_test.c +552 −0
  72. drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +208 −0
  73. drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c +9 −0
  74. drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +1215 −0
  75. drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +317 −0
  76. drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +176 −0
  77. drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +984 −0
  78. drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +39 −0
  79. drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +724 −0
  80. drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +47 −0
  81. drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +1269 −0
  82. drivers/gpu/drm/amd/amdgpu/atom-bits.h +48 −0
  83. drivers/gpu/drm/amd/amdgpu/atom-names.h +100 −0
  84. drivers/gpu/drm/amd/amdgpu/atom-types.h +42 −0
  85. drivers/gpu/drm/amd/amdgpu/atom.c +1408 −0
  86. drivers/gpu/drm/amd/amdgpu/atom.h +159 −0
  87. drivers/gpu/drm/amd/amdgpu/atombios.h +8555 −0
  88. drivers/gpu/drm/amd/amdgpu/atombios_crtc.c +807 −0
  89. drivers/gpu/drm/amd/amdgpu/atombios_crtc.h +58 −0
  90. drivers/gpu/drm/amd/amdgpu/atombios_dp.c +775 −0
  91. drivers/gpu/drm/amd/amdgpu/atombios_dp.h +42 −0
  92. drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +2066 −0
  93. drivers/gpu/drm/amd/amdgpu/atombios_encoders.h +73 −0
  94. drivers/gpu/drm/amd/amdgpu/atombios_i2c.c +158 −0
  95. drivers/gpu/drm/amd/amdgpu/atombios_i2c.h +31 −0
  96. drivers/gpu/drm/amd/amdgpu/ci_dpm.c +6699 −0
  97. drivers/gpu/drm/amd/amdgpu/ci_dpm.h +348 −0
  98. drivers/gpu/drm/amd/amdgpu/ci_smc.c +279 −0
  99. drivers/gpu/drm/amd/amdgpu/cik.c +2513 −0
  100. drivers/gpu/drm/amd/amdgpu/cik.h +33 −0
  101. drivers/gpu/drm/amd/amdgpu/cik_dpm.h +30 −0
  102. drivers/gpu/drm/amd/amdgpu/cik_ih.c +471 −0
  103. drivers/gpu/drm/amd/amdgpu/cik_ih.h +29 −0
  104. drivers/gpu/drm/amd/amdgpu/cik_sdma.c +1407 −0
  105. drivers/gpu/drm/amd/amdgpu/cik_sdma.h +29 −0
  106. drivers/gpu/drm/amd/amdgpu/cikd.h +555 −0
  107. drivers/gpu/drm/amd/amdgpu/clearstate_ci.h +944 −0
  108. drivers/gpu/drm/amd/amdgpu/clearstate_defs.h +44 −0
  109. drivers/gpu/drm/amd/amdgpu/clearstate_vi.h +944 −0
  110. drivers/gpu/drm/amd/amdgpu/cz_dpm.c +1941 −0
  111. drivers/gpu/drm/amd/amdgpu/cz_dpm.h +237 −0
  112. drivers/gpu/drm/amd/amdgpu/cz_ih.c +452 −0
  113. drivers/gpu/drm/amd/amdgpu/cz_ih.h +29 −0
  114. drivers/gpu/drm/amd/amdgpu/cz_ppsmc.h +185 −0
  115. drivers/gpu/drm/amd/amdgpu/cz_smc.c +962 −0
  116. drivers/gpu/drm/amd/amdgpu/cz_smumgr.h +94 −0
  117. drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +3802 −0
  118. drivers/gpu/drm/amd/amdgpu/dce_v10_0.h +29 −0
  119. drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +3801 −0
  120. drivers/gpu/drm/amd/amdgpu/dce_v11_0.h +29 −0
  121. drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +3753 −0
  122. drivers/gpu/drm/amd/amdgpu/dce_v8_0.h +29 −0
  123. drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +5644 −0
  124. drivers/gpu/drm/amd/amdgpu/gfx_v7_0.h +37 −0
  125. drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +4329 −0
  126. drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h +33 −0
  127. drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +1339 −0
  128. drivers/gpu/drm/amd/amdgpu/gmc_v7_0.h +36 −0
  129. drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +1301 −0
  130. drivers/gpu/drm/amd/amdgpu/gmc_v8_0.h +36 −0
  131. drivers/gpu/drm/amd/amdgpu/iceland_dpm.c +195 −0
  132. drivers/gpu/drm/amd/amdgpu/iceland_ih.c +450 −0
  133. drivers/gpu/drm/amd/amdgpu/iceland_ih.h +29 −0
  134. drivers/gpu/drm/amd/amdgpu/iceland_sdma_pkt_open.h +2167 −0
  135. drivers/gpu/drm/amd/amdgpu/iceland_smc.c +675 −0
  136. drivers/gpu/drm/amd/amdgpu/iceland_smumgr.h +41 −0
  137. drivers/gpu/drm/amd/amdgpu/kv_dpm.c +3343 −0
  138. drivers/gpu/drm/amd/amdgpu/kv_dpm.h +229 −0
  139. drivers/gpu/drm/amd/amdgpu/kv_smc.c +219 −0
  140. drivers/gpu/drm/amd/amdgpu/ppsmc.h +196 −0
  141. drivers/gpu/drm/amd/amdgpu/pptable.h +698 −0
  142. drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +1417 −0
  143. drivers/gpu/drm/amd/amdgpu/sdma_v2_4.h +29 −0
  144. drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +1483 −0
  145. drivers/gpu/drm/amd/amdgpu/sdma_v3_0.h +29 −0
  146. drivers/gpu/drm/amd/amdgpu/smu7.h +170 −0
  147. drivers/gpu/drm/amd/amdgpu/smu7_discrete.h +514 −0
  148. drivers/gpu/drm/amd/amdgpu/smu7_fusion.h +300 −0
  149. drivers/gpu/drm/amd/amdgpu/smu8.h +72 −0
  150. drivers/gpu/drm/amd/amdgpu/smu8_fusion.h +127 −0
  151. drivers/gpu/drm/amd/amdgpu/smu_ucode_xfer_cz.h +147 −0
  152. drivers/gpu/drm/amd/amdgpu/smu_ucode_xfer_vi.h +100 −0
  153. drivers/gpu/drm/amd/amdgpu/tonga_dpm.c +194 −0
  154. drivers/gpu/drm/amd/amdgpu/tonga_ih.c +473 −0
  155. drivers/gpu/drm/amd/amdgpu/tonga_ih.h +29 −0
  156. drivers/gpu/drm/amd/amdgpu/tonga_ppsmc.h +198 −0
  157. drivers/gpu/drm/amd/amdgpu/tonga_sdma_pkt_open.h +2240 −0
  158. drivers/gpu/drm/amd/amdgpu/tonga_smc.c +852 −0
  159. drivers/gpu/drm/amd/amdgpu/tonga_smumgr.h +42 −0
  160. drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +905 −0
  161. drivers/gpu/drm/amd/amdgpu/uvd_v4_2.h +29 −0
  162. drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +844 −0
  163. drivers/gpu/drm/amd/amdgpu/uvd_v5_0.h +29 −0
  164. drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +824 −0
  165. drivers/gpu/drm/amd/amdgpu/uvd_v6_0.h +29 −0
  166. drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +663 −0
  167. drivers/gpu/drm/amd/amdgpu/vce_v2_0.h +29 −0
  168. drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +573 −0
  169. drivers/gpu/drm/amd/amdgpu/vce_v3_0.h +29 −0
  170. drivers/gpu/drm/amd/amdgpu/vi.c +1377 −0
  171. drivers/gpu/drm/amd/amdgpu/vi.h +33 −0
  172. drivers/gpu/drm/amd/amdgpu/vi_dpm.h +36 −0
  173. drivers/gpu/drm/amd/amdgpu/vid.h +368 −0
  174. drivers/gpu/drm/amd/amdkfd/Makefile +2 −0
  175. drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c +66 −0
  176. drivers/gpu/drm/amd/amdkfd/cik_int.h +41 −0
  177. drivers/gpu/drm/amd/amdkfd/cik_regs.h +13 −164
  178. drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +393 −2
  179. drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +886 −0
  180. drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h +193 −0
  181. drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c +168 −0
  182. drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h +294 −0
  183. drivers/gpu/drm/amd/amdkfd/kfd_device.c +59 −1
  184. drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +57 −25
  185. drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +24 −3
  186. drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c +17 −1
  187. drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c +9 −1
  188. drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c +7 −8
  189. drivers/gpu/drm/amd/amdkfd/kfd_events.c +969 −0
  190. drivers/gpu/drm/amd/amdkfd/kfd_events.h +84 −0
  191. drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +188 −0
  192. drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +3 −2
  193. drivers/gpu/drm/amd/amdkfd/kfd_module.c +7 −2
  194. drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +36 −10
  195. drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h +4 −2
  196. drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h +290 −0
  197. drivers/gpu/drm/amd/amdkfd/kfd_priv.h +95 −4
  198. drivers/gpu/drm/amd/amdkfd/kfd_process.c +47 −2
  199. drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +17 −1
  200. drivers/gpu/drm/amd/include/amd_shared.h +81 −0
  201. drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_d.h +921 −0
  202. drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_sh_mask.h +10250 −0
  203. drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_d.h +1068 −0
  204. drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_enum.h +1198 −0
  205. drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_sh_mask.h +11494 −0
  206. drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_1_d.h +3577 −0
  207. drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_1_enum.h +1068 −0
  208. drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_1_sh_mask.h +33080 −0
Documentation/DocBook/drm.tmpl+38−26
@@ -2439,6 +2439,18 @@ void intel_crt_init(struct drm_device *dev) · 2438 unmodified lines
2439 <title>Tile group</title>2439 <title>Tile group</title>
2440!Pdrivers/gpu/drm/drm_crtc.c Tile group2440!Pdrivers/gpu/drm/drm_crtc.c Tile group
2441 </sect2>2441 </sect2>
2442 <sect2>
2443 <title>Bridges</title>
2444 <sect3>
2445 <title>Overview</title>
2446!Pdrivers/gpu/drm/drm_bridge.c overview
2447 </sect3>
2448 <sect3>
2449 <title>Default bridge callback sequence</title>
2450!Pdrivers/gpu/drm/drm_bridge.c bridge callbacks
2451 </sect3>
2452!Edrivers/gpu/drm/drm_bridge.c
2453 </sect2>
2442 </sect1>2454 </sect1>
2443 2455
2444 <!-- Internals: kms properties -->2456 <!-- Internals: kms properties -->
@@ -2573,7 +2585,22 @@ void intel_crt_init(struct drm_device *dev) · 128 unmodified lines
2573 <td valign="top" >Description/Restrictions</td>2585 <td valign="top" >Description/Restrictions</td>
2574 </tr>2586 </tr>
2575 <tr>2587 <tr>
2576 <td rowspan="36" valign="top" >DRM</td>2588 <td rowspan="37" valign="top" >DRM</td>
2589 <td valign="top" >Generic</td>
2590 <td valign="top" >“rotation”</td>
2591 <td valign="top" >BITMASK</td>
2592 <td valign="top" >{ 0, "rotate-0" },
2593 { 1, "rotate-90" },
2594 { 2, "rotate-180" },
2595 { 3, "rotate-270" },
2596 { 4, "reflect-x" },
2597 { 5, "reflect-y" }</td>
2598 <td valign="top" >CRTC, Plane</td>
2599 <td valign="top" >rotate-(degrees) rotates the image by the specified amount in degrees
2600 in counter clockwise direction. reflect-x and reflect-y reflects the
2601 image along the specified axis prior to rotation</td>
2602 </tr>
2603 <tr>
2577 <td rowspan="5" valign="top" >Connector</td>2604 <td rowspan="5" valign="top" >Connector</td>
2578 <td valign="top" >“EDID”</td>2605 <td valign="top" >“EDID”</td>
2579 <td valign="top" >BLOB | IMMUTABLE</td>2606 <td valign="top" >BLOB | IMMUTABLE</td>
@@ -2834,7 +2861,7 @@ void intel_crt_init(struct drm_device *dev) · 254 unmodified lines
2834 <td valign="top" >TBD</td>2861 <td valign="top" >TBD</td>
2835 </tr>2862 </tr>
2836 <tr>2863 <tr>
2837 <td rowspan="21" valign="top" >i915</td>2864 <td rowspan="20" valign="top" >i915</td>
2838 <td rowspan="2" valign="top" >Generic</td>2865 <td rowspan="2" valign="top" >Generic</td>
2839 <td valign="top" >"Broadcast RGB"</td>2866 <td valign="top" >"Broadcast RGB"</td>
2840 <td valign="top" >ENUM</td>2867 <td valign="top" >ENUM</td>
@@ -2850,14 +2877,6 @@ void intel_crt_init(struct drm_device *dev) · 9 unmodified lines
2850 <td valign="top" >TBD</td>2877 <td valign="top" >TBD</td>
2851 </tr>2878 </tr>
2852 <tr>2879 <tr>
2853 <td rowspan="1" valign="top" >Plane</td>
2854 <td valign="top" >“rotation”</td>
2855 <td valign="top" >BITMASK</td>
2856 <td valign="top" >{ 0, "rotate-0" }, { 2, "rotate-180" }</td>
2857 <td valign="top" >Plane</td>
2858 <td valign="top" >TBD</td>
2859 </tr>
2860 <tr>
2861 <td rowspan="17" valign="top" >SDVO-TV</td>2880 <td rowspan="17" valign="top" >SDVO-TV</td>
2862 <td valign="top" >“mode”</td>2881 <td valign="top" >“mode”</td>
2863 <td valign="top" >ENUM</td>2882 <td valign="top" >ENUM</td>
@@ -3365,19 +3384,7 @@ void intel_crt_init(struct drm_device *dev) · 501 unmodified lines
3365 </tr>3384 </tr>
3366 <tr>3385 <tr>
3367 <td rowspan="2" valign="top" >omap</td>3386 <td rowspan="2" valign="top" >omap</td>
3368 <td rowspan="2" valign="top" >Generic</td>3387 <td valign="top" >Generic</td>
3369 <td valign="top" >“rotation”</td>
3370 <td valign="top" >BITMASK</td>
3371 <td valign="top" >{ 0, "rotate-0" },
3372 { 1, "rotate-90" },
3373 { 2, "rotate-180" },
3374 { 3, "rotate-270" },
3375 { 4, "reflect-x" },
3376 { 5, "reflect-y" }</td>
3377 <td valign="top" >CRTC, Plane</td>
3378 <td valign="top" >TBD</td>
3379 </tr>
3380 <tr>
3381 <td valign="top" >“zorder”</td>3388 <td valign="top" >“zorder”</td>
3382 <td valign="top" >RANGE</td>3389 <td valign="top" >RANGE</td>
3383 <td valign="top" >Min=0, Max=3</td>3390 <td valign="top" >Min=0, Max=3</td>
@@ -4067,7 +4074,7 @@ int num_ioctls;</synopsis> · 683 unmodified lines
4067 <title>DPIO</title>4074 <title>DPIO</title>
4068!Pdrivers/gpu/drm/i915/i915_reg.h DPIO4075!Pdrivers/gpu/drm/i915/i915_reg.h DPIO
4069 <table id="dpiox2">4076 <table id="dpiox2">
4070 <title>Dual channel PHY (VLV/CHV)</title>4077 <title>Dual channel PHY (VLV/CHV/BXT)</title>
4071 <tgroup cols="8">4078 <tgroup cols="8">
4072 <colspec colname="c0" />4079 <colspec colname="c0" />
4073 <colspec colname="c1" />4080 <colspec colname="c1" />
@@ -4118,7 +4125,7 @@ int num_ioctls;</synopsis> · 44 unmodified lines
4118 </tgroup>4125 </tgroup>
4119 </table>4126 </table>
4120 <table id="dpiox1">4127 <table id="dpiox1">
4121 <title>Single channel PHY (CHV)</title>4128 <title>Single channel PHY (CHV/BXT)</title>
4122 <tgroup cols="4">4129 <tgroup cols="4">
4123 <colspec colname="c0" />4130 <colspec colname="c0" />
4124 <colspec colname="c1" />4131 <colspec colname="c1" />
@@ -4153,6 +4160,12 @@ int num_ioctls;</synopsis> · 28 unmodified lines
4153 </tgroup>4160 </tgroup>
4154 </table>4161 </table>
4155 </sect2>4162 </sect2>
4163
4164 <sect2>
4165 <title>CSR firmware support for DMC</title>
4166!Pdrivers/gpu/drm/i915/intel_csr.c csr support for dmc
4167!Idrivers/gpu/drm/i915/intel_csr.c
4168 </sect2>
4156 </sect1>4169 </sect1>
4157 4170
4158 <sect1>4171 <sect1>
@@ -4204,7 +4217,6 @@ int num_ioctls;</synopsis> · 45 unmodified lines
4204!Idrivers/gpu/drm/i915/i915_gem_shrinker.c4217!Idrivers/gpu/drm/i915/i915_gem_shrinker.c
4205 </sect2>4218 </sect2>
4206 </sect1>4219 </sect1>
4207
4208 <sect1>4220 <sect1>
4209 <title> Tracing </title>4221 <title> Tracing </title>
4210 <para>4222 <para>
Documentation/devicetree/bindings/drm/msm/dsi.txt+120−0
@@ -0,0 +1,120 @@
1Qualcomm Technologies Inc. adreno/snapdragon DSI output
2
3DSI Controller:
4Required properties:
5- compatible:
6 * "qcom,mdss-dsi-ctrl"
7- reg: Physical base address and length of the registers of controller
8- reg-names: The names of register regions. The following regions are required:
9 * "dsi_ctrl"
10- qcom,dsi-host-index: The ID of DSI controller hardware instance. This should
11 be 0 or 1, since we have 2 DSI controllers at most for now.
12- interrupts: The interrupt signal from the DSI block.
13- power-domains: Should be <&mmcc MDSS_GDSC>.
14- clocks: device clocks
15 See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details.
16- clock-names: the following clocks are required:
17 * "bus_clk"
18 * "byte_clk"
19 * "core_clk"
20 * "core_mmss_clk"
21 * "iface_clk"
22 * "mdp_core_clk"
23 * "pixel_clk"
24- vdd-supply: phandle to vdd regulator device node
25- vddio-supply: phandle to vdd-io regulator device node
26- vdda-supply: phandle to vdda regulator device node
27- qcom,dsi-phy: phandle to DSI PHY device node
28
29Optional properties:
30- panel@0: Node of panel connected to this DSI controller.
31 See files in Documentation/devicetree/bindings/panel/ for each supported
32 panel.
33- qcom,dual-panel-mode: Boolean value indicating if the DSI controller is
34 driving a panel which needs 2 DSI links.
35- qcom,master-panel: Boolean value indicating if the DSI controller is driving
36 the master link of the 2-DSI panel.
37- qcom,sync-dual-panel: Boolean value indicating if the DSI controller is
38 driving a 2-DSI panel whose 2 links need receive command simultaneously.
39- interrupt-parent: phandle to the MDP block if the interrupt signal is routed
40 through MDP block
41
42DSI PHY:
43Required properties:
44- compatible: Could be the following
45 * "qcom,dsi-phy-28nm-hpm"
46 * "qcom,dsi-phy-28nm-lp"
47- reg: Physical base address and length of the registers of PLL, PHY and PHY
48 regulator
49- reg-names: The names of register regions. The following regions are required:
50 * "dsi_pll"
51 * "dsi_phy"
52 * "dsi_phy_regulator"
53- qcom,dsi-phy-index: The ID of DSI PHY hardware instance. This should
54 be 0 or 1, since we have 2 DSI PHYs at most for now.
55- power-domains: Should be <&mmcc MDSS_GDSC>.
56- clocks: device clocks
57 See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details.
58- clock-names: the following clocks are required:
59 * "iface_clk"
60- vddio-supply: phandle to vdd-io regulator device node
61
62Example:
63 mdss_dsi0: qcom,mdss_dsi@fd922800 {
64 compatible = "qcom,mdss-dsi-ctrl";
65 qcom,dsi-host-index = <0>;
66 interrupt-parent = <&mdss_mdp>;
67 interrupts = <4 0>;
68 reg-names = "dsi_ctrl";
69 reg = <0xfd922800 0x200>;
70 power-domains = <&mmcc MDSS_GDSC>;
71 clock-names =
72 "bus_clk",
73 "byte_clk",
74 "core_clk",
75 "core_mmss_clk",
76 "iface_clk",
77 "mdp_core_clk",
78 "pixel_clk";
79 clocks =
80 <&mmcc MDSS_AXI_CLK>,
81 <&mmcc MDSS_BYTE0_CLK>,
82 <&mmcc MDSS_ESC0_CLK>,
83 <&mmcc MMSS_MISC_AHB_CLK>,
84 <&mmcc MDSS_AHB_CLK>,
85 <&mmcc MDSS_MDP_CLK>,
86 <&mmcc MDSS_PCLK0_CLK>;
87 vdda-supply = <&pma8084_l2>;
88 vdd-supply = <&pma8084_l22>;
89 vddio-supply = <&pma8084_l12>;
90
91 qcom,dsi-phy = <&mdss_dsi_phy0>;
92
93 qcom,dual-panel-mode;
94 qcom,master-panel;
95 qcom,sync-dual-panel;
96
97 panel: panel@0 {
98 compatible = "sharp,lq101r1sx01";
99 reg = <0>;
100 link2 = <&secondary>;
101
102 power-supply = <...>;
103 backlight = <...>;
104 };
105 };
106
107 mdss_dsi_phy0: qcom,mdss_dsi_phy@fd922a00 {
108 compatible = "qcom,dsi-phy-28nm-hpm";
109 qcom,dsi-phy-index = <0>;
110 reg-names =
111 "dsi_pll",
112 "dsi_phy",
113 "dsi_phy_regulator";
114 reg = <0xfd922a00 0xd4>,
115 <0xfd922b00 0x2b0>,
116 <0xfd922d80 0x7b>;
117 clock-names = "iface_clk";
118 clocks = <&mmcc MDSS_AHB_CLK>;
119 vddio-supply = <&pma8084_l12>;
120 };
Documentation/devicetree/bindings/drm/msm/edp.txt+60−0
@@ -0,0 +1,60 @@
1Qualcomm Technologies Inc. adreno/snapdragon eDP output
2
3Required properties:
4- compatible:
5 * "qcom,mdss-edp"
6- reg: Physical base address and length of the registers of controller and PLL
7- reg-names: The names of register regions. The following regions are required:
8 * "edp"
9 * "pll_base"
10- interrupts: The interrupt signal from the eDP block.
11- power-domains: Should be <&mmcc MDSS_GDSC>.
12- clocks: device clocks
13 See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details.
14- clock-names: the following clocks are required:
15 * "core_clk"
16 * "iface_clk"
17 * "mdp_core_clk"
18 * "pixel_clk"
19 * "link_clk"
20- #clock-cells: The value should be 1.
21- vdda-supply: phandle to vdda regulator device node
22- lvl-vdd-supply: phandle to regulator device node which is used to supply power
23 to HPD receiving chip
24- panel-en-gpios: GPIO pin to supply power to panel.
25- panel-hpd-gpios: GPIO pin used for eDP hpd.
26
27
28Optional properties:
29- interrupt-parent: phandle to the MDP block if the interrupt signal is routed
30 through MDP block
31
32Example:
33 mdss_edp: qcom,mdss_edp@fd923400 {
34 compatible = "qcom,mdss-edp";
35 reg-names =
36 "edp",
37 "pll_base";
38 reg = <0xfd923400 0x700>,
39 <0xfd923a00 0xd4>;
40 interrupt-parent = <&mdss_mdp>;
41 interrupts = <12 0>;
42 power-domains = <&mmcc MDSS_GDSC>;
43 clock-names =
44 "core_clk",
45 "pixel_clk",
46 "iface_clk",
47 "link_clk",
48 "mdp_core_clk";
49 clocks =
50 <&mmcc MDSS_EDPAUX_CLK>,
51 <&mmcc MDSS_EDPPIXEL_CLK>,
52 <&mmcc MDSS_AHB_CLK>,
53 <&mmcc MDSS_EDPLINK_CLK>,
54 <&mmcc MDSS_MDP_CLK>;
55 #clock-cells = <1>;
56 vdda-supply = <&pma8084_l12>;
57 lvl-vdd-supply = <&lvl_vreg>;
58 panel-en-gpios = <&tlmm 137 0>;
59 panel-hpd-gpios = <&tlmm 103 0>;
60 };
Documentation/devicetree/bindings/drm/msm/hdmi.txt+6−0
@@ -20,6 +20,9 @@ Required properties: · 19 unmodified lines
20Optional properties:20Optional properties:
21- qcom,hdmi-tx-mux-en-gpio: hdmi mux enable pin21- qcom,hdmi-tx-mux-en-gpio: hdmi mux enable pin
22- qcom,hdmi-tx-mux-sel-gpio: hdmi mux select pin22- qcom,hdmi-tx-mux-sel-gpio: hdmi mux select pin
23- pinctrl-names: the pin control state names; should contain "default"
24- pinctrl-0: the default pinctrl state (active)
25- pinctrl-1: the "sleep" pinctrl state
23 26
24Example:27Example:
25 28
@@ -44,5 +47,8 @@ Example: · 18 unmodified lines
44 qcom,hdmi-tx-hpd = <&msmgpio 72 GPIO_ACTIVE_HIGH>;47 qcom,hdmi-tx-hpd = <&msmgpio 72 GPIO_ACTIVE_HIGH>;
45 core-vdda-supply = <&pm8921_hdmi_mvs>;48 core-vdda-supply = <&pm8921_hdmi_mvs>;
46 hdmi-mux-supply = <&ext_3p3v>;49 hdmi-mux-supply = <&ext_3p3v>;
50 pinctrl-names = "default", "sleep";
51 pinctrl-0 = <&hpd_active &ddc_active &cec_active>;
52 pinctrl-1 = <&hpd_suspend &ddc_suspend &cec_suspend>;
47 };53 };
48};54};
Documentation/devicetree/bindings/drm/tilcdc/slave.txt+0−18
@@ -1,18 +0,0 @@
1Device-Tree bindings for tilcdc DRM encoder slave output driver
2
3Required properties:
4 - compatible: value should be "ti,tilcdc,slave".
5 - i2c: the phandle for the i2c device the encoder slave is connected to
6
7Recommended properties:
8 - pinctrl-names, pinctrl-0: the pincontrol settings to configure
9 muxing properly for pins that connect to TFP410 device
10
11Example:
12
13 hdmi {
14 compatible = "ti,tilcdc,slave";
15 i2c = <&i2c0>;
16 pinctrl-names = "default";
17 pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
18 };
Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt+27−0
@@ -18,6 +18,12 @@ Optional properties: · 17 unmodified lines
18 - max-pixelclock: The maximum pixel clock that can be supported18 - max-pixelclock: The maximum pixel clock that can be supported
19 by the lcd controller in KHz.19 by the lcd controller in KHz.
20 20
21Optional nodes:
22
23 - port/ports: to describe a connection to an external encoder. The
24 binding follows Documentation/devicetree/bindings/graph.txt and
25 suppors a single port with a single endpoint.
26
21Example:27Example:
22 28
23 fb: fb@4830e000 {29 fb: fb@4830e000 {
@@ -26,4 +32,25 @@ Example: · 2 unmodified lines
26 interrupt-parent = <&intc>;32 interrupt-parent = <&intc>;
27 interrupts = <36>;33 interrupts = <36>;
28 ti,hwmods = "lcdc";34 ti,hwmods = "lcdc";
35
36 port {
37 lcdc_0: endpoint@0 {
38 remote-endpoint = <&hdmi_0>;
39 };
40 };
41 };
42
43 tda19988: tda19988 {
44 compatible = "nxp,tda998x";
45 reg = <0x70>;
46
47 pinctrl-names = "default", "off";
48 pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
49 pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
50
51 port {
52 hdmi_0: endpoint@0 {
53 remote-endpoint = <&lcdc_0>;
54 };
55 };
29 };56 };
Documentation/devicetree/bindings/panel/hannstar,hsd100pxn1.txt+7−0
@@ -0,0 +1,7 @@
1HannStar Display Corp. HSD100PXN1 10.1" XGA LVDS panel
2
3Required properties:
4- compatible: should be "hannstar,hsd100pxn1"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/lg,lb070wv8.txt+7−0
@@ -0,0 +1,7 @@
1LG 7" (800x480 pixels) TFT LCD panel
2
3Required properties:
4- compatible: should be "lg,lb070wv8"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
Documentation/devicetree/bindings/video/exynos-mic.txt+51−0
@@ -0,0 +1,51 @@
1Device-Tree bindings for Samsung Exynos SoC mobile image compressor (MIC)
2
3MIC (mobile image compressor) resides between decon and mipi dsi. Mipi dsi is
4not capable to transfer high resoltuion frame data as decon can send. MIC
5solves this problem by compressing the frame data by 1/2 before it is
6transferred through mipi dsi. The compressed frame data must be uncompressed in
7the panel PCB.
8
9Required properties:
10- compatible: value should be "samsung,exynos5433-mic".
11- reg: physical base address and length of the MIC registers set and system
12 register of mic.
13- clocks: must include clock specifiers corresponding to entries in the
14 clock-names property.
15- clock-names: list of clock names sorted in the same order as the clocks
16 property. Must contain "pclk_mic0", "sclk_rgb_vclk_to_mic0".
17- samsung,disp-syscon: the reference node for syscon for DISP block.
18- ports: contains a port which is connected to decon node and dsi node.
19 address-cells and size-cells must 1 and 0, respectively.
20- port: contains an endpoint node which is connected to the endpoint in the
21 decon node or dsi node. The reg value must be 0 and 1 respectively.
22
23Example:
24SoC specific DT entry:
25mic: mic@13930000 {
26 compatible = "samsung,exynos5433-mic";
27 reg = <0x13930000 0x48>;
28 clocks = <&cmu_disp CLK_PCLK_MIC0>,
29 <&cmu_disp CLK_SCLK_RGB_VCLK_TO_MIC0>;
30 clock-names = "pclk_mic0", "sclk_rgb_vclk_to_mic0";
31 samsung,disp-syscon = <&syscon_disp>;
32
33 ports {
34 #address-cells = <1>;
35 #size-cells = <0>;
36
37 port@0 {
38 reg = <0>;
39 mic_to_decon: endpoint {
40 remote-endpoint = <&decon_to_mic>;
41 };
42 };
43
44 port@1 {
45 reg = <1>;
46 mic_to_dsi: endpoint {
47 remote-endpoint = <&dsi_to_mic>;
48 };
49 };
50 };
51};
Documentation/devicetree/bindings/video/exynos5433-decon.txt+65−0
@@ -0,0 +1,65 @@
1Device-Tree bindings for Samsung Exynos SoC display controller (DECON)
2
3DECON (Display and Enhancement Controller) is the Display Controller for the
4Exynos series 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 "samsung,exynos5433-decon";
9- reg: physical base address and length of the DECON registers set.
10- interrupts: should contain a list of all DECON IP block interrupts in the
11 order: VSYNC, LCD_SYSTEM. The interrupt specifier format
12 depends on the interrupt controller used.
13- interrupt-names: should contain the interrupt names: "vsync", "lcd_sys"
14 in the same order as they were listed in the interrupts
15 property.
16- clocks: must include clock specifiers corresponding to entries in the
17 clock-names property.
18- clock-names: list of clock names sorted in the same order as the clocks
19 property. Must contain "aclk_decon", "aclk_smmu_decon0x",
20 "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk",
21 "sclk_decon_eclk"
22- ports: contains a port which is connected to mic node. address-cells and
23 size-cells must 1 and 0, respectively.
24- port: contains an endpoint node which is connected to the endpoint in the mic
25 node. The reg value muset be 0.
26- i80-if-timings: specify whether the panel which is connected to decon uses
27 i80 lcd interface or mipi video interface. This node contains
28 no timing information as that of fimd does. Because there is
29 no register in decon to specify i80 interface timing value,
30 it is not needed, but make it remain to use same kind of node
31 in fimd and exynos7 decon.
32
33Example:
34SoC specific DT entry:
35decon: decon@13800000 {
36 compatible = "samsung,exynos5433-decon";
37 reg = <0x13800000 0x2104>;
38 clocks = <&cmu_disp CLK_ACLK_DECON>, <&cmu_disp CLK_ACLK_SMMU_DECON0X>,
39 <&cmu_disp CLK_ACLK_XIU_DECON0X>,
40 <&cmu_disp CLK_PCLK_SMMU_DECON0X>,
41 <&cmu_disp CLK_SCLK_DECON_VCLK>,
42 <&cmu_disp CLK_SCLK_DECON_ECLK>;
43 clock-names = "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x",
44 "pclk_smmu_decon0x", "sclk_decon_vclk", "sclk_decon_eclk";
45 interrupt-names = "vsync", "lcd_sys";
46 interrupts = <0 202 0>, <0 203 0>;
47
48 ports {
49 #address-cells = <1>;
50 #size-cells = <0>;
51
52 port@0 {
53 reg = <0>;
54 decon_to_mic: endpoint {
55 remote-endpoint = <&mic_to_decon>;
56 };
57 };
58 };
59};
60
61Board specific DT entry:
62&decon {
63 i80-if-timings {
64 };
65};
Documentation/devicetree/bindings/video/exynos_dsim.txt+25−6
@@ -6,17 +6,19 @@ Required properties: · 5 unmodified lines
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,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
8 "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */8 "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
9 "samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
9 - reg: physical base address and length of the registers set for the device10 - reg: physical base address and length of the registers set for the device
10 - interrupts: should contain DSI interrupt11 - interrupts: should contain DSI interrupt
11 - clocks: list of clock specifiers, must contain an entry for each required12 - clocks: list of clock specifiers, must contain an entry for each required
12 entry in clock-names13 entry in clock-names
13 - clock-names: should include "bus_clk"and "pll_clk" entries14 - clock-names: should include "bus_clk"and "sclk_mipi" entries
15 the use of "pll_clk" is deprecated
14 - phys: list of phy specifiers, must contain an entry for each required16 - phys: list of phy specifiers, must contain an entry for each required
15 entry in phy-names17 entry in phy-names
16 - phy-names: should include "dsim" entry18 - phy-names: should include "dsim" entry
17 - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)19 - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)
18 - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)20 - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
19 - samsung,pll-clock-frequency: specifies frequency of the "pll_clk" clock21 - samsung,pll-clock-frequency: specifies frequency of the oscillator clock
20 - #address-cells, #size-cells: should be set respectively to <1> and <0>22 - #address-cells, #size-cells: should be set respectively to <1> and <0>
21 according to DSI host bindings (see MIPI DSI bindings [1])23 according to DSI host bindings (see MIPI DSI bindings [1])
22 24
@@ -30,10 +32,19 @@ Video interfaces: · 7 unmodified lines
30 Device node can contain video interface port nodes according to [2].32 Device node can contain video interface port nodes according to [2].
31 The following are properties specific to those nodes:33 The following are properties specific to those nodes:
32 34
33 port node:35 port node inbound:
34 - reg: (required) can be 0 for input RGB/I80 port or 1 for DSI port;36 - reg: (required) must be 0.
37 port node outbound:
38 - reg: (required) must be 1.
35 39
36 endpoint node of DSI port (reg = 1):40 endpoint node connected from mic node (reg = 0):
41 - remote-endpoint: specifies the endpoint in mic node. This node is required
42 for Exynos5433 mipi dsi. So mic can access to panel node
43 thoughout this dsi node.
44 endpoint node connected to panel node (reg = 1):
45 - remote-endpoint: specifies the endpoint in panel node. This node is
46 required in all kinds of exynos mipi dsi to represent
47 the connection between mipi dsi and panel.
37 - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst48 - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
38 mode49 mode
39 - samsung,esc-clock-frequency: specifies DSI frequency in escape mode50 - samsung,esc-clock-frequency: specifies DSI frequency in escape mode
@@ -48,7 +59,7 @@ Example: · 8 unmodified lines
48 reg = <0x11C80000 0x10000>;59 reg = <0x11C80000 0x10000>;
49 interrupts = <0 79 0>;60 interrupts = <0 79 0>;
50 clocks = <&clock 286>, <&clock 143>;61 clocks = <&clock 286>, <&clock 143>;
51 clock-names = "bus_clk", "pll_clk";62 clock-names = "bus_clk", "sclk_mipi";
52 phys = <&mipi_phy 1>;63 phys = <&mipi_phy 1>;
53 phy-names = "dsim";64 phy-names = "dsim";
54 vddcore-supply = <&vusb_reg>;65 vddcore-supply = <&vusb_reg>;
@@ -72,7 +83,15 @@ Example: · 17 unmodified lines
72 #address-cells = <1>;83 #address-cells = <1>;
73 #size-cells = <0>;84 #size-cells = <0>;
74 85
86 port@0 {
87 reg = <0>;
88 decon_to_mic: endpoint {
89 remote-endpoint = <&mic_to_decon>;
90 };
91 };
92
75 port@1 {93 port@1 {
94 reg = <1>;
76 dsi_ep: endpoint {95 dsi_ep: endpoint {
77 reg = <0>;96 reg = <0>;
78 samsung,burst-clock-frequency = <500000000>;97 samsung,burst-clock-frequency = <500000000>;
MAINTAINERS+10−1
@@ -632,7 +632,7 @@ F: drivers/iommu/amd_iommu*.[ch] · 631 unmodified lines
632F: include/linux/amd-iommu.h632F: include/linux/amd-iommu.h
633 633
634AMD KFD634AMD KFD
635M: Oded Gabbay <oded.gabbay@amd.com>635M: Oded Gabbay <oded.gabbay@gmail.com>
636L: dri-devel@lists.freedesktop.org636L: dri-devel@lists.freedesktop.org
637T: git git://people.freedesktop.org/~gabbayo/linux.git637T: git git://people.freedesktop.org/~gabbayo/linux.git
638S: Supported638S: Supported
@@ -10777,6 +10777,15 @@ F: drivers/block/virtio_blk.c · 10138 unmodified lines
10777F: include/linux/virtio_*.h10777F: include/linux/virtio_*.h
10778F: include/uapi/linux/virtio_*.h10778F: include/uapi/linux/virtio_*.h
10779 10779
10780VIRTIO GPU DRIVER
10781M: David Airlie <airlied@linux.ie>
10782M: Gerd Hoffmann <kraxel@redhat.com>
10783L: dri-devel@lists.freedesktop.org
10784L: virtualization@lists.linux-foundation.org
10785S: Maintained
10786F: drivers/gpu/drm/virtio/
10787F: include/uapi/linux/virtio_gpu.h
10788
10780VIRTIO HOST (VHOST)10789VIRTIO HOST (VHOST)
10781M: "Michael S. Tsirkin" <mst@redhat.com>10790M: "Michael S. Tsirkin" <mst@redhat.com>
10782L: kvm@vger.kernel.org10791L: kvm@vger.kernel.org
arch/arm/boot/dts/exynos4.dtsi+1−1
@@ -166,7 +166,7 @@ · 165 unmodified lines
166 phys = <&mipi_phy 1>;166 phys = <&mipi_phy 1>;
167 phy-names = "dsim";167 phy-names = "dsim";
168 clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;168 clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
169 clock-names = "bus_clk", "pll_clk";169 clock-names = "bus_clk", "sclk_mipi";
170 status = "disabled";170 status = "disabled";
171 #address-cells = <1>;171 #address-cells = <1>;
172 #size-cells = <0>;172 #size-cells = <0>;
arch/x86/kernel/early-quirks.c+1−0
@@ -546,6 +546,7 @@ static const struct pci_device_id intel_stolen_ids[] __initconst = { · 545 unmodified lines
546 INTEL_BDW_D_IDS(&gen8_stolen_funcs),546 INTEL_BDW_D_IDS(&gen8_stolen_funcs),
547 INTEL_CHV_IDS(&chv_stolen_funcs),547 INTEL_CHV_IDS(&chv_stolen_funcs),
548 INTEL_SKL_IDS(&gen9_stolen_funcs),548 INTEL_SKL_IDS(&gen9_stolen_funcs),
549 INTEL_BXT_IDS(&gen9_stolen_funcs),
549};550};
550 551
551static void __init intel_graphics_stolen(int num, int slot, int func)552static void __init intel_graphics_stolen(int num, int slot, int func)
drivers/gpu/drm/Kconfig+23−0
@@ -120,6 +120,27 @@ config DRM_RADEON · 119 unmodified lines
120 120
121source "drivers/gpu/drm/radeon/Kconfig"121source "drivers/gpu/drm/radeon/Kconfig"
122 122
123config DRM_AMDGPU
124 tristate "AMD GPU"
125 depends on DRM && PCI
126 select FB_CFB_FILLRECT
127 select FB_CFB_COPYAREA
128 select FB_CFB_IMAGEBLIT
129 select FW_LOADER
130 select DRM_KMS_HELPER
131 select DRM_KMS_FB_HELPER
132 select DRM_TTM
133 select POWER_SUPPLY
134 select HWMON
135 select BACKLIGHT_CLASS_DEVICE
136 select INTERVAL_TREE
137 help
138 Choose this option if you have a recent AMD Radeon graphics card.
139
140 If M is selected, the module will be called amdgpu.
141
142source "drivers/gpu/drm/amd/amdgpu/Kconfig"
143
123source "drivers/gpu/drm/nouveau/Kconfig"144source "drivers/gpu/drm/nouveau/Kconfig"
124 145
125config DRM_I810146config DRM_I810
@@ -206,6 +227,8 @@ source "drivers/gpu/drm/qxl/Kconfig" · 80 unmodified lines
206 227
207source "drivers/gpu/drm/bochs/Kconfig"228source "drivers/gpu/drm/bochs/Kconfig"
208 229
230source "drivers/gpu/drm/virtio/Kconfig"
231
209source "drivers/gpu/drm/msm/Kconfig"232source "drivers/gpu/drm/msm/Kconfig"
210 233
211source "drivers/gpu/drm/tegra/Kconfig"234source "drivers/gpu/drm/tegra/Kconfig"
drivers/gpu/drm/Makefile+3−3
@@ -2,8 +2,6 @@ · 1 unmodified line
2# Makefile for the drm device driver. This driver provides support for the2# Makefile for the drm device driver. This driver provides support for the
3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4 4
5ccflags-y := -Iinclude/drm
6
7drm-y := drm_auth.o drm_bufs.o drm_cache.o \5drm-y := drm_auth.o drm_bufs.o drm_cache.o \
8 drm_context.o drm_dma.o \6 drm_context.o drm_dma.o \
9 drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \7 drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
@@ -39,6 +37,7 @@ obj-$(CONFIG_DRM_TDFX) += tdfx/ · 29 unmodified lines
39obj-$(CONFIG_DRM_R128) += r128/37obj-$(CONFIG_DRM_R128) += r128/
40obj-$(CONFIG_HSA_AMD) += amd/amdkfd/38obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
41obj-$(CONFIG_DRM_RADEON)+= radeon/39obj-$(CONFIG_DRM_RADEON)+= radeon/
40obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/
42obj-$(CONFIG_DRM_MGA) += mga/41obj-$(CONFIG_DRM_MGA) += mga/
43obj-$(CONFIG_DRM_I810) += i810/42obj-$(CONFIG_DRM_I810) += i810/
44obj-$(CONFIG_DRM_I915) += i915/43obj-$(CONFIG_DRM_I915) += i915/
@@ -60,9 +59,10 @@ obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/ · 15 unmodified lines
60obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/59obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
61obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/60obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
62obj-$(CONFIG_DRM_OMAP) += omapdrm/61obj-$(CONFIG_DRM_OMAP) += omapdrm/
63obj-$(CONFIG_DRM_TILCDC) += tilcdc/62obj-y += tilcdc/
64obj-$(CONFIG_DRM_QXL) += qxl/63obj-$(CONFIG_DRM_QXL) += qxl/
65obj-$(CONFIG_DRM_BOCHS) += bochs/64obj-$(CONFIG_DRM_BOCHS) += bochs/
65obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/
66obj-$(CONFIG_DRM_MSM) += msm/66obj-$(CONFIG_DRM_MSM) += msm/
67obj-$(CONFIG_DRM_TEGRA) += tegra/67obj-$(CONFIG_DRM_TEGRA) += tegra/
68obj-$(CONFIG_DRM_STI) += sti/68obj-$(CONFIG_DRM_STI) += sti/
drivers/gpu/drm/amd/amdgpu/Kconfig+17−0
@@ -0,0 +1,17 @@
1config DRM_AMDGPU_CIK
2 bool "Enable amdgpu support for CIK parts"
3 depends on DRM_AMDGPU
4 help
5 Choose this option if you want to enable experimental support
6 for CIK asics.
7
8 CIK is already supported in radeon. CIK support in amdgpu
9 is for experimentation and testing.
10
11config DRM_AMDGPU_USERPTR
12 bool "Always enable userptr write support"
13 depends on DRM_AMDGPU
14 select MMU_NOTIFIER
15 help
16 This option selects CONFIG_MMU_NOTIFIER if it isn't already
17 selected to enabled full userptr support.
drivers/gpu/drm/amd/amdgpu/Makefile+81−0
@@ -0,0 +1,81 @@
1#
2# Makefile for the drm device driver. This driver provides support for the
3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4
5ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/asic_reg \
6 -Idrivers/gpu/drm/amd/include
7
8amdgpu-y := amdgpu_drv.o
9
10# add KMS driver
11amdgpu-y += amdgpu_device.o amdgpu_kms.o \
12 amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
13 atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
14 amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
15 amdgpu_fb.o amdgpu_gem.o amdgpu_ring.o \
16 amdgpu_cs.o amdgpu_bios.o amdgpu_benchmark.o amdgpu_test.o \
17 amdgpu_pm.o atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \
18 atombios_encoders.o amdgpu_semaphore.o amdgpu_sa.o atombios_i2c.o \
19 amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
20 amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o
21
22# add asic specific block
23amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o gmc_v7_0.o cik_ih.o kv_smc.o kv_dpm.o \
24 ci_smc.o ci_dpm.o dce_v8_0.o gfx_v7_0.o cik_sdma.o uvd_v4_2.o vce_v2_0.o
25
26amdgpu-y += \
27 vi.o
28
29# add GMC block
30amdgpu-y += \
31 gmc_v8_0.o
32
33# add IH block
34amdgpu-y += \
35 amdgpu_irq.o \
36 amdgpu_ih.o \
37 iceland_ih.o \
38 tonga_ih.o \
39 cz_ih.o
40
41# add SMC block
42amdgpu-y += \
43 amdgpu_dpm.o \
44 cz_smc.o cz_dpm.o \
45 tonga_smc.o tonga_dpm.o \
46 iceland_smc.o iceland_dpm.o
47
48# add DCE block
49amdgpu-y += \
50 dce_v10_0.o \
51 dce_v11_0.o
52
53# add GFX block
54amdgpu-y += \
55 amdgpu_gfx.o \
56 gfx_v8_0.o
57
58# add async DMA block
59amdgpu-y += \
60 sdma_v2_4.o \
61 sdma_v3_0.o
62
63# add UVD block
64amdgpu-y += \
65 amdgpu_uvd.o \
66 uvd_v5_0.o \
67 uvd_v6_0.o
68
69# add VCE block
70amdgpu-y += \
71 amdgpu_vce.o \
72 vce_v3_0.o
73
74amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
75amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
76amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
77amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o
78
79obj-$(CONFIG_DRM_AMDGPU)+= amdgpu.o
80
81CFLAGS_amdgpu_trace_points.o := -I$(src)
drivers/gpu/drm/amd/amdgpu/ObjectID.h+736−0
@@ -0,0 +1,736 @@
1/*
2* Copyright 2006-2007 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/* based on stg/asic_reg/drivers/inc/asic_reg/ObjectID.h ver 23 */
23
24#ifndef _OBJECTID_H
25#define _OBJECTID_H
26
27#if defined(_X86_)
28#pragma pack(1)
29#endif
30
31/****************************************************/
32/* Graphics Object Type Definition */
33/****************************************************/
34#define GRAPH_OBJECT_TYPE_NONE 0x0
35#define GRAPH_OBJECT_TYPE_GPU 0x1
36#define GRAPH_OBJECT_TYPE_ENCODER 0x2
37#define GRAPH_OBJECT_TYPE_CONNECTOR 0x3
38#define GRAPH_OBJECT_TYPE_ROUTER 0x4
39/* deleted */
40#define GRAPH_OBJECT_TYPE_DISPLAY_PATH 0x6
41#define GRAPH_OBJECT_TYPE_GENERIC 0x7
42
43/****************************************************/
44/* Encoder Object ID Definition */
45/****************************************************/
46#define ENCODER_OBJECT_ID_NONE 0x00
47
48/* Radeon Class Display Hardware */
49#define ENCODER_OBJECT_ID_INTERNAL_LVDS 0x01
50#define ENCODER_OBJECT_ID_INTERNAL_TMDS1 0x02
51#define ENCODER_OBJECT_ID_INTERNAL_TMDS2 0x03
52#define ENCODER_OBJECT_ID_INTERNAL_DAC1 0x04
53#define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */
54#define ENCODER_OBJECT_ID_INTERNAL_SDVOA 0x06
55#define ENCODER_OBJECT_ID_INTERNAL_SDVOB 0x07
56
57/* External Third Party Encoders */
58#define ENCODER_OBJECT_ID_SI170B 0x08
59#define ENCODER_OBJECT_ID_CH7303 0x09
60#define ENCODER_OBJECT_ID_CH7301 0x0A
61#define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */
62#define ENCODER_OBJECT_ID_EXTERNAL_SDVOA 0x0C
63#define ENCODER_OBJECT_ID_EXTERNAL_SDVOB 0x0D
64#define ENCODER_OBJECT_ID_TITFP513 0x0E
65#define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */
66#define ENCODER_OBJECT_ID_VT1623 0x10
67#define ENCODER_OBJECT_ID_HDMI_SI1930 0x11
68#define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12
69#define ENCODER_OBJECT_ID_ALMOND 0x22
70#define ENCODER_OBJECT_ID_TRAVIS 0x23
71#define ENCODER_OBJECT_ID_NUTMEG 0x22
72#define ENCODER_OBJECT_ID_HDMI_ANX9805 0x26
73
74/* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */
75#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13
76#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14
77#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 0x15
78#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */
79#define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */
80#define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */
81#define ENCODER_OBJECT_ID_INTERNAL_DDI 0x19
82#define ENCODER_OBJECT_ID_VT1625 0x1A
83#define ENCODER_OBJECT_ID_HDMI_SI1932 0x1B
84#define ENCODER_OBJECT_ID_DP_AN9801 0x1C
85#define ENCODER_OBJECT_ID_DP_DP501 0x1D
86#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY 0x1E
87#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA 0x1F
88#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 0x20
89#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 0x21
90#define ENCODER_OBJECT_ID_INTERNAL_VCE 0x24
91#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 0x25
92#define ENCODER_OBJECT_ID_INTERNAL_AMCLK 0x27
93
94#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF
95
96/****************************************************/
97/* Connector Object ID Definition */
98/****************************************************/
99#define CONNECTOR_OBJECT_ID_NONE 0x00
100#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I 0x01
101#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I 0x02
102#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D 0x03
103#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D 0x04
104#define CONNECTOR_OBJECT_ID_VGA 0x05
105#define CONNECTOR_OBJECT_ID_COMPOSITE 0x06
106#define CONNECTOR_OBJECT_ID_SVIDEO 0x07
107#define CONNECTOR_OBJECT_ID_YPbPr 0x08
108#define CONNECTOR_OBJECT_ID_D_CONNECTOR 0x09
109#define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */
110#define CONNECTOR_OBJECT_ID_SCART 0x0B
111#define CONNECTOR_OBJECT_ID_HDMI_TYPE_A 0x0C
112#define CONNECTOR_OBJECT_ID_HDMI_TYPE_B 0x0D
113#define CONNECTOR_OBJECT_ID_LVDS 0x0E
114#define CONNECTOR_OBJECT_ID_7PIN_DIN 0x0F
115#define CONNECTOR_OBJECT_ID_PCIE_CONNECTOR 0x10
116#define CONNECTOR_OBJECT_ID_CROSSFIRE 0x11
117#define CONNECTOR_OBJECT_ID_HARDCODE_DVI 0x12
118#define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13
119#define CONNECTOR_OBJECT_ID_eDP 0x14
120#define CONNECTOR_OBJECT_ID_MXM 0x15
121#define CONNECTOR_OBJECT_ID_LVDS_eDP 0x16
122
123/* deleted */
124
125/****************************************************/
126/* Router Object ID Definition */
127/****************************************************/
128#define ROUTER_OBJECT_ID_NONE 0x00
129#define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01
130
131/****************************************************/
132/* Generic Object ID Definition */
133/****************************************************/
134#define GENERIC_OBJECT_ID_NONE 0x00
135#define GENERIC_OBJECT_ID_GLSYNC 0x01
136#define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02
137#define GENERIC_OBJECT_ID_MXM_OPM 0x03
138#define GENERIC_OBJECT_ID_STEREO_PIN 0x04 //This object could show up from Misc Object table, it follows ATOM_OBJECT format, and contains one ATOM_OBJECT_GPIO_CNTL_RECORD for the stereo pin
139
140/****************************************************/
141/* Graphics Object ENUM ID Definition */
142/****************************************************/
143#define GRAPH_OBJECT_ENUM_ID1 0x01
144#define GRAPH_OBJECT_ENUM_ID2 0x02
145#define GRAPH_OBJECT_ENUM_ID3 0x03
146#define GRAPH_OBJECT_ENUM_ID4 0x04
147#define GRAPH_OBJECT_ENUM_ID5 0x05
148#define GRAPH_OBJECT_ENUM_ID6 0x06
149#define GRAPH_OBJECT_ENUM_ID7 0x07
150
151/****************************************************/
152/* Graphics Object ID Bit definition */
153/****************************************************/
154#define OBJECT_ID_MASK 0x00FF
155#define ENUM_ID_MASK 0x0700
156#define RESERVED1_ID_MASK 0x0800
157#define OBJECT_TYPE_MASK 0x7000
158#define RESERVED2_ID_MASK 0x8000
159
160#define OBJECT_ID_SHIFT 0x00
161#define ENUM_ID_SHIFT 0x08
162#define OBJECT_TYPE_SHIFT 0x0C
163
164
165/****************************************************/
166/* Graphics Object family definition */
167/****************************************************/
168#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \
169 GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT)
170/****************************************************/
171/* GPU Object ID definition - Shared with BIOS */
172/****************************************************/
173#define GPU_ENUM_ID1 ( GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\
174 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT)
175
176/****************************************************/
177/* Encoder Object ID definition - Shared with BIOS */
178/****************************************************/
179/*
180#define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101
181#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 0x2102
182#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 0x2103
183#define ENCODER_INTERNAL_DAC1_ENUM_ID1 0x2104
184#define ENCODER_INTERNAL_DAC2_ENUM_ID1 0x2105
185#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 0x2106
186#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 0x2107
187#define ENCODER_SIL170B_ENUM_ID1 0x2108
188#define ENCODER_CH7303_ENUM_ID1 0x2109
189#define ENCODER_CH7301_ENUM_ID1 0x210A
190#define ENCODER_INTERNAL_DVO1_ENUM_ID1 0x210B
191#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 0x210C
192#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 0x210D
193#define ENCODER_TITFP513_ENUM_ID1 0x210E
194#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 0x210F
195#define ENCODER_VT1623_ENUM_ID1 0x2110
196#define ENCODER_HDMI_SI1930_ENUM_ID1 0x2111
197#define ENCODER_HDMI_INTERNAL_ENUM_ID1 0x2112
198#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 0x2113
199#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 0x2114
200#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 0x2115
201#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116
202#define ENCODER_SI178_ENUM_ID1 0x2117
203#define ENCODER_MVPU_FPGA_ENUM_ID1 0x2118
204#define ENCODER_INTERNAL_DDI_ENUM_ID1 0x2119
205#define ENCODER_VT1625_ENUM_ID1 0x211A
206#define ENCODER_HDMI_SI1932_ENUM_ID1 0x211B
207#define ENCODER_ENCODER_DP_AN9801_ENUM_ID1 0x211C
208#define ENCODER_DP_DP501_ENUM_ID1 0x211D
209#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 0x211E
210*/
211#define ENCODER_INTERNAL_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
212 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
213 ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT)
214
215#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
216 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
217 ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT)
218
219#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
220 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
221 ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT)
222
223#define ENCODER_INTERNAL_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
224 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
225 ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT)
226
227#define ENCODER_INTERNAL_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
228 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
229 ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT)
230
231#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
232 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
233 ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
234
235#define ENCODER_INTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
236 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
237 ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
238
239#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
240 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
241 ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT)
242
243#define ENCODER_SIL170B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
244 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
245 ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT)
246
247#define ENCODER_CH7303_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
248 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
249 ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT)
250
251#define ENCODER_CH7301_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
252 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
253 ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT)
254
255#define ENCODER_INTERNAL_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
256 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
257 ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT)
258
259#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
260 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
261 ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
262
263#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
264 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
265 ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
266
267
268#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
269 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
270 ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT)
271
272
273#define ENCODER_TITFP513_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
274 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
275 ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT)
276
277#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
278 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
279 ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT)
280
281#define ENCODER_VT1623_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
282 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
283 ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT)
284
285#define ENCODER_HDMI_SI1930_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
286 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
287 ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT)
288
289#define ENCODER_HDMI_INTERNAL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
290 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
291 ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT)
292
293#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
294 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
295 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
296
297
298#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
299 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
300 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
301
302
303#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
304 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
305 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT)
306
307#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
308 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
309 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT)
310
311#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
312 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
313 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) // Shared with CV/TV and CRT
314
315#define ENCODER_SI178_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
316 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
317 ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT)
318
319#define ENCODER_MVPU_FPGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
320 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
321 ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT)
322
323#define ENCODER_INTERNAL_DDI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
324 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
325 ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT)
326
327#define ENCODER_VT1625_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
328 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
329 ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT)
330
331#define ENCODER_HDMI_SI1932_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
332 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
333 ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT)
334
335#define ENCODER_DP_DP501_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
336 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
337 ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT)
338
339#define ENCODER_DP_AN9801_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
340 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
341 ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT)
342
343#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
344 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
345 ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
346
347#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
348 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
349 ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
350
351#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
352 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
353 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT)
354
355#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
356 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
357 ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT)
358
359#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
360 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
361 ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT)
362
363#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
364 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
365 ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
366
367#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
368 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
369 ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
370
371#define ENCODER_INTERNAL_UNIPHY3_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
372 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
373 ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 << OBJECT_ID_SHIFT)
374
375#define ENCODER_INTERNAL_UNIPHY3_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
376 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
377 ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 << OBJECT_ID_SHIFT)
378
379#define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
380 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
381 ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT)
382
383#define ENCODER_ALMOND_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
384 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
385 ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT)
386
387#define ENCODER_ALMOND_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
388 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
389 ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT)
390
391#define ENCODER_TRAVIS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
392 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
393 ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT)
394
395#define ENCODER_TRAVIS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
396 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
397 ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT)
398
399#define ENCODER_NUTMEG_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
400 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
401 ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT)
402
403#define ENCODER_VCE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
404 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
405 ENCODER_OBJECT_ID_INTERNAL_VCE << OBJECT_ID_SHIFT)
406
407#define ENCODER_HDMI_ANX9805_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
408 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
409 ENCODER_OBJECT_ID_HDMI_ANX9805 << OBJECT_ID_SHIFT)
410
411/****************************************************/
412/* Connector Object ID definition - Shared with BIOS */
413/****************************************************/
414/*
415#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 0x3101
416#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 0x3102
417#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 0x3103
418#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 0x3104
419#define CONNECTOR_VGA_ENUM_ID1 0x3105
420#define CONNECTOR_COMPOSITE_ENUM_ID1 0x3106
421#define CONNECTOR_SVIDEO_ENUM_ID1 0x3107
422#define CONNECTOR_YPbPr_ENUM_ID1 0x3108
423#define CONNECTOR_D_CONNECTORE_ENUM_ID1 0x3109
424#define CONNECTOR_9PIN_DIN_ENUM_ID1 0x310A
425#define CONNECTOR_SCART_ENUM_ID1 0x310B
426#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 0x310C
427#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 0x310D
428#define CONNECTOR_LVDS_ENUM_ID1 0x310E
429#define CONNECTOR_7PIN_DIN_ENUM_ID1 0x310F
430#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 0x3110
431*/
432#define CONNECTOR_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
433 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
434 CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT)
435
436#define CONNECTOR_LVDS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
437 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
438 CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT)
439
440#define CONNECTOR_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
441 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
442 CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT)
443
444#define CONNECTOR_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
445 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
446 CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT)
447
448#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
449 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
450 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
451
452#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
453 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
454 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
455
456#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
457 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
458 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
459
460#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
461 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
462 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
463
464#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
465 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
466 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
467
468#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
469 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
470 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
471
472#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
473 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
474 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
475
476#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
477 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
478 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
479
480#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
481 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
482 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
483
484#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
485 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
486 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
487
488#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
489 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
490 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
491
492#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
493 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
494 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
495
496#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
497 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
498 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
499
500#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
501 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
502 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
503
504#define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
505 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
506 CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
507
508#define CONNECTOR_VGA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
509 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
510 CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
511
512#define CONNECTOR_COMPOSITE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
513 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
514 CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT)
515
516#define CONNECTOR_COMPOSITE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
517 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
518 CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT)
519
520#define CONNECTOR_SVIDEO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
521 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
522 CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT)
523
524#define CONNECTOR_SVIDEO_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
525 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
526 CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT)
527
528#define CONNECTOR_YPbPr_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
529 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
530 CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT)
531
532#define CONNECTOR_YPbPr_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
533 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
534 CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT)
535
536#define CONNECTOR_D_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
537 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
538 CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT)
539
540#define CONNECTOR_D_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
541 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
542 CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT)
543
544#define CONNECTOR_9PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
545 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
546 CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT)
547
548#define CONNECTOR_9PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
549 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
550 CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT)
551
552#define CONNECTOR_SCART_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
553 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
554 CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT)
555
556#define CONNECTOR_SCART_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
557 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
558 CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT)
559
560#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
561 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
562 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
563
564#define CONNECTOR_HDMI_TYPE_A_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
565 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
566 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
567
568#define CONNECTOR_HDMI_TYPE_A_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
569 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
570 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
571
572#define CONNECTOR_HDMI_TYPE_A_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
573 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
574 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
575
576#define CONNECTOR_HDMI_TYPE_A_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
577 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
578 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
579
580#define CONNECTOR_HDMI_TYPE_A_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
581 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
582 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
583
584#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
585 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
586 CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
587
588#define CONNECTOR_HDMI_TYPE_B_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
589 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
590 CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
591
592#define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
593 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
594 CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
595
596#define CONNECTOR_7PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
597 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
598 CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
599
600#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
601 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
602 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
603
604#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
605 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
606 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
607
608#define CONNECTOR_CROSSFIRE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
609 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
610 CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
611
612#define CONNECTOR_CROSSFIRE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
613 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
614 CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
615
616
617#define CONNECTOR_HARDCODE_DVI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
618 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
619 CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
620
621#define CONNECTOR_HARDCODE_DVI_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
622 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
623 CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
624
625#define CONNECTOR_DISPLAYPORT_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
626 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
627 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
628
629#define CONNECTOR_DISPLAYPORT_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
630 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
631 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
632
633#define CONNECTOR_DISPLAYPORT_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
634 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
635 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
636
637#define CONNECTOR_DISPLAYPORT_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
638 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
639 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
640
641#define CONNECTOR_DISPLAYPORT_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
642 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
643 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
644
645#define CONNECTOR_DISPLAYPORT_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
646 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
647 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
648
649#define CONNECTOR_MXM_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
650 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
651 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_A
652
653#define CONNECTOR_MXM_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
654 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
655 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_B
656
657#define CONNECTOR_MXM_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
658 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
659 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_C
660
661#define CONNECTOR_MXM_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
662 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
663 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_D
664
665#define CONNECTOR_MXM_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
666 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
667 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_LVDS_TXxx
668
669#define CONNECTOR_MXM_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
670 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
671 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_LVDS_UXxx
672
673#define CONNECTOR_MXM_ENUM_ID7 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
674 GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\
675 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DAC
676
677#define CONNECTOR_LVDS_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
678 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
679 CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT)
680
681#define CONNECTOR_LVDS_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
682 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
683 CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT)
684
685/****************************************************/
686/* Router Object ID definition - Shared with BIOS */
687/****************************************************/
688#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\
689 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
690 ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT)
691
692/* deleted */
693
694/****************************************************/
695/* Generic Object ID definition - Shared with BIOS */
696/****************************************************/
697#define GENERICOBJECT_GLSYNC_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
698 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
699 GENERIC_OBJECT_ID_GLSYNC << OBJECT_ID_SHIFT)
700
701#define GENERICOBJECT_PX2_NON_DRIVABLE_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
702 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
703 GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT)
704
705#define GENERICOBJECT_PX2_NON_DRIVABLE_ID2 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
706 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
707 GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT)
708
709#define GENERICOBJECT_MXM_OPM_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
710 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
711 GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT)
712
713#define GENERICOBJECT_STEREO_PIN_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
714 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
715 GENERIC_OBJECT_ID_STEREO_PIN << OBJECT_ID_SHIFT)
716
717/****************************************************/
718/* Object Cap definition - Shared with BIOS */
719/****************************************************/
720#define GRAPHICS_OBJECT_CAP_I2C 0x00000001L
721#define GRAPHICS_OBJECT_CAP_TABLE_ID 0x00000002L
722
723
724#define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID 0x01
725#define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID 0x02
726#define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID 0x03
727
728#if defined(_X86_)
729#pragma pack()
730#endif
731
732#endif /*GRAPHICTYPE */
733
734
735
736
drivers/gpu/drm/amd/amdgpu/amdgpu.h+2337−0
@@ -0,0 +1,2337 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __AMDGPU_H__
29#define __AMDGPU_H__
30
31#include <linux/atomic.h>
32#include <linux/wait.h>
33#include <linux/list.h>
34#include <linux/kref.h>
35#include <linux/interval_tree.h>
36#include <linux/hashtable.h>
37#include <linux/fence.h>
38
39#include <ttm/ttm_bo_api.h>
40#include <ttm/ttm_bo_driver.h>
41#include <ttm/ttm_placement.h>
42#include <ttm/ttm_module.h>
43#include <ttm/ttm_execbuf_util.h>
44
45#include <drm/drm_gem.h>
46#include <drm/amdgpu_drm.h>
47
48#include "amd_shared.h"
49#include "amdgpu_family.h"
50#include "amdgpu_mode.h"
51#include "amdgpu_ih.h"
52#include "amdgpu_irq.h"
53#include "amdgpu_ucode.h"
54#include "amdgpu_gds.h"
55
56/*
57 * Modules parameters.
58 */
59extern int amdgpu_modeset;
60extern int amdgpu_vram_limit;
61extern int amdgpu_gart_size;
62extern int amdgpu_benchmarking;
63extern int amdgpu_testing;
64extern int amdgpu_audio;
65extern int amdgpu_disp_priority;
66extern int amdgpu_hw_i2c;
67extern int amdgpu_pcie_gen2;
68extern int amdgpu_msi;
69extern int amdgpu_lockup_timeout;
70extern int amdgpu_dpm;
71extern int amdgpu_smc_load_fw;
72extern int amdgpu_aspm;
73extern int amdgpu_runtime_pm;
74extern int amdgpu_hard_reset;
75extern unsigned amdgpu_ip_block_mask;
76extern int amdgpu_bapm;
77extern int amdgpu_deep_color;
78extern int amdgpu_vm_size;
79extern int amdgpu_vm_block_size;
80
81#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */
82#define AMDGPU_FENCE_JIFFIES_TIMEOUT (HZ / 2)
83/* AMDGPU_IB_POOL_SIZE must be a power of 2 */
84#define AMDGPU_IB_POOL_SIZE 16
85#define AMDGPU_DEBUGFS_MAX_COMPONENTS 32
86#define AMDGPUFB_CONN_LIMIT 4
87#define AMDGPU_BIOS_NUM_SCRATCH 8
88
89/* max number of rings */
90#define AMDGPU_MAX_RINGS 16
91#define AMDGPU_MAX_GFX_RINGS 1
92#define AMDGPU_MAX_COMPUTE_RINGS 8
93#define AMDGPU_MAX_VCE_RINGS 2
94
95/* number of hw syncs before falling back on blocking */
96#define AMDGPU_NUM_SYNCS 4
97
98/* hardcode that limit for now */
99#define AMDGPU_VA_RESERVED_SIZE (8 << 20)
100
101/* hard reset data */
102#define AMDGPU_ASIC_RESET_DATA 0x39d5e86b
103
104/* reset flags */
105#define AMDGPU_RESET_GFX (1 << 0)
106#define AMDGPU_RESET_COMPUTE (1 << 1)
107#define AMDGPU_RESET_DMA (1 << 2)
108#define AMDGPU_RESET_CP (1 << 3)
109#define AMDGPU_RESET_GRBM (1 << 4)
110#define AMDGPU_RESET_DMA1 (1 << 5)
111#define AMDGPU_RESET_RLC (1 << 6)
112#define AMDGPU_RESET_SEM (1 << 7)
113#define AMDGPU_RESET_IH (1 << 8)
114#define AMDGPU_RESET_VMC (1 << 9)
115#define AMDGPU_RESET_MC (1 << 10)
116#define AMDGPU_RESET_DISPLAY (1 << 11)
117#define AMDGPU_RESET_UVD (1 << 12)
118#define AMDGPU_RESET_VCE (1 << 13)
119#define AMDGPU_RESET_VCE1 (1 << 14)
120
121/* CG block flags */
122#define AMDGPU_CG_BLOCK_GFX (1 << 0)
123#define AMDGPU_CG_BLOCK_MC (1 << 1)
124#define AMDGPU_CG_BLOCK_SDMA (1 << 2)
125#define AMDGPU_CG_BLOCK_UVD (1 << 3)
126#define AMDGPU_CG_BLOCK_VCE (1 << 4)
127#define AMDGPU_CG_BLOCK_HDP (1 << 5)
128#define AMDGPU_CG_BLOCK_BIF (1 << 6)
129
130/* CG flags */
131#define AMDGPU_CG_SUPPORT_GFX_MGCG (1 << 0)
132#define AMDGPU_CG_SUPPORT_GFX_MGLS (1 << 1)
133#define AMDGPU_CG_SUPPORT_GFX_CGCG (1 << 2)
134#define AMDGPU_CG_SUPPORT_GFX_CGLS (1 << 3)
135#define AMDGPU_CG_SUPPORT_GFX_CGTS (1 << 4)
136#define AMDGPU_CG_SUPPORT_GFX_CGTS_LS (1 << 5)
137#define AMDGPU_CG_SUPPORT_GFX_CP_LS (1 << 6)
138#define AMDGPU_CG_SUPPORT_GFX_RLC_LS (1 << 7)
139#define AMDGPU_CG_SUPPORT_MC_LS (1 << 8)
140#define AMDGPU_CG_SUPPORT_MC_MGCG (1 << 9)
141#define AMDGPU_CG_SUPPORT_SDMA_LS (1 << 10)
142#define AMDGPU_CG_SUPPORT_SDMA_MGCG (1 << 11)
143#define AMDGPU_CG_SUPPORT_BIF_LS (1 << 12)
144#define AMDGPU_CG_SUPPORT_UVD_MGCG (1 << 13)
145#define AMDGPU_CG_SUPPORT_VCE_MGCG (1 << 14)
146#define AMDGPU_CG_SUPPORT_HDP_LS (1 << 15)
147#define AMDGPU_CG_SUPPORT_HDP_MGCG (1 << 16)
148
149/* PG flags */
150#define AMDGPU_PG_SUPPORT_GFX_PG (1 << 0)
151#define AMDGPU_PG_SUPPORT_GFX_SMG (1 << 1)
152#define AMDGPU_PG_SUPPORT_GFX_DMG (1 << 2)
153#define AMDGPU_PG_SUPPORT_UVD (1 << 3)
154#define AMDGPU_PG_SUPPORT_VCE (1 << 4)
155#define AMDGPU_PG_SUPPORT_CP (1 << 5)
156#define AMDGPU_PG_SUPPORT_GDS (1 << 6)
157#define AMDGPU_PG_SUPPORT_RLC_SMU_HS (1 << 7)
158#define AMDGPU_PG_SUPPORT_SDMA (1 << 8)
159#define AMDGPU_PG_SUPPORT_ACP (1 << 9)
160#define AMDGPU_PG_SUPPORT_SAMU (1 << 10)
161
162/* GFX current status */
163#define AMDGPU_GFX_NORMAL_MODE 0x00000000L
164#define AMDGPU_GFX_SAFE_MODE 0x00000001L
165#define AMDGPU_GFX_PG_DISABLED_MODE 0x00000002L
166#define AMDGPU_GFX_CG_DISABLED_MODE 0x00000004L
167#define AMDGPU_GFX_LBPW_DISABLED_MODE 0x00000008L
168
169/* max cursor sizes (in pixels) */
170#define CIK_CURSOR_WIDTH 128
171#define CIK_CURSOR_HEIGHT 128
172
173struct amdgpu_device;
174struct amdgpu_fence;
175struct amdgpu_ib;
176struct amdgpu_vm;
177struct amdgpu_ring;
178struct amdgpu_semaphore;
179struct amdgpu_cs_parser;
180struct amdgpu_irq_src;
181
182enum amdgpu_cp_irq {
183 AMDGPU_CP_IRQ_GFX_EOP = 0,
184 AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP,
185 AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE1_EOP,
186 AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE2_EOP,
187 AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE3_EOP,
188 AMDGPU_CP_IRQ_COMPUTE_MEC2_PIPE0_EOP,
189 AMDGPU_CP_IRQ_COMPUTE_MEC2_PIPE1_EOP,
190 AMDGPU_CP_IRQ_COMPUTE_MEC2_PIPE2_EOP,
191 AMDGPU_CP_IRQ_COMPUTE_MEC2_PIPE3_EOP,
192
193 AMDGPU_CP_IRQ_LAST
194};
195
196enum amdgpu_sdma_irq {
197 AMDGPU_SDMA_IRQ_TRAP0 = 0,
198 AMDGPU_SDMA_IRQ_TRAP1,
199
200 AMDGPU_SDMA_IRQ_LAST
201};
202
203enum amdgpu_thermal_irq {
204 AMDGPU_THERMAL_IRQ_LOW_TO_HIGH = 0,
205 AMDGPU_THERMAL_IRQ_HIGH_TO_LOW,
206
207 AMDGPU_THERMAL_IRQ_LAST
208};
209
210int amdgpu_set_clockgating_state(struct amdgpu_device *adev,
211 enum amd_ip_block_type block_type,
212 enum amd_clockgating_state state);
213int amdgpu_set_powergating_state(struct amdgpu_device *adev,
214 enum amd_ip_block_type block_type,
215 enum amd_powergating_state state);
216
217struct amdgpu_ip_block_version {
218 enum amd_ip_block_type type;
219 u32 major;
220 u32 minor;
221 u32 rev;
222 const struct amd_ip_funcs *funcs;
223};
224
225int amdgpu_ip_block_version_cmp(struct amdgpu_device *adev,
226 enum amd_ip_block_type type,
227 u32 major, u32 minor);
228
229const struct amdgpu_ip_block_version * amdgpu_get_ip_block(
230 struct amdgpu_device *adev,
231 enum amd_ip_block_type type);
232
233/* provided by hw blocks that can move/clear data. e.g., gfx or sdma */
234struct amdgpu_buffer_funcs {
235 /* maximum bytes in a single operation */
236 uint32_t copy_max_bytes;
237
238 /* number of dw to reserve per operation */
239 unsigned copy_num_dw;
240
241 /* used for buffer migration */
242 void (*emit_copy_buffer)(struct amdgpu_ring *ring,
243 /* src addr in bytes */
244 uint64_t src_offset,
245 /* dst addr in bytes */
246 uint64_t dst_offset,
247 /* number of byte to transfer */
248 uint32_t byte_count);
249
250 /* maximum bytes in a single operation */
251 uint32_t fill_max_bytes;
252
253 /* number of dw to reserve per operation */
254 unsigned fill_num_dw;
255
256 /* used for buffer clearing */
257 void (*emit_fill_buffer)(struct amdgpu_ring *ring,
258 /* value to write to memory */
259 uint32_t src_data,
260 /* dst addr in bytes */
261 uint64_t dst_offset,
262 /* number of byte to fill */
263 uint32_t byte_count);
264};
265
266/* provided by hw blocks that can write ptes, e.g., sdma */
267struct amdgpu_vm_pte_funcs {
268 /* copy pte entries from GART */
269 void (*copy_pte)(struct amdgpu_ib *ib,
270 uint64_t pe, uint64_t src,
271 unsigned count);
272 /* write pte one entry at a time with addr mapping */
273 void (*write_pte)(struct amdgpu_ib *ib,
274 uint64_t pe,
275 uint64_t addr, unsigned count,
276 uint32_t incr, uint32_t flags);
277 /* for linear pte/pde updates without addr mapping */
278 void (*set_pte_pde)(struct amdgpu_ib *ib,
279 uint64_t pe,
280 uint64_t addr, unsigned count,
281 uint32_t incr, uint32_t flags);
282 /* pad the indirect buffer to the necessary number of dw */
283 void (*pad_ib)(struct amdgpu_ib *ib);
284};
285
286/* provided by the gmc block */
287struct amdgpu_gart_funcs {
288 /* flush the vm tlb via mmio */
289 void (*flush_gpu_tlb)(struct amdgpu_device *adev,
290 uint32_t vmid);
291 /* write pte/pde updates using the cpu */
292 int (*set_pte_pde)(struct amdgpu_device *adev,
293 void *cpu_pt_addr, /* cpu addr of page table */
294 uint32_t gpu_page_idx, /* pte/pde to update */
295 uint64_t addr, /* addr to write into pte/pde */
296 uint32_t flags); /* access flags */
297};
298
299/* provided by the ih block */
300struct amdgpu_ih_funcs {
301 /* ring read/write ptr handling, called from interrupt context */
302 u32 (*get_wptr)(struct amdgpu_device *adev);
303 void (*decode_iv)(struct amdgpu_device *adev,
304 struct amdgpu_iv_entry *entry);
305 void (*set_rptr)(struct amdgpu_device *adev);
306};
307
308/* provided by hw blocks that expose a ring buffer for commands */
309struct amdgpu_ring_funcs {
310 /* ring read/write ptr handling */
311 u32 (*get_rptr)(struct amdgpu_ring *ring);
312 u32 (*get_wptr)(struct amdgpu_ring *ring);
313 void (*set_wptr)(struct amdgpu_ring *ring);
314 /* validating and patching of IBs */
315 int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx);
316 /* command emit functions */
317 void (*emit_ib)(struct amdgpu_ring *ring,
318 struct amdgpu_ib *ib);
319 void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr,
320 uint64_t seq, unsigned flags);
321 bool (*emit_semaphore)(struct amdgpu_ring *ring,
322 struct amdgpu_semaphore *semaphore,
323 bool emit_wait);
324 void (*emit_vm_flush)(struct amdgpu_ring *ring, unsigned vm_id,
325 uint64_t pd_addr);
326 void (*emit_hdp_flush)(struct amdgpu_ring *ring);
327 void (*emit_gds_switch)(struct amdgpu_ring *ring, uint32_t vmid,
328 uint32_t gds_base, uint32_t gds_size,
329 uint32_t gws_base, uint32_t gws_size,
330 uint32_t oa_base, uint32_t oa_size);
331 /* testing functions */
332 int (*test_ring)(struct amdgpu_ring *ring);
333 int (*test_ib)(struct amdgpu_ring *ring);
334 bool (*is_lockup)(struct amdgpu_ring *ring);
335};
336
337/*
338 * BIOS.
339 */
340bool amdgpu_get_bios(struct amdgpu_device *adev);
341bool amdgpu_read_bios(struct amdgpu_device *adev);
342
343/*
344 * Dummy page
345 */
346struct amdgpu_dummy_page {
347 struct page *page;
348 dma_addr_t addr;
349};
350int amdgpu_dummy_page_init(struct amdgpu_device *adev);
351void amdgpu_dummy_page_fini(struct amdgpu_device *adev);
352
353
354/*
355 * Clocks
356 */
357
358#define AMDGPU_MAX_PPLL 3
359
360struct amdgpu_clock {
361 struct amdgpu_pll ppll[AMDGPU_MAX_PPLL];
362 struct amdgpu_pll spll;
363 struct amdgpu_pll mpll;
364 /* 10 Khz units */
365 uint32_t default_mclk;
366 uint32_t default_sclk;
367 uint32_t default_dispclk;
368 uint32_t current_dispclk;
369 uint32_t dp_extclk;
370 uint32_t max_pixel_clock;
371};
372
373/*
374 * Fences.
375 */
376struct amdgpu_fence_driver {
377 struct amdgpu_ring *ring;
378 uint64_t gpu_addr;
379 volatile uint32_t *cpu_addr;
380 /* sync_seq is protected by ring emission lock */
381 uint64_t sync_seq[AMDGPU_MAX_RINGS];
382 atomic64_t last_seq;
383 bool initialized;
384 bool delayed_irq;
385 struct amdgpu_irq_src *irq_src;
386 unsigned irq_type;
387 struct delayed_work lockup_work;
388};
389
390/* some special values for the owner field */
391#define AMDGPU_FENCE_OWNER_UNDEFINED ((void*)0ul)
392#define AMDGPU_FENCE_OWNER_VM ((void*)1ul)
393#define AMDGPU_FENCE_OWNER_MOVE ((void*)2ul)
394
395#define AMDGPU_FENCE_FLAG_64BIT (1 << 0)
396#define AMDGPU_FENCE_FLAG_INT (1 << 1)
397
398struct amdgpu_fence {
399 struct fence base;
400
401 /* RB, DMA, etc. */
402 struct amdgpu_ring *ring;
403 uint64_t seq;
404
405 /* filp or special value for fence creator */
406 void *owner;
407
408 wait_queue_t fence_wake;
409};
410
411struct amdgpu_user_fence {
412 /* write-back bo */
413 struct amdgpu_bo *bo;
414 /* write-back address offset to bo start */
415 uint32_t offset;
416};
417
418int amdgpu_fence_driver_init(struct amdgpu_device *adev);
419void amdgpu_fence_driver_fini(struct amdgpu_device *adev);
420void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev);
421
422void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
423int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
424 struct amdgpu_irq_src *irq_src,
425 unsigned irq_type);
426int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,
427 struct amdgpu_fence **fence);
428void amdgpu_fence_process(struct amdgpu_ring *ring);
429int amdgpu_fence_wait_next(struct amdgpu_ring *ring);
430int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
431unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring);
432
433bool amdgpu_fence_signaled(struct amdgpu_fence *fence);
434int amdgpu_fence_wait(struct amdgpu_fence *fence, bool interruptible);
435int amdgpu_fence_wait_any(struct amdgpu_device *adev,
436 struct amdgpu_fence **fences,
437 bool intr);
438long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev,
439 u64 *target_seq, bool intr,
440 long timeout);
441struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence);
442void amdgpu_fence_unref(struct amdgpu_fence **fence);
443
444bool amdgpu_fence_need_sync(struct amdgpu_fence *fence,
445 struct amdgpu_ring *ring);
446void amdgpu_fence_note_sync(struct amdgpu_fence *fence,
447 struct amdgpu_ring *ring);
448
449static inline struct amdgpu_fence *amdgpu_fence_later(struct amdgpu_fence *a,
450 struct amdgpu_fence *b)
451{
452 if (!a) {
453 return b;
454 }
455
456 if (!b) {
457 return a;
458 }
459
460 BUG_ON(a->ring != b->ring);
461
462 if (a->seq > b->seq) {
463 return a;
464 } else {
465 return b;
466 }
467}
468
469static inline bool amdgpu_fence_is_earlier(struct amdgpu_fence *a,
470 struct amdgpu_fence *b)
471{
472 if (!a) {
473 return false;
474 }
475
476 if (!b) {
477 return true;
478 }
479
480 BUG_ON(a->ring != b->ring);
481
482 return a->seq < b->seq;
483}
484
485int amdgpu_user_fence_emit(struct amdgpu_ring *ring, struct amdgpu_user_fence *user,
486 void *owner, struct amdgpu_fence **fence);
487
488/*
489 * TTM.
490 */
491struct amdgpu_mman {
492 struct ttm_bo_global_ref bo_global_ref;
493 struct drm_global_reference mem_global_ref;
494 struct ttm_bo_device bdev;
495 bool mem_global_referenced;
496 bool initialized;
497
498#if defined(CONFIG_DEBUG_FS)
499 struct dentry *vram;
500 struct dentry *gtt;
501#endif
502
503 /* buffer handling */
504 const struct amdgpu_buffer_funcs *buffer_funcs;
505 struct amdgpu_ring *buffer_funcs_ring;
506};
507
508int amdgpu_copy_buffer(struct amdgpu_ring *ring,
509 uint64_t src_offset,
510 uint64_t dst_offset,
511 uint32_t byte_count,
512 struct reservation_object *resv,
513 struct amdgpu_fence **fence);
514int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
515
516struct amdgpu_bo_list_entry {
517 struct amdgpu_bo *robj;
518 struct ttm_validate_buffer tv;
519 struct amdgpu_bo_va *bo_va;
520 unsigned prefered_domains;
521 unsigned allowed_domains;
522 uint32_t priority;
523};
524
525struct amdgpu_bo_va_mapping {
526 struct list_head list;
527 struct interval_tree_node it;
528 uint64_t offset;
529 uint32_t flags;
530};
531
532/* bo virtual addresses in a specific vm */
533struct amdgpu_bo_va {
534 /* protected by bo being reserved */
535 struct list_head bo_list;
536 uint64_t addr;
537 struct amdgpu_fence *last_pt_update;
538 unsigned ref_count;
539
540 /* protected by vm mutex */
541 struct list_head mappings;
542 struct list_head vm_status;
543
544 /* constant after initialization */
545 struct amdgpu_vm *vm;
546 struct amdgpu_bo *bo;
547};
548
549#define AMDGPU_GEM_DOMAIN_MAX 0x3
550
551struct amdgpu_bo {
552 /* Protected by gem.mutex */
553 struct list_head list;
554 /* Protected by tbo.reserved */
555 u32 initial_domain;
556 struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
557 struct ttm_placement placement;
558 struct ttm_buffer_object tbo;
559 struct ttm_bo_kmap_obj kmap;
560 u64 flags;
561 unsigned pin_count;
562 void *kptr;
563 u64 tiling_flags;
564 u64 metadata_flags;
565 void *metadata;
566 u32 metadata_size;
567 /* list of all virtual address to which this bo
568 * is associated to
569 */
570 struct list_head va;
571 /* Constant after initialization */
572 struct amdgpu_device *adev;
573 struct drm_gem_object gem_base;
574
575 struct ttm_bo_kmap_obj dma_buf_vmap;
576 pid_t pid;
577 struct amdgpu_mn *mn;
578 struct list_head mn_list;
579};
580#define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, gem_base)
581
582void amdgpu_gem_object_free(struct drm_gem_object *obj);
583int amdgpu_gem_object_open(struct drm_gem_object *obj,
584 struct drm_file *file_priv);
585void amdgpu_gem_object_close(struct drm_gem_object *obj,
586 struct drm_file *file_priv);
587unsigned long amdgpu_gem_timeout(uint64_t timeout_ns);
588struct sg_table *amdgpu_gem_prime_get_sg_table(struct drm_gem_object *obj);
589struct drm_gem_object *amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
590 struct dma_buf_attachment *attach,
591 struct sg_table *sg);
592struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev,
593 struct drm_gem_object *gobj,
594 int flags);
595int amdgpu_gem_prime_pin(struct drm_gem_object *obj);
596void amdgpu_gem_prime_unpin(struct drm_gem_object *obj);
597struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *);
598void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj);
599void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
600int amdgpu_gem_debugfs_init(struct amdgpu_device *adev);
601
602/* sub-allocation manager, it has to be protected by another lock.
603 * By conception this is an helper for other part of the driver
604 * like the indirect buffer or semaphore, which both have their
605 * locking.
606 *
607 * Principe is simple, we keep a list of sub allocation in offset
608 * order (first entry has offset == 0, last entry has the highest
609 * offset).
610 *
611 * When allocating new object we first check if there is room at
612 * the end total_size - (last_object_offset + last_object_size) >=
613 * alloc_size. If so we allocate new object there.
614 *
615 * When there is not enough room at the end, we start waiting for
616 * each sub object until we reach object_offset+object_size >=
617 * alloc_size, this object then become the sub object we return.
618 *
619 * Alignment can't be bigger than page size.
620 *
621 * Hole are not considered for allocation to keep things simple.
622 * Assumption is that there won't be hole (all object on same
623 * alignment).
624 */
625struct amdgpu_sa_manager {
626 wait_queue_head_t wq;
627 struct amdgpu_bo *bo;
628 struct list_head *hole;
629 struct list_head flist[AMDGPU_MAX_RINGS];
630 struct list_head olist;
631 unsigned size;
632 uint64_t gpu_addr;
633 void *cpu_ptr;
634 uint32_t domain;
635 uint32_t align;
636};
637
638struct amdgpu_sa_bo;
639
640/* sub-allocation buffer */
641struct amdgpu_sa_bo {
642 struct list_head olist;
643 struct list_head flist;
644 struct amdgpu_sa_manager *manager;
645 unsigned soffset;
646 unsigned eoffset;
647 struct amdgpu_fence *fence;
648};
649
650/*
651 * GEM objects.
652 */
653struct amdgpu_gem {
654 struct mutex mutex;
655 struct list_head objects;
656};
657
658int amdgpu_gem_init(struct amdgpu_device *adev);
659void amdgpu_gem_fini(struct amdgpu_device *adev);
660int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
661 int alignment, u32 initial_domain,
662 u64 flags, bool kernel,
663 struct drm_gem_object **obj);
664
665int amdgpu_mode_dumb_create(struct drm_file *file_priv,
666 struct drm_device *dev,
667 struct drm_mode_create_dumb *args);
668int amdgpu_mode_dumb_mmap(struct drm_file *filp,
669 struct drm_device *dev,
670 uint32_t handle, uint64_t *offset_p);
671
672/*
673 * Semaphores.
674 */
675struct amdgpu_semaphore {
676 struct amdgpu_sa_bo *sa_bo;
677 signed waiters;
678 uint64_t gpu_addr;
679};
680
681int amdgpu_semaphore_create(struct amdgpu_device *adev,
682 struct amdgpu_semaphore **semaphore);
683bool amdgpu_semaphore_emit_signal(struct amdgpu_ring *ring,
684 struct amdgpu_semaphore *semaphore);
685bool amdgpu_semaphore_emit_wait(struct amdgpu_ring *ring,
686 struct amdgpu_semaphore *semaphore);
687void amdgpu_semaphore_free(struct amdgpu_device *adev,
688 struct amdgpu_semaphore **semaphore,
689 struct amdgpu_fence *fence);
690
691/*
692 * Synchronization
693 */
694struct amdgpu_sync {
695 struct amdgpu_semaphore *semaphores[AMDGPU_NUM_SYNCS];
696 struct amdgpu_fence *sync_to[AMDGPU_MAX_RINGS];
697 struct amdgpu_fence *last_vm_update;
698};
699
700void amdgpu_sync_create(struct amdgpu_sync *sync);
701void amdgpu_sync_fence(struct amdgpu_sync *sync,
702 struct amdgpu_fence *fence);
703int amdgpu_sync_resv(struct amdgpu_device *adev,
704 struct amdgpu_sync *sync,
705 struct reservation_object *resv,
706 void *owner);
707int amdgpu_sync_rings(struct amdgpu_sync *sync,
708 struct amdgpu_ring *ring);
709void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync,
710 struct amdgpu_fence *fence);
711
712/*
713 * GART structures, functions & helpers
714 */
715struct amdgpu_mc;
716
717#define AMDGPU_GPU_PAGE_SIZE 4096
718#define AMDGPU_GPU_PAGE_MASK (AMDGPU_GPU_PAGE_SIZE - 1)
719#define AMDGPU_GPU_PAGE_SHIFT 12
720#define AMDGPU_GPU_PAGE_ALIGN(a) (((a) + AMDGPU_GPU_PAGE_MASK) & ~AMDGPU_GPU_PAGE_MASK)
721
722struct amdgpu_gart {
723 dma_addr_t table_addr;
724 struct amdgpu_bo *robj;
725 void *ptr;
726 unsigned num_gpu_pages;
727 unsigned num_cpu_pages;
728 unsigned table_size;
729 struct page **pages;
730 dma_addr_t *pages_addr;
731 bool ready;
732 const struct amdgpu_gart_funcs *gart_funcs;
733};
734
735int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev);
736void amdgpu_gart_table_ram_free(struct amdgpu_device *adev);
737int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
738void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
739int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
740void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
741int amdgpu_gart_init(struct amdgpu_device *adev);
742void amdgpu_gart_fini(struct amdgpu_device *adev);
743void amdgpu_gart_unbind(struct amdgpu_device *adev, unsigned offset,
744 int pages);
745int amdgpu_gart_bind(struct amdgpu_device *adev, unsigned offset,
746 int pages, struct page **pagelist,
747 dma_addr_t *dma_addr, uint32_t flags);
748
749/*
750 * GPU MC structures, functions & helpers
751 */
752struct amdgpu_mc {
753 resource_size_t aper_size;
754 resource_size_t aper_base;
755 resource_size_t agp_base;
756 /* for some chips with <= 32MB we need to lie
757 * about vram size near mc fb location */
758 u64 mc_vram_size;
759 u64 visible_vram_size;
760 u64 gtt_size;
761 u64 gtt_start;
762 u64 gtt_end;
763 u64 vram_start;
764 u64 vram_end;
765 unsigned vram_width;
766 u64 real_vram_size;
767 int vram_mtrr;
768 u64 gtt_base_align;
769 u64 mc_mask;
770 const struct firmware *fw; /* MC firmware */
771 uint32_t fw_version;
772 struct amdgpu_irq_src vm_fault;
773 uint32_t vram_type;
774};
775
776/*
777 * GPU doorbell structures, functions & helpers
778 */
779typedef enum _AMDGPU_DOORBELL_ASSIGNMENT
780{
781 AMDGPU_DOORBELL_KIQ = 0x000,
782 AMDGPU_DOORBELL_HIQ = 0x001,
783 AMDGPU_DOORBELL_DIQ = 0x002,
784 AMDGPU_DOORBELL_MEC_RING0 = 0x010,
785 AMDGPU_DOORBELL_MEC_RING1 = 0x011,
786 AMDGPU_DOORBELL_MEC_RING2 = 0x012,
787 AMDGPU_DOORBELL_MEC_RING3 = 0x013,
788 AMDGPU_DOORBELL_MEC_RING4 = 0x014,
789 AMDGPU_DOORBELL_MEC_RING5 = 0x015,
790 AMDGPU_DOORBELL_MEC_RING6 = 0x016,
791 AMDGPU_DOORBELL_MEC_RING7 = 0x017,
792 AMDGPU_DOORBELL_GFX_RING0 = 0x020,
793 AMDGPU_DOORBELL_sDMA_ENGINE0 = 0x1E0,
794 AMDGPU_DOORBELL_sDMA_ENGINE1 = 0x1E1,
795 AMDGPU_DOORBELL_IH = 0x1E8,
796 AMDGPU_DOORBELL_MAX_ASSIGNMENT = 0x3FF,
797 AMDGPU_DOORBELL_INVALID = 0xFFFF
798} AMDGPU_DOORBELL_ASSIGNMENT;
799
800struct amdgpu_doorbell {
801 /* doorbell mmio */
802 resource_size_t base;
803 resource_size_t size;
804 u32 __iomem *ptr;
805 u32 num_doorbells; /* Number of doorbells actually reserved for amdgpu. */
806};
807
808void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
809 phys_addr_t *aperture_base,
810 size_t *aperture_size,
811 size_t *start_offset);
812
813/*
814 * IRQS.
815 */
816
817struct amdgpu_flip_work {
818 struct work_struct flip_work;
819 struct work_struct unpin_work;
820 struct amdgpu_device *adev;
821 int crtc_id;
822 uint64_t base;
823 struct drm_pending_vblank_event *event;
824 struct amdgpu_bo *old_rbo;
825 struct fence *fence;
826};
827
828
829/*
830 * CP & rings.
831 */
832
833struct amdgpu_ib {
834 struct amdgpu_sa_bo *sa_bo;
835 uint32_t length_dw;
836 uint64_t gpu_addr;
837 uint32_t *ptr;
838 struct amdgpu_ring *ring;
839 struct amdgpu_fence *fence;
840 struct amdgpu_user_fence *user;
841 struct amdgpu_vm *vm;
842 struct amdgpu_ctx *ctx;
843 struct amdgpu_sync sync;
844 uint32_t gds_base, gds_size;
845 uint32_t gws_base, gws_size;
846 uint32_t oa_base, oa_size;
847 uint32_t flags;
848};
849
850enum amdgpu_ring_type {
851 AMDGPU_RING_TYPE_GFX,
852 AMDGPU_RING_TYPE_COMPUTE,
853 AMDGPU_RING_TYPE_SDMA,
854 AMDGPU_RING_TYPE_UVD,
855 AMDGPU_RING_TYPE_VCE
856};
857
858struct amdgpu_ring {
859 struct amdgpu_device *adev;
860 const struct amdgpu_ring_funcs *funcs;
861 struct amdgpu_fence_driver fence_drv;
862
863 struct mutex *ring_lock;
864 struct amdgpu_bo *ring_obj;
865 volatile uint32_t *ring;
866 unsigned rptr_offs;
867 u64 next_rptr_gpu_addr;
868 volatile u32 *next_rptr_cpu_addr;
869 unsigned wptr;
870 unsigned wptr_old;
871 unsigned ring_size;
872 unsigned ring_free_dw;
873 int count_dw;
874 atomic_t last_rptr;
875 atomic64_t last_activity;
876 uint64_t gpu_addr;
877 uint32_t align_mask;
878 uint32_t ptr_mask;
879 bool ready;
880 u32 nop;
881 u32 idx;
882 u64 last_semaphore_signal_addr;
883 u64 last_semaphore_wait_addr;
884 u32 me;
885 u32 pipe;
886 u32 queue;
887 struct amdgpu_bo *mqd_obj;
888 u32 doorbell_index;
889 bool use_doorbell;
890 unsigned wptr_offs;
891 unsigned next_rptr_offs;
892 unsigned fence_offs;
893 struct amdgpu_ctx *current_ctx;
894 enum amdgpu_ring_type type;
895 char name[16];
896};
897
898/*
899 * VM
900 */
901
902/* maximum number of VMIDs */
903#define AMDGPU_NUM_VM 16
904
905/* number of entries in page table */
906#define AMDGPU_VM_PTE_COUNT (1 << amdgpu_vm_block_size)
907
908/* PTBs (Page Table Blocks) need to be aligned to 32K */
909#define AMDGPU_VM_PTB_ALIGN_SIZE 32768
910#define AMDGPU_VM_PTB_ALIGN_MASK (AMDGPU_VM_PTB_ALIGN_SIZE - 1)
911#define AMDGPU_VM_PTB_ALIGN(a) (((a) + AMDGPU_VM_PTB_ALIGN_MASK) & ~AMDGPU_VM_PTB_ALIGN_MASK)
912
913#define AMDGPU_PTE_VALID (1 << 0)
914#define AMDGPU_PTE_SYSTEM (1 << 1)
915#define AMDGPU_PTE_SNOOPED (1 << 2)
916
917/* VI only */
918#define AMDGPU_PTE_EXECUTABLE (1 << 4)
919
920#define AMDGPU_PTE_READABLE (1 << 5)
921#define AMDGPU_PTE_WRITEABLE (1 << 6)
922
923/* PTE (Page Table Entry) fragment field for different page sizes */
924#define AMDGPU_PTE_FRAG_4KB (0 << 7)
925#define AMDGPU_PTE_FRAG_64KB (4 << 7)
926#define AMDGPU_LOG2_PAGES_PER_FRAG 4
927
928struct amdgpu_vm_pt {
929 struct amdgpu_bo *bo;
930 uint64_t addr;
931};
932
933struct amdgpu_vm_id {
934 unsigned id;
935 uint64_t pd_gpu_addr;
936 /* last flushed PD/PT update */
937 struct amdgpu_fence *flushed_updates;
938 /* last use of vmid */
939 struct amdgpu_fence *last_id_use;
940};
941
942struct amdgpu_vm {
943 struct mutex mutex;
944
945 struct rb_root va;
946
947 /* protecting invalidated and freed */
948 spinlock_t status_lock;
949
950 /* BOs moved, but not yet updated in the PT */
951 struct list_head invalidated;
952
953 /* BOs freed, but not yet updated in the PT */
954 struct list_head freed;
955
956 /* contains the page directory */
957 struct amdgpu_bo *page_directory;
958 unsigned max_pde_used;
959
960 /* array of page tables, one for each page directory entry */
961 struct amdgpu_vm_pt *page_tables;
962
963 /* for id and flush management per ring */
964 struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS];
965};
966
967struct amdgpu_vm_manager {
968 struct amdgpu_fence *active[AMDGPU_NUM_VM];
969 uint32_t max_pfn;
970 /* number of VMIDs */
971 unsigned nvm;
972 /* vram base address for page table entry */
973 u64 vram_base_offset;
974 /* is vm enabled? */
975 bool enabled;
976 /* for hw to save the PD addr on suspend/resume */
977 uint32_t saved_table_addr[AMDGPU_NUM_VM];
978 /* vm pte handling */
979 const struct amdgpu_vm_pte_funcs *vm_pte_funcs;
980 struct amdgpu_ring *vm_pte_funcs_ring;
981};
982
983/*
984 * context related structures
985 */
986
987struct amdgpu_ctx_state {
988 uint64_t flags;
989 uint32_t hangs;
990};
991
992struct amdgpu_ctx {
993 /* call kref_get()before CS start and kref_put() after CS fence signaled */
994 struct kref refcount;
995 struct amdgpu_fpriv *fpriv;
996 struct amdgpu_ctx_state state;
997 uint32_t id;
998 unsigned reset_counter;
999};
1000
1001struct amdgpu_ctx_mgr {
1002 struct amdgpu_device *adev;
1003 struct idr ctx_handles;
1004 /* lock for IDR system */
1005 struct mutex lock;
1006};
1007
1008/*
1009 * file private structure
1010 */
1011
1012struct amdgpu_fpriv {
1013 struct amdgpu_vm vm;
1014 struct mutex bo_list_lock;
1015 struct idr bo_list_handles;
1016 struct amdgpu_ctx_mgr ctx_mgr;
1017};
1018
1019/*
1020 * residency list
1021 */
1022
1023struct amdgpu_bo_list {
1024 struct mutex lock;
1025 struct amdgpu_bo *gds_obj;
1026 struct amdgpu_bo *gws_obj;
1027 struct amdgpu_bo *oa_obj;
1028 bool has_userptr;
1029 unsigned num_entries;
1030 struct amdgpu_bo_list_entry *array;
1031};
1032
1033struct amdgpu_bo_list *
1034amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id);
1035void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
1036void amdgpu_bo_list_free(struct amdgpu_bo_list *list);
1037
1038/*
1039 * GFX stuff
1040 */
1041#include "clearstate_defs.h"
1042
1043struct amdgpu_rlc {
1044 /* for power gating */
1045 struct amdgpu_bo *save_restore_obj;
1046 uint64_t save_restore_gpu_addr;
1047 volatile uint32_t *sr_ptr;
1048 const u32 *reg_list;
1049 u32 reg_list_size;
1050 /* for clear state */
1051 struct amdgpu_bo *clear_state_obj;
1052 uint64_t clear_state_gpu_addr;
1053 volatile uint32_t *cs_ptr;
1054 const struct cs_section_def *cs_data;
1055 u32 clear_state_size;
1056 /* for cp tables */
1057 struct amdgpu_bo *cp_table_obj;
1058 uint64_t cp_table_gpu_addr;
1059 volatile uint32_t *cp_table_ptr;
1060 u32 cp_table_size;
1061};
1062
1063struct amdgpu_mec {
1064 struct amdgpu_bo *hpd_eop_obj;
1065 u64 hpd_eop_gpu_addr;
1066 u32 num_pipe;
1067 u32 num_mec;
1068 u32 num_queue;
1069};
1070
1071/*
1072 * GPU scratch registers structures, functions & helpers
1073 */
1074struct amdgpu_scratch {
1075 unsigned num_reg;
1076 uint32_t reg_base;
1077 bool free[32];
1078 uint32_t reg[32];
1079};
1080
1081/*
1082 * GFX configurations
1083 */
1084struct amdgpu_gca_config {
1085 unsigned max_shader_engines;
1086 unsigned max_tile_pipes;
1087 unsigned max_cu_per_sh;
1088 unsigned max_sh_per_se;
1089 unsigned max_backends_per_se;
1090 unsigned max_texture_channel_caches;
1091 unsigned max_gprs;
1092 unsigned max_gs_threads;
1093 unsigned max_hw_contexts;
1094 unsigned sc_prim_fifo_size_frontend;
1095 unsigned sc_prim_fifo_size_backend;
1096 unsigned sc_hiz_tile_fifo_size;
1097 unsigned sc_earlyz_tile_fifo_size;
1098
1099 unsigned num_tile_pipes;
1100 unsigned backend_enable_mask;
1101 unsigned mem_max_burst_length_bytes;
1102 unsigned mem_row_size_in_kb;
1103 unsigned shader_engine_tile_size;
1104 unsigned num_gpus;
1105 unsigned multi_gpu_tile_size;
1106 unsigned mc_arb_ramcfg;
1107 unsigned gb_addr_config;
1108
1109 uint32_t tile_mode_array[32];
1110 uint32_t macrotile_mode_array[16];
1111};
1112
1113struct amdgpu_gfx {
1114 struct mutex gpu_clock_mutex;
1115 struct amdgpu_gca_config config;
1116 struct amdgpu_rlc rlc;
1117 struct amdgpu_mec mec;
1118 struct amdgpu_scratch scratch;
1119 const struct firmware *me_fw; /* ME firmware */
1120 uint32_t me_fw_version;
1121 const struct firmware *pfp_fw; /* PFP firmware */
1122 uint32_t pfp_fw_version;
1123 const struct firmware *ce_fw; /* CE firmware */
1124 uint32_t ce_fw_version;
1125 const struct firmware *rlc_fw; /* RLC firmware */
1126 uint32_t rlc_fw_version;
1127 const struct firmware *mec_fw; /* MEC firmware */
1128 uint32_t mec_fw_version;
1129 const struct firmware *mec2_fw; /* MEC2 firmware */
1130 uint32_t mec2_fw_version;
1131 uint32_t me_feature_version;
1132 uint32_t ce_feature_version;
1133 uint32_t pfp_feature_version;
1134 struct amdgpu_ring gfx_ring[AMDGPU_MAX_GFX_RINGS];
1135 unsigned num_gfx_rings;
1136 struct amdgpu_ring compute_ring[AMDGPU_MAX_COMPUTE_RINGS];
1137 unsigned num_compute_rings;
1138 struct amdgpu_irq_src eop_irq;
1139 struct amdgpu_irq_src priv_reg_irq;
1140 struct amdgpu_irq_src priv_inst_irq;
1141 /* gfx status */
1142 uint32_t gfx_current_status;
1143 /* sync signal for const engine */
1144 unsigned ce_sync_offs;
1145 /* ce ram size*/
1146 unsigned ce_ram_size;
1147};
1148
1149int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm,
1150 unsigned size, struct amdgpu_ib *ib);
1151void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib);
1152int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,
1153 struct amdgpu_ib *ib, void *owner);
1154int amdgpu_ib_pool_init(struct amdgpu_device *adev);
1155void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
1156int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
1157/* Ring access between begin & end cannot sleep */
1158void amdgpu_ring_free_size(struct amdgpu_ring *ring);
1159int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
1160int amdgpu_ring_lock(struct amdgpu_ring *ring, unsigned ndw);
1161void amdgpu_ring_commit(struct amdgpu_ring *ring);
1162void amdgpu_ring_unlock_commit(struct amdgpu_ring *ring);
1163void amdgpu_ring_undo(struct amdgpu_ring *ring);
1164void amdgpu_ring_unlock_undo(struct amdgpu_ring *ring);
1165void amdgpu_ring_lockup_update(struct amdgpu_ring *ring);
1166bool amdgpu_ring_test_lockup(struct amdgpu_ring *ring);
1167unsigned amdgpu_ring_backup(struct amdgpu_ring *ring,
1168 uint32_t **data);
1169int amdgpu_ring_restore(struct amdgpu_ring *ring,
1170 unsigned size, uint32_t *data);
1171int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
1172 unsigned ring_size, u32 nop, u32 align_mask,
1173 struct amdgpu_irq_src *irq_src, unsigned irq_type,
1174 enum amdgpu_ring_type ring_type);
1175void amdgpu_ring_fini(struct amdgpu_ring *ring);
1176
1177/*
1178 * CS.
1179 */
1180struct amdgpu_cs_chunk {
1181 uint32_t chunk_id;
1182 uint32_t length_dw;
1183 uint32_t *kdata;
1184 void __user *user_ptr;
1185};
1186
1187struct amdgpu_cs_parser {
1188 struct amdgpu_device *adev;
1189 struct drm_file *filp;
1190 struct amdgpu_ctx *ctx;
1191 struct amdgpu_bo_list *bo_list;
1192 /* chunks */
1193 unsigned nchunks;
1194 struct amdgpu_cs_chunk *chunks;
1195 /* relocations */
1196 struct amdgpu_bo_list_entry *vm_bos;
1197 struct list_head validated;
1198
1199 struct amdgpu_ib *ibs;
1200 uint32_t num_ibs;
1201
1202 struct ww_acquire_ctx ticket;
1203
1204 /* user fence */
1205 struct amdgpu_user_fence uf;
1206};
1207
1208static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, uint32_t ib_idx, int idx)
1209{
1210 return p->ibs[ib_idx].ptr[idx];
1211}
1212
1213/*
1214 * Writeback
1215 */
1216#define AMDGPU_MAX_WB 1024 /* Reserve at most 1024 WB slots for amdgpu-owned rings. */
1217
1218struct amdgpu_wb {
1219 struct amdgpu_bo *wb_obj;
1220 volatile uint32_t *wb;
1221 uint64_t gpu_addr;
1222 u32 num_wb; /* Number of wb slots actually reserved for amdgpu. */
1223 unsigned long used[DIV_ROUND_UP(AMDGPU_MAX_WB, BITS_PER_LONG)];
1224};
1225
1226int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb);
1227void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb);
1228
1229/**
1230 * struct amdgpu_pm - power management datas
1231 * It keeps track of various data needed to take powermanagement decision.
1232 */
1233
1234enum amdgpu_pm_state_type {
1235 /* not used for dpm */
1236 POWER_STATE_TYPE_DEFAULT,
1237 POWER_STATE_TYPE_POWERSAVE,
1238 /* user selectable states */
1239 POWER_STATE_TYPE_BATTERY,
1240 POWER_STATE_TYPE_BALANCED,
1241 POWER_STATE_TYPE_PERFORMANCE,
1242 /* internal states */
1243 POWER_STATE_TYPE_INTERNAL_UVD,
1244 POWER_STATE_TYPE_INTERNAL_UVD_SD,
1245 POWER_STATE_TYPE_INTERNAL_UVD_HD,
1246 POWER_STATE_TYPE_INTERNAL_UVD_HD2,
1247 POWER_STATE_TYPE_INTERNAL_UVD_MVC,
1248 POWER_STATE_TYPE_INTERNAL_BOOT,
1249 POWER_STATE_TYPE_INTERNAL_THERMAL,
1250 POWER_STATE_TYPE_INTERNAL_ACPI,
1251 POWER_STATE_TYPE_INTERNAL_ULV,
1252 POWER_STATE_TYPE_INTERNAL_3DPERF,
1253};
1254
1255enum amdgpu_int_thermal_type {
1256 THERMAL_TYPE_NONE,
1257 THERMAL_TYPE_EXTERNAL,
1258 THERMAL_TYPE_EXTERNAL_GPIO,
1259 THERMAL_TYPE_RV6XX,
1260 THERMAL_TYPE_RV770,
1261 THERMAL_TYPE_ADT7473_WITH_INTERNAL,
1262 THERMAL_TYPE_EVERGREEN,
1263 THERMAL_TYPE_SUMO,
1264 THERMAL_TYPE_NI,
1265 THERMAL_TYPE_SI,
1266 THERMAL_TYPE_EMC2103_WITH_INTERNAL,
1267 THERMAL_TYPE_CI,
1268 THERMAL_TYPE_KV,
1269};
1270
1271enum amdgpu_dpm_auto_throttle_src {
1272 AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL,
1273 AMDGPU_DPM_AUTO_THROTTLE_SRC_EXTERNAL
1274};
1275
1276enum amdgpu_dpm_event_src {
1277 AMDGPU_DPM_EVENT_SRC_ANALOG = 0,
1278 AMDGPU_DPM_EVENT_SRC_EXTERNAL = 1,
1279 AMDGPU_DPM_EVENT_SRC_DIGITAL = 2,
1280 AMDGPU_DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,
1281 AMDGPU_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
1282};
1283
1284#define AMDGPU_MAX_VCE_LEVELS 6
1285
1286enum amdgpu_vce_level {
1287 AMDGPU_VCE_LEVEL_AC_ALL = 0, /* AC, All cases */
1288 AMDGPU_VCE_LEVEL_DC_EE = 1, /* DC, entropy encoding */
1289 AMDGPU_VCE_LEVEL_DC_LL_LOW = 2, /* DC, low latency queue, res <= 720 */
1290 AMDGPU_VCE_LEVEL_DC_LL_HIGH = 3, /* DC, low latency queue, 1080 >= res > 720 */
1291 AMDGPU_VCE_LEVEL_DC_GP_LOW = 4, /* DC, general purpose queue, res <= 720 */
1292 AMDGPU_VCE_LEVEL_DC_GP_HIGH = 5, /* DC, general purpose queue, 1080 >= res > 720 */
1293};
1294
1295struct amdgpu_ps {
1296 u32 caps; /* vbios flags */
1297 u32 class; /* vbios flags */
1298 u32 class2; /* vbios flags */
1299 /* UVD clocks */
1300 u32 vclk;
1301 u32 dclk;
1302 /* VCE clocks */
1303 u32 evclk;
1304 u32 ecclk;
1305 bool vce_active;
1306 enum amdgpu_vce_level vce_level;
1307 /* asic priv */
1308 void *ps_priv;
1309};
1310
1311struct amdgpu_dpm_thermal {
1312 /* thermal interrupt work */
1313 struct work_struct work;
1314 /* low temperature threshold */
1315 int min_temp;
1316 /* high temperature threshold */
1317 int max_temp;
1318 /* was last interrupt low to high or high to low */
1319 bool high_to_low;
1320 /* interrupt source */
1321 struct amdgpu_irq_src irq;
1322};
1323
1324enum amdgpu_clk_action
1325{
1326 AMDGPU_SCLK_UP = 1,
1327 AMDGPU_SCLK_DOWN
1328};
1329
1330struct amdgpu_blacklist_clocks
1331{
1332 u32 sclk;
1333 u32 mclk;
1334 enum amdgpu_clk_action action;
1335};
1336
1337struct amdgpu_clock_and_voltage_limits {
1338 u32 sclk;
1339 u32 mclk;
1340 u16 vddc;
1341 u16 vddci;
1342};
1343
1344struct amdgpu_clock_array {
1345 u32 count;
1346 u32 *values;
1347};
1348
1349struct amdgpu_clock_voltage_dependency_entry {
1350 u32 clk;
1351 u16 v;
1352};
1353
1354struct amdgpu_clock_voltage_dependency_table {
1355 u32 count;
1356 struct amdgpu_clock_voltage_dependency_entry *entries;
1357};
1358
1359union amdgpu_cac_leakage_entry {
1360 struct {
1361 u16 vddc;
1362 u32 leakage;
1363 };
1364 struct {
1365 u16 vddc1;
1366 u16 vddc2;
1367 u16 vddc3;
1368 };
1369};
1370
1371struct amdgpu_cac_leakage_table {
1372 u32 count;
1373 union amdgpu_cac_leakage_entry *entries;
1374};
1375
1376struct amdgpu_phase_shedding_limits_entry {
1377 u16 voltage;
1378 u32 sclk;
1379 u32 mclk;
1380};
1381
1382struct amdgpu_phase_shedding_limits_table {
1383 u32 count;
1384 struct amdgpu_phase_shedding_limits_entry *entries;
1385};
1386
1387struct amdgpu_uvd_clock_voltage_dependency_entry {
1388 u32 vclk;
1389 u32 dclk;
1390 u16 v;
1391};
1392
1393struct amdgpu_uvd_clock_voltage_dependency_table {
1394 u8 count;
1395 struct amdgpu_uvd_clock_voltage_dependency_entry *entries;
1396};
1397
1398struct amdgpu_vce_clock_voltage_dependency_entry {
1399 u32 ecclk;
1400 u32 evclk;
1401 u16 v;
1402};
1403
1404struct amdgpu_vce_clock_voltage_dependency_table {
1405 u8 count;
1406 struct amdgpu_vce_clock_voltage_dependency_entry *entries;
1407};
1408
1409struct amdgpu_ppm_table {
1410 u8 ppm_design;
1411 u16 cpu_core_number;
1412 u32 platform_tdp;
1413 u32 small_ac_platform_tdp;
1414 u32 platform_tdc;
1415 u32 small_ac_platform_tdc;
1416 u32 apu_tdp;
1417 u32 dgpu_tdp;
1418 u32 dgpu_ulv_power;
1419 u32 tj_max;
1420};
1421
1422struct amdgpu_cac_tdp_table {
1423 u16 tdp;
1424 u16 configurable_tdp;
1425 u16 tdc;
1426 u16 battery_power_limit;
1427 u16 small_power_limit;
1428 u16 low_cac_leakage;
1429 u16 high_cac_leakage;
1430 u16 maximum_power_delivery_limit;
1431};
1432
1433struct amdgpu_dpm_dynamic_state {
1434 struct amdgpu_clock_voltage_dependency_table vddc_dependency_on_sclk;
1435 struct amdgpu_clock_voltage_dependency_table vddci_dependency_on_mclk;
1436 struct amdgpu_clock_voltage_dependency_table vddc_dependency_on_mclk;
1437 struct amdgpu_clock_voltage_dependency_table mvdd_dependency_on_mclk;
1438 struct amdgpu_clock_voltage_dependency_table vddc_dependency_on_dispclk;
1439 struct amdgpu_uvd_clock_voltage_dependency_table uvd_clock_voltage_dependency_table;
1440 struct amdgpu_vce_clock_voltage_dependency_table vce_clock_voltage_dependency_table;
1441 struct amdgpu_clock_voltage_dependency_table samu_clock_voltage_dependency_table;
1442 struct amdgpu_clock_voltage_dependency_table acp_clock_voltage_dependency_table;
1443 struct amdgpu_clock_voltage_dependency_table vddgfx_dependency_on_sclk;
1444 struct amdgpu_clock_array valid_sclk_values;
1445 struct amdgpu_clock_array valid_mclk_values;
1446 struct amdgpu_clock_and_voltage_limits max_clock_voltage_on_dc;
1447 struct amdgpu_clock_and_voltage_limits max_clock_voltage_on_ac;
1448 u32 mclk_sclk_ratio;
1449 u32 sclk_mclk_delta;
1450 u16 vddc_vddci_delta;
1451 u16 min_vddc_for_pcie_gen2;
1452 struct amdgpu_cac_leakage_table cac_leakage_table;
1453 struct amdgpu_phase_shedding_limits_table phase_shedding_limits_table;
1454 struct amdgpu_ppm_table *ppm_table;
1455 struct amdgpu_cac_tdp_table *cac_tdp_table;
1456};
1457
1458struct amdgpu_dpm_fan {
1459 u16 t_min;
1460 u16 t_med;
1461 u16 t_high;
1462 u16 pwm_min;
1463 u16 pwm_med;
1464 u16 pwm_high;
1465 u8 t_hyst;
1466 u32 cycle_delay;
1467 u16 t_max;
1468 u8 control_mode;
1469 u16 default_max_fan_pwm;
1470 u16 default_fan_output_sensitivity;
1471 u16 fan_output_sensitivity;
1472 bool ucode_fan_control;
1473};
1474
1475enum amdgpu_pcie_gen {
1476 AMDGPU_PCIE_GEN1 = 0,
1477 AMDGPU_PCIE_GEN2 = 1,
1478 AMDGPU_PCIE_GEN3 = 2,
1479 AMDGPU_PCIE_GEN_INVALID = 0xffff
1480};
1481
1482enum amdgpu_dpm_forced_level {
1483 AMDGPU_DPM_FORCED_LEVEL_AUTO = 0,
1484 AMDGPU_DPM_FORCED_LEVEL_LOW = 1,
1485 AMDGPU_DPM_FORCED_LEVEL_HIGH = 2,
1486};
1487
1488struct amdgpu_vce_state {
1489 /* vce clocks */
1490 u32 evclk;
1491 u32 ecclk;
1492 /* gpu clocks */
1493 u32 sclk;
1494 u32 mclk;
1495 u8 clk_idx;
1496 u8 pstate;
1497};
1498
1499struct amdgpu_dpm_funcs {
1500 int (*get_temperature)(struct amdgpu_device *adev);
1501 int (*pre_set_power_state)(struct amdgpu_device *adev);
1502 int (*set_power_state)(struct amdgpu_device *adev);
1503 void (*post_set_power_state)(struct amdgpu_device *adev);
1504 void (*display_configuration_changed)(struct amdgpu_device *adev);
1505 u32 (*get_sclk)(struct amdgpu_device *adev, bool low);
1506 u32 (*get_mclk)(struct amdgpu_device *adev, bool low);
1507 void (*print_power_state)(struct amdgpu_device *adev, struct amdgpu_ps *ps);
1508 void (*debugfs_print_current_performance_level)(struct amdgpu_device *adev, struct seq_file *m);
1509 int (*force_performance_level)(struct amdgpu_device *adev, enum amdgpu_dpm_forced_level level);
1510 bool (*vblank_too_short)(struct amdgpu_device *adev);
1511 void (*powergate_uvd)(struct amdgpu_device *adev, bool gate);
1512 void (*powergate_vce)(struct amdgpu_device *adev, bool gate);
1513 void (*enable_bapm)(struct amdgpu_device *adev, bool enable);
1514 void (*set_fan_control_mode)(struct amdgpu_device *adev, u32 mode);
1515 u32 (*get_fan_control_mode)(struct amdgpu_device *adev);
1516 int (*set_fan_speed_percent)(struct amdgpu_device *adev, u32 speed);
1517 int (*get_fan_speed_percent)(struct amdgpu_device *adev, u32 *speed);
1518};
1519
1520struct amdgpu_dpm {
1521 struct amdgpu_ps *ps;
1522 /* number of valid power states */
1523 int num_ps;
1524 /* current power state that is active */
1525 struct amdgpu_ps *current_ps;
1526 /* requested power state */
1527 struct amdgpu_ps *requested_ps;
1528 /* boot up power state */
1529 struct amdgpu_ps *boot_ps;
1530 /* default uvd power state */
1531 struct amdgpu_ps *uvd_ps;
1532 /* vce requirements */
1533 struct amdgpu_vce_state vce_states[AMDGPU_MAX_VCE_LEVELS];
1534 enum amdgpu_vce_level vce_level;
1535 enum amdgpu_pm_state_type state;
1536 enum amdgpu_pm_state_type user_state;
1537 u32 platform_caps;
1538 u32 voltage_response_time;
1539 u32 backbias_response_time;
1540 void *priv;
1541 u32 new_active_crtcs;
1542 int new_active_crtc_count;
1543 u32 current_active_crtcs;
1544 int current_active_crtc_count;
1545 struct amdgpu_dpm_dynamic_state dyn_state;
1546 struct amdgpu_dpm_fan fan;
1547 u32 tdp_limit;
1548 u32 near_tdp_limit;
1549 u32 near_tdp_limit_adjusted;
1550 u32 sq_ramping_threshold;
1551 u32 cac_leakage;
1552 u16 tdp_od_limit;
1553 u32 tdp_adjustment;
1554 u16 load_line_slope;
1555 bool power_control;
1556 bool ac_power;
1557 /* special states active */
1558 bool thermal_active;
1559 bool uvd_active;
1560 bool vce_active;
1561 /* thermal handling */
1562 struct amdgpu_dpm_thermal thermal;
1563 /* forced levels */
1564 enum amdgpu_dpm_forced_level forced_level;
1565};
1566
1567struct amdgpu_pm {
1568 struct mutex mutex;
1569 u32 current_sclk;
1570 u32 current_mclk;
1571 u32 default_sclk;
1572 u32 default_mclk;
1573 struct amdgpu_i2c_chan *i2c_bus;
1574 /* internal thermal controller on rv6xx+ */
1575 enum amdgpu_int_thermal_type int_thermal_type;
1576 struct device *int_hwmon_dev;
1577 /* fan control parameters */
1578 bool no_fan;
1579 u8 fan_pulses_per_revolution;
1580 u8 fan_min_rpm;
1581 u8 fan_max_rpm;
1582 /* dpm */
1583 bool dpm_enabled;
1584 struct amdgpu_dpm dpm;
1585 const struct firmware *fw; /* SMC firmware */
1586 uint32_t fw_version;
1587 const struct amdgpu_dpm_funcs *funcs;
1588};
1589
1590/*
1591 * UVD
1592 */
1593#define AMDGPU_MAX_UVD_HANDLES 10
1594#define AMDGPU_UVD_STACK_SIZE (1024*1024)
1595#define AMDGPU_UVD_HEAP_SIZE (1024*1024)
1596#define AMDGPU_UVD_FIRMWARE_OFFSET 256
1597
1598struct amdgpu_uvd {
1599 struct amdgpu_bo *vcpu_bo;
1600 void *cpu_addr;
1601 uint64_t gpu_addr;
1602 void *saved_bo;
1603 atomic_t handles[AMDGPU_MAX_UVD_HANDLES];
1604 struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES];
1605 struct delayed_work idle_work;
1606 const struct firmware *fw; /* UVD firmware */
1607 struct amdgpu_ring ring;
1608 struct amdgpu_irq_src irq;
1609 bool address_64_bit;
1610};
1611
1612/*
1613 * VCE
1614 */
1615#define AMDGPU_MAX_VCE_HANDLES 16
1616#define AMDGPU_VCE_FIRMWARE_OFFSET 256
1617
1618struct amdgpu_vce {
1619 struct amdgpu_bo *vcpu_bo;
1620 uint64_t gpu_addr;
1621 unsigned fw_version;
1622 unsigned fb_version;
1623 atomic_t handles[AMDGPU_MAX_VCE_HANDLES];
1624 struct drm_file *filp[AMDGPU_MAX_VCE_HANDLES];
1625 struct delayed_work idle_work;
1626 const struct firmware *fw; /* VCE firmware */
1627 struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS];
1628 struct amdgpu_irq_src irq;
1629};
1630
1631/*
1632 * SDMA
1633 */
1634struct amdgpu_sdma {
1635 /* SDMA firmware */
1636 const struct firmware *fw;
1637 uint32_t fw_version;
1638
1639 struct amdgpu_ring ring;
1640};
1641
1642/*
1643 * Firmware
1644 */
1645struct amdgpu_firmware {
1646 struct amdgpu_firmware_info ucode[AMDGPU_UCODE_ID_MAXIMUM];
1647 bool smu_load;
1648 struct amdgpu_bo *fw_buf;
1649 unsigned int fw_size;
1650};
1651
1652/*
1653 * Benchmarking
1654 */
1655void amdgpu_benchmark(struct amdgpu_device *adev, int test_number);
1656
1657
1658/*
1659 * Testing
1660 */
1661void amdgpu_test_moves(struct amdgpu_device *adev);
1662void amdgpu_test_ring_sync(struct amdgpu_device *adev,
1663 struct amdgpu_ring *cpA,
1664 struct amdgpu_ring *cpB);
1665void amdgpu_test_syncing(struct amdgpu_device *adev);
1666
1667/*
1668 * MMU Notifier
1669 */
1670#if defined(CONFIG_MMU_NOTIFIER)
1671int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr);
1672void amdgpu_mn_unregister(struct amdgpu_bo *bo);
1673#else
1674static int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
1675{
1676 return -ENODEV;
1677}
1678static void amdgpu_mn_unregister(struct amdgpu_bo *bo) {}
1679#endif
1680
1681/*
1682 * Debugfs
1683 */
1684struct amdgpu_debugfs {
1685 struct drm_info_list *files;
1686 unsigned num_files;
1687};
1688
1689int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
1690 struct drm_info_list *files,
1691 unsigned nfiles);
1692int amdgpu_debugfs_fence_init(struct amdgpu_device *adev);
1693
1694#if defined(CONFIG_DEBUG_FS)
1695int amdgpu_debugfs_init(struct drm_minor *minor);
1696void amdgpu_debugfs_cleanup(struct drm_minor *minor);
1697#endif
1698
1699/*
1700 * amdgpu smumgr functions
1701 */
1702struct amdgpu_smumgr_funcs {
1703 int (*check_fw_load_finish)(struct amdgpu_device *adev, uint32_t fwtype);
1704 int (*request_smu_load_fw)(struct amdgpu_device *adev);
1705 int (*request_smu_specific_fw)(struct amdgpu_device *adev, uint32_t fwtype);
1706};
1707
1708/*
1709 * amdgpu smumgr
1710 */
1711struct amdgpu_smumgr {
1712 struct amdgpu_bo *toc_buf;
1713 struct amdgpu_bo *smu_buf;
1714 /* asic priv smu data */
1715 void *priv;
1716 spinlock_t smu_lock;
1717 /* smumgr functions */
1718 const struct amdgpu_smumgr_funcs *smumgr_funcs;
1719 /* ucode loading complete flag */
1720 uint32_t fw_flags;
1721};
1722
1723/*
1724 * ASIC specific register table accessible by UMD
1725 */
1726struct amdgpu_allowed_register_entry {
1727 uint32_t reg_offset;
1728 bool untouched;
1729 bool grbm_indexed;
1730};
1731
1732struct amdgpu_cu_info {
1733 uint32_t number; /* total active CU number */
1734 uint32_t ao_cu_mask;
1735 uint32_t bitmap[4][4];
1736};
1737
1738
1739/*
1740 * ASIC specific functions.
1741 */
1742struct amdgpu_asic_funcs {
1743 bool (*read_disabled_bios)(struct amdgpu_device *adev);
1744 int (*read_register)(struct amdgpu_device *adev, u32 se_num,
1745 u32 sh_num, u32 reg_offset, u32 *value);
1746 void (*set_vga_state)(struct amdgpu_device *adev, bool state);
1747 int (*reset)(struct amdgpu_device *adev);
1748 /* wait for mc_idle */
1749 int (*wait_for_mc_idle)(struct amdgpu_device *adev);
1750 /* get the reference clock */
1751 u32 (*get_xclk)(struct amdgpu_device *adev);
1752 /* get the gpu clock counter */
1753 uint64_t (*get_gpu_clock_counter)(struct amdgpu_device *adev);
1754 int (*get_cu_info)(struct amdgpu_device *adev, struct amdgpu_cu_info *info);
1755 /* MM block clocks */
1756 int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);
1757 int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);
1758};
1759
1760/*
1761 * IOCTL.
1762 */
1763int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
1764 struct drm_file *filp);
1765int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
1766 struct drm_file *filp);
1767
1768int amdgpu_gem_info_ioctl(struct drm_device *dev, void *data,
1769 struct drm_file *filp);
1770int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
1771 struct drm_file *filp);
1772int amdgpu_gem_mmap_ioctl(struct drm_device *dev, void *data,
1773 struct drm_file *filp);
1774int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
1775 struct drm_file *filp);
1776int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
1777 struct drm_file *filp);
1778int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
1779 struct drm_file *filp);
1780int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
1781int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
1782
1783int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
1784 struct drm_file *filp);
1785
1786/* VRAM scratch page for HDP bug, default vram page */
1787struct amdgpu_vram_scratch {
1788 struct amdgpu_bo *robj;
1789 volatile uint32_t *ptr;
1790 u64 gpu_addr;
1791};
1792
1793/*
1794 * ACPI
1795 */
1796struct amdgpu_atif_notification_cfg {
1797 bool enabled;
1798 int command_code;
1799};
1800
1801struct amdgpu_atif_notifications {
1802 bool display_switch;
1803 bool expansion_mode_change;
1804 bool thermal_state;
1805 bool forced_power_state;
1806 bool system_power_state;
1807 bool display_conf_change;
1808 bool px_gfx_switch;
1809 bool brightness_change;
1810 bool dgpu_display_event;
1811};
1812
1813struct amdgpu_atif_functions {
1814 bool system_params;
1815 bool sbios_requests;
1816 bool select_active_disp;
1817 bool lid_state;
1818 bool get_tv_standard;
1819 bool set_tv_standard;
1820 bool get_panel_expansion_mode;
1821 bool set_panel_expansion_mode;
1822 bool temperature_change;
1823 bool graphics_device_types;
1824};
1825
1826struct amdgpu_atif {
1827 struct amdgpu_atif_notifications notifications;
1828 struct amdgpu_atif_functions functions;
1829 struct amdgpu_atif_notification_cfg notification_cfg;
1830 struct amdgpu_encoder *encoder_for_bl;
1831};
1832
1833struct amdgpu_atcs_functions {
1834 bool get_ext_state;
1835 bool pcie_perf_req;
1836 bool pcie_dev_rdy;
1837 bool pcie_bus_width;
1838};
1839
1840struct amdgpu_atcs {
1841 struct amdgpu_atcs_functions functions;
1842};
1843
1844int amdgpu_ctx_alloc(struct amdgpu_device *adev,struct amdgpu_fpriv *fpriv,
1845 uint32_t *id,uint32_t flags);
1846int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
1847 uint32_t id);
1848
1849void amdgpu_ctx_fini(struct amdgpu_fpriv *fpriv);
1850struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id);
1851int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
1852
1853extern int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
1854 struct drm_file *filp);
1855
1856/*
1857 * Core structure, functions and helpers.
1858 */
1859typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device*, uint32_t);
1860typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
1861
1862typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
1863typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);
1864
1865struct amdgpu_device {
1866 struct device *dev;
1867 struct drm_device *ddev;
1868 struct pci_dev *pdev;
1869 struct rw_semaphore exclusive_lock;
1870
1871 /* ASIC */
1872 enum amdgpu_asic_type asic_type;
1873 uint32_t family;
1874 uint32_t rev_id;
1875 uint32_t external_rev_id;
1876 unsigned long flags;
1877 int usec_timeout;
1878 const struct amdgpu_asic_funcs *asic_funcs;
1879 bool shutdown;
1880 bool suspend;
1881 bool need_dma32;
1882 bool accel_working;
1883 bool needs_reset;
1884 struct work_struct reset_work;
1885 struct notifier_block acpi_nb;
1886 struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS];
1887 struct amdgpu_debugfs debugfs[AMDGPU_DEBUGFS_MAX_COMPONENTS];
1888 unsigned debugfs_count;
1889#if defined(CONFIG_DEBUG_FS)
1890 struct dentry *debugfs_regs;
1891#endif
1892 struct amdgpu_atif atif;
1893 struct amdgpu_atcs atcs;
1894 struct mutex srbm_mutex;
1895 /* GRBM index mutex. Protects concurrent access to GRBM index */
1896 struct mutex grbm_idx_mutex;
1897 struct dev_pm_domain vga_pm_domain;
1898 bool have_disp_power_ref;
1899
1900 /* BIOS */
1901 uint8_t *bios;
1902 bool is_atom_bios;
1903 uint16_t bios_header_start;
1904 struct amdgpu_bo *stollen_vga_memory;
1905 uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH];
1906
1907 /* Register/doorbell mmio */
1908 resource_size_t rmmio_base;
1909 resource_size_t rmmio_size;
1910 void __iomem *rmmio;
1911 /* protects concurrent MM_INDEX/DATA based register access */
1912 spinlock_t mmio_idx_lock;
1913 /* protects concurrent SMC based register access */
1914 spinlock_t smc_idx_lock;
1915 amdgpu_rreg_t smc_rreg;
1916 amdgpu_wreg_t smc_wreg;
1917 /* protects concurrent PCIE register access */
1918 spinlock_t pcie_idx_lock;
1919 amdgpu_rreg_t pcie_rreg;
1920 amdgpu_wreg_t pcie_wreg;
1921 /* protects concurrent UVD register access */
1922 spinlock_t uvd_ctx_idx_lock;
1923 amdgpu_rreg_t uvd_ctx_rreg;
1924 amdgpu_wreg_t uvd_ctx_wreg;
1925 /* protects concurrent DIDT register access */
1926 spinlock_t didt_idx_lock;
1927 amdgpu_rreg_t didt_rreg;
1928 amdgpu_wreg_t didt_wreg;
1929 /* protects concurrent ENDPOINT (audio) register access */
1930 spinlock_t audio_endpt_idx_lock;
1931 amdgpu_block_rreg_t audio_endpt_rreg;
1932 amdgpu_block_wreg_t audio_endpt_wreg;
1933 void __iomem *rio_mem;
1934 resource_size_t rio_mem_size;
1935 struct amdgpu_doorbell doorbell;
1936
1937 /* clock/pll info */
1938 struct amdgpu_clock clock;
1939
1940 /* MC */
1941 struct amdgpu_mc mc;
1942 struct amdgpu_gart gart;
1943 struct amdgpu_dummy_page dummy_page;
1944 struct amdgpu_vm_manager vm_manager;
1945
1946 /* memory management */
1947 struct amdgpu_mman mman;
1948 struct amdgpu_gem gem;
1949 struct amdgpu_vram_scratch vram_scratch;
1950 struct amdgpu_wb wb;
1951 atomic64_t vram_usage;
1952 atomic64_t vram_vis_usage;
1953 atomic64_t gtt_usage;
1954 atomic64_t num_bytes_moved;
1955 atomic_t gpu_reset_counter;
1956
1957 /* display */
1958 struct amdgpu_mode_info mode_info;
1959 struct work_struct hotplug_work;
1960 struct amdgpu_irq_src crtc_irq;
1961 struct amdgpu_irq_src pageflip_irq;
1962 struct amdgpu_irq_src hpd_irq;
1963
1964 /* rings */
1965 wait_queue_head_t fence_queue;
1966 unsigned fence_context;
1967 struct mutex ring_lock;
1968 unsigned num_rings;
1969 struct amdgpu_ring *rings[AMDGPU_MAX_RINGS];
1970 bool ib_pool_ready;
1971 struct amdgpu_sa_manager ring_tmp_bo;
1972
1973 /* interrupts */
1974 struct amdgpu_irq irq;
1975
1976 /* dpm */
1977 struct amdgpu_pm pm;
1978 u32 cg_flags;
1979 u32 pg_flags;
1980
1981 /* amdgpu smumgr */
1982 struct amdgpu_smumgr smu;
1983
1984 /* gfx */
1985 struct amdgpu_gfx gfx;
1986
1987 /* sdma */
1988 struct amdgpu_sdma sdma[2];
1989 struct amdgpu_irq_src sdma_trap_irq;
1990 struct amdgpu_irq_src sdma_illegal_inst_irq;
1991
1992 /* uvd */
1993 bool has_uvd;
1994 struct amdgpu_uvd uvd;
1995
1996 /* vce */
1997 struct amdgpu_vce vce;
1998
1999 /* firmwares */
2000 struct amdgpu_firmware firmware;
2001
2002 /* GDS */
2003 struct amdgpu_gds gds;
2004
2005 const struct amdgpu_ip_block_version *ip_blocks;
2006 int num_ip_blocks;
2007 bool *ip_block_enabled;
2008 struct mutex mn_lock;
2009 DECLARE_HASHTABLE(mn_hash, 7);
2010
2011 /* tracking pinned memory */
2012 u64 vram_pin_size;
2013 u64 gart_pin_size;
2014};
2015
2016bool amdgpu_device_is_px(struct drm_device *dev);
2017int amdgpu_device_init(struct amdgpu_device *adev,
2018 struct drm_device *ddev,
2019 struct pci_dev *pdev,
2020 uint32_t flags);
2021void amdgpu_device_fini(struct amdgpu_device *adev);
2022int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
2023
2024uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
2025 bool always_indirect);
2026void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
2027 bool always_indirect);
2028u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg);
2029void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v);
2030
2031u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index);
2032void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
2033
2034/*
2035 * Cast helper
2036 */
2037extern const struct fence_ops amdgpu_fence_ops;
2038static inline struct amdgpu_fence *to_amdgpu_fence(struct fence *f)
2039{
2040 struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, base);
2041
2042 if (__f->base.ops == &amdgpu_fence_ops)
2043 return __f;
2044
2045 return NULL;
2046}
2047
2048/*
2049 * Registers read & write functions.
2050 */
2051#define RREG32(reg) amdgpu_mm_rreg(adev, (reg), false)
2052#define RREG32_IDX(reg) amdgpu_mm_rreg(adev, (reg), true)
2053#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_mm_rreg(adev, (reg), false))
2054#define WREG32(reg, v) amdgpu_mm_wreg(adev, (reg), (v), false)
2055#define WREG32_IDX(reg, v) amdgpu_mm_wreg(adev, (reg), (v), true)
2056#define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
2057#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
2058#define RREG32_PCIE(reg) adev->pcie_rreg(adev, (reg))
2059#define WREG32_PCIE(reg, v) adev->pcie_wreg(adev, (reg), (v))
2060#define RREG32_SMC(reg) adev->smc_rreg(adev, (reg))
2061#define WREG32_SMC(reg, v) adev->smc_wreg(adev, (reg), (v))
2062#define RREG32_UVD_CTX(reg) adev->uvd_ctx_rreg(adev, (reg))
2063#define WREG32_UVD_CTX(reg, v) adev->uvd_ctx_wreg(adev, (reg), (v))
2064#define RREG32_DIDT(reg) adev->didt_rreg(adev, (reg))
2065#define WREG32_DIDT(reg, v) adev->didt_wreg(adev, (reg), (v))
2066#define RREG32_AUDIO_ENDPT(block, reg) adev->audio_endpt_rreg(adev, (block), (reg))
2067#define WREG32_AUDIO_ENDPT(block, reg, v) adev->audio_endpt_wreg(adev, (block), (reg), (v))
2068#define WREG32_P(reg, val, mask) \
2069 do { \
2070 uint32_t tmp_ = RREG32(reg); \
2071 tmp_ &= (mask); \
2072 tmp_ |= ((val) & ~(mask)); \
2073 WREG32(reg, tmp_); \
2074 } while (0)
2075#define WREG32_AND(reg, and) WREG32_P(reg, 0, and)
2076#define WREG32_OR(reg, or) WREG32_P(reg, or, ~(or))
2077#define WREG32_PLL_P(reg, val, mask) \
2078 do { \
2079 uint32_t tmp_ = RREG32_PLL(reg); \
2080 tmp_ &= (mask); \
2081 tmp_ |= ((val) & ~(mask)); \
2082 WREG32_PLL(reg, tmp_); \
2083 } while (0)
2084#define DREG32_SYS(sqf, adev, reg) seq_printf((sqf), #reg " : 0x%08X\n", amdgpu_mm_rreg((adev), (reg), false))
2085#define RREG32_IO(reg) amdgpu_io_rreg(adev, (reg))
2086#define WREG32_IO(reg, v) amdgpu_io_wreg(adev, (reg), (v))
2087
2088#define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
2089#define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
2090
2091#define REG_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
2092#define REG_FIELD_MASK(reg, field) reg##__##field##_MASK
2093
2094#define REG_SET_FIELD(orig_val, reg, field, field_val) \
2095 (((orig_val) & ~REG_FIELD_MASK(reg, field)) | \
2096 (REG_FIELD_MASK(reg, field) & ((field_val) << REG_FIELD_SHIFT(reg, field))))
2097
2098#define REG_GET_FIELD(value, reg, field) \
2099 (((value) & REG_FIELD_MASK(reg, field)) >> REG_FIELD_SHIFT(reg, field))
2100
2101/*
2102 * BIOS helpers.
2103 */
2104#define RBIOS8(i) (adev->bios[i])
2105#define RBIOS16(i) (RBIOS8(i) | (RBIOS8((i)+1) << 8))
2106#define RBIOS32(i) ((RBIOS16(i)) | (RBIOS16((i)+2) << 16))
2107
2108/*
2109 * RING helpers.
2110 */
2111static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
2112{
2113 if (ring->count_dw <= 0)
2114 DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
2115 ring->ring[ring->wptr++] = v;
2116 ring->wptr &= ring->ptr_mask;
2117 ring->count_dw--;
2118 ring->ring_free_dw--;
2119}
2120
2121/*
2122 * ASICs macro.
2123 */
2124#define amdgpu_asic_set_vga_state(adev, state) (adev)->asic_funcs->set_vga_state((adev), (state))
2125#define amdgpu_asic_reset(adev) (adev)->asic_funcs->reset((adev))
2126#define amdgpu_asic_wait_for_mc_idle(adev) (adev)->asic_funcs->wait_for_mc_idle((adev))
2127#define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev))
2128#define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d))
2129#define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec))
2130#define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev))
2131#define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev))
2132#define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v)))
2133#define amdgpu_asic_get_cu_info(adev, info) (adev)->asic_funcs->get_cu_info((adev), (info))
2134#define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid))
2135#define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags))
2136#define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count)))
2137#define amdgpu_vm_write_pte(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (addr), (count), (incr), (flags)))
2138#define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags)))
2139#define amdgpu_vm_pad_ib(adev, ib) ((adev)->vm_manager.vm_pte_funcs->pad_ib((ib)))
2140#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
2141#define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r))
2142#define amdgpu_ring_test_ib(r) (r)->funcs->test_ib((r))
2143#define amdgpu_ring_is_lockup(r) (r)->funcs->is_lockup((r))
2144#define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r))
2145#define amdgpu_ring_get_wptr(r) (r)->funcs->get_wptr((r))
2146#define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r))
2147#define amdgpu_ring_emit_ib(r, ib) (r)->funcs->emit_ib((r), (ib))
2148#define amdgpu_ring_emit_vm_flush(r, vmid, addr) (r)->funcs->emit_vm_flush((r), (vmid), (addr))
2149#define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags))
2150#define amdgpu_ring_emit_semaphore(r, semaphore, emit_wait) (r)->funcs->emit_semaphore((r), (semaphore), (emit_wait))
2151#define amdgpu_ring_emit_gds_switch(r, v, db, ds, wb, ws, ab, as) (r)->funcs->emit_gds_switch((r), (v), (db), (ds), (wb), (ws), (ab), (as))
2152#define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r))
2153#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
2154#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
2155#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
2156#define amdgpu_display_set_vga_render_state(adev, r) (adev)->mode_info.funcs->set_vga_render_state((adev), (r))
2157#define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc))
2158#define amdgpu_display_vblank_wait(adev, crtc) (adev)->mode_info.funcs->vblank_wait((adev), (crtc))
2159#define amdgpu_display_is_display_hung(adev) (adev)->mode_info.funcs->is_display_hung((adev))
2160#define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l))
2161#define amdgpu_display_backlight_get_level(adev, e) (adev)->mode_info.funcs->backlight_get_level((e))
2162#define amdgpu_display_hpd_sense(adev, h) (adev)->mode_info.funcs->hpd_sense((adev), (h))
2163#define amdgpu_display_hpd_set_polarity(adev, h) (adev)->mode_info.funcs->hpd_set_polarity((adev), (h))
2164#define amdgpu_display_hpd_get_gpio_reg(adev) (adev)->mode_info.funcs->hpd_get_gpio_reg((adev))
2165#define amdgpu_display_bandwidth_update(adev) (adev)->mode_info.funcs->bandwidth_update((adev))
2166#define amdgpu_display_page_flip(adev, crtc, base) (adev)->mode_info.funcs->page_flip((adev), (crtc), (base))
2167#define amdgpu_display_page_flip_get_scanoutpos(adev, crtc, vbl, pos) (adev)->mode_info.funcs->page_flip_get_scanoutpos((adev), (crtc), (vbl), (pos))
2168#define amdgpu_display_add_encoder(adev, e, s, c) (adev)->mode_info.funcs->add_encoder((adev), (e), (s), (c))
2169#define amdgpu_display_add_connector(adev, ci, sd, ct, ib, coi, h, r) (adev)->mode_info.funcs->add_connector((adev), (ci), (sd), (ct), (ib), (coi), (h), (r))
2170#define amdgpu_display_stop_mc_access(adev, s) (adev)->mode_info.funcs->stop_mc_access((adev), (s))
2171#define amdgpu_display_resume_mc_access(adev, s) (adev)->mode_info.funcs->resume_mc_access((adev), (s))
2172#define amdgpu_emit_copy_buffer(adev, r, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((r), (s), (d), (b))
2173#define amdgpu_emit_fill_buffer(adev, r, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((r), (s), (d), (b))
2174#define amdgpu_dpm_get_temperature(adev) (adev)->pm.funcs->get_temperature((adev))
2175#define amdgpu_dpm_pre_set_power_state(adev) (adev)->pm.funcs->pre_set_power_state((adev))
2176#define amdgpu_dpm_set_power_state(adev) (adev)->pm.funcs->set_power_state((adev))
2177#define amdgpu_dpm_post_set_power_state(adev) (adev)->pm.funcs->post_set_power_state((adev))
2178#define amdgpu_dpm_display_configuration_changed(adev) (adev)->pm.funcs->display_configuration_changed((adev))
2179#define amdgpu_dpm_get_sclk(adev, l) (adev)->pm.funcs->get_sclk((adev), (l))
2180#define amdgpu_dpm_get_mclk(adev, l) (adev)->pm.funcs->get_mclk((adev), (l))
2181#define amdgpu_dpm_print_power_state(adev, ps) (adev)->pm.funcs->print_power_state((adev), (ps))
2182#define amdgpu_dpm_debugfs_print_current_performance_level(adev, m) (adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m))
2183#define amdgpu_dpm_force_performance_level(adev, l) (adev)->pm.funcs->force_performance_level((adev), (l))
2184#define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev))
2185#define amdgpu_dpm_powergate_uvd(adev, g) (adev)->pm.funcs->powergate_uvd((adev), (g))
2186#define amdgpu_dpm_powergate_vce(adev, g) (adev)->pm.funcs->powergate_vce((adev), (g))
2187#define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e))
2188#define amdgpu_dpm_set_fan_control_mode(adev, m) (adev)->pm.funcs->set_fan_control_mode((adev), (m))
2189#define amdgpu_dpm_get_fan_control_mode(adev) (adev)->pm.funcs->get_fan_control_mode((adev))
2190#define amdgpu_dpm_set_fan_speed_percent(adev, s) (adev)->pm.funcs->set_fan_speed_percent((adev), (s))
2191#define amdgpu_dpm_get_fan_speed_percent(adev, s) (adev)->pm.funcs->get_fan_speed_percent((adev), (s))
2192
2193#define amdgpu_gds_switch(adev, r, v, d, w, a) (adev)->gds.funcs->patch_gds_switch((r), (v), (d), (w), (a))
2194
2195/* Common functions */
2196int amdgpu_gpu_reset(struct amdgpu_device *adev);
2197void amdgpu_pci_config_reset(struct amdgpu_device *adev);
2198bool amdgpu_card_posted(struct amdgpu_device *adev);
2199void amdgpu_update_display_priority(struct amdgpu_device *adev);
2200bool amdgpu_boot_test_post_card(struct amdgpu_device *adev);
2201int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data);
2202int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,
2203 u32 ip_instance, u32 ring,
2204 struct amdgpu_ring **out_ring);
2205void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain);
2206bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
2207int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
2208 uint32_t flags);
2209bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
2210bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
2211uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
2212 struct ttm_mem_reg *mem);
2213void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base);
2214void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
2215void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
2216void amdgpu_program_register_sequence(struct amdgpu_device *adev,
2217 const u32 *registers,
2218 const u32 array_size);
2219
2220bool amdgpu_device_is_px(struct drm_device *dev);
2221/* atpx handler */
2222#if defined(CONFIG_VGA_SWITCHEROO)
2223void amdgpu_register_atpx_handler(void);
2224void amdgpu_unregister_atpx_handler(void);
2225#else
2226static inline void amdgpu_register_atpx_handler(void) {}
2227static inline void amdgpu_unregister_atpx_handler(void) {}
2228#endif
2229
2230/*
2231 * KMS
2232 */
2233extern const struct drm_ioctl_desc amdgpu_ioctls_kms[];
2234extern int amdgpu_max_kms_ioctl;
2235
2236int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags);
2237int amdgpu_driver_unload_kms(struct drm_device *dev);
2238void amdgpu_driver_lastclose_kms(struct drm_device *dev);
2239int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv);
2240void amdgpu_driver_postclose_kms(struct drm_device *dev,
2241 struct drm_file *file_priv);
2242void amdgpu_driver_preclose_kms(struct drm_device *dev,
2243 struct drm_file *file_priv);
2244int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon);
2245int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
2246u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, int crtc);
2247int amdgpu_enable_vblank_kms(struct drm_device *dev, int crtc);
2248void amdgpu_disable_vblank_kms(struct drm_device *dev, int crtc);
2249int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
2250 int *max_error,
2251 struct timeval *vblank_time,
2252 unsigned flags);
2253long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd,
2254 unsigned long arg);
2255
2256/*
2257 * vm
2258 */
2259int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
2260void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
2261struct amdgpu_bo_list_entry *amdgpu_vm_get_bos(struct amdgpu_device *adev,
2262 struct amdgpu_vm *vm,
2263 struct list_head *head);
2264struct amdgpu_fence *amdgpu_vm_grab_id(struct amdgpu_ring *ring,
2265 struct amdgpu_vm *vm);
2266void amdgpu_vm_flush(struct amdgpu_ring *ring,
2267 struct amdgpu_vm *vm,
2268 struct amdgpu_fence *updates);
2269void amdgpu_vm_fence(struct amdgpu_device *adev,
2270 struct amdgpu_vm *vm,
2271 struct amdgpu_fence *fence);
2272uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr);
2273int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
2274 struct amdgpu_vm *vm);
2275int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
2276 struct amdgpu_vm *vm);
2277int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
2278 struct amdgpu_vm *vm, struct amdgpu_sync *sync);
2279int amdgpu_vm_bo_update(struct amdgpu_device *adev,
2280 struct amdgpu_bo_va *bo_va,
2281 struct ttm_mem_reg *mem);
2282void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
2283 struct amdgpu_bo *bo);
2284struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
2285 struct amdgpu_bo *bo);
2286struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
2287 struct amdgpu_vm *vm,
2288 struct amdgpu_bo *bo);
2289int amdgpu_vm_bo_map(struct amdgpu_device *adev,
2290 struct amdgpu_bo_va *bo_va,
2291 uint64_t addr, uint64_t offset,
2292 uint64_t size, uint32_t flags);
2293int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
2294 struct amdgpu_bo_va *bo_va,
2295 uint64_t addr);
2296void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
2297 struct amdgpu_bo_va *bo_va);
2298
2299/*
2300 * functions used by amdgpu_encoder.c
2301 */
2302struct amdgpu_afmt_acr {
2303 u32 clock;
2304
2305 int n_32khz;
2306 int cts_32khz;
2307
2308 int n_44_1khz;
2309 int cts_44_1khz;
2310
2311 int n_48khz;
2312 int cts_48khz;
2313
2314};
2315
2316struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock);
2317
2318/* amdgpu_acpi.c */
2319#if defined(CONFIG_ACPI)
2320int amdgpu_acpi_init(struct amdgpu_device *adev);
2321void amdgpu_acpi_fini(struct amdgpu_device *adev);
2322bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev);
2323int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
2324 u8 perf_req, bool advertise);
2325int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
2326#else
2327static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; }
2328static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
2329#endif
2330
2331struct amdgpu_bo_va_mapping *
2332amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
2333 uint64_t addr, struct amdgpu_bo **bo);
2334
2335#include "amdgpu_object.h"
2336
2337#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c+768−0
@@ -0,0 +1,768 @@
1/*
2 * Copyright 2012 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/pci.h>
25#include <linux/acpi.h>
26#include <linux/slab.h>
27#include <linux/power_supply.h>
28#include <linux/vga_switcheroo.h>
29#include <acpi/video.h>
30#include <drm/drmP.h>
31#include <drm/drm_crtc_helper.h>
32#include "amdgpu.h"
33#include "amdgpu_acpi.h"
34#include "atom.h"
35
36#define ACPI_AC_CLASS "ac_adapter"
37
38extern void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev);
39
40struct atif_verify_interface {
41 u16 size; /* structure size in bytes (includes size field) */
42 u16 version; /* version */
43 u32 notification_mask; /* supported notifications mask */
44 u32 function_bits; /* supported functions bit vector */
45} __packed;
46
47struct atif_system_params {
48 u16 size; /* structure size in bytes (includes size field) */
49 u32 valid_mask; /* valid flags mask */
50 u32 flags; /* flags */
51 u8 command_code; /* notify command code */
52} __packed;
53
54struct atif_sbios_requests {
55 u16 size; /* structure size in bytes (includes size field) */
56 u32 pending; /* pending sbios requests */
57 u8 panel_exp_mode; /* panel expansion mode */
58 u8 thermal_gfx; /* thermal state: target gfx controller */
59 u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */
60 u8 forced_power_gfx; /* forced power state: target gfx controller */
61 u8 forced_power_state; /* forced power state: state id */
62 u8 system_power_src; /* system power source */
63 u8 backlight_level; /* panel backlight level (0-255) */
64} __packed;
65
66#define ATIF_NOTIFY_MASK 0x3
67#define ATIF_NOTIFY_NONE 0
68#define ATIF_NOTIFY_81 1
69#define ATIF_NOTIFY_N 2
70
71struct atcs_verify_interface {
72 u16 size; /* structure size in bytes (includes size field) */
73 u16 version; /* version */
74 u32 function_bits; /* supported functions bit vector */
75} __packed;
76
77#define ATCS_VALID_FLAGS_MASK 0x3
78
79struct atcs_pref_req_input {
80 u16 size; /* structure size in bytes (includes size field) */
81 u16 client_id; /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
82 u16 valid_flags_mask; /* valid flags mask */
83 u16 flags; /* flags */
84 u8 req_type; /* request type */
85 u8 perf_req; /* performance request */
86} __packed;
87
88struct atcs_pref_req_output {
89 u16 size; /* structure size in bytes (includes size field) */
90 u8 ret_val; /* return value */
91} __packed;
92
93/* Call the ATIF method
94 */
95/**
96 * amdgpu_atif_call - call an ATIF method
97 *
98 * @handle: acpi handle
99 * @function: the ATIF function to execute
100 * @params: ATIF function params
101 *
102 * Executes the requested ATIF function (all asics).
103 * Returns a pointer to the acpi output buffer.
104 */
105static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function,
106 struct acpi_buffer *params)
107{
108 acpi_status status;
109 union acpi_object atif_arg_elements[2];
110 struct acpi_object_list atif_arg;
111 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
112
113 atif_arg.count = 2;
114 atif_arg.pointer = &atif_arg_elements[0];
115
116 atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
117 atif_arg_elements[0].integer.value = function;
118
119 if (params) {
120 atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
121 atif_arg_elements[1].buffer.length = params->length;
122 atif_arg_elements[1].buffer.pointer = params->pointer;
123 } else {
124 /* We need a second fake parameter */
125 atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
126 atif_arg_elements[1].integer.value = 0;
127 }
128
129 status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer);
130
131 /* Fail only if calling the method fails and ATIF is supported */
132 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
133 DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
134 acpi_format_exception(status));
135 kfree(buffer.pointer);
136 return NULL;
137 }
138
139 return buffer.pointer;
140}
141
142/**
143 * amdgpu_atif_parse_notification - parse supported notifications
144 *
145 * @n: supported notifications struct
146 * @mask: supported notifications mask from ATIF
147 *
148 * Use the supported notifications mask from ATIF function
149 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications
150 * are supported (all asics).
151 */
152static void amdgpu_atif_parse_notification(struct amdgpu_atif_notifications *n, u32 mask)
153{
154 n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED;
155 n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED;
156 n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
157 n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
158 n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
159 n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED;
160 n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED;
161 n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
162 n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
163}
164
165/**
166 * amdgpu_atif_parse_functions - parse supported functions
167 *
168 * @f: supported functions struct
169 * @mask: supported functions mask from ATIF
170 *
171 * Use the supported functions mask from ATIF function
172 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions
173 * are supported (all asics).
174 */
175static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mask)
176{
177 f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
178 f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
179 f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED;
180 f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED;
181 f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED;
182 f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED;
183 f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED;
184 f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED;
185 f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
186 f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED;
187}
188
189/**
190 * amdgpu_atif_verify_interface - verify ATIF
191 *
192 * @handle: acpi handle
193 * @atif: amdgpu atif struct
194 *
195 * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function
196 * to initialize ATIF and determine what features are supported
197 * (all asics).
198 * returns 0 on success, error on failure.
199 */
200static int amdgpu_atif_verify_interface(acpi_handle handle,
201 struct amdgpu_atif *atif)
202{
203 union acpi_object *info;
204 struct atif_verify_interface output;
205 size_t size;
206 int err = 0;
207
208 info = amdgpu_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
209 if (!info)
210 return -EIO;
211
212 memset(&output, 0, sizeof(output));
213
214 size = *(u16 *) info->buffer.pointer;
215 if (size < 12) {
216 DRM_INFO("ATIF buffer is too small: %zu\n", size);
217 err = -EINVAL;
218 goto out;
219 }
220 size = min(sizeof(output), size);
221
222 memcpy(&output, info->buffer.pointer, size);
223
224 /* TODO: check version? */
225 DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
226
227 amdgpu_atif_parse_notification(&atif->notifications, output.notification_mask);
228 amdgpu_atif_parse_functions(&atif->functions, output.function_bits);
229
230out:
231 kfree(info);
232 return err;
233}
234
235/**
236 * amdgpu_atif_get_notification_params - determine notify configuration
237 *
238 * @handle: acpi handle
239 * @n: atif notification configuration struct
240 *
241 * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function
242 * to determine if a notifier is used and if so which one
243 * (all asics). This is either Notify(VGA, 0x81) or Notify(VGA, n)
244 * where n is specified in the result if a notifier is used.
245 * Returns 0 on success, error on failure.
246 */
247static int amdgpu_atif_get_notification_params(acpi_handle handle,
248 struct amdgpu_atif_notification_cfg *n)
249{
250 union acpi_object *info;
251 struct atif_system_params params;
252 size_t size;
253 int err = 0;
254
255 info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL);
256 if (!info) {
257 err = -EIO;
258 goto out;
259 }
260
261 size = *(u16 *) info->buffer.pointer;
262 if (size < 10) {
263 err = -EINVAL;
264 goto out;
265 }
266
267 memset(&params, 0, sizeof(params));
268 size = min(sizeof(params), size);
269 memcpy(&params, info->buffer.pointer, size);
270
271 DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
272 params.flags, params.valid_mask);
273 params.flags = params.flags & params.valid_mask;
274
275 if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
276 n->enabled = false;
277 n->command_code = 0;
278 } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
279 n->enabled = true;
280 n->command_code = 0x81;
281 } else {
282 if (size < 11) {
283 err = -EINVAL;
284 goto out;
285 }
286 n->enabled = true;
287 n->command_code = params.command_code;
288 }
289
290out:
291 DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
292 (n->enabled ? "enabled" : "disabled"),
293 n->command_code);
294 kfree(info);
295 return err;
296}
297
298/**
299 * amdgpu_atif_get_sbios_requests - get requested sbios event
300 *
301 * @handle: acpi handle
302 * @req: atif sbios request struct
303 *
304 * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function
305 * to determine what requests the sbios is making to the driver
306 * (all asics).
307 * Returns 0 on success, error on failure.
308 */
309static int amdgpu_atif_get_sbios_requests(acpi_handle handle,
310 struct atif_sbios_requests *req)
311{
312 union acpi_object *info;
313 size_t size;
314 int count = 0;
315
316 info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL);
317 if (!info)
318 return -EIO;
319
320 size = *(u16 *)info->buffer.pointer;
321 if (size < 0xd) {
322 count = -EINVAL;
323 goto out;
324 }
325 memset(req, 0, sizeof(*req));
326
327 size = min(sizeof(*req), size);
328 memcpy(req, info->buffer.pointer, size);
329 DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
330
331 count = hweight32(req->pending);
332
333out:
334 kfree(info);
335 return count;
336}
337
338/**
339 * amdgpu_atif_handler - handle ATIF notify requests
340 *
341 * @adev: amdgpu_device pointer
342 * @event: atif sbios request struct
343 *
344 * Checks the acpi event and if it matches an atif event,
345 * handles it.
346 * Returns NOTIFY code
347 */
348int amdgpu_atif_handler(struct amdgpu_device *adev,
349 struct acpi_bus_event *event)
350{
351 struct amdgpu_atif *atif = &adev->atif;
352 struct atif_sbios_requests req;
353 acpi_handle handle;
354 int count;
355
356 DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
357 event->device_class, event->type);
358
359 if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
360 return NOTIFY_DONE;
361
362 if (!atif->notification_cfg.enabled ||
363 event->type != atif->notification_cfg.command_code)
364 /* Not our event */
365 return NOTIFY_DONE;
366
367 /* Check pending SBIOS requests */
368 handle = ACPI_HANDLE(&adev->pdev->dev);
369 count = amdgpu_atif_get_sbios_requests(handle, &req);
370
371 if (count <= 0)
372 return NOTIFY_DONE;
373
374 DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
375
376 if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
377 struct amdgpu_encoder *enc = atif->encoder_for_bl;
378
379 if (enc) {
380 struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
381
382 DRM_DEBUG_DRIVER("Changing brightness to %d\n",
383 req.backlight_level);
384
385 amdgpu_display_backlight_set_level(adev, enc, req.backlight_level);
386
387#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
388 backlight_force_update(dig->bl_dev,
389 BACKLIGHT_UPDATE_HOTKEY);
390#endif
391 }
392 }
393 /* TODO: check other events */
394
395 /* We've handled the event, stop the notifier chain. The ACPI interface
396 * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
397 * userspace if the event was generated only to signal a SBIOS
398 * request.
399 */
400 return NOTIFY_BAD;
401}
402
403/* Call the ATCS method
404 */
405/**
406 * amdgpu_atcs_call - call an ATCS method
407 *
408 * @handle: acpi handle
409 * @function: the ATCS function to execute
410 * @params: ATCS function params
411 *
412 * Executes the requested ATCS function (all asics).
413 * Returns a pointer to the acpi output buffer.
414 */
415static union acpi_object *amdgpu_atcs_call(acpi_handle handle, int function,
416 struct acpi_buffer *params)
417{
418 acpi_status status;
419 union acpi_object atcs_arg_elements[2];
420 struct acpi_object_list atcs_arg;
421 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
422
423 atcs_arg.count = 2;
424 atcs_arg.pointer = &atcs_arg_elements[0];
425
426 atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;
427 atcs_arg_elements[0].integer.value = function;
428
429 if (params) {
430 atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;
431 atcs_arg_elements[1].buffer.length = params->length;
432 atcs_arg_elements[1].buffer.pointer = params->pointer;
433 } else {
434 /* We need a second fake parameter */
435 atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;
436 atcs_arg_elements[1].integer.value = 0;
437 }
438
439 status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer);
440
441 /* Fail only if calling the method fails and ATIF is supported */
442 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
443 DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
444 acpi_format_exception(status));
445 kfree(buffer.pointer);
446 return NULL;
447 }
448
449 return buffer.pointer;
450}
451
452/**
453 * amdgpu_atcs_parse_functions - parse supported functions
454 *
455 * @f: supported functions struct
456 * @mask: supported functions mask from ATCS
457 *
458 * Use the supported functions mask from ATCS function
459 * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
460 * are supported (all asics).
461 */
462static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mask)
463{
464 f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
465 f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
466 f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
467 f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
468}
469
470/**
471 * amdgpu_atcs_verify_interface - verify ATCS
472 *
473 * @handle: acpi handle
474 * @atcs: amdgpu atcs struct
475 *
476 * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
477 * to initialize ATCS and determine what features are supported
478 * (all asics).
479 * returns 0 on success, error on failure.
480 */
481static int amdgpu_atcs_verify_interface(acpi_handle handle,
482 struct amdgpu_atcs *atcs)
483{
484 union acpi_object *info;
485 struct atcs_verify_interface output;
486 size_t size;
487 int err = 0;
488
489 info = amdgpu_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
490 if (!info)
491 return -EIO;
492
493 memset(&output, 0, sizeof(output));
494
495 size = *(u16 *) info->buffer.pointer;
496 if (size < 8) {
497 DRM_INFO("ATCS buffer is too small: %zu\n", size);
498 err = -EINVAL;
499 goto out;
500 }
501 size = min(sizeof(output), size);
502
503 memcpy(&output, info->buffer.pointer, size);
504
505 /* TODO: check version? */
506 DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
507
508 amdgpu_atcs_parse_functions(&atcs->functions, output.function_bits);
509
510out:
511 kfree(info);
512 return err;
513}
514
515/**
516 * amdgpu_acpi_is_pcie_performance_request_supported
517 *
518 * @adev: amdgpu_device pointer
519 *
520 * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods
521 * are supported (all asics).
522 * returns true if supported, false if not.
523 */
524bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev)
525{
526 struct amdgpu_atcs *atcs = &adev->atcs;
527
528 if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)
529 return true;
530
531 return false;
532}
533
534/**
535 * amdgpu_acpi_pcie_notify_device_ready
536 *
537 * @adev: amdgpu_device pointer
538 *
539 * Executes the PCIE_DEVICE_READY_NOTIFICATION method
540 * (all asics).
541 * returns 0 on success, error on failure.
542 */
543int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev)
544{
545 acpi_handle handle;
546 union acpi_object *info;
547 struct amdgpu_atcs *atcs = &adev->atcs;
548
549 /* Get the device handle */
550 handle = ACPI_HANDLE(&adev->pdev->dev);
551 if (!handle)
552 return -EINVAL;
553
554 if (!atcs->functions.pcie_dev_rdy)
555 return -EINVAL;
556
557 info = amdgpu_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
558 if (!info)
559 return -EIO;
560
561 kfree(info);
562
563 return 0;
564}
565
566/**
567 * amdgpu_acpi_pcie_performance_request
568 *
569 * @adev: amdgpu_device pointer
570 * @perf_req: requested perf level (pcie gen speed)
571 * @advertise: set advertise caps flag if set
572 *
573 * Executes the PCIE_PERFORMANCE_REQUEST method to
574 * change the pcie gen speed (all asics).
575 * returns 0 on success, error on failure.
576 */
577int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
578 u8 perf_req, bool advertise)
579{
580 acpi_handle handle;
581 union acpi_object *info;
582 struct amdgpu_atcs *atcs = &adev->atcs;
583 struct atcs_pref_req_input atcs_input;
584 struct atcs_pref_req_output atcs_output;
585 struct acpi_buffer params;
586 size_t size;
587 u32 retry = 3;
588
589 /* Get the device handle */
590 handle = ACPI_HANDLE(&adev->pdev->dev);
591 if (!handle)
592 return -EINVAL;
593
594 if (!atcs->functions.pcie_perf_req)
595 return -EINVAL;
596
597 atcs_input.size = sizeof(struct atcs_pref_req_input);
598 /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
599 atcs_input.client_id = adev->pdev->devfn | (adev->pdev->bus->number << 8);
600 atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
601 atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
602 if (advertise)
603 atcs_input.flags |= ATCS_ADVERTISE_CAPS;
604 atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
605 atcs_input.perf_req = perf_req;
606
607 params.length = sizeof(struct atcs_pref_req_input);
608 params.pointer = &atcs_input;
609
610 while (retry--) {
611 info = amdgpu_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, &params);
612 if (!info)
613 return -EIO;
614
615 memset(&atcs_output, 0, sizeof(atcs_output));
616
617 size = *(u16 *) info->buffer.pointer;
618 if (size < 3) {
619 DRM_INFO("ATCS buffer is too small: %zu\n", size);
620 kfree(info);
621 return -EINVAL;
622 }
623 size = min(sizeof(atcs_output), size);
624
625 memcpy(&atcs_output, info->buffer.pointer, size);
626
627 kfree(info);
628
629 switch (atcs_output.ret_val) {
630 case ATCS_REQUEST_REFUSED:
631 default:
632 return -EINVAL;
633 case ATCS_REQUEST_COMPLETE:
634 return 0;
635 case ATCS_REQUEST_IN_PROGRESS:
636 udelay(10);
637 break;
638 }
639 }
640
641 return 0;
642}
643
644/**
645 * amdgpu_acpi_event - handle notify events
646 *
647 * @nb: notifier block
648 * @val: val
649 * @data: acpi event
650 *
651 * Calls relevant amdgpu functions in response to various
652 * acpi events.
653 * Returns NOTIFY code
654 */
655static int amdgpu_acpi_event(struct notifier_block *nb,
656 unsigned long val,
657 void *data)
658{
659 struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, acpi_nb);
660 struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
661
662 if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
663 if (power_supply_is_system_supplied() > 0)
664 DRM_DEBUG_DRIVER("pm: AC\n");
665 else
666 DRM_DEBUG_DRIVER("pm: DC\n");
667
668 amdgpu_pm_acpi_event_handler(adev);
669 }
670
671 /* Check for pending SBIOS requests */
672 return amdgpu_atif_handler(adev, entry);
673}
674
675/* Call all ACPI methods here */
676/**
677 * amdgpu_acpi_init - init driver acpi support
678 *
679 * @adev: amdgpu_device pointer
680 *
681 * Verifies the AMD ACPI interfaces and registers with the acpi
682 * notifier chain (all asics).
683 * Returns 0 on success, error on failure.
684 */
685int amdgpu_acpi_init(struct amdgpu_device *adev)
686{
687 acpi_handle handle;
688 struct amdgpu_atif *atif = &adev->atif;
689 struct amdgpu_atcs *atcs = &adev->atcs;
690 int ret;
691
692 /* Get the device handle */
693 handle = ACPI_HANDLE(&adev->pdev->dev);
694
695 if (!adev->bios || !handle)
696 return 0;
697
698 /* Call the ATCS method */
699 ret = amdgpu_atcs_verify_interface(handle, atcs);
700 if (ret) {
701 DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
702 }
703
704 /* Call the ATIF method */
705 ret = amdgpu_atif_verify_interface(handle, atif);
706 if (ret) {
707 DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
708 goto out;
709 }
710
711 if (atif->notifications.brightness_change) {
712 struct drm_encoder *tmp;
713
714 /* Find the encoder controlling the brightness */
715 list_for_each_entry(tmp, &adev->ddev->mode_config.encoder_list,
716 head) {
717 struct amdgpu_encoder *enc = to_amdgpu_encoder(tmp);
718
719 if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
720 enc->enc_priv) {
721 if (adev->is_atom_bios) {
722 struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
723 if (dig->bl_dev) {
724 atif->encoder_for_bl = enc;
725 break;
726 }
727 }
728 }
729 }
730 }
731
732 if (atif->functions.sbios_requests && !atif->functions.system_params) {
733 /* XXX check this workraround, if sbios request function is
734 * present we have to see how it's configured in the system
735 * params
736 */
737 atif->functions.system_params = true;
738 }
739
740 if (atif->functions.system_params) {
741 ret = amdgpu_atif_get_notification_params(handle,
742 &atif->notification_cfg);
743 if (ret) {
744 DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
745 ret);
746 /* Disable notification */
747 atif->notification_cfg.enabled = false;
748 }
749 }
750
751out:
752 adev->acpi_nb.notifier_call = amdgpu_acpi_event;
753 register_acpi_notifier(&adev->acpi_nb);
754
755 return ret;
756}
757
758/**
759 * amdgpu_acpi_fini - tear down driver acpi support
760 *
761 * @adev: amdgpu_device pointer
762 *
763 * Unregisters with the acpi notifier chain (all asics).
764 */
765void amdgpu_acpi_fini(struct amdgpu_device *adev)
766{
767 unregister_acpi_notifier(&adev->acpi_nb);
768}
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h+445−0
@@ -0,0 +1,445 @@
1/*
2 * Copyright 2012 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 AMDGPU_ACPI_H
25#define AMDGPU_ACPI_H
26
27struct amdgpu_device;
28struct acpi_bus_event;
29
30int amdgpu_atif_handler(struct amdgpu_device *adev,
31 struct acpi_bus_event *event);
32
33/* AMD hw uses four ACPI control methods:
34 * 1. ATIF
35 * ARG0: (ACPI_INTEGER) function code
36 * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
37 * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
38 * ATIF provides an entry point for the gfx driver to interact with the sbios.
39 * The AMD ACPI notification mechanism uses Notify (VGA, 0x81) or a custom
40 * notification. Which notification is used as indicated by the ATIF Control
41 * Method GET_SYSTEM_PARAMETERS. When the driver receives Notify (VGA, 0x81) or
42 * a custom notification it invokes ATIF Control Method GET_SYSTEM_BIOS_REQUESTS
43 * to identify pending System BIOS requests and associated parameters. For
44 * example, if one of the pending requests is DISPLAY_SWITCH_REQUEST, the driver
45 * will perform display device detection and invoke ATIF Control Method
46 * SELECT_ACTIVE_DISPLAYS.
47 *
48 * 2. ATPX
49 * ARG0: (ACPI_INTEGER) function code
50 * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
51 * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
52 * ATPX methods are used on PowerXpress systems to handle mux switching and
53 * discrete GPU power control.
54 *
55 * 3. ATRM
56 * ARG0: (ACPI_INTEGER) offset of vbios rom data
57 * ARG1: (ACPI_BUFFER) size of the buffer to fill (up to 4K).
58 * OUTPUT: (ACPI_BUFFER) output buffer
59 * ATRM provides an interfacess to access the discrete GPU vbios image on
60 * PowerXpress systems with multiple GPUs.
61 *
62 * 4. ATCS
63 * ARG0: (ACPI_INTEGER) function code
64 * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
65 * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
66 * ATCS provides an interface to AMD chipset specific functionality.
67 *
68 */
69/* ATIF */
70#define ATIF_FUNCTION_VERIFY_INTERFACE 0x0
71/* ARG0: ATIF_FUNCTION_VERIFY_INTERFACE
72 * ARG1: none
73 * OUTPUT:
74 * WORD - structure size in bytes (includes size field)
75 * WORD - version
76 * DWORD - supported notifications mask
77 * DWORD - supported functions bit vector
78 */
79/* Notifications mask */
80# define ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED (1 << 0)
81# define ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED (1 << 1)
82# define ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED (1 << 2)
83# define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED (1 << 3)
84# define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED (1 << 4)
85# define ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED (1 << 5)
86# define ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED (1 << 6)
87# define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED (1 << 7)
88# define ATIF_DGPU_DISPLAY_EVENT_SUPPORTED (1 << 8)
89/* supported functions vector */
90# define ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED (1 << 0)
91# define ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED (1 << 1)
92# define ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED (1 << 2)
93# define ATIF_GET_LID_STATE_SUPPORTED (1 << 3)
94# define ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED (1 << 4)
95# define ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED (1 << 5)
96# define ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED (1 << 6)
97# define ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED (1 << 7)
98# define ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED (1 << 12)
99# define ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED (1 << 14)
100#define ATIF_FUNCTION_GET_SYSTEM_PARAMETERS 0x1
101/* ARG0: ATIF_FUNCTION_GET_SYSTEM_PARAMETERS
102 * ARG1: none
103 * OUTPUT:
104 * WORD - structure size in bytes (includes size field)
105 * DWORD - valid flags mask
106 * DWORD - flags
107 *
108 * OR
109 *
110 * WORD - structure size in bytes (includes size field)
111 * DWORD - valid flags mask
112 * DWORD - flags
113 * BYTE - notify command code
114 *
115 * flags
116 * bits 1:0:
117 * 0 - Notify(VGA, 0x81) is not used for notification
118 * 1 - Notify(VGA, 0x81) is used for notification
119 * 2 - Notify(VGA, n) is used for notification where
120 * n (0xd0-0xd9) is specified in notify command code.
121 * bit 2:
122 * 1 - lid changes not reported though int10
123 */
124#define ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS 0x2
125/* ARG0: ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS
126 * ARG1: none
127 * OUTPUT:
128 * WORD - structure size in bytes (includes size field)
129 * DWORD - pending sbios requests
130 * BYTE - panel expansion mode
131 * BYTE - thermal state: target gfx controller
132 * BYTE - thermal state: state id (0: exit state, non-0: state)
133 * BYTE - forced power state: target gfx controller
134 * BYTE - forced power state: state id
135 * BYTE - system power source
136 * BYTE - panel backlight level (0-255)
137 */
138/* pending sbios requests */
139# define ATIF_DISPLAY_SWITCH_REQUEST (1 << 0)
140# define ATIF_EXPANSION_MODE_CHANGE_REQUEST (1 << 1)
141# define ATIF_THERMAL_STATE_CHANGE_REQUEST (1 << 2)
142# define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST (1 << 3)
143# define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST (1 << 4)
144# define ATIF_DISPLAY_CONF_CHANGE_REQUEST (1 << 5)
145# define ATIF_PX_GFX_SWITCH_REQUEST (1 << 6)
146# define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST (1 << 7)
147# define ATIF_DGPU_DISPLAY_EVENT (1 << 8)
148/* panel expansion mode */
149# define ATIF_PANEL_EXPANSION_DISABLE 0
150# define ATIF_PANEL_EXPANSION_FULL 1
151# define ATIF_PANEL_EXPANSION_ASPECT 2
152/* target gfx controller */
153# define ATIF_TARGET_GFX_SINGLE 0
154# define ATIF_TARGET_GFX_PX_IGPU 1
155# define ATIF_TARGET_GFX_PX_DGPU 2
156/* system power source */
157# define ATIF_POWER_SOURCE_AC 1
158# define ATIF_POWER_SOURCE_DC 2
159# define ATIF_POWER_SOURCE_RESTRICTED_AC_1 3
160# define ATIF_POWER_SOURCE_RESTRICTED_AC_2 4
161#define ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS 0x3
162/* ARG0: ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS
163 * ARG1:
164 * WORD - structure size in bytes (includes size field)
165 * WORD - selected displays
166 * WORD - connected displays
167 * OUTPUT:
168 * WORD - structure size in bytes (includes size field)
169 * WORD - selected displays
170 */
171# define ATIF_LCD1 (1 << 0)
172# define ATIF_CRT1 (1 << 1)
173# define ATIF_TV (1 << 2)
174# define ATIF_DFP1 (1 << 3)
175# define ATIF_CRT2 (1 << 4)
176# define ATIF_LCD2 (1 << 5)
177# define ATIF_DFP2 (1 << 7)
178# define ATIF_CV (1 << 8)
179# define ATIF_DFP3 (1 << 9)
180# define ATIF_DFP4 (1 << 10)
181# define ATIF_DFP5 (1 << 11)
182# define ATIF_DFP6 (1 << 12)
183#define ATIF_FUNCTION_GET_LID_STATE 0x4
184/* ARG0: ATIF_FUNCTION_GET_LID_STATE
185 * ARG1: none
186 * OUTPUT:
187 * WORD - structure size in bytes (includes size field)
188 * BYTE - lid state (0: open, 1: closed)
189 *
190 * GET_LID_STATE only works at boot and resume, for general lid
191 * status, use the kernel provided status
192 */
193#define ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS 0x5
194/* ARG0: ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS
195 * ARG1: none
196 * OUTPUT:
197 * WORD - structure size in bytes (includes size field)
198 * BYTE - 0
199 * BYTE - TV standard
200 */
201# define ATIF_TV_STD_NTSC 0
202# define ATIF_TV_STD_PAL 1
203# define ATIF_TV_STD_PALM 2
204# define ATIF_TV_STD_PAL60 3
205# define ATIF_TV_STD_NTSCJ 4
206# define ATIF_TV_STD_PALCN 5
207# define ATIF_TV_STD_PALN 6
208# define ATIF_TV_STD_SCART_RGB 9
209#define ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS 0x6
210/* ARG0: ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS
211 * ARG1:
212 * WORD - structure size in bytes (includes size field)
213 * BYTE - 0
214 * BYTE - TV standard
215 * OUTPUT: none
216 */
217#define ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS 0x7
218/* ARG0: ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS
219 * ARG1: none
220 * OUTPUT:
221 * WORD - structure size in bytes (includes size field)
222 * BYTE - panel expansion mode
223 */
224#define ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS 0x8
225/* ARG0: ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS
226 * ARG1:
227 * WORD - structure size in bytes (includes size field)
228 * BYTE - panel expansion mode
229 * OUTPUT: none
230 */
231#define ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION 0xD
232/* ARG0: ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION
233 * ARG1:
234 * WORD - structure size in bytes (includes size field)
235 * WORD - gfx controller id
236 * BYTE - current temperature (degress Celsius)
237 * OUTPUT: none
238 */
239#define ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES 0xF
240/* ARG0: ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES
241 * ARG1: none
242 * OUTPUT:
243 * WORD - number of gfx devices
244 * WORD - device structure size in bytes (excludes device size field)
245 * DWORD - flags \
246 * WORD - bus number } repeated structure
247 * WORD - device number /
248 */
249/* flags */
250# define ATIF_PX_REMOVABLE_GRAPHICS_DEVICE (1 << 0)
251# define ATIF_XGP_PORT (1 << 1)
252# define ATIF_VGA_ENABLED_GRAPHICS_DEVICE (1 << 2)
253# define ATIF_XGP_PORT_IN_DOCK (1 << 3)
254
255/* ATPX */
256#define ATPX_FUNCTION_VERIFY_INTERFACE 0x0
257/* ARG0: ATPX_FUNCTION_VERIFY_INTERFACE
258 * ARG1: none
259 * OUTPUT:
260 * WORD - structure size in bytes (includes size field)
261 * WORD - version
262 * DWORD - supported functions bit vector
263 */
264/* supported functions vector */
265# define ATPX_GET_PX_PARAMETERS_SUPPORTED (1 << 0)
266# define ATPX_POWER_CONTROL_SUPPORTED (1 << 1)
267# define ATPX_DISPLAY_MUX_CONTROL_SUPPORTED (1 << 2)
268# define ATPX_I2C_MUX_CONTROL_SUPPORTED (1 << 3)
269# define ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED (1 << 4)
270# define ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED (1 << 5)
271# define ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED (1 << 7)
272# define ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED (1 << 8)
273#define ATPX_FUNCTION_GET_PX_PARAMETERS 0x1
274/* ARG0: ATPX_FUNCTION_GET_PX_PARAMETERS
275 * ARG1: none
276 * OUTPUT:
277 * WORD - structure size in bytes (includes size field)
278 * DWORD - valid flags mask
279 * DWORD - flags
280 */
281/* flags */
282# define ATPX_LVDS_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 0)
283# define ATPX_CRT1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 1)
284# define ATPX_DVI1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 2)
285# define ATPX_CRT1_RGB_SIGNAL_MUXED (1 << 3)
286# define ATPX_TV_SIGNAL_MUXED (1 << 4)
287# define ATPX_DFP_SIGNAL_MUXED (1 << 5)
288# define ATPX_SEPARATE_MUX_FOR_I2C (1 << 6)
289# define ATPX_DYNAMIC_PX_SUPPORTED (1 << 7)
290# define ATPX_ACF_NOT_SUPPORTED (1 << 8)
291# define ATPX_FIXED_NOT_SUPPORTED (1 << 9)
292# define ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED (1 << 10)
293# define ATPX_DGPU_REQ_POWER_FOR_DISPLAYS (1 << 11)
294#define ATPX_FUNCTION_POWER_CONTROL 0x2
295/* ARG0: ATPX_FUNCTION_POWER_CONTROL
296 * ARG1:
297 * WORD - structure size in bytes (includes size field)
298 * BYTE - dGPU power state (0: power off, 1: power on)
299 * OUTPUT: none
300 */
301#define ATPX_FUNCTION_DISPLAY_MUX_CONTROL 0x3
302/* ARG0: ATPX_FUNCTION_DISPLAY_MUX_CONTROL
303 * ARG1:
304 * WORD - structure size in bytes (includes size field)
305 * WORD - display mux control (0: iGPU, 1: dGPU)
306 * OUTPUT: none
307 */
308# define ATPX_INTEGRATED_GPU 0
309# define ATPX_DISCRETE_GPU 1
310#define ATPX_FUNCTION_I2C_MUX_CONTROL 0x4
311/* ARG0: ATPX_FUNCTION_I2C_MUX_CONTROL
312 * ARG1:
313 * WORD - structure size in bytes (includes size field)
314 * WORD - i2c/aux/hpd mux control (0: iGPU, 1: dGPU)
315 * OUTPUT: none
316 */
317#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION 0x5
318/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION
319 * ARG1:
320 * WORD - structure size in bytes (includes size field)
321 * WORD - target gpu (0: iGPU, 1: dGPU)
322 * OUTPUT: none
323 */
324#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION 0x6
325/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION
326 * ARG1:
327 * WORD - structure size in bytes (includes size field)
328 * WORD - target gpu (0: iGPU, 1: dGPU)
329 * OUTPUT: none
330 */
331#define ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING 0x8
332/* ARG0: ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING
333 * ARG1: none
334 * OUTPUT:
335 * WORD - number of display connectors
336 * WORD - connector structure size in bytes (excludes connector size field)
337 * BYTE - flags \
338 * BYTE - ATIF display vector bit position } repeated
339 * BYTE - adapter id (0: iGPU, 1-n: dGPU ordered by pcie bus number) } structure
340 * WORD - connector ACPI id /
341 */
342/* flags */
343# define ATPX_DISPLAY_OUTPUT_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 0)
344# define ATPX_DISPLAY_HPD_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 1)
345# define ATPX_DISPLAY_I2C_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 2)
346#define ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS 0x9
347/* ARG0: ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS
348 * ARG1: none
349 * OUTPUT:
350 * WORD - number of HPD/DDC ports
351 * WORD - port structure size in bytes (excludes port size field)
352 * BYTE - ATIF display vector bit position \
353 * BYTE - hpd id } reapeated structure
354 * BYTE - ddc id /
355 *
356 * available on A+A systems only
357 */
358/* hpd id */
359# define ATPX_HPD_NONE 0
360# define ATPX_HPD1 1
361# define ATPX_HPD2 2
362# define ATPX_HPD3 3
363# define ATPX_HPD4 4
364# define ATPX_HPD5 5
365# define ATPX_HPD6 6
366/* ddc id */
367# define ATPX_DDC_NONE 0
368# define ATPX_DDC1 1
369# define ATPX_DDC2 2
370# define ATPX_DDC3 3
371# define ATPX_DDC4 4
372# define ATPX_DDC5 5
373# define ATPX_DDC6 6
374# define ATPX_DDC7 7
375# define ATPX_DDC8 8
376
377/* ATCS */
378#define ATCS_FUNCTION_VERIFY_INTERFACE 0x0
379/* ARG0: ATCS_FUNCTION_VERIFY_INTERFACE
380 * ARG1: none
381 * OUTPUT:
382 * WORD - structure size in bytes (includes size field)
383 * WORD - version
384 * DWORD - supported functions bit vector
385 */
386/* supported functions vector */
387# define ATCS_GET_EXTERNAL_STATE_SUPPORTED (1 << 0)
388# define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED (1 << 1)
389# define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED (1 << 2)
390# define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED (1 << 3)
391#define ATCS_FUNCTION_GET_EXTERNAL_STATE 0x1
392/* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE
393 * ARG1: none
394 * OUTPUT:
395 * WORD - structure size in bytes (includes size field)
396 * DWORD - valid flags mask
397 * DWORD - flags (0: undocked, 1: docked)
398 */
399/* flags */
400# define ATCS_DOCKED (1 << 0)
401#define ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST 0x2
402/* ARG0: ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST
403 * ARG1:
404 * WORD - structure size in bytes (includes size field)
405 * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
406 * WORD - valid flags mask
407 * WORD - flags
408 * BYTE - request type
409 * BYTE - performance request
410 * OUTPUT:
411 * WORD - structure size in bytes (includes size field)
412 * BYTE - return value
413 */
414/* flags */
415# define ATCS_ADVERTISE_CAPS (1 << 0)
416# define ATCS_WAIT_FOR_COMPLETION (1 << 1)
417/* request type */
418# define ATCS_PCIE_LINK_SPEED 1
419/* performance request */
420# define ATCS_REMOVE 0
421# define ATCS_FORCE_LOW_POWER 1
422# define ATCS_PERF_LEVEL_1 2 /* PCIE Gen 1 */
423# define ATCS_PERF_LEVEL_2 3 /* PCIE Gen 2 */
424# define ATCS_PERF_LEVEL_3 4 /* PCIE Gen 3 */
425/* return value */
426# define ATCS_REQUEST_REFUSED 1
427# define ATCS_REQUEST_COMPLETE 2
428# define ATCS_REQUEST_IN_PROGRESS 3
429#define ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION 0x3
430/* ARG0: ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION
431 * ARG1: none
432 * OUTPUT: none
433 */
434#define ATCS_FUNCTION_SET_PCIE_BUS_WIDTH 0x4
435/* ARG0: ATCS_FUNCTION_SET_PCIE_BUS_WIDTH
436 * ARG1:
437 * WORD - structure size in bytes (includes size field)
438 * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
439 * BYTE - number of active lanes
440 * OUTPUT:
441 * WORD - structure size in bytes (includes size field)
442 * BYTE - number of active lanes
443 */
444
445#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c+105−0
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Christian König.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Christian König
25 */
26#include <linux/hdmi.h>
27#include <linux/gcd.h>
28#include <drm/drmP.h>
29#include <drm/amdgpu_drm.h>
30#include "amdgpu.h"
31
32static const struct amdgpu_afmt_acr amdgpu_afmt_predefined_acr[] = {
33 /* 32kHz 44.1kHz 48kHz */
34 /* Clock N CTS N CTS N CTS */
35 { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */
36 { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
37 { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
38 { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
39 { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
40 { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
41 { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */
42 { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
43 { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */
44 { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
45};
46
47
48/*
49 * calculate CTS and N values if they are not found in the table
50 */
51static void amdgpu_afmt_calc_cts(uint32_t clock, int *CTS, int *N, int freq)
52{
53 int n, cts;
54 unsigned long div, mul;
55
56 /* Safe, but overly large values */
57 n = 128 * freq;
58 cts = clock * 1000;
59
60 /* Smallest valid fraction */
61 div = gcd(n, cts);
62
63 n /= div;
64 cts /= div;
65
66 /*
67 * The optimal N is 128*freq/1000. Calculate the closest larger
68 * value that doesn't truncate any bits.
69 */
70 mul = ((128*freq/1000) + (n-1))/n;
71
72 n *= mul;
73 cts *= mul;
74
75 /* Check that we are in spec (not always possible) */
76 if (n < (128*freq/1500))
77 printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n");
78 if (n > (128*freq/300))
79 printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n");
80
81 *N = n;
82 *CTS = cts;
83
84 DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
85 *N, *CTS, freq);
86}
87
88struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock)
89{
90 struct amdgpu_afmt_acr res;
91 u8 i;
92
93 /* Precalculated values for common clocks */
94 for (i = 0; i < ARRAY_SIZE(amdgpu_afmt_predefined_acr); i++) {
95 if (amdgpu_afmt_predefined_acr[i].clock == clock)
96 return amdgpu_afmt_predefined_acr[i];
97 }
98
99 /* And odd clocks get manually calculated */
100 amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
101 amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
102 amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
103
104 return res;
105}
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c+1598−0
@@ -0,0 +1,1598 @@
1/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
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: Dave Airlie
24 * Alex Deucher
25 */
26#include <drm/drmP.h>
27#include <drm/amdgpu_drm.h>
28#include "amdgpu.h"
29#include "amdgpu_atombios.h"
30#include "amdgpu_i2c.h"
31
32#include "atom.h"
33#include "atom-bits.h"
34#include "atombios_encoders.h"
35#include "bif/bif_4_1_d.h"
36
37static void amdgpu_atombios_lookup_i2c_gpio_quirks(struct amdgpu_device *adev,
38 ATOM_GPIO_I2C_ASSIGMENT *gpio,
39 u8 index)
40{
41
42}
43
44static struct amdgpu_i2c_bus_rec amdgpu_atombios_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio)
45{
46 struct amdgpu_i2c_bus_rec i2c;
47
48 memset(&i2c, 0, sizeof(struct amdgpu_i2c_bus_rec));
49
50 i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex);
51 i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex);
52 i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex);
53 i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex);
54 i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex);
55 i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex);
56 i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex);
57 i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex);
58 i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
59 i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
60 i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
61 i2c.en_data_mask = (1 << gpio->ucDataEnShift);
62 i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
63 i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
64 i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
65 i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
66
67 if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
68 i2c.hw_capable = true;
69 else
70 i2c.hw_capable = false;
71
72 if (gpio->sucI2cId.ucAccess == 0xa0)
73 i2c.mm_i2c = true;
74 else
75 i2c.mm_i2c = false;
76
77 i2c.i2c_id = gpio->sucI2cId.ucAccess;
78
79 if (i2c.mask_clk_reg)
80 i2c.valid = true;
81 else
82 i2c.valid = false;
83
84 return i2c;
85}
86
87struct amdgpu_i2c_bus_rec amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device *adev,
88 uint8_t id)
89{
90 struct atom_context *ctx = adev->mode_info.atom_context;
91 ATOM_GPIO_I2C_ASSIGMENT *gpio;
92 struct amdgpu_i2c_bus_rec i2c;
93 int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
94 struct _ATOM_GPIO_I2C_INFO *i2c_info;
95 uint16_t data_offset, size;
96 int i, num_indices;
97
98 memset(&i2c, 0, sizeof(struct amdgpu_i2c_bus_rec));
99 i2c.valid = false;
100
101 if (amdgpu_atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
102 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
103
104 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
105 sizeof(ATOM_GPIO_I2C_ASSIGMENT);
106
107 gpio = &i2c_info->asGPIO_Info[0];
108 for (i = 0; i < num_indices; i++) {
109
110 amdgpu_atombios_lookup_i2c_gpio_quirks(adev, gpio, i);
111
112 if (gpio->sucI2cId.ucAccess == id) {
113 i2c = amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio);
114 break;
115 }
116 gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
117 ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
118 }
119 }
120
121 return i2c;
122}
123
124void amdgpu_atombios_i2c_init(struct amdgpu_device *adev)
125{
126 struct atom_context *ctx = adev->mode_info.atom_context;
127 ATOM_GPIO_I2C_ASSIGMENT *gpio;
128 struct amdgpu_i2c_bus_rec i2c;
129 int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
130 struct _ATOM_GPIO_I2C_INFO *i2c_info;
131 uint16_t data_offset, size;
132 int i, num_indices;
133 char stmp[32];
134
135 if (amdgpu_atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
136 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
137
138 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
139 sizeof(ATOM_GPIO_I2C_ASSIGMENT);
140
141 gpio = &i2c_info->asGPIO_Info[0];
142 for (i = 0; i < num_indices; i++) {
143 amdgpu_atombios_lookup_i2c_gpio_quirks(adev, gpio, i);
144
145 i2c = amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio);
146
147 if (i2c.valid) {
148 sprintf(stmp, "0x%x", i2c.i2c_id);
149 adev->i2c_bus[i] = amdgpu_i2c_create(adev->ddev, &i2c, stmp);
150 }
151 gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
152 ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
153 }
154 }
155}
156
157struct amdgpu_gpio_rec
158amdgpu_atombios_lookup_gpio(struct amdgpu_device *adev,
159 u8 id)
160{
161 struct atom_context *ctx = adev->mode_info.atom_context;
162 struct amdgpu_gpio_rec gpio;
163 int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);
164 struct _ATOM_GPIO_PIN_LUT *gpio_info;
165 ATOM_GPIO_PIN_ASSIGNMENT *pin;
166 u16 data_offset, size;
167 int i, num_indices;
168
169 memset(&gpio, 0, sizeof(struct amdgpu_gpio_rec));
170 gpio.valid = false;
171
172 if (amdgpu_atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
173 gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
174
175 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
176 sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
177
178 pin = gpio_info->asGPIO_Pin;
179 for (i = 0; i < num_indices; i++) {
180 if (id == pin->ucGPIO_ID) {
181 gpio.id = pin->ucGPIO_ID;
182 gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex);
183 gpio.shift = pin->ucGpioPinBitShift;
184 gpio.mask = (1 << pin->ucGpioPinBitShift);
185 gpio.valid = true;
186 break;
187 }
188 pin = (ATOM_GPIO_PIN_ASSIGNMENT *)
189 ((u8 *)pin + sizeof(ATOM_GPIO_PIN_ASSIGNMENT));
190 }
191 }
192
193 return gpio;
194}
195
196static struct amdgpu_hpd
197amdgpu_atombios_get_hpd_info_from_gpio(struct amdgpu_device *adev,
198 struct amdgpu_gpio_rec *gpio)
199{
200 struct amdgpu_hpd hpd;
201 u32 reg;
202
203 memset(&hpd, 0, sizeof(struct amdgpu_hpd));
204
205 reg = amdgpu_display_hpd_get_gpio_reg(adev);
206
207 hpd.gpio = *gpio;
208 if (gpio->reg == reg) {
209 switch(gpio->mask) {
210 case (1 << 0):
211 hpd.hpd = AMDGPU_HPD_1;
212 break;
213 case (1 << 8):
214 hpd.hpd = AMDGPU_HPD_2;
215 break;
216 case (1 << 16):
217 hpd.hpd = AMDGPU_HPD_3;
218 break;
219 case (1 << 24):
220 hpd.hpd = AMDGPU_HPD_4;
221 break;
222 case (1 << 26):
223 hpd.hpd = AMDGPU_HPD_5;
224 break;
225 case (1 << 28):
226 hpd.hpd = AMDGPU_HPD_6;
227 break;
228 default:
229 hpd.hpd = AMDGPU_HPD_NONE;
230 break;
231 }
232 } else
233 hpd.hpd = AMDGPU_HPD_NONE;
234 return hpd;
235}
236
237static bool amdgpu_atombios_apply_quirks(struct amdgpu_device *adev,
238 uint32_t supported_device,
239 int *connector_type,
240 struct amdgpu_i2c_bus_rec *i2c_bus,
241 uint16_t *line_mux,
242 struct amdgpu_hpd *hpd)
243{
244 return true;
245}
246
247static const int object_connector_convert[] = {
248 DRM_MODE_CONNECTOR_Unknown,
249 DRM_MODE_CONNECTOR_DVII,
250 DRM_MODE_CONNECTOR_DVII,
251 DRM_MODE_CONNECTOR_DVID,
252 DRM_MODE_CONNECTOR_DVID,
253 DRM_MODE_CONNECTOR_VGA,
254 DRM_MODE_CONNECTOR_Composite,
255 DRM_MODE_CONNECTOR_SVIDEO,
256 DRM_MODE_CONNECTOR_Unknown,
257 DRM_MODE_CONNECTOR_Unknown,
258 DRM_MODE_CONNECTOR_9PinDIN,
259 DRM_MODE_CONNECTOR_Unknown,
260 DRM_MODE_CONNECTOR_HDMIA,
261 DRM_MODE_CONNECTOR_HDMIB,
262 DRM_MODE_CONNECTOR_LVDS,
263 DRM_MODE_CONNECTOR_9PinDIN,
264 DRM_MODE_CONNECTOR_Unknown,
265 DRM_MODE_CONNECTOR_Unknown,
266 DRM_MODE_CONNECTOR_Unknown,
267 DRM_MODE_CONNECTOR_DisplayPort,
268 DRM_MODE_CONNECTOR_eDP,
269 DRM_MODE_CONNECTOR_Unknown
270};
271
272bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev)
273{
274 struct amdgpu_mode_info *mode_info = &adev->mode_info;
275 struct atom_context *ctx = mode_info->atom_context;
276 int index = GetIndexIntoMasterTable(DATA, Object_Header);
277 u16 size, data_offset;
278 u8 frev, crev;
279 ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
280 ATOM_ENCODER_OBJECT_TABLE *enc_obj;
281 ATOM_OBJECT_TABLE *router_obj;
282 ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
283 ATOM_OBJECT_HEADER *obj_header;
284 int i, j, k, path_size, device_support;
285 int connector_type;
286 u16 conn_id, connector_object_id;
287 struct amdgpu_i2c_bus_rec ddc_bus;
288 struct amdgpu_router router;
289 struct amdgpu_gpio_rec gpio;
290 struct amdgpu_hpd hpd;
291
292 if (!amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
293 return false;
294
295 if (crev < 2)
296 return false;
297
298 obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);
299 path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
300 (ctx->bios + data_offset +
301 le16_to_cpu(obj_header->usDisplayPathTableOffset));
302 con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
303 (ctx->bios + data_offset +
304 le16_to_cpu(obj_header->usConnectorObjectTableOffset));
305 enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)
306 (ctx->bios + data_offset +
307 le16_to_cpu(obj_header->usEncoderObjectTableOffset));
308 router_obj = (ATOM_OBJECT_TABLE *)
309 (ctx->bios + data_offset +
310 le16_to_cpu(obj_header->usRouterObjectTableOffset));
311 device_support = le16_to_cpu(obj_header->usDeviceSupport);
312
313 path_size = 0;
314 for (i = 0; i < path_obj->ucNumOfDispPath; i++) {
315 uint8_t *addr = (uint8_t *) path_obj->asDispPath;
316 ATOM_DISPLAY_OBJECT_PATH *path;
317 addr += path_size;
318 path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
319 path_size += le16_to_cpu(path->usSize);
320
321 if (device_support & le16_to_cpu(path->usDeviceTag)) {
322 uint8_t con_obj_id, con_obj_num, con_obj_type;
323
324 con_obj_id =
325 (le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK)
326 >> OBJECT_ID_SHIFT;
327 con_obj_num =
328 (le16_to_cpu(path->usConnObjectId) & ENUM_ID_MASK)
329 >> ENUM_ID_SHIFT;
330 con_obj_type =
331 (le16_to_cpu(path->usConnObjectId) &
332 OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
333
334 connector_type =
335 object_connector_convert[con_obj_id];
336 connector_object_id = con_obj_id;
337
338 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
339 continue;
340
341 router.ddc_valid = false;
342 router.cd_valid = false;
343 for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {
344 uint8_t grph_obj_id, grph_obj_num, grph_obj_type;
345
346 grph_obj_id =
347 (le16_to_cpu(path->usGraphicObjIds[j]) &
348 OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
349 grph_obj_num =
350 (le16_to_cpu(path->usGraphicObjIds[j]) &
351 ENUM_ID_MASK) >> ENUM_ID_SHIFT;
352 grph_obj_type =
353 (le16_to_cpu(path->usGraphicObjIds[j]) &
354 OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
355
356 if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
357 for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {
358 u16 encoder_obj = le16_to_cpu(enc_obj->asObjects[k].usObjectID);
359 if (le16_to_cpu(path->usGraphicObjIds[j]) == encoder_obj) {
360 ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
361 (ctx->bios + data_offset +
362 le16_to_cpu(enc_obj->asObjects[k].usRecordOffset));
363 ATOM_ENCODER_CAP_RECORD *cap_record;
364 u16 caps = 0;
365
366 while (record->ucRecordSize > 0 &&
367 record->ucRecordType > 0 &&
368 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
369 switch (record->ucRecordType) {
370 case ATOM_ENCODER_CAP_RECORD_TYPE:
371 cap_record =(ATOM_ENCODER_CAP_RECORD *)
372 record;
373 caps = le16_to_cpu(cap_record->usEncoderCap);
374 break;
375 }
376 record = (ATOM_COMMON_RECORD_HEADER *)
377 ((char *)record + record->ucRecordSize);
378 }
379 amdgpu_display_add_encoder(adev, encoder_obj,
380 le16_to_cpu(path->usDeviceTag),
381 caps);
382 }
383 }
384 } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) {
385 for (k = 0; k < router_obj->ucNumberOfObjects; k++) {
386 u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID);
387 if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) {
388 ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
389 (ctx->bios + data_offset +
390 le16_to_cpu(router_obj->asObjects[k].usRecordOffset));
391 ATOM_I2C_RECORD *i2c_record;
392 ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
393 ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path;
394 ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path;
395 ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table =
396 (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
397 (ctx->bios + data_offset +
398 le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset));
399 u8 *num_dst_objs = (u8 *)
400 ((u8 *)router_src_dst_table + 1 +
401 (router_src_dst_table->ucNumberOfSrc * 2));
402 u16 *dst_objs = (u16 *)(num_dst_objs + 1);
403 int enum_id;
404
405 router.router_id = router_obj_id;
406 for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) {
407 if (le16_to_cpu(path->usConnObjectId) ==
408 le16_to_cpu(dst_objs[enum_id]))
409 break;
410 }
411
412 while (record->ucRecordSize > 0 &&
413 record->ucRecordType > 0 &&
414 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
415 switch (record->ucRecordType) {
416 case ATOM_I2C_RECORD_TYPE:
417 i2c_record =
418 (ATOM_I2C_RECORD *)
419 record;
420 i2c_config =
421 (ATOM_I2C_ID_CONFIG_ACCESS *)
422 &i2c_record->sucI2cId;
423 router.i2c_info =
424 amdgpu_atombios_lookup_i2c_gpio(adev,
425 i2c_config->
426 ucAccess);
427 router.i2c_addr = i2c_record->ucI2CAddr >> 1;
428 break;
429 case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE:
430 ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *)
431 record;
432 router.ddc_valid = true;
433 router.ddc_mux_type = ddc_path->ucMuxType;
434 router.ddc_mux_control_pin = ddc_path->ucMuxControlPin;
435 router.ddc_mux_state = ddc_path->ucMuxState[enum_id];
436 break;
437 case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE:
438 cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *)
439 record;
440 router.cd_valid = true;
441 router.cd_mux_type = cd_path->ucMuxType;
442 router.cd_mux_control_pin = cd_path->ucMuxControlPin;
443 router.cd_mux_state = cd_path->ucMuxState[enum_id];
444 break;
445 }
446 record = (ATOM_COMMON_RECORD_HEADER *)
447 ((char *)record + record->ucRecordSize);
448 }
449 }
450 }
451 }
452 }
453
454 /* look up gpio for ddc, hpd */
455 ddc_bus.valid = false;
456 hpd.hpd = AMDGPU_HPD_NONE;
457 if ((le16_to_cpu(path->usDeviceTag) &
458 (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
459 for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
460 if (le16_to_cpu(path->usConnObjectId) ==
461 le16_to_cpu(con_obj->asObjects[j].
462 usObjectID)) {
463 ATOM_COMMON_RECORD_HEADER
464 *record =
465 (ATOM_COMMON_RECORD_HEADER
466 *)
467 (ctx->bios + data_offset +
468 le16_to_cpu(con_obj->
469 asObjects[j].
470 usRecordOffset));
471 ATOM_I2C_RECORD *i2c_record;
472 ATOM_HPD_INT_RECORD *hpd_record;
473 ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
474
475 while (record->ucRecordSize > 0 &&
476 record->ucRecordType > 0 &&
477 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
478 switch (record->ucRecordType) {
479 case ATOM_I2C_RECORD_TYPE:
480 i2c_record =
481 (ATOM_I2C_RECORD *)
482 record;
483 i2c_config =
484 (ATOM_I2C_ID_CONFIG_ACCESS *)
485 &i2c_record->sucI2cId;
486 ddc_bus = amdgpu_atombios_lookup_i2c_gpio(adev,
487 i2c_config->
488 ucAccess);
489 break;
490 case ATOM_HPD_INT_RECORD_TYPE:
491 hpd_record =
492 (ATOM_HPD_INT_RECORD *)
493 record;
494 gpio = amdgpu_atombios_lookup_gpio(adev,
495 hpd_record->ucHPDIntGPIOID);
496 hpd = amdgpu_atombios_get_hpd_info_from_gpio(adev, &gpio);
497 hpd.plugged_state = hpd_record->ucPlugged_PinState;
498 break;
499 }
500 record =
501 (ATOM_COMMON_RECORD_HEADER
502 *) ((char *)record
503 +
504 record->
505 ucRecordSize);
506 }
507 break;
508 }
509 }
510 }
511
512 /* needed for aux chan transactions */
513 ddc_bus.hpd = hpd.hpd;
514
515 conn_id = le16_to_cpu(path->usConnObjectId);
516
517 if (!amdgpu_atombios_apply_quirks
518 (adev, le16_to_cpu(path->usDeviceTag), &connector_type,
519 &ddc_bus, &conn_id, &hpd))
520 continue;
521
522 amdgpu_display_add_connector(adev,
523 conn_id,
524 le16_to_cpu(path->usDeviceTag),
525 connector_type, &ddc_bus,
526 connector_object_id,
527 &hpd,
528 &router);
529
530 }
531 }
532
533 amdgpu_link_encoder_connector(adev->ddev);
534
535 return true;
536}
537
538union firmware_info {
539 ATOM_FIRMWARE_INFO info;
540 ATOM_FIRMWARE_INFO_V1_2 info_12;
541 ATOM_FIRMWARE_INFO_V1_3 info_13;
542 ATOM_FIRMWARE_INFO_V1_4 info_14;
543 ATOM_FIRMWARE_INFO_V2_1 info_21;
544 ATOM_FIRMWARE_INFO_V2_2 info_22;
545};
546
547int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev)
548{
549 struct amdgpu_mode_info *mode_info = &adev->mode_info;
550 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
551 uint8_t frev, crev;
552 uint16_t data_offset;
553 int ret = -EINVAL;
554
555 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
556 &frev, &crev, &data_offset)) {
557 int i;
558 struct amdgpu_pll *ppll = &adev->clock.ppll[0];
559 struct amdgpu_pll *spll = &adev->clock.spll;
560 struct amdgpu_pll *mpll = &adev->clock.mpll;
561 union firmware_info *firmware_info =
562 (union firmware_info *)(mode_info->atom_context->bios +
563 data_offset);
564 /* pixel clocks */
565 ppll->reference_freq =
566 le16_to_cpu(firmware_info->info.usReferenceClock);
567 ppll->reference_div = 0;
568
569 if (crev < 2)
570 ppll->pll_out_min =
571 le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
572 else
573 ppll->pll_out_min =
574 le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output);
575 ppll->pll_out_max =
576 le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
577
578 if (crev >= 4) {
579 ppll->lcd_pll_out_min =
580 le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
581 if (ppll->lcd_pll_out_min == 0)
582 ppll->lcd_pll_out_min = ppll->pll_out_min;
583 ppll->lcd_pll_out_max =
584 le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
585 if (ppll->lcd_pll_out_max == 0)
586 ppll->lcd_pll_out_max = ppll->pll_out_max;
587 } else {
588 ppll->lcd_pll_out_min = ppll->pll_out_min;
589 ppll->lcd_pll_out_max = ppll->pll_out_max;
590 }
591
592 if (ppll->pll_out_min == 0)
593 ppll->pll_out_min = 64800;
594
595 ppll->pll_in_min =
596 le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input);
597 ppll->pll_in_max =
598 le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input);
599
600 ppll->min_post_div = 2;
601 ppll->max_post_div = 0x7f;
602 ppll->min_frac_feedback_div = 0;
603 ppll->max_frac_feedback_div = 9;
604 ppll->min_ref_div = 2;
605 ppll->max_ref_div = 0x3ff;
606 ppll->min_feedback_div = 4;
607 ppll->max_feedback_div = 0xfff;
608 ppll->best_vco = 0;
609
610 for (i = 1; i < AMDGPU_MAX_PPLL; i++)
611 adev->clock.ppll[i] = *ppll;
612
613 /* system clock */
614 spll->reference_freq =
615 le16_to_cpu(firmware_info->info_21.usCoreReferenceClock);
616 spll->reference_div = 0;
617
618 spll->pll_out_min =
619 le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Output);
620 spll->pll_out_max =
621 le32_to_cpu(firmware_info->info.ulMaxEngineClockPLL_Output);
622
623 /* ??? */
624 if (spll->pll_out_min == 0)
625 spll->pll_out_min = 64800;
626
627 spll->pll_in_min =
628 le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Input);
629 spll->pll_in_max =
630 le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input);
631
632 spll->min_post_div = 1;
633 spll->max_post_div = 1;
634 spll->min_ref_div = 2;
635 spll->max_ref_div = 0xff;
636 spll->min_feedback_div = 4;
637 spll->max_feedback_div = 0xff;
638 spll->best_vco = 0;
639
640 /* memory clock */
641 mpll->reference_freq =
642 le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock);
643 mpll->reference_div = 0;
644
645 mpll->pll_out_min =
646 le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Output);
647 mpll->pll_out_max =
648 le32_to_cpu(firmware_info->info.ulMaxMemoryClockPLL_Output);
649
650 /* ??? */
651 if (mpll->pll_out_min == 0)
652 mpll->pll_out_min = 64800;
653
654 mpll->pll_in_min =
655 le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Input);
656 mpll->pll_in_max =
657 le16_to_cpu(firmware_info->info.usMaxMemoryClockPLL_Input);
658
659 adev->clock.default_sclk =
660 le32_to_cpu(firmware_info->info.ulDefaultEngineClock);
661 adev->clock.default_mclk =
662 le32_to_cpu(firmware_info->info.ulDefaultMemoryClock);
663
664 mpll->min_post_div = 1;
665 mpll->max_post_div = 1;
666 mpll->min_ref_div = 2;
667 mpll->max_ref_div = 0xff;
668 mpll->min_feedback_div = 4;
669 mpll->max_feedback_div = 0xff;
670 mpll->best_vco = 0;
671
672 /* disp clock */
673 adev->clock.default_dispclk =
674 le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
675 if (adev->clock.default_dispclk == 0)
676 adev->clock.default_dispclk = 54000; /* 540 Mhz */
677 adev->clock.dp_extclk =
678 le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
679 adev->clock.current_dispclk = adev->clock.default_dispclk;
680
681 adev->clock.max_pixel_clock = le16_to_cpu(firmware_info->info.usMaxPixelClock);
682 if (adev->clock.max_pixel_clock == 0)
683 adev->clock.max_pixel_clock = 40000;
684
685 /* not technically a clock, but... */
686 adev->mode_info.firmware_flags =
687 le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess);
688
689 ret = 0;
690 }
691
692 adev->pm.current_sclk = adev->clock.default_sclk;
693 adev->pm.current_mclk = adev->clock.default_mclk;
694
695 return ret;
696}
697
698union igp_info {
699 struct _ATOM_INTEGRATED_SYSTEM_INFO info;
700 struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
701 struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
702 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
703 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
704 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_9 info_9;
705};
706
707static void amdgpu_atombios_get_igp_ss_overrides(struct amdgpu_device *adev,
708 struct amdgpu_atom_ss *ss,
709 int id)
710{
711 struct amdgpu_mode_info *mode_info = &adev->mode_info;
712 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
713 u16 data_offset, size;
714 union igp_info *igp_info;
715 u8 frev, crev;
716 u16 percentage = 0, rate = 0;
717
718 /* get any igp specific overrides */
719 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size,
720 &frev, &crev, &data_offset)) {
721 igp_info = (union igp_info *)
722 (mode_info->atom_context->bios + data_offset);
723 switch (crev) {
724 case 6:
725 switch (id) {
726 case ASIC_INTERNAL_SS_ON_TMDS:
727 percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage);
728 rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz);
729 break;
730 case ASIC_INTERNAL_SS_ON_HDMI:
731 percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage);
732 rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz);
733 break;
734 case ASIC_INTERNAL_SS_ON_LVDS:
735 percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage);
736 rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz);
737 break;
738 }
739 break;
740 case 7:
741 switch (id) {
742 case ASIC_INTERNAL_SS_ON_TMDS:
743 percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage);
744 rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz);
745 break;
746 case ASIC_INTERNAL_SS_ON_HDMI:
747 percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage);
748 rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz);
749 break;
750 case ASIC_INTERNAL_SS_ON_LVDS:
751 percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage);
752 rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz);
753 break;
754 }
755 break;
756 case 8:
757 switch (id) {
758 case ASIC_INTERNAL_SS_ON_TMDS:
759 percentage = le16_to_cpu(igp_info->info_8.usDVISSPercentage);
760 rate = le16_to_cpu(igp_info->info_8.usDVISSpreadRateIn10Hz);
761 break;
762 case ASIC_INTERNAL_SS_ON_HDMI:
763 percentage = le16_to_cpu(igp_info->info_8.usHDMISSPercentage);
764 rate = le16_to_cpu(igp_info->info_8.usHDMISSpreadRateIn10Hz);
765 break;
766 case ASIC_INTERNAL_SS_ON_LVDS:
767 percentage = le16_to_cpu(igp_info->info_8.usLvdsSSPercentage);
768 rate = le16_to_cpu(igp_info->info_8.usLvdsSSpreadRateIn10Hz);
769 break;
770 }
771 break;
772 case 9:
773 switch (id) {
774 case ASIC_INTERNAL_SS_ON_TMDS:
775 percentage = le16_to_cpu(igp_info->info_9.usDVISSPercentage);
776 rate = le16_to_cpu(igp_info->info_9.usDVISSpreadRateIn10Hz);
777 break;
778 case ASIC_INTERNAL_SS_ON_HDMI:
779 percentage = le16_to_cpu(igp_info->info_9.usHDMISSPercentage);
780 rate = le16_to_cpu(igp_info->info_9.usHDMISSpreadRateIn10Hz);
781 break;
782 case ASIC_INTERNAL_SS_ON_LVDS:
783 percentage = le16_to_cpu(igp_info->info_9.usLvdsSSPercentage);
784 rate = le16_to_cpu(igp_info->info_9.usLvdsSSpreadRateIn10Hz);
785 break;
786 }
787 break;
788 default:
789 DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
790 break;
791 }
792 if (percentage)
793 ss->percentage = percentage;
794 if (rate)
795 ss->rate = rate;
796 }
797}
798
799union asic_ss_info {
800 struct _ATOM_ASIC_INTERNAL_SS_INFO info;
801 struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2;
802 struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3;
803};
804
805union asic_ss_assignment {
806 struct _ATOM_ASIC_SS_ASSIGNMENT v1;
807 struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2;
808 struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3;
809};
810
811bool amdgpu_atombios_get_asic_ss_info(struct amdgpu_device *adev,
812 struct amdgpu_atom_ss *ss,
813 int id, u32 clock)
814{
815 struct amdgpu_mode_info *mode_info = &adev->mode_info;
816 int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
817 uint16_t data_offset, size;
818 union asic_ss_info *ss_info;
819 union asic_ss_assignment *ss_assign;
820 uint8_t frev, crev;
821 int i, num_indices;
822
823 if (id == ASIC_INTERNAL_MEMORY_SS) {
824 if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT))
825 return false;
826 }
827 if (id == ASIC_INTERNAL_ENGINE_SS) {
828 if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT))
829 return false;
830 }
831
832 memset(ss, 0, sizeof(struct amdgpu_atom_ss));
833 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size,
834 &frev, &crev, &data_offset)) {
835
836 ss_info =
837 (union asic_ss_info *)(mode_info->atom_context->bios + data_offset);
838
839 switch (frev) {
840 case 1:
841 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
842 sizeof(ATOM_ASIC_SS_ASSIGNMENT);
843
844 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info.asSpreadSpectrum[0]);
845 for (i = 0; i < num_indices; i++) {
846 if ((ss_assign->v1.ucClockIndication == id) &&
847 (clock <= le32_to_cpu(ss_assign->v1.ulTargetClockRange))) {
848 ss->percentage =
849 le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage);
850 ss->type = ss_assign->v1.ucSpreadSpectrumMode;
851 ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz);
852 ss->percentage_divider = 100;
853 return true;
854 }
855 ss_assign = (union asic_ss_assignment *)
856 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT));
857 }
858 break;
859 case 2:
860 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
861 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2);
862 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_2.asSpreadSpectrum[0]);
863 for (i = 0; i < num_indices; i++) {
864 if ((ss_assign->v2.ucClockIndication == id) &&
865 (clock <= le32_to_cpu(ss_assign->v2.ulTargetClockRange))) {
866 ss->percentage =
867 le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage);
868 ss->type = ss_assign->v2.ucSpreadSpectrumMode;
869 ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz);
870 ss->percentage_divider = 100;
871 if ((crev == 2) &&
872 ((id == ASIC_INTERNAL_ENGINE_SS) ||
873 (id == ASIC_INTERNAL_MEMORY_SS)))
874 ss->rate /= 100;
875 return true;
876 }
877 ss_assign = (union asic_ss_assignment *)
878 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2));
879 }
880 break;
881 case 3:
882 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
883 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
884 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_3.asSpreadSpectrum[0]);
885 for (i = 0; i < num_indices; i++) {
886 if ((ss_assign->v3.ucClockIndication == id) &&
887 (clock <= le32_to_cpu(ss_assign->v3.ulTargetClockRange))) {
888 ss->percentage =
889 le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage);
890 ss->type = ss_assign->v3.ucSpreadSpectrumMode;
891 ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz);
892 if (ss_assign->v3.ucSpreadSpectrumMode &
893 SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK)
894 ss->percentage_divider = 1000;
895 else
896 ss->percentage_divider = 100;
897 if ((id == ASIC_INTERNAL_ENGINE_SS) ||
898 (id == ASIC_INTERNAL_MEMORY_SS))
899 ss->rate /= 100;
900 if (adev->flags & AMDGPU_IS_APU)
901 amdgpu_atombios_get_igp_ss_overrides(adev, ss, id);
902 return true;
903 }
904 ss_assign = (union asic_ss_assignment *)
905 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3));
906 }
907 break;
908 default:
909 DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev, crev);
910 break;
911 }
912
913 }
914 return false;
915}
916
917union get_clock_dividers {
918 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1;
919 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2;
920 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
921 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
922 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
923 struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in;
924 struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out;
925};
926
927int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
928 u8 clock_type,
929 u32 clock,
930 bool strobe_mode,
931 struct atom_clock_dividers *dividers)
932{
933 union get_clock_dividers args;
934 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL);
935 u8 frev, crev;
936
937 memset(&args, 0, sizeof(args));
938 memset(dividers, 0, sizeof(struct atom_clock_dividers));
939
940 if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
941 return -EINVAL;
942
943 switch (crev) {
944 case 4:
945 /* fusion */
946 args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */
947
948 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
949
950 dividers->post_divider = dividers->post_div = args.v4.ucPostDiv;
951 dividers->real_clock = le32_to_cpu(args.v4.ulClock);
952 break;
953 case 6:
954 /* CI */
955 /* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, COMPUTE_GPUCLK_INPUT_FLAG_SCLK */
956 args.v6_in.ulClock.ulComputeClockFlag = clock_type;
957 args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock); /* 10 khz */
958
959 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
960
961 dividers->whole_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv);
962 dividers->frac_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac);
963 dividers->ref_div = args.v6_out.ucPllRefDiv;
964 dividers->post_div = args.v6_out.ucPllPostDiv;
965 dividers->flags = args.v6_out.ucPllCntlFlag;
966 dividers->real_clock = le32_to_cpu(args.v6_out.ulClock.ulClock);
967 dividers->post_divider = args.v6_out.ulClock.ucPostDiv;
968 break;
969 default:
970 return -EINVAL;
971 }
972 return 0;
973}
974
975int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
976 u32 clock,
977 bool strobe_mode,
978 struct atom_mpll_param *mpll_param)
979{
980 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args;
981 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam);
982 u8 frev, crev;
983
984 memset(&args, 0, sizeof(args));
985 memset(mpll_param, 0, sizeof(struct atom_mpll_param));
986
987 if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
988 return -EINVAL;
989
990 switch (frev) {
991 case 2:
992 switch (crev) {
993 case 1:
994 /* SI */
995 args.ulClock = cpu_to_le32(clock); /* 10 khz */
996 args.ucInputFlag = 0;
997 if (strobe_mode)
998 args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN;
999
1000 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1001
1002 mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac);
1003 mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv);
1004 mpll_param->post_div = args.ucPostDiv;
1005 mpll_param->dll_speed = args.ucDllSpeed;
1006 mpll_param->bwcntl = args.ucBWCntl;
1007 mpll_param->vco_mode =
1008 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK);
1009 mpll_param->yclk_sel =
1010 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0;
1011 mpll_param->qdr =
1012 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0;
1013 mpll_param->half_rate =
1014 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0;
1015 break;
1016 default:
1017 return -EINVAL;
1018 }
1019 break;
1020 default:
1021 return -EINVAL;
1022 }
1023 return 0;
1024}
1025
1026uint32_t amdgpu_atombios_get_engine_clock(struct amdgpu_device *adev)
1027{
1028 GET_ENGINE_CLOCK_PS_ALLOCATION args;
1029 int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock);
1030
1031 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1032 return le32_to_cpu(args.ulReturnEngineClock);
1033}
1034
1035uint32_t amdgpu_atombios_get_memory_clock(struct amdgpu_device *adev)
1036{
1037 GET_MEMORY_CLOCK_PS_ALLOCATION args;
1038 int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock);
1039
1040 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1041 return le32_to_cpu(args.ulReturnMemoryClock);
1042}
1043
1044void amdgpu_atombios_set_engine_clock(struct amdgpu_device *adev,
1045 uint32_t eng_clock)
1046{
1047 SET_ENGINE_CLOCK_PS_ALLOCATION args;
1048 int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock);
1049
1050 args.ulTargetEngineClock = cpu_to_le32(eng_clock); /* 10 khz */
1051
1052 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1053}
1054
1055void amdgpu_atombios_set_memory_clock(struct amdgpu_device *adev,
1056 uint32_t mem_clock)
1057{
1058 SET_MEMORY_CLOCK_PS_ALLOCATION args;
1059 int index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock);
1060
1061 if (adev->flags & AMDGPU_IS_APU)
1062 return;
1063
1064 args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */
1065
1066 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1067}
1068
1069void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
1070 u32 eng_clock, u32 mem_clock)
1071{
1072 SET_ENGINE_CLOCK_PS_ALLOCATION args;
1073 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
1074 u32 tmp;
1075
1076 memset(&args, 0, sizeof(args));
1077
1078 tmp = eng_clock & SET_CLOCK_FREQ_MASK;
1079 tmp |= (COMPUTE_ENGINE_PLL_PARAM << 24);
1080
1081 args.ulTargetEngineClock = cpu_to_le32(tmp);
1082 if (mem_clock)
1083 args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK);
1084
1085 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1086}
1087
1088union set_voltage {
1089 struct _SET_VOLTAGE_PS_ALLOCATION alloc;
1090 struct _SET_VOLTAGE_PARAMETERS v1;
1091 struct _SET_VOLTAGE_PARAMETERS_V2 v2;
1092 struct _SET_VOLTAGE_PARAMETERS_V1_3 v3;
1093};
1094
1095void amdgpu_atombios_set_voltage(struct amdgpu_device *adev,
1096 u16 voltage_level,
1097 u8 voltage_type)
1098{
1099 union set_voltage args;
1100 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
1101 u8 frev, crev, volt_index = voltage_level;
1102
1103 if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
1104 return;
1105
1106 /* 0xff01 is a flag rather then an actual voltage */
1107 if (voltage_level == 0xff01)
1108 return;
1109
1110 switch (crev) {
1111 case 1:
1112 args.v1.ucVoltageType = voltage_type;
1113 args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE;
1114 args.v1.ucVoltageIndex = volt_index;
1115 break;
1116 case 2:
1117 args.v2.ucVoltageType = voltage_type;
1118 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;
1119 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
1120 break;
1121 case 3:
1122 args.v3.ucVoltageType = voltage_type;
1123 args.v3.ucVoltageMode = ATOM_SET_VOLTAGE;
1124 args.v3.usVoltageLevel = cpu_to_le16(voltage_level);
1125 break;
1126 default:
1127 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
1128 return;
1129 }
1130
1131 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1132}
1133
1134int amdgpu_atombios_get_leakage_id_from_vbios(struct amdgpu_device *adev,
1135 u16 *leakage_id)
1136{
1137 union set_voltage args;
1138 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
1139 u8 frev, crev;
1140
1141 if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
1142 return -EINVAL;
1143
1144 switch (crev) {
1145 case 3:
1146 case 4:
1147 args.v3.ucVoltageType = 0;
1148 args.v3.ucVoltageMode = ATOM_GET_LEAKAGE_ID;
1149 args.v3.usVoltageLevel = 0;
1150
1151 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1152
1153 *leakage_id = le16_to_cpu(args.v3.usVoltageLevel);
1154 break;
1155 default:
1156 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
1157 return -EINVAL;
1158 }
1159
1160 return 0;
1161}
1162
1163int amdgpu_atombios_get_leakage_vddc_based_on_leakage_params(struct amdgpu_device *adev,
1164 u16 *vddc, u16 *vddci,
1165 u16 virtual_voltage_id,
1166 u16 vbios_voltage_id)
1167{
1168 int index = GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo);
1169 u8 frev, crev;
1170 u16 data_offset, size;
1171 int i, j;
1172 ATOM_ASIC_PROFILING_INFO_V2_1 *profile;
1173 u16 *leakage_bin, *vddc_id_buf, *vddc_buf, *vddci_id_buf, *vddci_buf;
1174
1175 *vddc = 0;
1176 *vddci = 0;
1177
1178 if (!amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
1179 &frev, &crev, &data_offset))
1180 return -EINVAL;
1181
1182 profile = (ATOM_ASIC_PROFILING_INFO_V2_1 *)
1183 (adev->mode_info.atom_context->bios + data_offset);
1184
1185 switch (frev) {
1186 case 1:
1187 return -EINVAL;
1188 case 2:
1189 switch (crev) {
1190 case 1:
1191 if (size < sizeof(ATOM_ASIC_PROFILING_INFO_V2_1))
1192 return -EINVAL;
1193 leakage_bin = (u16 *)
1194 (adev->mode_info.atom_context->bios + data_offset +
1195 le16_to_cpu(profile->usLeakageBinArrayOffset));
1196 vddc_id_buf = (u16 *)
1197 (adev->mode_info.atom_context->bios + data_offset +
1198 le16_to_cpu(profile->usElbVDDC_IdArrayOffset));
1199 vddc_buf = (u16 *)
1200 (adev->mode_info.atom_context->bios + data_offset +
1201 le16_to_cpu(profile->usElbVDDC_LevelArrayOffset));
1202 vddci_id_buf = (u16 *)
1203 (adev->mode_info.atom_context->bios + data_offset +
1204 le16_to_cpu(profile->usElbVDDCI_IdArrayOffset));
1205 vddci_buf = (u16 *)
1206 (adev->mode_info.atom_context->bios + data_offset +
1207 le16_to_cpu(profile->usElbVDDCI_LevelArrayOffset));
1208
1209 if (profile->ucElbVDDC_Num > 0) {
1210 for (i = 0; i < profile->ucElbVDDC_Num; i++) {
1211 if (vddc_id_buf[i] == virtual_voltage_id) {
1212 for (j = 0; j < profile->ucLeakageBinNum; j++) {
1213 if (vbios_voltage_id <= leakage_bin[j]) {
1214 *vddc = vddc_buf[j * profile->ucElbVDDC_Num + i];
1215 break;
1216 }
1217 }
1218 break;
1219 }
1220 }
1221 }
1222 if (profile->ucElbVDDCI_Num > 0) {
1223 for (i = 0; i < profile->ucElbVDDCI_Num; i++) {
1224 if (vddci_id_buf[i] == virtual_voltage_id) {
1225 for (j = 0; j < profile->ucLeakageBinNum; j++) {
1226 if (vbios_voltage_id <= leakage_bin[j]) {
1227 *vddci = vddci_buf[j * profile->ucElbVDDCI_Num + i];
1228 break;
1229 }
1230 }
1231 break;
1232 }
1233 }
1234 }
1235 break;
1236 default:
1237 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
1238 return -EINVAL;
1239 }
1240 break;
1241 default:
1242 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
1243 return -EINVAL;
1244 }
1245
1246 return 0;
1247}
1248
1249union get_voltage_info {
1250 struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 in;
1251 struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 evv_out;
1252};
1253
1254int amdgpu_atombios_get_voltage_evv(struct amdgpu_device *adev,
1255 u16 virtual_voltage_id,
1256 u16 *voltage)
1257{
1258 int index = GetIndexIntoMasterTable(COMMAND, GetVoltageInfo);
1259 u32 entry_id;
1260 u32 count = adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count;
1261 union get_voltage_info args;
1262
1263 for (entry_id = 0; entry_id < count; entry_id++) {
1264 if (adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].v ==
1265 virtual_voltage_id)
1266 break;
1267 }
1268
1269 if (entry_id >= count)
1270 return -EINVAL;
1271
1272 args.in.ucVoltageType = VOLTAGE_TYPE_VDDC;
1273 args.in.ucVoltageMode = ATOM_GET_VOLTAGE_EVV_VOLTAGE;
1274 args.in.usVoltageLevel = cpu_to_le16(virtual_voltage_id);
1275 args.in.ulSCLKFreq =
1276 cpu_to_le32(adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].clk);
1277
1278 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1279
1280 *voltage = le16_to_cpu(args.evv_out.usVoltageLevel);
1281
1282 return 0;
1283}
1284
1285union voltage_object_info {
1286 struct _ATOM_VOLTAGE_OBJECT_INFO v1;
1287 struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;
1288 struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3;
1289};
1290
1291union voltage_object {
1292 struct _ATOM_VOLTAGE_OBJECT v1;
1293 struct _ATOM_VOLTAGE_OBJECT_V2 v2;
1294 union _ATOM_VOLTAGE_OBJECT_V3 v3;
1295};
1296
1297
1298static ATOM_VOLTAGE_OBJECT_V3 *amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *v3,
1299 u8 voltage_type, u8 voltage_mode)
1300{
1301 u32 size = le16_to_cpu(v3->sHeader.usStructureSize);
1302 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
1303 u8 *start = (u8*)v3;
1304
1305 while (offset < size) {
1306 ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
1307 if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) &&
1308 (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode))
1309 return vo;
1310 offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize);
1311 }
1312 return NULL;
1313}
1314
1315bool
1316amdgpu_atombios_is_voltage_gpio(struct amdgpu_device *adev,
1317 u8 voltage_type, u8 voltage_mode)
1318{
1319 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
1320 u8 frev, crev;
1321 u16 data_offset, size;
1322 union voltage_object_info *voltage_info;
1323
1324 if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
1325 &frev, &crev, &data_offset)) {
1326 voltage_info = (union voltage_object_info *)
1327 (adev->mode_info.atom_context->bios + data_offset);
1328
1329 switch (frev) {
1330 case 3:
1331 switch (crev) {
1332 case 1:
1333 if (amdgpu_atombios_lookup_voltage_object_v3(&voltage_info->v3,
1334 voltage_type, voltage_mode))
1335 return true;
1336 break;
1337 default:
1338 DRM_ERROR("unknown voltage object table\n");
1339 return false;
1340 }
1341 break;
1342 default:
1343 DRM_ERROR("unknown voltage object table\n");
1344 return false;
1345 }
1346
1347 }
1348 return false;
1349}
1350
1351int amdgpu_atombios_get_voltage_table(struct amdgpu_device *adev,
1352 u8 voltage_type, u8 voltage_mode,
1353 struct atom_voltage_table *voltage_table)
1354{
1355 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
1356 u8 frev, crev;
1357 u16 data_offset, size;
1358 int i;
1359 union voltage_object_info *voltage_info;
1360 union voltage_object *voltage_object = NULL;
1361
1362 if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
1363 &frev, &crev, &data_offset)) {
1364 voltage_info = (union voltage_object_info *)
1365 (adev->mode_info.atom_context->bios + data_offset);
1366
1367 switch (frev) {
1368 case 3:
1369 switch (crev) {
1370 case 1:
1371 voltage_object = (union voltage_object *)
1372 amdgpu_atombios_lookup_voltage_object_v3(&voltage_info->v3,
1373 voltage_type, voltage_mode);
1374 if (voltage_object) {
1375 ATOM_GPIO_VOLTAGE_OBJECT_V3 *gpio =
1376 &voltage_object->v3.asGpioVoltageObj;
1377 VOLTAGE_LUT_ENTRY_V2 *lut;
1378 if (gpio->ucGpioEntryNum > MAX_VOLTAGE_ENTRIES)
1379 return -EINVAL;
1380 lut = &gpio->asVolGpioLut[0];
1381 for (i = 0; i < gpio->ucGpioEntryNum; i++) {
1382 voltage_table->entries[i].value =
1383 le16_to_cpu(lut->usVoltageValue);
1384 voltage_table->entries[i].smio_low =
1385 le32_to_cpu(lut->ulVoltageId);
1386 lut = (VOLTAGE_LUT_ENTRY_V2 *)
1387 ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY_V2));
1388 }
1389 voltage_table->mask_low = le32_to_cpu(gpio->ulGpioMaskVal);
1390 voltage_table->count = gpio->ucGpioEntryNum;
1391 voltage_table->phase_delay = gpio->ucPhaseDelay;
1392 return 0;
1393 }
1394 break;
1395 default:
1396 DRM_ERROR("unknown voltage object table\n");
1397 return -EINVAL;
1398 }
1399 break;
1400 default:
1401 DRM_ERROR("unknown voltage object table\n");
1402 return -EINVAL;
1403 }
1404 }
1405 return -EINVAL;
1406}
1407
1408union vram_info {
1409 struct _ATOM_VRAM_INFO_V3 v1_3;
1410 struct _ATOM_VRAM_INFO_V4 v1_4;
1411 struct _ATOM_VRAM_INFO_HEADER_V2_1 v2_1;
1412};
1413
1414#define MEM_ID_MASK 0xff000000
1415#define MEM_ID_SHIFT 24
1416#define CLOCK_RANGE_MASK 0x00ffffff
1417#define CLOCK_RANGE_SHIFT 0
1418#define LOW_NIBBLE_MASK 0xf
1419#define DATA_EQU_PREV 0
1420#define DATA_FROM_TABLE 4
1421
1422int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
1423 u8 module_index,
1424 struct atom_mc_reg_table *reg_table)
1425{
1426 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
1427 u8 frev, crev, num_entries, t_mem_id, num_ranges = 0;
1428 u32 i = 0, j;
1429 u16 data_offset, size;
1430 union vram_info *vram_info;
1431
1432 memset(reg_table, 0, sizeof(struct atom_mc_reg_table));
1433
1434 if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
1435 &frev, &crev, &data_offset)) {
1436 vram_info = (union vram_info *)
1437 (adev->mode_info.atom_context->bios + data_offset);
1438 switch (frev) {
1439 case 1:
1440 DRM_ERROR("old table version %d, %d\n", frev, crev);
1441 return -EINVAL;
1442 case 2:
1443 switch (crev) {
1444 case 1:
1445 if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
1446 ATOM_INIT_REG_BLOCK *reg_block =
1447 (ATOM_INIT_REG_BLOCK *)
1448 ((u8 *)vram_info + le16_to_cpu(vram_info->v2_1.usMemClkPatchTblOffset));
1449 ATOM_MEMORY_SETTING_DATA_BLOCK *reg_data =
1450 (ATOM_MEMORY_SETTING_DATA_BLOCK *)
1451 ((u8 *)reg_block + (2 * sizeof(u16)) +
1452 le16_to_cpu(reg_block->usRegIndexTblSize));
1453 ATOM_INIT_REG_INDEX_FORMAT *format = &reg_block->asRegIndexBuf[0];
1454 num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) /
1455 sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1;
1456 if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE)
1457 return -EINVAL;
1458 while (i < num_entries) {
1459 if (format->ucPreRegDataLength & ACCESS_PLACEHOLDER)
1460 break;
1461 reg_table->mc_reg_address[i].s1 =
1462 (u16)(le16_to_cpu(format->usRegIndex));
1463 reg_table->mc_reg_address[i].pre_reg_data =
1464 (u8)(format->ucPreRegDataLength);
1465 i++;
1466 format = (ATOM_INIT_REG_INDEX_FORMAT *)
1467 ((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT));
1468 }
1469 reg_table->last = i;
1470 while ((le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) &&
1471 (num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES)) {
1472 t_mem_id = (u8)((le32_to_cpu(*(u32 *)reg_data) & MEM_ID_MASK)
1473 >> MEM_ID_SHIFT);
1474 if (module_index == t_mem_id) {
1475 reg_table->mc_reg_table_entry[num_ranges].mclk_max =
1476 (u32)((le32_to_cpu(*(u32 *)reg_data) & CLOCK_RANGE_MASK)
1477 >> CLOCK_RANGE_SHIFT);
1478 for (i = 0, j = 1; i < reg_table->last; i++) {
1479 if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_FROM_TABLE) {
1480 reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
1481 (u32)le32_to_cpu(*((u32 *)reg_data + j));
1482 j++;
1483 } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
1484 reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
1485 reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];
1486 }
1487 }
1488 num_ranges++;
1489 }
1490 reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)
1491 ((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize));
1492 }
1493 if (le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK)
1494 return -EINVAL;
1495 reg_table->num_entries = num_ranges;
1496 } else
1497 return -EINVAL;
1498 break;
1499 default:
1500 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
1501 return -EINVAL;
1502 }
1503 break;
1504 default:
1505 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
1506 return -EINVAL;
1507 }
1508 return 0;
1509 }
1510 return -EINVAL;
1511}
1512
1513void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock)
1514{
1515 uint32_t bios_6_scratch;
1516
1517 bios_6_scratch = RREG32(mmBIOS_SCRATCH_6);
1518
1519 if (lock) {
1520 bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
1521 bios_6_scratch &= ~ATOM_S6_ACC_MODE;
1522 } else {
1523 bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
1524 bios_6_scratch |= ATOM_S6_ACC_MODE;
1525 }
1526
1527 WREG32(mmBIOS_SCRATCH_6, bios_6_scratch);
1528}
1529
1530void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev)
1531{
1532 uint32_t bios_2_scratch, bios_6_scratch;
1533
1534 bios_2_scratch = RREG32(mmBIOS_SCRATCH_2);
1535 bios_6_scratch = RREG32(mmBIOS_SCRATCH_6);
1536
1537 /* let the bios control the backlight */
1538 bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
1539
1540 /* tell the bios not to handle mode switching */
1541 bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
1542
1543 /* clear the vbios dpms state */
1544 bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE;
1545
1546 WREG32(mmBIOS_SCRATCH_2, bios_2_scratch);
1547 WREG32(mmBIOS_SCRATCH_6, bios_6_scratch);
1548}
1549
1550void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev)
1551{
1552 int i;
1553
1554 for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
1555 adev->bios_scratch[i] = RREG32(mmBIOS_SCRATCH_0 + i);
1556}
1557
1558void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev)
1559{
1560 int i;
1561
1562 for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
1563 WREG32(mmBIOS_SCRATCH_0 + i, adev->bios_scratch[i]);
1564}
1565
1566/* Atom needs data in little endian format
1567 * so swap as appropriate when copying data to
1568 * or from atom. Note that atom operates on
1569 * dw units.
1570 */
1571void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
1572{
1573#ifdef __BIG_ENDIAN
1574 u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */
1575 u32 *dst32, *src32;
1576 int i;
1577
1578 memcpy(src_tmp, src, num_bytes);
1579 src32 = (u32 *)src_tmp;
1580 dst32 = (u32 *)dst_tmp;
1581 if (to_le) {
1582 for (i = 0; i < ((num_bytes + 3) / 4); i++)
1583 dst32[i] = cpu_to_le32(src32[i]);
1584 memcpy(dst, dst_tmp, num_bytes);
1585 } else {
1586 u8 dws = num_bytes & ~3;
1587 for (i = 0; i < ((num_bytes + 3) / 4); i++)
1588 dst32[i] = le32_to_cpu(src32[i]);
1589 memcpy(dst, dst_tmp, dws);
1590 if (num_bytes % 4) {
1591 for (i = 0; i < (num_bytes % 4); i++)
1592 dst[dws+i] = dst_tmp[dws+i];
1593 }
1594 }
1595#else
1596 memcpy(dst, src, num_bytes);
1597#endif
1598}
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h+206−0
@@ -0,0 +1,206 @@
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 __AMDGPU_ATOMBIOS_H__
25#define __AMDGPU_ATOMBIOS_H__
26
27struct atom_clock_dividers {
28 u32 post_div;
29 union {
30 struct {
31#ifdef __BIG_ENDIAN
32 u32 reserved : 6;
33 u32 whole_fb_div : 12;
34 u32 frac_fb_div : 14;
35#else
36 u32 frac_fb_div : 14;
37 u32 whole_fb_div : 12;
38 u32 reserved : 6;
39#endif
40 };
41 u32 fb_div;
42 };
43 u32 ref_div;
44 bool enable_post_div;
45 bool enable_dithen;
46 u32 vco_mode;
47 u32 real_clock;
48 /* added for CI */
49 u32 post_divider;
50 u32 flags;
51};
52
53struct atom_mpll_param {
54 union {
55 struct {
56#ifdef __BIG_ENDIAN
57 u32 reserved : 8;
58 u32 clkfrac : 12;
59 u32 clkf : 12;
60#else
61 u32 clkf : 12;
62 u32 clkfrac : 12;
63 u32 reserved : 8;
64#endif
65 };
66 u32 fb_div;
67 };
68 u32 post_div;
69 u32 bwcntl;
70 u32 dll_speed;
71 u32 vco_mode;
72 u32 yclk_sel;
73 u32 qdr;
74 u32 half_rate;
75};
76
77#define MEM_TYPE_GDDR5 0x50
78#define MEM_TYPE_GDDR4 0x40
79#define MEM_TYPE_GDDR3 0x30
80#define MEM_TYPE_DDR2 0x20
81#define MEM_TYPE_GDDR1 0x10
82#define MEM_TYPE_DDR3 0xb0
83#define MEM_TYPE_MASK 0xf0
84
85struct atom_memory_info {
86 u8 mem_vendor;
87 u8 mem_type;
88};
89
90#define MAX_AC_TIMING_ENTRIES 16
91
92struct atom_memory_clock_range_table
93{
94 u8 num_entries;
95 u8 rsv[3];
96 u32 mclk[MAX_AC_TIMING_ENTRIES];
97};
98
99#define VBIOS_MC_REGISTER_ARRAY_SIZE 32
100#define VBIOS_MAX_AC_TIMING_ENTRIES 20
101
102struct atom_mc_reg_entry {
103 u32 mclk_max;
104 u32 mc_data[VBIOS_MC_REGISTER_ARRAY_SIZE];
105};
106
107struct atom_mc_register_address {
108 u16 s1;
109 u8 pre_reg_data;
110};
111
112struct atom_mc_reg_table {
113 u8 last;
114 u8 num_entries;
115 struct atom_mc_reg_entry mc_reg_table_entry[VBIOS_MAX_AC_TIMING_ENTRIES];
116 struct atom_mc_register_address mc_reg_address[VBIOS_MC_REGISTER_ARRAY_SIZE];
117};
118
119#define MAX_VOLTAGE_ENTRIES 32
120
121struct atom_voltage_table_entry
122{
123 u16 value;
124 u32 smio_low;
125};
126
127struct atom_voltage_table
128{
129 u32 count;
130 u32 mask_low;
131 u32 phase_delay;
132 struct atom_voltage_table_entry entries[MAX_VOLTAGE_ENTRIES];
133};
134
135struct amdgpu_gpio_rec
136amdgpu_atombios_lookup_gpio(struct amdgpu_device *adev,
137 u8 id);
138
139struct amdgpu_i2c_bus_rec amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device *adev,
140 uint8_t id);
141void amdgpu_atombios_i2c_init(struct amdgpu_device *adev);
142
143bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev);
144
145int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev);
146
147bool amdgpu_atombios_get_asic_ss_info(struct amdgpu_device *adev,
148 struct amdgpu_atom_ss *ss,
149 int id, u32 clock);
150
151int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
152 u8 clock_type,
153 u32 clock,
154 bool strobe_mode,
155 struct atom_clock_dividers *dividers);
156
157int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
158 u32 clock,
159 bool strobe_mode,
160 struct atom_mpll_param *mpll_param);
161
162uint32_t amdgpu_atombios_get_engine_clock(struct amdgpu_device *adev);
163uint32_t amdgpu_atombios_get_memory_clock(struct amdgpu_device *adev);
164void amdgpu_atombios_set_engine_clock(struct amdgpu_device *adev,
165 uint32_t eng_clock);
166void amdgpu_atombios_set_memory_clock(struct amdgpu_device *adev,
167 uint32_t mem_clock);
168void amdgpu_atombios_set_voltage(struct amdgpu_device *adev,
169 u16 voltage_level,
170 u8 voltage_type);
171
172void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
173 u32 eng_clock, u32 mem_clock);
174
175int amdgpu_atombios_get_leakage_id_from_vbios(struct amdgpu_device *adev,
176 u16 *leakage_id);
177
178int amdgpu_atombios_get_leakage_vddc_based_on_leakage_params(struct amdgpu_device *adev,
179 u16 *vddc, u16 *vddci,
180 u16 virtual_voltage_id,
181 u16 vbios_voltage_id);
182
183int amdgpu_atombios_get_voltage_evv(struct amdgpu_device *adev,
184 u16 virtual_voltage_id,
185 u16 *voltage);
186
187bool
188amdgpu_atombios_is_voltage_gpio(struct amdgpu_device *adev,
189 u8 voltage_type, u8 voltage_mode);
190
191int amdgpu_atombios_get_voltage_table(struct amdgpu_device *adev,
192 u8 voltage_type, u8 voltage_mode,
193 struct atom_voltage_table *voltage_table);
194
195int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
196 u8 module_index,
197 struct atom_mc_reg_table *reg_table);
198
199void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock);
200void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev);
201void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev);
202void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev);
203
204void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
205
206#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c+572−0
@@ -0,0 +1,572 @@
1/*
2 * Copyright (c) 2010 Red Hat Inc.
3 * Author : Dave Airlie <airlied@redhat.com>
4 *
5 * Licensed under GPLv2
6 *
7 * ATPX support for both Intel/ATI
8 */
9#include <linux/vga_switcheroo.h>
10#include <linux/slab.h>
11#include <linux/acpi.h>
12#include <linux/pci.h>
13
14#include "amdgpu_acpi.h"
15
16struct amdgpu_atpx_functions {
17 bool px_params;
18 bool power_cntl;
19 bool disp_mux_cntl;
20 bool i2c_mux_cntl;
21 bool switch_start;
22 bool switch_end;
23 bool disp_connectors_mapping;
24 bool disp_detetion_ports;
25};
26
27struct amdgpu_atpx {
28 acpi_handle handle;
29 struct amdgpu_atpx_functions functions;
30};
31
32static struct amdgpu_atpx_priv {
33 bool atpx_detected;
34 /* handle for device - and atpx */
35 acpi_handle dhandle;
36 acpi_handle other_handle;
37 struct amdgpu_atpx atpx;
38} amdgpu_atpx_priv;
39
40struct atpx_verify_interface {
41 u16 size; /* structure size in bytes (includes size field) */
42 u16 version; /* version */
43 u32 function_bits; /* supported functions bit vector */
44} __packed;
45
46struct atpx_px_params {
47 u16 size; /* structure size in bytes (includes size field) */
48 u32 valid_flags; /* which flags are valid */
49 u32 flags; /* flags */
50} __packed;
51
52struct atpx_power_control {
53 u16 size;
54 u8 dgpu_state;
55} __packed;
56
57struct atpx_mux {
58 u16 size;
59 u16 mux;
60} __packed;
61
62bool amdgpu_has_atpx(void) {
63 return amdgpu_atpx_priv.atpx_detected;
64}
65
66/**
67 * amdgpu_atpx_call - call an ATPX method
68 *
69 * @handle: acpi handle
70 * @function: the ATPX function to execute
71 * @params: ATPX function params
72 *
73 * Executes the requested ATPX function (all asics).
74 * Returns a pointer to the acpi output buffer.
75 */
76static union acpi_object *amdgpu_atpx_call(acpi_handle handle, int function,
77 struct acpi_buffer *params)
78{
79 acpi_status status;
80 union acpi_object atpx_arg_elements[2];
81 struct acpi_object_list atpx_arg;
82 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
83
84 atpx_arg.count = 2;
85 atpx_arg.pointer = &atpx_arg_elements[0];
86
87 atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
88 atpx_arg_elements[0].integer.value = function;
89
90 if (params) {
91 atpx_arg_elements[1].type = ACPI_TYPE_BUFFER;
92 atpx_arg_elements[1].buffer.length = params->length;
93 atpx_arg_elements[1].buffer.pointer = params->pointer;
94 } else {
95 /* We need a second fake parameter */
96 atpx_arg_elements[1].type = ACPI_TYPE_INTEGER;
97 atpx_arg_elements[1].integer.value = 0;
98 }
99
100 status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
101
102 /* Fail only if calling the method fails and ATPX is supported */
103 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
104 printk("failed to evaluate ATPX got %s\n",
105 acpi_format_exception(status));
106 kfree(buffer.pointer);
107 return NULL;
108 }
109
110 return buffer.pointer;
111}
112
113/**
114 * amdgpu_atpx_parse_functions - parse supported functions
115 *
116 * @f: supported functions struct
117 * @mask: supported functions mask from ATPX
118 *
119 * Use the supported functions mask from ATPX function
120 * ATPX_FUNCTION_VERIFY_INTERFACE to determine what functions
121 * are supported (all asics).
122 */
123static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mask)
124{
125 f->px_params = mask & ATPX_GET_PX_PARAMETERS_SUPPORTED;
126 f->power_cntl = mask & ATPX_POWER_CONTROL_SUPPORTED;
127 f->disp_mux_cntl = mask & ATPX_DISPLAY_MUX_CONTROL_SUPPORTED;
128 f->i2c_mux_cntl = mask & ATPX_I2C_MUX_CONTROL_SUPPORTED;
129 f->switch_start = mask & ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED;
130 f->switch_end = mask & ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED;
131 f->disp_connectors_mapping = mask & ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED;
132 f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED;
133}
134
135/**
136 * amdgpu_atpx_validate_functions - validate ATPX functions
137 *
138 * @atpx: amdgpu atpx struct
139 *
140 * Validate that required functions are enabled (all asics).
141 * returns 0 on success, error on failure.
142 */
143static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
144{
145 /* make sure required functions are enabled */
146 /* dGPU power control is required */
147 atpx->functions.power_cntl = true;
148
149 if (atpx->functions.px_params) {
150 union acpi_object *info;
151 struct atpx_px_params output;
152 size_t size;
153 u32 valid_bits;
154
155 info = amdgpu_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
156 if (!info)
157 return -EIO;
158
159 memset(&output, 0, sizeof(output));
160
161 size = *(u16 *) info->buffer.pointer;
162 if (size < 10) {
163 printk("ATPX buffer is too small: %zu\n", size);
164 kfree(info);
165 return -EINVAL;
166 }
167 size = min(sizeof(output), size);
168
169 memcpy(&output, info->buffer.pointer, size);
170
171 valid_bits = output.flags & output.valid_flags;
172 /* if separate mux flag is set, mux controls are required */
173 if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) {
174 atpx->functions.i2c_mux_cntl = true;
175 atpx->functions.disp_mux_cntl = true;
176 }
177 /* if any outputs are muxed, mux controls are required */
178 if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED |
179 ATPX_TV_SIGNAL_MUXED |
180 ATPX_DFP_SIGNAL_MUXED))
181 atpx->functions.disp_mux_cntl = true;
182
183 kfree(info);
184 }
185 return 0;
186}
187
188/**
189 * amdgpu_atpx_verify_interface - verify ATPX
190 *
191 * @atpx: amdgpu atpx struct
192 *
193 * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function
194 * to initialize ATPX and determine what features are supported
195 * (all asics).
196 * returns 0 on success, error on failure.
197 */
198static int amdgpu_atpx_verify_interface(struct amdgpu_atpx *atpx)
199{
200 union acpi_object *info;
201 struct atpx_verify_interface output;
202 size_t size;
203 int err = 0;
204
205 info = amdgpu_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE, NULL);
206 if (!info)
207 return -EIO;
208
209 memset(&output, 0, sizeof(output));
210
211 size = *(u16 *) info->buffer.pointer;
212 if (size < 8) {
213 printk("ATPX buffer is too small: %zu\n", size);
214 err = -EINVAL;
215 goto out;
216 }
217 size = min(sizeof(output), size);
218
219 memcpy(&output, info->buffer.pointer, size);
220
221 /* TODO: check version? */
222 printk("ATPX version %u, functions 0x%08x\n",
223 output.version, output.function_bits);
224
225 amdgpu_atpx_parse_functions(&atpx->functions, output.function_bits);
226
227out:
228 kfree(info);
229 return err;
230}
231
232/**
233 * amdgpu_atpx_set_discrete_state - power up/down discrete GPU
234 *
235 * @atpx: atpx info struct
236 * @state: discrete GPU state (0 = power down, 1 = power up)
237 *
238 * Execute the ATPX_FUNCTION_POWER_CONTROL ATPX function to
239 * power down/up the discrete GPU (all asics).
240 * Returns 0 on success, error on failure.
241 */
242static int amdgpu_atpx_set_discrete_state(struct amdgpu_atpx *atpx, u8 state)
243{
244 struct acpi_buffer params;
245 union acpi_object *info;
246 struct atpx_power_control input;
247
248 if (atpx->functions.power_cntl) {
249 input.size = 3;
250 input.dgpu_state = state;
251 params.length = input.size;
252 params.pointer = &input;
253 info = amdgpu_atpx_call(atpx->handle,
254 ATPX_FUNCTION_POWER_CONTROL,
255 &params);
256 if (!info)
257 return -EIO;
258 kfree(info);
259 }
260 return 0;
261}
262
263/**
264 * amdgpu_atpx_switch_disp_mux - switch display mux
265 *
266 * @atpx: atpx info struct
267 * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
268 *
269 * Execute the ATPX_FUNCTION_DISPLAY_MUX_CONTROL ATPX function to
270 * switch the display mux between the discrete GPU and integrated GPU
271 * (all asics).
272 * Returns 0 on success, error on failure.
273 */
274static int amdgpu_atpx_switch_disp_mux(struct amdgpu_atpx *atpx, u16 mux_id)
275{
276 struct acpi_buffer params;
277 union acpi_object *info;
278 struct atpx_mux input;
279
280 if (atpx->functions.disp_mux_cntl) {
281 input.size = 4;
282 input.mux = mux_id;
283 params.length = input.size;
284 params.pointer = &input;
285 info = amdgpu_atpx_call(atpx->handle,
286 ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
287 &params);
288 if (!info)
289 return -EIO;
290 kfree(info);
291 }
292 return 0;
293}
294
295/**
296 * amdgpu_atpx_switch_i2c_mux - switch i2c/hpd mux
297 *
298 * @atpx: atpx info struct
299 * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
300 *
301 * Execute the ATPX_FUNCTION_I2C_MUX_CONTROL ATPX function to
302 * switch the i2c/hpd mux between the discrete GPU and integrated GPU
303 * (all asics).
304 * Returns 0 on success, error on failure.
305 */
306static int amdgpu_atpx_switch_i2c_mux(struct amdgpu_atpx *atpx, u16 mux_id)
307{
308 struct acpi_buffer params;
309 union acpi_object *info;
310 struct atpx_mux input;
311
312 if (atpx->functions.i2c_mux_cntl) {
313 input.size = 4;
314 input.mux = mux_id;
315 params.length = input.size;
316 params.pointer = &input;
317 info = amdgpu_atpx_call(atpx->handle,
318 ATPX_FUNCTION_I2C_MUX_CONTROL,
319 &params);
320 if (!info)
321 return -EIO;
322 kfree(info);
323 }
324 return 0;
325}
326
327/**
328 * amdgpu_atpx_switch_start - notify the sbios of a GPU switch
329 *
330 * @atpx: atpx info struct
331 * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
332 *
333 * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION ATPX
334 * function to notify the sbios that a switch between the discrete GPU and
335 * integrated GPU has begun (all asics).
336 * Returns 0 on success, error on failure.
337 */
338static int amdgpu_atpx_switch_start(struct amdgpu_atpx *atpx, u16 mux_id)
339{
340 struct acpi_buffer params;
341 union acpi_object *info;
342 struct atpx_mux input;
343
344 if (atpx->functions.switch_start) {
345 input.size = 4;
346 input.mux = mux_id;
347 params.length = input.size;
348 params.pointer = &input;
349 info = amdgpu_atpx_call(atpx->handle,
350 ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
351 &params);
352 if (!info)
353 return -EIO;
354 kfree(info);
355 }
356 return 0;
357}
358
359/**
360 * amdgpu_atpx_switch_end - notify the sbios of a GPU switch
361 *
362 * @atpx: atpx info struct
363 * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
364 *
365 * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION ATPX
366 * function to notify the sbios that a switch between the discrete GPU and
367 * integrated GPU has ended (all asics).
368 * Returns 0 on success, error on failure.
369 */
370static int amdgpu_atpx_switch_end(struct amdgpu_atpx *atpx, u16 mux_id)
371{
372 struct acpi_buffer params;
373 union acpi_object *info;
374 struct atpx_mux input;
375
376 if (atpx->functions.switch_end) {
377 input.size = 4;
378 input.mux = mux_id;
379 params.length = input.size;
380 params.pointer = &input;
381 info = amdgpu_atpx_call(atpx->handle,
382 ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
383 &params);
384 if (!info)
385 return -EIO;
386 kfree(info);
387 }
388 return 0;
389}
390
391/**
392 * amdgpu_atpx_switchto - switch to the requested GPU
393 *
394 * @id: GPU to switch to
395 *
396 * Execute the necessary ATPX functions to switch between the discrete GPU and
397 * integrated GPU (all asics).
398 * Returns 0 on success, error on failure.
399 */
400static int amdgpu_atpx_switchto(enum vga_switcheroo_client_id id)
401{
402 u16 gpu_id;
403
404 if (id == VGA_SWITCHEROO_IGD)
405 gpu_id = ATPX_INTEGRATED_GPU;
406 else
407 gpu_id = ATPX_DISCRETE_GPU;
408
409 amdgpu_atpx_switch_start(&amdgpu_atpx_priv.atpx, gpu_id);
410 amdgpu_atpx_switch_disp_mux(&amdgpu_atpx_priv.atpx, gpu_id);
411 amdgpu_atpx_switch_i2c_mux(&amdgpu_atpx_priv.atpx, gpu_id);
412 amdgpu_atpx_switch_end(&amdgpu_atpx_priv.atpx, gpu_id);
413
414 return 0;
415}
416
417/**
418 * amdgpu_atpx_power_state - power down/up the requested GPU
419 *
420 * @id: GPU to power down/up
421 * @state: requested power state (0 = off, 1 = on)
422 *
423 * Execute the necessary ATPX function to power down/up the discrete GPU
424 * (all asics).
425 * Returns 0 on success, error on failure.
426 */
427static int amdgpu_atpx_power_state(enum vga_switcheroo_client_id id,
428 enum vga_switcheroo_state state)
429{
430 /* on w500 ACPI can't change intel gpu state */
431 if (id == VGA_SWITCHEROO_IGD)
432 return 0;
433
434 amdgpu_atpx_set_discrete_state(&amdgpu_atpx_priv.atpx, state);
435 return 0;
436}
437
438/**
439 * amdgpu_atpx_pci_probe_handle - look up the ATPX handle
440 *
441 * @pdev: pci device
442 *
443 * Look up the ATPX handles (all asics).
444 * Returns true if the handles are found, false if not.
445 */
446static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)
447{
448 acpi_handle dhandle, atpx_handle;
449 acpi_status status;
450
451 dhandle = ACPI_HANDLE(&pdev->dev);
452 if (!dhandle)
453 return false;
454
455 status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
456 if (ACPI_FAILURE(status)) {
457 amdgpu_atpx_priv.other_handle = dhandle;
458 return false;
459 }
460 amdgpu_atpx_priv.dhandle = dhandle;
461 amdgpu_atpx_priv.atpx.handle = atpx_handle;
462 return true;
463}
464
465/**
466 * amdgpu_atpx_init - verify the ATPX interface
467 *
468 * Verify the ATPX interface (all asics).
469 * Returns 0 on success, error on failure.
470 */
471static int amdgpu_atpx_init(void)
472{
473 int r;
474
475 /* set up the ATPX handle */
476 r = amdgpu_atpx_verify_interface(&amdgpu_atpx_priv.atpx);
477 if (r)
478 return r;
479
480 /* validate the atpx setup */
481 r = amdgpu_atpx_validate(&amdgpu_atpx_priv.atpx);
482 if (r)
483 return r;
484
485 return 0;
486}
487
488/**
489 * amdgpu_atpx_get_client_id - get the client id
490 *
491 * @pdev: pci device
492 *
493 * look up whether we are the integrated or discrete GPU (all asics).
494 * Returns the client id.
495 */
496static int amdgpu_atpx_get_client_id(struct pci_dev *pdev)
497{
498 if (amdgpu_atpx_priv.dhandle == ACPI_HANDLE(&pdev->dev))
499 return VGA_SWITCHEROO_IGD;
500 else
501 return VGA_SWITCHEROO_DIS;
502}
503
504static struct vga_switcheroo_handler amdgpu_atpx_handler = {
505 .switchto = amdgpu_atpx_switchto,
506 .power_state = amdgpu_atpx_power_state,
507 .init = amdgpu_atpx_init,
508 .get_client_id = amdgpu_atpx_get_client_id,
509};
510
511/**
512 * amdgpu_atpx_detect - detect whether we have PX
513 *
514 * Check if we have a PX system (all asics).
515 * Returns true if we have a PX system, false if not.
516 */
517static bool amdgpu_atpx_detect(void)
518{
519 char acpi_method_name[255] = { 0 };
520 struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
521 struct pci_dev *pdev = NULL;
522 bool has_atpx = false;
523 int vga_count = 0;
524
525 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
526 vga_count++;
527
528 has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
529 }
530
531 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
532 vga_count++;
533
534 has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
535 }
536
537 if (has_atpx && vga_count == 2) {
538 acpi_get_name(amdgpu_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
539 printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
540 acpi_method_name);
541 amdgpu_atpx_priv.atpx_detected = true;
542 return true;
543 }
544 return false;
545}
546
547/**
548 * amdgpu_register_atpx_handler - register with vga_switcheroo
549 *
550 * Register the PX callbacks with vga_switcheroo (all asics).
551 */
552void amdgpu_register_atpx_handler(void)
553{
554 bool r;
555
556 /* detect if we have any ATPX + 2 VGA in the system */
557 r = amdgpu_atpx_detect();
558 if (!r)
559 return;
560
561 vga_switcheroo_register_handler(&amdgpu_atpx_handler);
562}
563
564/**
565 * amdgpu_unregister_atpx_handler - unregister with vga_switcheroo
566 *
567 * Unregister the PX callbacks with vga_switcheroo (all asics).
568 */
569void amdgpu_unregister_atpx_handler(void)
570{
571 vga_switcheroo_unregister_handler();
572}
drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c+221−0
@@ -0,0 +1,221 @@
1/*
2 * Copyright 2009 Jerome Glisse.
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 * Authors: Jerome Glisse
23 */
24#include <drm/drmP.h>
25#include <drm/amdgpu_drm.h>
26#include "amdgpu.h"
27
28#define AMDGPU_BENCHMARK_ITERATIONS 1024
29#define AMDGPU_BENCHMARK_COMMON_MODES_N 17
30
31static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
32 uint64_t saddr, uint64_t daddr, int n)
33{
34 unsigned long start_jiffies;
35 unsigned long end_jiffies;
36 struct amdgpu_fence *fence = NULL;
37 int i, r;
38
39 start_jiffies = jiffies;
40 for (i = 0; i < n; i++) {
41 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
42 r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence);
43 if (r)
44 goto exit_do_move;
45 r = amdgpu_fence_wait(fence, false);
46 if (r)
47 goto exit_do_move;
48 amdgpu_fence_unref(&fence);
49 }
50 end_jiffies = jiffies;
51 r = jiffies_to_msecs(end_jiffies - start_jiffies);
52
53exit_do_move:
54 if (fence)
55 amdgpu_fence_unref(&fence);
56 return r;
57}
58
59
60static void amdgpu_benchmark_log_results(int n, unsigned size,
61 unsigned int time,
62 unsigned sdomain, unsigned ddomain,
63 char *kind)
64{
65 unsigned int throughput = (n * (size >> 10)) / time;
66 DRM_INFO("amdgpu: %s %u bo moves of %u kB from"
67 " %d to %d in %u ms, throughput: %u Mb/s or %u MB/s\n",
68 kind, n, size >> 10, sdomain, ddomain, time,
69 throughput * 8, throughput);
70}
71
72static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
73 unsigned sdomain, unsigned ddomain)
74{
75 struct amdgpu_bo *dobj = NULL;
76 struct amdgpu_bo *sobj = NULL;
77 uint64_t saddr, daddr;
78 int r, n;
79 int time;
80
81 n = AMDGPU_BENCHMARK_ITERATIONS;
82 r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, sdomain, 0, NULL, &sobj);
83 if (r) {
84 goto out_cleanup;
85 }
86 r = amdgpu_bo_reserve(sobj, false);
87 if (unlikely(r != 0))
88 goto out_cleanup;
89 r = amdgpu_bo_pin(sobj, sdomain, &saddr);
90 amdgpu_bo_unreserve(sobj);
91 if (r) {
92 goto out_cleanup;
93 }
94 r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, ddomain, 0, NULL, &dobj);
95 if (r) {
96 goto out_cleanup;
97 }
98 r = amdgpu_bo_reserve(dobj, false);
99 if (unlikely(r != 0))
100 goto out_cleanup;
101 r = amdgpu_bo_pin(dobj, ddomain, &daddr);
102 amdgpu_bo_unreserve(dobj);
103 if (r) {
104 goto out_cleanup;
105 }
106
107 if (adev->mman.buffer_funcs) {
108 time = amdgpu_benchmark_do_move(adev, size, saddr, daddr, n);
109 if (time < 0)
110 goto out_cleanup;
111 if (time > 0)
112 amdgpu_benchmark_log_results(n, size, time,
113 sdomain, ddomain, "dma");
114 }
115
116out_cleanup:
117 if (sobj) {
118 r = amdgpu_bo_reserve(sobj, false);
119 if (likely(r == 0)) {
120 amdgpu_bo_unpin(sobj);
121 amdgpu_bo_unreserve(sobj);
122 }
123 amdgpu_bo_unref(&sobj);
124 }
125 if (dobj) {
126 r = amdgpu_bo_reserve(dobj, false);
127 if (likely(r == 0)) {
128 amdgpu_bo_unpin(dobj);
129 amdgpu_bo_unreserve(dobj);
130 }
131 amdgpu_bo_unref(&dobj);
132 }
133
134 if (r) {
135 DRM_ERROR("Error while benchmarking BO move.\n");
136 }
137}
138
139void amdgpu_benchmark(struct amdgpu_device *adev, int test_number)
140{
141 int i;
142 int common_modes[AMDGPU_BENCHMARK_COMMON_MODES_N] = {
143 640 * 480 * 4,
144 720 * 480 * 4,
145 800 * 600 * 4,
146 848 * 480 * 4,
147 1024 * 768 * 4,
148 1152 * 768 * 4,
149 1280 * 720 * 4,
150 1280 * 800 * 4,
151 1280 * 854 * 4,
152 1280 * 960 * 4,
153 1280 * 1024 * 4,
154 1440 * 900 * 4,
155 1400 * 1050 * 4,
156 1680 * 1050 * 4,
157 1600 * 1200 * 4,
158 1920 * 1080 * 4,
159 1920 * 1200 * 4
160 };
161
162 switch (test_number) {
163 case 1:
164 /* simple test, VRAM to GTT and GTT to VRAM */
165 amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_GTT,
166 AMDGPU_GEM_DOMAIN_VRAM);
167 amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM,
168 AMDGPU_GEM_DOMAIN_GTT);
169 break;
170 case 2:
171 /* simple test, VRAM to VRAM */
172 amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM,
173 AMDGPU_GEM_DOMAIN_VRAM);
174 break;
175 case 3:
176 /* GTT to VRAM, buffer size sweep, powers of 2 */
177 for (i = 1; i <= 16384; i <<= 1)
178 amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
179 AMDGPU_GEM_DOMAIN_GTT,
180 AMDGPU_GEM_DOMAIN_VRAM);
181 break;
182 case 4:
183 /* VRAM to GTT, buffer size sweep, powers of 2 */
184 for (i = 1; i <= 16384; i <<= 1)
185 amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
186 AMDGPU_GEM_DOMAIN_VRAM,
187 AMDGPU_GEM_DOMAIN_GTT);
188 break;
189 case 5:
190 /* VRAM to VRAM, buffer size sweep, powers of 2 */
191 for (i = 1; i <= 16384; i <<= 1)
192 amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
193 AMDGPU_GEM_DOMAIN_VRAM,
194 AMDGPU_GEM_DOMAIN_VRAM);
195 break;
196 case 6:
197 /* GTT to VRAM, buffer size sweep, common modes */
198 for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++)
199 amdgpu_benchmark_move(adev, common_modes[i],
200 AMDGPU_GEM_DOMAIN_GTT,
201 AMDGPU_GEM_DOMAIN_VRAM);
202 break;
203 case 7:
204 /* VRAM to GTT, buffer size sweep, common modes */
205 for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++)
206 amdgpu_benchmark_move(adev, common_modes[i],
207 AMDGPU_GEM_DOMAIN_VRAM,
208 AMDGPU_GEM_DOMAIN_GTT);
209 break;
210 case 8:
211 /* VRAM to VRAM, buffer size sweep, common modes */
212 for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++)
213 amdgpu_benchmark_move(adev, common_modes[i],
214 AMDGPU_GEM_DOMAIN_VRAM,
215 AMDGPU_GEM_DOMAIN_VRAM);
216 break;
217
218 default:
219 DRM_ERROR("Unknown benchmark\n");
220 }
221}
drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c+363−0
@@ -0,0 +1,363 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include <drm/drmP.h>
29#include "amdgpu.h"
30#include "atom.h"
31
32#include <linux/vga_switcheroo.h>
33#include <linux/slab.h>
34#include <linux/acpi.h>
35/*
36 * BIOS.
37 */
38
39/* If you boot an IGP board with a discrete card as the primary,
40 * the IGP rom is not accessible via the rom bar as the IGP rom is
41 * part of the system bios. On boot, the system bios puts a
42 * copy of the igp rom at the start of vram if a discrete card is
43 * present.
44 */
45static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
46{
47 uint8_t __iomem *bios;
48 resource_size_t vram_base;
49 resource_size_t size = 256 * 1024; /* ??? */
50
51 if (!(adev->flags & AMDGPU_IS_APU))
52 if (!amdgpu_card_posted(adev))
53 return false;
54
55 adev->bios = NULL;
56 vram_base = pci_resource_start(adev->pdev, 0);
57 bios = ioremap(vram_base, size);
58 if (!bios) {
59 return false;
60 }
61
62 if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
63 iounmap(bios);
64 return false;
65 }
66 adev->bios = kmalloc(size, GFP_KERNEL);
67 if (adev->bios == NULL) {
68 iounmap(bios);
69 return false;
70 }
71 memcpy_fromio(adev->bios, bios, size);
72 iounmap(bios);
73 return true;
74}
75
76bool amdgpu_read_bios(struct amdgpu_device *adev)
77{
78 uint8_t __iomem *bios, val1, val2;
79 size_t size;
80
81 adev->bios = NULL;
82 /* XXX: some cards may return 0 for rom size? ddx has a workaround */
83 bios = pci_map_rom(adev->pdev, &size);
84 if (!bios) {
85 return false;
86 }
87
88 val1 = readb(&bios[0]);
89 val2 = readb(&bios[1]);
90
91 if (size == 0 || val1 != 0x55 || val2 != 0xaa) {
92 pci_unmap_rom(adev->pdev, bios);
93 return false;
94 }
95 adev->bios = kzalloc(size, GFP_KERNEL);
96 if (adev->bios == NULL) {
97 pci_unmap_rom(adev->pdev, bios);
98 return false;
99 }
100 memcpy_fromio(adev->bios, bios, size);
101 pci_unmap_rom(adev->pdev, bios);
102 return true;
103}
104
105static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
106{
107 uint8_t __iomem *bios;
108 size_t size;
109
110 adev->bios = NULL;
111
112 bios = pci_platform_rom(adev->pdev, &size);
113 if (!bios) {
114 return false;
115 }
116
117 if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
118 return false;
119 }
120 adev->bios = kmemdup(bios, size, GFP_KERNEL);
121 if (adev->bios == NULL) {
122 return false;
123 }
124
125 return true;
126}
127
128#ifdef CONFIG_ACPI
129/* ATRM is used to get the BIOS on the discrete cards in
130 * dual-gpu systems.
131 */
132/* retrieve the ROM in 4k blocks */
133#define ATRM_BIOS_PAGE 4096
134/**
135 * amdgpu_atrm_call - fetch a chunk of the vbios
136 *
137 * @atrm_handle: acpi ATRM handle
138 * @bios: vbios image pointer
139 * @offset: offset of vbios image data to fetch
140 * @len: length of vbios image data to fetch
141 *
142 * Executes ATRM to fetch a chunk of the discrete
143 * vbios image on PX systems (all asics).
144 * Returns the length of the buffer fetched.
145 */
146static int amdgpu_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
147 int offset, int len)
148{
149 acpi_status status;
150 union acpi_object atrm_arg_elements[2], *obj;
151 struct acpi_object_list atrm_arg;
152 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
153
154 atrm_arg.count = 2;
155 atrm_arg.pointer = &atrm_arg_elements[0];
156
157 atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
158 atrm_arg_elements[0].integer.value = offset;
159
160 atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
161 atrm_arg_elements[1].integer.value = len;
162
163 status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
164 if (ACPI_FAILURE(status)) {
165 printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
166 return -ENODEV;
167 }
168
169 obj = (union acpi_object *)buffer.pointer;
170 memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
171 len = obj->buffer.length;
172 kfree(buffer.pointer);
173 return len;
174}
175
176static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
177{
178 int ret;
179 int size = 256 * 1024;
180 int i;
181 struct pci_dev *pdev = NULL;
182 acpi_handle dhandle, atrm_handle;
183 acpi_status status;
184 bool found = false;
185
186 /* ATRM is for the discrete card only */
187 if (adev->flags & AMDGPU_IS_APU)
188 return false;
189
190 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
191 dhandle = ACPI_HANDLE(&pdev->dev);
192 if (!dhandle)
193 continue;
194
195 status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
196 if (!ACPI_FAILURE(status)) {
197 found = true;
198 break;
199 }
200 }
201
202 if (!found) {
203 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
204 dhandle = ACPI_HANDLE(&pdev->dev);
205 if (!dhandle)
206 continue;
207
208 status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
209 if (!ACPI_FAILURE(status)) {
210 found = true;
211 break;
212 }
213 }
214 }
215
216 if (!found)
217 return false;
218
219 adev->bios = kmalloc(size, GFP_KERNEL);
220 if (!adev->bios) {
221 DRM_ERROR("Unable to allocate bios\n");
222 return false;
223 }
224
225 for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
226 ret = amdgpu_atrm_call(atrm_handle,
227 adev->bios,
228 (i * ATRM_BIOS_PAGE),
229 ATRM_BIOS_PAGE);
230 if (ret < ATRM_BIOS_PAGE)
231 break;
232 }
233
234 if (i == 0 || adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) {
235 kfree(adev->bios);
236 return false;
237 }
238 return true;
239}
240#else
241static inline bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
242{
243 return false;
244}
245#endif
246
247static bool amdgpu_read_disabled_bios(struct amdgpu_device *adev)
248{
249 if (adev->flags & AMDGPU_IS_APU)
250 return igp_read_bios_from_vram(adev);
251 else
252 return amdgpu_asic_read_disabled_bios(adev);
253}
254
255#ifdef CONFIG_ACPI
256static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
257{
258 bool ret = false;
259 struct acpi_table_header *hdr;
260 acpi_size tbl_size;
261 UEFI_ACPI_VFCT *vfct;
262 GOP_VBIOS_CONTENT *vbios;
263 VFCT_IMAGE_HEADER *vhdr;
264
265 if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
266 return false;
267 if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
268 DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
269 goto out_unmap;
270 }
271
272 vfct = (UEFI_ACPI_VFCT *)hdr;
273 if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
274 DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
275 goto out_unmap;
276 }
277
278 vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
279 vhdr = &vbios->VbiosHeader;
280 DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
281 vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
282 vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
283
284 if (vhdr->PCIBus != adev->pdev->bus->number ||
285 vhdr->PCIDevice != PCI_SLOT(adev->pdev->devfn) ||
286 vhdr->PCIFunction != PCI_FUNC(adev->pdev->devfn) ||
287 vhdr->VendorID != adev->pdev->vendor ||
288 vhdr->DeviceID != adev->pdev->device) {
289 DRM_INFO("ACPI VFCT table is not for this card\n");
290 goto out_unmap;
291 }
292
293 if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
294 DRM_ERROR("ACPI VFCT image truncated\n");
295 goto out_unmap;
296 }
297
298 adev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
299 ret = !!adev->bios;
300
301out_unmap:
302 return ret;
303}
304#else
305static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
306{
307 return false;
308}
309#endif
310
311bool amdgpu_get_bios(struct amdgpu_device *adev)
312{
313 bool r;
314 uint16_t tmp;
315
316 r = amdgpu_atrm_get_bios(adev);
317 if (r == false)
318 r = amdgpu_acpi_vfct_bios(adev);
319 if (r == false)
320 r = igp_read_bios_from_vram(adev);
321 if (r == false)
322 r = amdgpu_read_bios(adev);
323 if (r == false) {
324 r = amdgpu_read_disabled_bios(adev);
325 }
326 if (r == false) {
327 r = amdgpu_read_platform_bios(adev);
328 }
329 if (r == false || adev->bios == NULL) {
330 DRM_ERROR("Unable to locate a BIOS ROM\n");
331 adev->bios = NULL;
332 return false;
333 }
334 if (adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) {
335 printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]);
336 goto free_bios;
337 }
338
339 tmp = RBIOS16(0x18);
340 if (RBIOS8(tmp + 0x14) != 0x0) {
341 DRM_INFO("Not an x86 BIOS ROM, not using.\n");
342 goto free_bios;
343 }
344
345 adev->bios_header_start = RBIOS16(0x48);
346 if (!adev->bios_header_start) {
347 goto free_bios;
348 }
349 tmp = adev->bios_header_start + 4;
350 if (!memcmp(adev->bios + tmp, "ATOM", 4) ||
351 !memcmp(adev->bios + tmp, "MOTA", 4)) {
352 adev->is_atom_bios = true;
353 } else {
354 adev->is_atom_bios = false;
355 }
356
357 DRM_DEBUG("%sBIOS detected\n", adev->is_atom_bios ? "ATOM" : "COM");
358 return true;
359free_bios:
360 kfree(adev->bios);
361 adev->bios = NULL;
362 return false;
363}
drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c+268−0
@@ -0,0 +1,268 @@
1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 *
25 */
26/*
27 * Authors:
28 * Christian König <deathsimple@vodafone.de>
29 */
30
31#include <drm/drmP.h>
32#include "amdgpu.h"
33
34static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv,
35 struct amdgpu_bo_list **result,
36 int *id)
37{
38 int r;
39
40 *result = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL);
41 if (!*result)
42 return -ENOMEM;
43
44 mutex_lock(&fpriv->bo_list_lock);
45 r = idr_alloc(&fpriv->bo_list_handles, *result,
46 1, 0, GFP_KERNEL);
47 if (r < 0) {
48 mutex_unlock(&fpriv->bo_list_lock);
49 kfree(*result);
50 return r;
51 }
52 *id = r;
53
54 mutex_init(&(*result)->lock);
55 (*result)->num_entries = 0;
56 (*result)->array = NULL;
57
58 mutex_lock(&(*result)->lock);
59 mutex_unlock(&fpriv->bo_list_lock);
60
61 return 0;
62}
63
64static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
65{
66 struct amdgpu_bo_list *list;
67
68 mutex_lock(&fpriv->bo_list_lock);
69 list = idr_find(&fpriv->bo_list_handles, id);
70 if (list) {
71 mutex_lock(&list->lock);
72 idr_remove(&fpriv->bo_list_handles, id);
73 mutex_unlock(&list->lock);
74 amdgpu_bo_list_free(list);
75 }
76 mutex_unlock(&fpriv->bo_list_lock);
77}
78
79static int amdgpu_bo_list_set(struct amdgpu_device *adev,
80 struct drm_file *filp,
81 struct amdgpu_bo_list *list,
82 struct drm_amdgpu_bo_list_entry *info,
83 unsigned num_entries)
84{
85 struct amdgpu_bo_list_entry *array;
86 struct amdgpu_bo *gds_obj = adev->gds.gds_gfx_bo;
87 struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo;
88 struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo;
89
90 bool has_userptr = false;
91 unsigned i;
92
93 array = drm_malloc_ab(num_entries, sizeof(struct amdgpu_bo_list_entry));
94 if (!array)
95 return -ENOMEM;
96 memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry));
97
98 for (i = 0; i < num_entries; ++i) {
99 struct amdgpu_bo_list_entry *entry = &array[i];
100 struct drm_gem_object *gobj;
101
102 gobj = drm_gem_object_lookup(adev->ddev, filp, info[i].bo_handle);
103 if (!gobj)
104 goto error_free;
105
106 entry->robj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
107 drm_gem_object_unreference_unlocked(gobj);
108 entry->priority = info[i].bo_priority;
109 entry->prefered_domains = entry->robj->initial_domain;
110 entry->allowed_domains = entry->prefered_domains;
111 if (entry->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
112 entry->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
113 if (amdgpu_ttm_tt_has_userptr(entry->robj->tbo.ttm)) {
114 has_userptr = true;
115 entry->prefered_domains = AMDGPU_GEM_DOMAIN_GTT;
116 entry->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
117 }
118 entry->tv.bo = &entry->robj->tbo;
119 entry->tv.shared = true;
120
121 if (entry->prefered_domains == AMDGPU_GEM_DOMAIN_GDS)
122 gds_obj = entry->robj;
123 if (entry->prefered_domains == AMDGPU_GEM_DOMAIN_GWS)
124 gws_obj = entry->robj;
125 if (entry->prefered_domains == AMDGPU_GEM_DOMAIN_OA)
126 oa_obj = entry->robj;
127 }
128
129 for (i = 0; i < list->num_entries; ++i)
130 amdgpu_bo_unref(&list->array[i].robj);
131
132 drm_free_large(list->array);
133
134 list->gds_obj = gds_obj;
135 list->gws_obj = gws_obj;
136 list->oa_obj = oa_obj;
137 list->has_userptr = has_userptr;
138 list->array = array;
139 list->num_entries = num_entries;
140
141 return 0;
142
143error_free:
144 drm_free_large(array);
145 return -ENOENT;
146}
147
148struct amdgpu_bo_list *
149amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id)
150{
151 struct amdgpu_bo_list *result;
152
153 mutex_lock(&fpriv->bo_list_lock);
154 result = idr_find(&fpriv->bo_list_handles, id);
155 if (result)
156 mutex_lock(&result->lock);
157 mutex_unlock(&fpriv->bo_list_lock);
158 return result;
159}
160
161void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
162{
163 mutex_unlock(&list->lock);
164}
165
166void amdgpu_bo_list_free(struct amdgpu_bo_list *list)
167{
168 unsigned i;
169
170 for (i = 0; i < list->num_entries; ++i)
171 amdgpu_bo_unref(&list->array[i].robj);
172
173 mutex_destroy(&list->lock);
174 drm_free_large(list->array);
175 kfree(list);
176}
177
178int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
179 struct drm_file *filp)
180{
181 const uint32_t info_size = sizeof(struct drm_amdgpu_bo_list_entry);
182
183 struct amdgpu_device *adev = dev->dev_private;
184 struct amdgpu_fpriv *fpriv = filp->driver_priv;
185 union drm_amdgpu_bo_list *args = data;
186 uint32_t handle = args->in.list_handle;
187 const void __user *uptr = (const void*)(long)args->in.bo_info_ptr;
188
189 struct drm_amdgpu_bo_list_entry *info;
190 struct amdgpu_bo_list *list;
191
192 int r;
193
194 info = drm_malloc_ab(args->in.bo_number,
195 sizeof(struct drm_amdgpu_bo_list_entry));
196 if (!info)
197 return -ENOMEM;
198
199 /* copy the handle array from userspace to a kernel buffer */
200 r = -EFAULT;
201 if (likely(info_size == args->in.bo_info_size)) {
202 unsigned long bytes = args->in.bo_number *
203 args->in.bo_info_size;
204
205 if (copy_from_user(info, uptr, bytes))
206 goto error_free;
207
208 } else {
209 unsigned long bytes = min(args->in.bo_info_size, info_size);
210 unsigned i;
211
212 memset(info, 0, args->in.bo_number * info_size);
213 for (i = 0; i < args->in.bo_number; ++i) {
214 if (copy_from_user(&info[i], uptr, bytes))
215 goto error_free;
216
217 uptr += args->in.bo_info_size;
218 }
219 }
220
221 switch (args->in.operation) {
222 case AMDGPU_BO_LIST_OP_CREATE:
223 r = amdgpu_bo_list_create(fpriv, &list, &handle);
224 if (r)
225 goto error_free;
226
227 r = amdgpu_bo_list_set(adev, filp, list, info,
228 args->in.bo_number);
229 amdgpu_bo_list_put(list);
230 if (r)
231 goto error_free;
232
233 break;
234
235 case AMDGPU_BO_LIST_OP_DESTROY:
236 amdgpu_bo_list_destroy(fpriv, handle);
237 handle = 0;
238 break;
239
240 case AMDGPU_BO_LIST_OP_UPDATE:
241 r = -ENOENT;
242 list = amdgpu_bo_list_get(fpriv, handle);
243 if (!list)
244 goto error_free;
245
246 r = amdgpu_bo_list_set(adev, filp, list, info,
247 args->in.bo_number);
248 amdgpu_bo_list_put(list);
249 if (r)
250 goto error_free;
251
252 break;
253
254 default:
255 r = -EINVAL;
256 goto error_free;
257 }
258
259 memset(args, 0, sizeof(*args));
260 args->out.list_handle = handle;
261 drm_free_large(info);
262
263 return 0;
264
265error_free:
266 drm_free_large(info);
267 return r;
268}
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c+1907−0
@@ -0,0 +1,1907 @@
1/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
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: Dave Airlie
24 * Alex Deucher
25 */
26#include <drm/drmP.h>
27#include <drm/drm_edid.h>
28#include <drm/drm_crtc_helper.h>
29#include <drm/drm_fb_helper.h>
30#include <drm/amdgpu_drm.h>
31#include "amdgpu.h"
32#include "atom.h"
33#include "atombios_encoders.h"
34#include "atombios_dp.h"
35#include "amdgpu_connectors.h"
36#include "amdgpu_i2c.h"
37
38#include <linux/pm_runtime.h>
39
40void amdgpu_connector_hotplug(struct drm_connector *connector)
41{
42 struct drm_device *dev = connector->dev;
43 struct amdgpu_device *adev = dev->dev_private;
44 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
45
46 /* bail if the connector does not have hpd pin, e.g.,
47 * VGA, TV, etc.
48 */
49 if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE)
50 return;
51
52 amdgpu_display_hpd_set_polarity(adev, amdgpu_connector->hpd.hpd);
53
54 /* if the connector is already off, don't turn it back on */
55 if (connector->dpms != DRM_MODE_DPMS_ON)
56 return;
57
58 /* just deal with DP (not eDP) here. */
59 if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
60 struct amdgpu_connector_atom_dig *dig_connector =
61 amdgpu_connector->con_priv;
62
63 /* if existing sink type was not DP no need to retrain */
64 if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT)
65 return;
66
67 /* first get sink type as it may be reset after (un)plug */
68 dig_connector->dp_sink_type = amdgpu_atombios_dp_get_sinktype(amdgpu_connector);
69 /* don't do anything if sink is not display port, i.e.,
70 * passive dp->(dvi|hdmi) adaptor
71 */
72 if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
73 int saved_dpms = connector->dpms;
74 /* Only turn off the display if it's physically disconnected */
75 if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {
76 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
77 } else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
78 /* set it to OFF so that drm_helper_connector_dpms()
79 * won't return immediately since the current state
80 * is ON at this point.
81 */
82 connector->dpms = DRM_MODE_DPMS_OFF;
83 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
84 }
85 connector->dpms = saved_dpms;
86 }
87 }
88}
89
90static void amdgpu_connector_property_change_mode(struct drm_encoder *encoder)
91{
92 struct drm_crtc *crtc = encoder->crtc;
93
94 if (crtc && crtc->enabled) {
95 drm_crtc_helper_set_mode(crtc, &crtc->mode,
96 crtc->x, crtc->y, crtc->primary->fb);
97 }
98}
99
100int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector)
101{
102 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
103 struct amdgpu_connector_atom_dig *dig_connector;
104 int bpc = 8;
105 unsigned mode_clock, max_tmds_clock;
106
107 switch (connector->connector_type) {
108 case DRM_MODE_CONNECTOR_DVII:
109 case DRM_MODE_CONNECTOR_HDMIB:
110 if (amdgpu_connector->use_digital) {
111 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
112 if (connector->display_info.bpc)
113 bpc = connector->display_info.bpc;
114 }
115 }
116 break;
117 case DRM_MODE_CONNECTOR_DVID:
118 case DRM_MODE_CONNECTOR_HDMIA:
119 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
120 if (connector->display_info.bpc)
121 bpc = connector->display_info.bpc;
122 }
123 break;
124 case DRM_MODE_CONNECTOR_DisplayPort:
125 dig_connector = amdgpu_connector->con_priv;
126 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
127 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) ||
128 drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
129 if (connector->display_info.bpc)
130 bpc = connector->display_info.bpc;
131 }
132 break;
133 case DRM_MODE_CONNECTOR_eDP:
134 case DRM_MODE_CONNECTOR_LVDS:
135 if (connector->display_info.bpc)
136 bpc = connector->display_info.bpc;
137 else {
138 const struct drm_connector_helper_funcs *connector_funcs =
139 connector->helper_private;
140 struct drm_encoder *encoder = connector_funcs->best_encoder(connector);
141 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
142 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
143
144 if (dig->lcd_misc & ATOM_PANEL_MISC_V13_6BIT_PER_COLOR)
145 bpc = 6;
146 else if (dig->lcd_misc & ATOM_PANEL_MISC_V13_8BIT_PER_COLOR)
147 bpc = 8;
148 }
149 break;
150 }
151
152 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
153 /*
154 * Pre DCE-8 hw can't handle > 12 bpc, and more than 12 bpc doesn't make
155 * much sense without support for > 12 bpc framebuffers. RGB 4:4:4 at
156 * 12 bpc is always supported on hdmi deep color sinks, as this is
157 * required by the HDMI-1.3 spec. Clamp to a safe 12 bpc maximum.
158 */
159 if (bpc > 12) {
160 DRM_DEBUG("%s: HDMI deep color %d bpc unsupported. Using 12 bpc.\n",
161 connector->name, bpc);
162 bpc = 12;
163 }
164
165 /* Any defined maximum tmds clock limit we must not exceed? */
166 if (connector->max_tmds_clock > 0) {
167 /* mode_clock is clock in kHz for mode to be modeset on this connector */
168 mode_clock = amdgpu_connector->pixelclock_for_modeset;
169
170 /* Maximum allowable input clock in kHz */
171 max_tmds_clock = connector->max_tmds_clock * 1000;
172
173 DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n",
174 connector->name, mode_clock, max_tmds_clock);
175
176 /* Check if bpc is within clock limit. Try to degrade gracefully otherwise */
177 if ((bpc == 12) && (mode_clock * 3/2 > max_tmds_clock)) {
178 if ((connector->display_info.edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
179 (mode_clock * 5/4 <= max_tmds_clock))
180 bpc = 10;
181 else
182 bpc = 8;
183
184 DRM_DEBUG("%s: HDMI deep color 12 bpc exceeds max tmds clock. Using %d bpc.\n",
185 connector->name, bpc);
186 }
187
188 if ((bpc == 10) && (mode_clock * 5/4 > max_tmds_clock)) {
189 bpc = 8;
190 DRM_DEBUG("%s: HDMI deep color 10 bpc exceeds max tmds clock. Using %d bpc.\n",
191 connector->name, bpc);
192 } else if (bpc > 8) {
193 /* max_tmds_clock missing, but hdmi spec mandates it for deep color. */
194 DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n",
195 connector->name);
196 bpc = 8;
197 }
198 }
199 }
200
201 if ((amdgpu_deep_color == 0) && (bpc > 8)) {
202 DRM_DEBUG("%s: Deep color disabled. Set amdgpu module param deep_color=1 to enable.\n",
203 connector->name);
204 bpc = 8;
205 }
206
207 DRM_DEBUG("%s: Display bpc=%d, returned bpc=%d\n",
208 connector->name, connector->display_info.bpc, bpc);
209
210 return bpc;
211}
212
213static void
214amdgpu_connector_update_scratch_regs(struct drm_connector *connector,
215 enum drm_connector_status status)
216{
217 struct drm_encoder *best_encoder = NULL;
218 struct drm_encoder *encoder = NULL;
219 const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
220 bool connected;
221 int i;
222
223 best_encoder = connector_funcs->best_encoder(connector);
224
225 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
226 if (connector->encoder_ids[i] == 0)
227 break;
228
229 encoder = drm_encoder_find(connector->dev,
230 connector->encoder_ids[i]);
231 if (!encoder)
232 continue;
233
234 if ((encoder == best_encoder) && (status == connector_status_connected))
235 connected = true;
236 else
237 connected = false;
238
239 amdgpu_atombios_encoder_set_bios_scratch_regs(connector, encoder, connected);
240
241 }
242}
243
244static struct drm_encoder *
245amdgpu_connector_find_encoder(struct drm_connector *connector,
246 int encoder_type)
247{
248 struct drm_encoder *encoder;
249 int i;
250
251 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
252 if (connector->encoder_ids[i] == 0)
253 break;
254 encoder = drm_encoder_find(connector->dev,
255 connector->encoder_ids[i]);
256 if (!encoder)
257 continue;
258
259 if (encoder->encoder_type == encoder_type)
260 return encoder;
261 }
262 return NULL;
263}
264
265struct edid *amdgpu_connector_edid(struct drm_connector *connector)
266{
267 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
268 struct drm_property_blob *edid_blob = connector->edid_blob_ptr;
269
270 if (amdgpu_connector->edid) {
271 return amdgpu_connector->edid;
272 } else if (edid_blob) {
273 struct edid *edid = kmemdup(edid_blob->data, edid_blob->length, GFP_KERNEL);
274 if (edid)
275 amdgpu_connector->edid = edid;
276 }
277 return amdgpu_connector->edid;
278}
279
280static struct edid *
281amdgpu_connector_get_hardcoded_edid(struct amdgpu_device *adev)
282{
283 struct edid *edid;
284
285 if (adev->mode_info.bios_hardcoded_edid) {
286 edid = kmalloc(adev->mode_info.bios_hardcoded_edid_size, GFP_KERNEL);
287 if (edid) {
288 memcpy((unsigned char *)edid,
289 (unsigned char *)adev->mode_info.bios_hardcoded_edid,
290 adev->mode_info.bios_hardcoded_edid_size);
291 return edid;
292 }
293 }
294 return NULL;
295}
296
297static void amdgpu_connector_get_edid(struct drm_connector *connector)
298{
299 struct drm_device *dev = connector->dev;
300 struct amdgpu_device *adev = dev->dev_private;
301 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
302
303 if (amdgpu_connector->edid)
304 return;
305
306 /* on hw with routers, select right port */
307 if (amdgpu_connector->router.ddc_valid)
308 amdgpu_i2c_router_select_ddc_port(amdgpu_connector);
309
310 if ((amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=
311 ENCODER_OBJECT_ID_NONE) &&
312 amdgpu_connector->ddc_bus->has_aux) {
313 amdgpu_connector->edid = drm_get_edid(connector,
314 &amdgpu_connector->ddc_bus->aux.ddc);
315 } else if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
316 (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
317 struct amdgpu_connector_atom_dig *dig = amdgpu_connector->con_priv;
318
319 if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
320 dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
321 amdgpu_connector->ddc_bus->has_aux)
322 amdgpu_connector->edid = drm_get_edid(connector,
323 &amdgpu_connector->ddc_bus->aux.ddc);
324 else if (amdgpu_connector->ddc_bus)
325 amdgpu_connector->edid = drm_get_edid(connector,
326 &amdgpu_connector->ddc_bus->adapter);
327 } else if (amdgpu_connector->ddc_bus) {
328 amdgpu_connector->edid = drm_get_edid(connector,
329 &amdgpu_connector->ddc_bus->adapter);
330 }
331
332 if (!amdgpu_connector->edid) {
333 /* some laptops provide a hardcoded edid in rom for LCDs */
334 if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ||
335 (connector->connector_type == DRM_MODE_CONNECTOR_eDP)))
336 amdgpu_connector->edid = amdgpu_connector_get_hardcoded_edid(adev);
337 }
338}
339
340static void amdgpu_connector_free_edid(struct drm_connector *connector)
341{
342 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
343
344 if (amdgpu_connector->edid) {
345 kfree(amdgpu_connector->edid);
346 amdgpu_connector->edid = NULL;
347 }
348}
349
350static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
351{
352 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
353 int ret;
354
355 if (amdgpu_connector->edid) {
356 drm_mode_connector_update_edid_property(connector, amdgpu_connector->edid);
357 ret = drm_add_edid_modes(connector, amdgpu_connector->edid);
358 drm_edid_to_eld(connector, amdgpu_connector->edid);
359 return ret;
360 }
361 drm_mode_connector_update_edid_property(connector, NULL);
362 return 0;
363}
364
365static struct drm_encoder *
366amdgpu_connector_best_single_encoder(struct drm_connector *connector)
367{
368 int enc_id = connector->encoder_ids[0];
369
370 /* pick the encoder ids */
371 if (enc_id)
372 return drm_encoder_find(connector->dev, enc_id);
373 return NULL;
374}
375
376static void amdgpu_get_native_mode(struct drm_connector *connector)
377{
378 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
379 struct amdgpu_encoder *amdgpu_encoder;
380
381 if (encoder == NULL)
382 return;
383
384 amdgpu_encoder = to_amdgpu_encoder(encoder);
385
386 if (!list_empty(&connector->probed_modes)) {
387 struct drm_display_mode *preferred_mode =
388 list_first_entry(&connector->probed_modes,
389 struct drm_display_mode, head);
390
391 amdgpu_encoder->native_mode = *preferred_mode;
392 } else {
393 amdgpu_encoder->native_mode.clock = 0;
394 }
395}
396
397static struct drm_display_mode *
398amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder)
399{
400 struct drm_device *dev = encoder->dev;
401 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
402 struct drm_display_mode *mode = NULL;
403 struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;
404
405 if (native_mode->hdisplay != 0 &&
406 native_mode->vdisplay != 0 &&
407 native_mode->clock != 0) {
408 mode = drm_mode_duplicate(dev, native_mode);
409 mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
410 drm_mode_set_name(mode);
411
412 DRM_DEBUG_KMS("Adding native panel mode %s\n", mode->name);
413 } else if (native_mode->hdisplay != 0 &&
414 native_mode->vdisplay != 0) {
415 /* mac laptops without an edid */
416 /* Note that this is not necessarily the exact panel mode,
417 * but an approximation based on the cvt formula. For these
418 * systems we should ideally read the mode info out of the
419 * registers or add a mode table, but this works and is much
420 * simpler.
421 */
422 mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false);
423 mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
424 DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name);
425 }
426 return mode;
427}
428
429static void amdgpu_connector_add_common_modes(struct drm_encoder *encoder,
430 struct drm_connector *connector)
431{
432 struct drm_device *dev = encoder->dev;
433 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
434 struct drm_display_mode *mode = NULL;
435 struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;
436 int i;
437 struct mode_size {
438 int w;
439 int h;
440 } common_modes[17] = {
441 { 640, 480},
442 { 720, 480},
443 { 800, 600},
444 { 848, 480},
445 {1024, 768},
446 {1152, 768},
447 {1280, 720},
448 {1280, 800},
449 {1280, 854},
450 {1280, 960},
451 {1280, 1024},
452 {1440, 900},
453 {1400, 1050},
454 {1680, 1050},
455 {1600, 1200},
456 {1920, 1080},
457 {1920, 1200}
458 };
459
460 for (i = 0; i < 17; i++) {
461 if (amdgpu_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
462 if (common_modes[i].w > 1024 ||
463 common_modes[i].h > 768)
464 continue;
465 }
466 if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
467 if (common_modes[i].w > native_mode->hdisplay ||
468 common_modes[i].h > native_mode->vdisplay ||
469 (common_modes[i].w == native_mode->hdisplay &&
470 common_modes[i].h == native_mode->vdisplay))
471 continue;
472 }
473 if (common_modes[i].w < 320 || common_modes[i].h < 200)
474 continue;
475
476 mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
477 drm_mode_probed_add(connector, mode);
478 }
479}
480
481static int amdgpu_connector_set_property(struct drm_connector *connector,
482 struct drm_property *property,
483 uint64_t val)
484{
485 struct drm_device *dev = connector->dev;
486 struct amdgpu_device *adev = dev->dev_private;
487 struct drm_encoder *encoder;
488 struct amdgpu_encoder *amdgpu_encoder;
489
490 if (property == adev->mode_info.coherent_mode_property) {
491 struct amdgpu_encoder_atom_dig *dig;
492 bool new_coherent_mode;
493
494 /* need to find digital encoder on connector */
495 encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
496 if (!encoder)
497 return 0;
498
499 amdgpu_encoder = to_amdgpu_encoder(encoder);
500
501 if (!amdgpu_encoder->enc_priv)
502 return 0;
503
504 dig = amdgpu_encoder->enc_priv;
505 new_coherent_mode = val ? true : false;
506 if (dig->coherent_mode != new_coherent_mode) {
507 dig->coherent_mode = new_coherent_mode;
508 amdgpu_connector_property_change_mode(&amdgpu_encoder->base);
509 }
510 }
511
512 if (property == adev->mode_info.audio_property) {
513 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
514 /* need to find digital encoder on connector */
515 encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
516 if (!encoder)
517 return 0;
518
519 amdgpu_encoder = to_amdgpu_encoder(encoder);
520
521 if (amdgpu_connector->audio != val) {
522 amdgpu_connector->audio = val;
523 amdgpu_connector_property_change_mode(&amdgpu_encoder->base);
524 }
525 }
526
527 if (property == adev->mode_info.dither_property) {
528 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
529 /* need to find digital encoder on connector */
530 encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
531 if (!encoder)
532 return 0;
533
534 amdgpu_encoder = to_amdgpu_encoder(encoder);
535
536 if (amdgpu_connector->dither != val) {
537 amdgpu_connector->dither = val;
538 amdgpu_connector_property_change_mode(&amdgpu_encoder->base);
539 }
540 }
541
542 if (property == adev->mode_info.underscan_property) {
543 /* need to find digital encoder on connector */
544 encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
545 if (!encoder)
546 return 0;
547
548 amdgpu_encoder = to_amdgpu_encoder(encoder);
549
550 if (amdgpu_encoder->underscan_type != val) {
551 amdgpu_encoder->underscan_type = val;
552 amdgpu_connector_property_change_mode(&amdgpu_encoder->base);
553 }
554 }
555
556 if (property == adev->mode_info.underscan_hborder_property) {
557 /* need to find digital encoder on connector */
558 encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
559 if (!encoder)
560 return 0;
561
562 amdgpu_encoder = to_amdgpu_encoder(encoder);
563
564 if (amdgpu_encoder->underscan_hborder != val) {
565 amdgpu_encoder->underscan_hborder = val;
566 amdgpu_connector_property_change_mode(&amdgpu_encoder->base);
567 }
568 }
569
570 if (property == adev->mode_info.underscan_vborder_property) {
571 /* need to find digital encoder on connector */
572 encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
573 if (!encoder)
574 return 0;
575
576 amdgpu_encoder = to_amdgpu_encoder(encoder);
577
578 if (amdgpu_encoder->underscan_vborder != val) {
579 amdgpu_encoder->underscan_vborder = val;
580 amdgpu_connector_property_change_mode(&amdgpu_encoder->base);
581 }
582 }
583
584 if (property == adev->mode_info.load_detect_property) {
585 struct amdgpu_connector *amdgpu_connector =
586 to_amdgpu_connector(connector);
587
588 if (val == 0)
589 amdgpu_connector->dac_load_detect = false;
590 else
591 amdgpu_connector->dac_load_detect = true;
592 }
593
594 if (property == dev->mode_config.scaling_mode_property) {
595 enum amdgpu_rmx_type rmx_type;
596
597 if (connector->encoder) {
598 amdgpu_encoder = to_amdgpu_encoder(connector->encoder);
599 } else {
600 const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
601 amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector));
602 }
603
604 switch (val) {
605 default:
606 case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break;
607 case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break;
608 case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break;
609 case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break;
610 }
611 if (amdgpu_encoder->rmx_type == rmx_type)
612 return 0;
613
614 if ((rmx_type != DRM_MODE_SCALE_NONE) &&
615 (amdgpu_encoder->native_mode.clock == 0))
616 return 0;
617
618 amdgpu_encoder->rmx_type = rmx_type;
619
620 amdgpu_connector_property_change_mode(&amdgpu_encoder->base);
621 }
622
623 return 0;
624}
625
626static void
627amdgpu_connector_fixup_lcd_native_mode(struct drm_encoder *encoder,
628 struct drm_connector *connector)
629{
630 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
631 struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;
632 struct drm_display_mode *t, *mode;
633
634 /* If the EDID preferred mode doesn't match the native mode, use it */
635 list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
636 if (mode->type & DRM_MODE_TYPE_PREFERRED) {
637 if (mode->hdisplay != native_mode->hdisplay ||
638 mode->vdisplay != native_mode->vdisplay)
639 memcpy(native_mode, mode, sizeof(*mode));
640 }
641 }
642
643 /* Try to get native mode details from EDID if necessary */
644 if (!native_mode->clock) {
645 list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
646 if (mode->hdisplay == native_mode->hdisplay &&
647 mode->vdisplay == native_mode->vdisplay) {
648 *native_mode = *mode;
649 drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);
650 DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n");
651 break;
652 }
653 }
654 }
655
656 if (!native_mode->clock) {
657 DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n");
658 amdgpu_encoder->rmx_type = RMX_OFF;
659 }
660}
661
662static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector)
663{
664 struct drm_encoder *encoder;
665 int ret = 0;
666 struct drm_display_mode *mode;
667
668 amdgpu_connector_get_edid(connector);
669 ret = amdgpu_connector_ddc_get_modes(connector);
670 if (ret > 0) {
671 encoder = amdgpu_connector_best_single_encoder(connector);
672 if (encoder) {
673 amdgpu_connector_fixup_lcd_native_mode(encoder, connector);
674 /* add scaled modes */
675 amdgpu_connector_add_common_modes(encoder, connector);
676 }
677 return ret;
678 }
679
680 encoder = amdgpu_connector_best_single_encoder(connector);
681 if (!encoder)
682 return 0;
683
684 /* we have no EDID modes */
685 mode = amdgpu_connector_lcd_native_mode(encoder);
686 if (mode) {
687 ret = 1;
688 drm_mode_probed_add(connector, mode);
689 /* add the width/height from vbios tables if available */
690 connector->display_info.width_mm = mode->width_mm;
691 connector->display_info.height_mm = mode->height_mm;
692 /* add scaled modes */
693 amdgpu_connector_add_common_modes(encoder, connector);
694 }
695
696 return ret;
697}
698
699static int amdgpu_connector_lvds_mode_valid(struct drm_connector *connector,
700 struct drm_display_mode *mode)
701{
702 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
703
704 if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
705 return MODE_PANEL;
706
707 if (encoder) {
708 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
709 struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;
710
711 /* AVIVO hardware supports downscaling modes larger than the panel
712 * to the panel size, but I'm not sure this is desirable.
713 */
714 if ((mode->hdisplay > native_mode->hdisplay) ||
715 (mode->vdisplay > native_mode->vdisplay))
716 return MODE_PANEL;
717
718 /* if scaling is disabled, block non-native modes */
719 if (amdgpu_encoder->rmx_type == RMX_OFF) {
720 if ((mode->hdisplay != native_mode->hdisplay) ||
721 (mode->vdisplay != native_mode->vdisplay))
722 return MODE_PANEL;
723 }
724 }
725
726 return MODE_OK;
727}
728
729static enum drm_connector_status
730amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
731{
732 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
733 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
734 enum drm_connector_status ret = connector_status_disconnected;
735 int r;
736
737 r = pm_runtime_get_sync(connector->dev->dev);
738 if (r < 0)
739 return connector_status_disconnected;
740
741 if (encoder) {
742 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
743 struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;
744
745 /* check if panel is valid */
746 if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
747 ret = connector_status_connected;
748
749 }
750
751 /* check for edid as well */
752 amdgpu_connector_get_edid(connector);
753 if (amdgpu_connector->edid)
754 ret = connector_status_connected;
755 /* check acpi lid status ??? */
756
757 amdgpu_connector_update_scratch_regs(connector, ret);
758 pm_runtime_mark_last_busy(connector->dev->dev);
759 pm_runtime_put_autosuspend(connector->dev->dev);
760 return ret;
761}
762
763static void amdgpu_connector_destroy(struct drm_connector *connector)
764{
765 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
766
767 if (amdgpu_connector->ddc_bus->has_aux)
768 drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);
769 amdgpu_connector_free_edid(connector);
770 kfree(amdgpu_connector->con_priv);
771 drm_connector_unregister(connector);
772 drm_connector_cleanup(connector);
773 kfree(connector);
774}
775
776static int amdgpu_connector_set_lcd_property(struct drm_connector *connector,
777 struct drm_property *property,
778 uint64_t value)
779{
780 struct drm_device *dev = connector->dev;
781 struct amdgpu_encoder *amdgpu_encoder;
782 enum amdgpu_rmx_type rmx_type;
783
784 DRM_DEBUG_KMS("\n");
785 if (property != dev->mode_config.scaling_mode_property)
786 return 0;
787
788 if (connector->encoder)
789 amdgpu_encoder = to_amdgpu_encoder(connector->encoder);
790 else {
791 const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
792 amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector));
793 }
794
795 switch (value) {
796 case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break;
797 case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break;
798 case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break;
799 default:
800 case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break;
801 }
802 if (amdgpu_encoder->rmx_type == rmx_type)
803 return 0;
804
805 amdgpu_encoder->rmx_type = rmx_type;
806
807 amdgpu_connector_property_change_mode(&amdgpu_encoder->base);
808 return 0;
809}
810
811
812static const struct drm_connector_helper_funcs amdgpu_connector_lvds_helper_funcs = {
813 .get_modes = amdgpu_connector_lvds_get_modes,
814 .mode_valid = amdgpu_connector_lvds_mode_valid,
815 .best_encoder = amdgpu_connector_best_single_encoder,
816};
817
818static const struct drm_connector_funcs amdgpu_connector_lvds_funcs = {
819 .dpms = drm_helper_connector_dpms,
820 .detect = amdgpu_connector_lvds_detect,
821 .fill_modes = drm_helper_probe_single_connector_modes,
822 .destroy = amdgpu_connector_destroy,
823 .set_property = amdgpu_connector_set_lcd_property,
824};
825
826static int amdgpu_connector_vga_get_modes(struct drm_connector *connector)
827{
828 int ret;
829
830 amdgpu_connector_get_edid(connector);
831 ret = amdgpu_connector_ddc_get_modes(connector);
832
833 return ret;
834}
835
836static int amdgpu_connector_vga_mode_valid(struct drm_connector *connector,
837 struct drm_display_mode *mode)
838{
839 struct drm_device *dev = connector->dev;
840 struct amdgpu_device *adev = dev->dev_private;
841
842 /* XXX check mode bandwidth */
843
844 if ((mode->clock / 10) > adev->clock.max_pixel_clock)
845 return MODE_CLOCK_HIGH;
846
847 return MODE_OK;
848}
849
850static enum drm_connector_status
851amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
852{
853 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
854 struct drm_encoder *encoder;
855 const struct drm_encoder_helper_funcs *encoder_funcs;
856 bool dret = false;
857 enum drm_connector_status ret = connector_status_disconnected;
858 int r;
859
860 r = pm_runtime_get_sync(connector->dev->dev);
861 if (r < 0)
862 return connector_status_disconnected;
863
864 encoder = amdgpu_connector_best_single_encoder(connector);
865 if (!encoder)
866 ret = connector_status_disconnected;
867
868 if (amdgpu_connector->ddc_bus)
869 dret = amdgpu_ddc_probe(amdgpu_connector, false);
870 if (dret) {
871 amdgpu_connector->detected_by_load = false;
872 amdgpu_connector_free_edid(connector);
873 amdgpu_connector_get_edid(connector);
874
875 if (!amdgpu_connector->edid) {
876 DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
877 connector->name);
878 ret = connector_status_connected;
879 } else {
880 amdgpu_connector->use_digital =
881 !!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
882
883 /* some oems have boards with separate digital and analog connectors
884 * with a shared ddc line (often vga + hdmi)
885 */
886 if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) {
887 amdgpu_connector_free_edid(connector);
888 ret = connector_status_disconnected;
889 } else {
890 ret = connector_status_connected;
891 }
892 }
893 } else {
894
895 /* if we aren't forcing don't do destructive polling */
896 if (!force) {
897 /* only return the previous status if we last
898 * detected a monitor via load.
899 */
900 if (amdgpu_connector->detected_by_load)
901 ret = connector->status;
902 goto out;
903 }
904
905 if (amdgpu_connector->dac_load_detect && encoder) {
906 encoder_funcs = encoder->helper_private;
907 ret = encoder_funcs->detect(encoder, connector);
908 if (ret != connector_status_disconnected)
909 amdgpu_connector->detected_by_load = true;
910 }
911 }
912
913 amdgpu_connector_update_scratch_regs(connector, ret);
914
915out:
916 pm_runtime_mark_last_busy(connector->dev->dev);
917 pm_runtime_put_autosuspend(connector->dev->dev);
918
919 return ret;
920}
921
922static const struct drm_connector_helper_funcs amdgpu_connector_vga_helper_funcs = {
923 .get_modes = amdgpu_connector_vga_get_modes,
924 .mode_valid = amdgpu_connector_vga_mode_valid,
925 .best_encoder = amdgpu_connector_best_single_encoder,
926};
927
928static const struct drm_connector_funcs amdgpu_connector_vga_funcs = {
929 .dpms = drm_helper_connector_dpms,
930 .detect = amdgpu_connector_vga_detect,
931 .fill_modes = drm_helper_probe_single_connector_modes,
932 .destroy = amdgpu_connector_destroy,
933 .set_property = amdgpu_connector_set_property,
934};
935
936static bool
937amdgpu_connector_check_hpd_status_unchanged(struct drm_connector *connector)
938{
939 struct drm_device *dev = connector->dev;
940 struct amdgpu_device *adev = dev->dev_private;
941 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
942 enum drm_connector_status status;
943
944 if (amdgpu_connector->hpd.hpd != AMDGPU_HPD_NONE) {
945 if (amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd))
946 status = connector_status_connected;
947 else
948 status = connector_status_disconnected;
949 if (connector->status == status)
950 return true;
951 }
952
953 return false;
954}
955
956/*
957 * DVI is complicated
958 * Do a DDC probe, if DDC probe passes, get the full EDID so
959 * we can do analog/digital monitor detection at this point.
960 * If the monitor is an analog monitor or we got no DDC,
961 * we need to find the DAC encoder object for this connector.
962 * If we got no DDC, we do load detection on the DAC encoder object.
963 * If we got analog DDC or load detection passes on the DAC encoder
964 * we have to check if this analog encoder is shared with anyone else (TV)
965 * if its shared we have to set the other connector to disconnected.
966 */
967static enum drm_connector_status
968amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
969{
970 struct drm_device *dev = connector->dev;
971 struct amdgpu_device *adev = dev->dev_private;
972 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
973 struct drm_encoder *encoder = NULL;
974 const struct drm_encoder_helper_funcs *encoder_funcs;
975 int i, r;
976 enum drm_connector_status ret = connector_status_disconnected;
977 bool dret = false, broken_edid = false;
978
979 r = pm_runtime_get_sync(connector->dev->dev);
980 if (r < 0)
981 return connector_status_disconnected;
982
983 if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
984 ret = connector->status;
985 goto exit;
986 }
987
988 if (amdgpu_connector->ddc_bus)
989 dret = amdgpu_ddc_probe(amdgpu_connector, false);
990 if (dret) {
991 amdgpu_connector->detected_by_load = false;
992 amdgpu_connector_free_edid(connector);
993 amdgpu_connector_get_edid(connector);
994
995 if (!amdgpu_connector->edid) {
996 DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
997 connector->name);
998 ret = connector_status_connected;
999 broken_edid = true; /* defer use_digital to later */
1000 } else {
1001 amdgpu_connector->use_digital =
1002 !!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
1003
1004 /* some oems have boards with separate digital and analog connectors
1005 * with a shared ddc line (often vga + hdmi)
1006 */
1007 if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) {
1008 amdgpu_connector_free_edid(connector);
1009 ret = connector_status_disconnected;
1010 } else {
1011 ret = connector_status_connected;
1012 }
1013
1014 /* This gets complicated. We have boards with VGA + HDMI with a
1015 * shared DDC line and we have boards with DVI-D + HDMI with a shared
1016 * DDC line. The latter is more complex because with DVI<->HDMI adapters
1017 * you don't really know what's connected to which port as both are digital.
1018 */
1019 if (amdgpu_connector->shared_ddc && (ret == connector_status_connected)) {
1020 struct drm_connector *list_connector;
1021 struct amdgpu_connector *list_amdgpu_connector;
1022 list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
1023 if (connector == list_connector)
1024 continue;
1025 list_amdgpu_connector = to_amdgpu_connector(list_connector);
1026 if (list_amdgpu_connector->shared_ddc &&
1027 (list_amdgpu_connector->ddc_bus->rec.i2c_id ==
1028 amdgpu_connector->ddc_bus->rec.i2c_id)) {
1029 /* cases where both connectors are digital */
1030 if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) {
1031 /* hpd is our only option in this case */
1032 if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {
1033 amdgpu_connector_free_edid(connector);
1034 ret = connector_status_disconnected;
1035 }
1036 }
1037 }
1038 }
1039 }
1040 }
1041 }
1042
1043 if ((ret == connector_status_connected) && (amdgpu_connector->use_digital == true))
1044 goto out;
1045
1046 /* DVI-D and HDMI-A are digital only */
1047 if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) ||
1048 (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
1049 goto out;
1050
1051 /* if we aren't forcing don't do destructive polling */
1052 if (!force) {
1053 /* only return the previous status if we last
1054 * detected a monitor via load.
1055 */
1056 if (amdgpu_connector->detected_by_load)
1057 ret = connector->status;
1058 goto out;
1059 }
1060
1061 /* find analog encoder */
1062 if (amdgpu_connector->dac_load_detect) {
1063 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1064 if (connector->encoder_ids[i] == 0)
1065 break;
1066
1067 encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
1068 if (!encoder)
1069 continue;
1070
1071 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&
1072 encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
1073 continue;
1074
1075 encoder_funcs = encoder->helper_private;
1076 if (encoder_funcs->detect) {
1077 if (!broken_edid) {
1078 if (ret != connector_status_connected) {
1079 /* deal with analog monitors without DDC */
1080 ret = encoder_funcs->detect(encoder, connector);
1081 if (ret == connector_status_connected) {
1082 amdgpu_connector->use_digital = false;
1083 }
1084 if (ret != connector_status_disconnected)
1085 amdgpu_connector->detected_by_load = true;
1086 }
1087 } else {
1088 enum drm_connector_status lret;
1089 /* assume digital unless load detected otherwise */
1090 amdgpu_connector->use_digital = true;
1091 lret = encoder_funcs->detect(encoder, connector);
1092 DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret);
1093 if (lret == connector_status_connected)
1094 amdgpu_connector->use_digital = false;
1095 }
1096 break;
1097 }
1098 }
1099 }
1100
1101out:
1102 /* updated in get modes as well since we need to know if it's analog or digital */
1103 amdgpu_connector_update_scratch_regs(connector, ret);
1104
1105exit:
1106 pm_runtime_mark_last_busy(connector->dev->dev);
1107 pm_runtime_put_autosuspend(connector->dev->dev);
1108
1109 return ret;
1110}
1111
1112/* okay need to be smart in here about which encoder to pick */
1113static struct drm_encoder *
1114amdgpu_connector_dvi_encoder(struct drm_connector *connector)
1115{
1116 int enc_id = connector->encoder_ids[0];
1117 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
1118 struct drm_encoder *encoder;
1119 int i;
1120 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1121 if (connector->encoder_ids[i] == 0)
1122 break;
1123
1124 encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
1125 if (!encoder)
1126 continue;
1127
1128 if (amdgpu_connector->use_digital == true) {
1129 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
1130 return encoder;
1131 } else {
1132 if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||
1133 encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
1134 return encoder;
1135 }
1136 }
1137
1138 /* see if we have a default encoder TODO */
1139
1140 /* then check use digitial */
1141 /* pick the first one */
1142 if (enc_id)
1143 return drm_encoder_find(connector->dev, enc_id);
1144 return NULL;
1145}
1146
1147static void amdgpu_connector_dvi_force(struct drm_connector *connector)
1148{
1149 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
1150 if (connector->force == DRM_FORCE_ON)
1151 amdgpu_connector->use_digital = false;
1152 if (connector->force == DRM_FORCE_ON_DIGITAL)
1153 amdgpu_connector->use_digital = true;
1154}
1155
1156static int amdgpu_connector_dvi_mode_valid(struct drm_connector *connector,
1157 struct drm_display_mode *mode)
1158{
1159 struct drm_device *dev = connector->dev;
1160 struct amdgpu_device *adev = dev->dev_private;
1161 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
1162
1163 /* XXX check mode bandwidth */
1164
1165 if (amdgpu_connector->use_digital && (mode->clock > 165000)) {
1166 if ((amdgpu_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) ||
1167 (amdgpu_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
1168 (amdgpu_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) {
1169 return MODE_OK;
1170 } else if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
1171 /* HDMI 1.3+ supports max clock of 340 Mhz */
1172 if (mode->clock > 340000)
1173 return MODE_CLOCK_HIGH;
1174 else
1175 return MODE_OK;
1176 } else {
1177 return MODE_CLOCK_HIGH;
1178 }
1179 }
1180
1181 /* check against the max pixel clock */
1182 if ((mode->clock / 10) > adev->clock.max_pixel_clock)
1183 return MODE_CLOCK_HIGH;
1184
1185 return MODE_OK;
1186}
1187
1188static const struct drm_connector_helper_funcs amdgpu_connector_dvi_helper_funcs = {
1189 .get_modes = amdgpu_connector_vga_get_modes,
1190 .mode_valid = amdgpu_connector_dvi_mode_valid,
1191 .best_encoder = amdgpu_connector_dvi_encoder,
1192};
1193
1194static const struct drm_connector_funcs amdgpu_connector_dvi_funcs = {
1195 .dpms = drm_helper_connector_dpms,
1196 .detect = amdgpu_connector_dvi_detect,
1197 .fill_modes = drm_helper_probe_single_connector_modes,
1198 .set_property = amdgpu_connector_set_property,
1199 .destroy = amdgpu_connector_destroy,
1200 .force = amdgpu_connector_dvi_force,
1201};
1202
1203static int amdgpu_connector_dp_get_modes(struct drm_connector *connector)
1204{
1205 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
1206 struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;
1207 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
1208 int ret;
1209
1210 if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
1211 (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
1212 struct drm_display_mode *mode;
1213
1214 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1215 if (!amdgpu_dig_connector->edp_on)
1216 amdgpu_atombios_encoder_set_edp_panel_power(connector,
1217 ATOM_TRANSMITTER_ACTION_POWER_ON);
1218 amdgpu_connector_get_edid(connector);
1219 ret = amdgpu_connector_ddc_get_modes(connector);
1220 if (!amdgpu_dig_connector->edp_on)
1221 amdgpu_atombios_encoder_set_edp_panel_power(connector,
1222 ATOM_TRANSMITTER_ACTION_POWER_OFF);
1223 } else {
1224 /* need to setup ddc on the bridge */
1225 if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=
1226 ENCODER_OBJECT_ID_NONE) {
1227 if (encoder)
1228 amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);
1229 }
1230 amdgpu_connector_get_edid(connector);
1231 ret = amdgpu_connector_ddc_get_modes(connector);
1232 }
1233
1234 if (ret > 0) {
1235 if (encoder) {
1236 amdgpu_connector_fixup_lcd_native_mode(encoder, connector);
1237 /* add scaled modes */
1238 amdgpu_connector_add_common_modes(encoder, connector);
1239 }
1240 return ret;
1241 }
1242
1243 if (!encoder)
1244 return 0;
1245
1246 /* we have no EDID modes */
1247 mode = amdgpu_connector_lcd_native_mode(encoder);
1248 if (mode) {
1249 ret = 1;
1250 drm_mode_probed_add(connector, mode);
1251 /* add the width/height from vbios tables if available */
1252 connector->display_info.width_mm = mode->width_mm;
1253 connector->display_info.height_mm = mode->height_mm;
1254 /* add scaled modes */
1255 amdgpu_connector_add_common_modes(encoder, connector);
1256 }
1257 } else {
1258 /* need to setup ddc on the bridge */
1259 if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=
1260 ENCODER_OBJECT_ID_NONE) {
1261 if (encoder)
1262 amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);
1263 }
1264 amdgpu_connector_get_edid(connector);
1265 ret = amdgpu_connector_ddc_get_modes(connector);
1266
1267 amdgpu_get_native_mode(connector);
1268 }
1269
1270 return ret;
1271}
1272
1273u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector)
1274{
1275 struct drm_encoder *encoder;
1276 struct amdgpu_encoder *amdgpu_encoder;
1277 int i;
1278
1279 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1280 if (connector->encoder_ids[i] == 0)
1281 break;
1282
1283 encoder = drm_encoder_find(connector->dev,
1284 connector->encoder_ids[i]);
1285 if (!encoder)
1286 continue;
1287
1288 amdgpu_encoder = to_amdgpu_encoder(encoder);
1289
1290 switch (amdgpu_encoder->encoder_id) {
1291 case ENCODER_OBJECT_ID_TRAVIS:
1292 case ENCODER_OBJECT_ID_NUTMEG:
1293 return amdgpu_encoder->encoder_id;
1294 default:
1295 break;
1296 }
1297 }
1298
1299 return ENCODER_OBJECT_ID_NONE;
1300}
1301
1302static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector)
1303{
1304 struct drm_encoder *encoder;
1305 struct amdgpu_encoder *amdgpu_encoder;
1306 int i;
1307 bool found = false;
1308
1309 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1310 if (connector->encoder_ids[i] == 0)
1311 break;
1312 encoder = drm_encoder_find(connector->dev,
1313 connector->encoder_ids[i]);
1314 if (!encoder)
1315 continue;
1316
1317 amdgpu_encoder = to_amdgpu_encoder(encoder);
1318 if (amdgpu_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2)
1319 found = true;
1320 }
1321
1322 return found;
1323}
1324
1325bool amdgpu_connector_is_dp12_capable(struct drm_connector *connector)
1326{
1327 struct drm_device *dev = connector->dev;
1328 struct amdgpu_device *adev = dev->dev_private;
1329
1330 if ((adev->clock.default_dispclk >= 53900) &&
1331 amdgpu_connector_encoder_is_hbr2(connector)) {
1332 return true;
1333 }
1334
1335 return false;
1336}
1337
1338static enum drm_connector_status
1339amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
1340{
1341 struct drm_device *dev = connector->dev;
1342 struct amdgpu_device *adev = dev->dev_private;
1343 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
1344 enum drm_connector_status ret = connector_status_disconnected;
1345 struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;
1346 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
1347 int r;
1348
1349 r = pm_runtime_get_sync(connector->dev->dev);
1350 if (r < 0)
1351 return connector_status_disconnected;
1352
1353 if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
1354 ret = connector->status;
1355 goto out;
1356 }
1357
1358 amdgpu_connector_free_edid(connector);
1359
1360 if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
1361 (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
1362 if (encoder) {
1363 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
1364 struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;
1365
1366 /* check if panel is valid */
1367 if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
1368 ret = connector_status_connected;
1369 }
1370 /* eDP is always DP */
1371 amdgpu_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
1372 if (!amdgpu_dig_connector->edp_on)
1373 amdgpu_atombios_encoder_set_edp_panel_power(connector,
1374 ATOM_TRANSMITTER_ACTION_POWER_ON);
1375 if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
1376 ret = connector_status_connected;
1377 if (!amdgpu_dig_connector->edp_on)
1378 amdgpu_atombios_encoder_set_edp_panel_power(connector,
1379 ATOM_TRANSMITTER_ACTION_POWER_OFF);
1380 } else if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=
1381 ENCODER_OBJECT_ID_NONE) {
1382 /* DP bridges are always DP */
1383 amdgpu_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
1384 /* get the DPCD from the bridge */
1385 amdgpu_atombios_dp_get_dpcd(amdgpu_connector);
1386
1387 if (encoder) {
1388 /* setup ddc on the bridge */
1389 amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);
1390 /* bridge chips are always aux */
1391 if (amdgpu_ddc_probe(amdgpu_connector, true)) /* try DDC */
1392 ret = connector_status_connected;
1393 else if (amdgpu_connector->dac_load_detect) { /* try load detection */
1394 const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
1395 ret = encoder_funcs->detect(encoder, connector);
1396 }
1397 }
1398 } else {
1399 amdgpu_dig_connector->dp_sink_type =
1400 amdgpu_atombios_dp_get_sinktype(amdgpu_connector);
1401 if (amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {
1402 ret = connector_status_connected;
1403 if (amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
1404 amdgpu_atombios_dp_get_dpcd(amdgpu_connector);
1405 } else {
1406 if (amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
1407 if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
1408 ret = connector_status_connected;
1409 } else {
1410 /* try non-aux ddc (DP to DVI/HDMI/etc. adapter) */
1411 if (amdgpu_ddc_probe(amdgpu_connector, false))
1412 ret = connector_status_connected;
1413 }
1414 }
1415 }
1416
1417 amdgpu_connector_update_scratch_regs(connector, ret);
1418out:
1419 pm_runtime_mark_last_busy(connector->dev->dev);
1420 pm_runtime_put_autosuspend(connector->dev->dev);
1421
1422 return ret;
1423}
1424
1425static int amdgpu_connector_dp_mode_valid(struct drm_connector *connector,
1426 struct drm_display_mode *mode)
1427{
1428 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
1429 struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;
1430
1431 /* XXX check mode bandwidth */
1432
1433 if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
1434 (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
1435 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
1436
1437 if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
1438 return MODE_PANEL;
1439
1440 if (encoder) {
1441 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
1442 struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;
1443
1444 /* AVIVO hardware supports downscaling modes larger than the panel
1445 * to the panel size, but I'm not sure this is desirable.
1446 */
1447 if ((mode->hdisplay > native_mode->hdisplay) ||
1448 (mode->vdisplay > native_mode->vdisplay))
1449 return MODE_PANEL;
1450
1451 /* if scaling is disabled, block non-native modes */
1452 if (amdgpu_encoder->rmx_type == RMX_OFF) {
1453 if ((mode->hdisplay != native_mode->hdisplay) ||
1454 (mode->vdisplay != native_mode->vdisplay))
1455 return MODE_PANEL;
1456 }
1457 }
1458 return MODE_OK;
1459 } else {
1460 if ((amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
1461 (amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
1462 return amdgpu_atombios_dp_mode_valid_helper(connector, mode);
1463 } else {
1464 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
1465 /* HDMI 1.3+ supports max clock of 340 Mhz */
1466 if (mode->clock > 340000)
1467 return MODE_CLOCK_HIGH;
1468 } else {
1469 if (mode->clock > 165000)
1470 return MODE_CLOCK_HIGH;
1471 }
1472 }
1473 }
1474
1475 return MODE_OK;
1476}
1477
1478static const struct drm_connector_helper_funcs amdgpu_connector_dp_helper_funcs = {
1479 .get_modes = amdgpu_connector_dp_get_modes,
1480 .mode_valid = amdgpu_connector_dp_mode_valid,
1481 .best_encoder = amdgpu_connector_dvi_encoder,
1482};
1483
1484static const struct drm_connector_funcs amdgpu_connector_dp_funcs = {
1485 .dpms = drm_helper_connector_dpms,
1486 .detect = amdgpu_connector_dp_detect,
1487 .fill_modes = drm_helper_probe_single_connector_modes,
1488 .set_property = amdgpu_connector_set_property,
1489 .destroy = amdgpu_connector_destroy,
1490 .force = amdgpu_connector_dvi_force,
1491};
1492
1493static const struct drm_connector_funcs amdgpu_connector_edp_funcs = {
1494 .dpms = drm_helper_connector_dpms,
1495 .detect = amdgpu_connector_dp_detect,
1496 .fill_modes = drm_helper_probe_single_connector_modes,
1497 .set_property = amdgpu_connector_set_lcd_property,
1498 .destroy = amdgpu_connector_destroy,
1499 .force = amdgpu_connector_dvi_force,
1500};
1501
1502void
1503amdgpu_connector_add(struct amdgpu_device *adev,
1504 uint32_t connector_id,
1505 uint32_t supported_device,
1506 int connector_type,
1507 struct amdgpu_i2c_bus_rec *i2c_bus,
1508 uint16_t connector_object_id,
1509 struct amdgpu_hpd *hpd,
1510 struct amdgpu_router *router)
1511{
1512 struct drm_device *dev = adev->ddev;
1513 struct drm_connector *connector;
1514 struct amdgpu_connector *amdgpu_connector;
1515 struct amdgpu_connector_atom_dig *amdgpu_dig_connector;
1516 struct drm_encoder *encoder;
1517 struct amdgpu_encoder *amdgpu_encoder;
1518 uint32_t subpixel_order = SubPixelNone;
1519 bool shared_ddc = false;
1520 bool is_dp_bridge = false;
1521 bool has_aux = false;
1522
1523 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
1524 return;
1525
1526 /* see if we already added it */
1527 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1528 amdgpu_connector = to_amdgpu_connector(connector);
1529 if (amdgpu_connector->connector_id == connector_id) {
1530 amdgpu_connector->devices |= supported_device;
1531 return;
1532 }
1533 if (amdgpu_connector->ddc_bus && i2c_bus->valid) {
1534 if (amdgpu_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) {
1535 amdgpu_connector->shared_ddc = true;
1536 shared_ddc = true;
1537 }
1538 if (amdgpu_connector->router_bus && router->ddc_valid &&
1539 (amdgpu_connector->router.router_id == router->router_id)) {
1540 amdgpu_connector->shared_ddc = false;
1541 shared_ddc = false;
1542 }
1543 }
1544 }
1545
1546 /* check if it's a dp bridge */
1547 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1548 amdgpu_encoder = to_amdgpu_encoder(encoder);
1549 if (amdgpu_encoder->devices & supported_device) {
1550 switch (amdgpu_encoder->encoder_id) {
1551 case ENCODER_OBJECT_ID_TRAVIS:
1552 case ENCODER_OBJECT_ID_NUTMEG:
1553 is_dp_bridge = true;
1554 break;
1555 default:
1556 break;
1557 }
1558 }
1559 }
1560
1561 amdgpu_connector = kzalloc(sizeof(struct amdgpu_connector), GFP_KERNEL);
1562 if (!amdgpu_connector)
1563 return;
1564
1565 connector = &amdgpu_connector->base;
1566
1567 amdgpu_connector->connector_id = connector_id;
1568 amdgpu_connector->devices = supported_device;
1569 amdgpu_connector->shared_ddc = shared_ddc;
1570 amdgpu_connector->connector_object_id = connector_object_id;
1571 amdgpu_connector->hpd = *hpd;
1572
1573 amdgpu_connector->router = *router;
1574 if (router->ddc_valid || router->cd_valid) {
1575 amdgpu_connector->router_bus = amdgpu_i2c_lookup(adev, &router->i2c_info);
1576 if (!amdgpu_connector->router_bus)
1577 DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n");
1578 }
1579
1580 if (is_dp_bridge) {
1581 amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);
1582 if (!amdgpu_dig_connector)
1583 goto failed;
1584 amdgpu_connector->con_priv = amdgpu_dig_connector;
1585 if (i2c_bus->valid) {
1586 amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
1587 if (amdgpu_connector->ddc_bus)
1588 has_aux = true;
1589 else
1590 DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1591 }
1592 switch (connector_type) {
1593 case DRM_MODE_CONNECTOR_VGA:
1594 case DRM_MODE_CONNECTOR_DVIA:
1595 default:
1596 drm_connector_init(dev, &amdgpu_connector->base,
1597 &amdgpu_connector_dp_funcs, connector_type);
1598 drm_connector_helper_add(&amdgpu_connector->base,
1599 &amdgpu_connector_dp_helper_funcs);
1600 connector->interlace_allowed = true;
1601 connector->doublescan_allowed = true;
1602 amdgpu_connector->dac_load_detect = true;
1603 drm_object_attach_property(&amdgpu_connector->base.base,
1604 adev->mode_info.load_detect_property,
1605 1);
1606 drm_object_attach_property(&amdgpu_connector->base.base,
1607 dev->mode_config.scaling_mode_property,
1608 DRM_MODE_SCALE_NONE);
1609 break;
1610 case DRM_MODE_CONNECTOR_DVII:
1611 case DRM_MODE_CONNECTOR_DVID:
1612 case DRM_MODE_CONNECTOR_HDMIA:
1613 case DRM_MODE_CONNECTOR_HDMIB:
1614 case DRM_MODE_CONNECTOR_DisplayPort:
1615 drm_connector_init(dev, &amdgpu_connector->base,
1616 &amdgpu_connector_dp_funcs, connector_type);
1617 drm_connector_helper_add(&amdgpu_connector->base,
1618 &amdgpu_connector_dp_helper_funcs);
1619 drm_object_attach_property(&amdgpu_connector->base.base,
1620 adev->mode_info.underscan_property,
1621 UNDERSCAN_OFF);
1622 drm_object_attach_property(&amdgpu_connector->base.base,
1623 adev->mode_info.underscan_hborder_property,
1624 0);
1625 drm_object_attach_property(&amdgpu_connector->base.base,
1626 adev->mode_info.underscan_vborder_property,
1627 0);
1628
1629 drm_object_attach_property(&amdgpu_connector->base.base,
1630 dev->mode_config.scaling_mode_property,
1631 DRM_MODE_SCALE_NONE);
1632
1633 drm_object_attach_property(&amdgpu_connector->base.base,
1634 adev->mode_info.dither_property,
1635 AMDGPU_FMT_DITHER_DISABLE);
1636
1637 if (amdgpu_audio != 0)
1638 drm_object_attach_property(&amdgpu_connector->base.base,
1639 adev->mode_info.audio_property,
1640 AMDGPU_AUDIO_AUTO);
1641
1642 subpixel_order = SubPixelHorizontalRGB;
1643 connector->interlace_allowed = true;
1644 if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
1645 connector->doublescan_allowed = true;
1646 else
1647 connector->doublescan_allowed = false;
1648 if (connector_type == DRM_MODE_CONNECTOR_DVII) {
1649 amdgpu_connector->dac_load_detect = true;
1650 drm_object_attach_property(&amdgpu_connector->base.base,
1651 adev->mode_info.load_detect_property,
1652 1);
1653 }
1654 break;
1655 case DRM_MODE_CONNECTOR_LVDS:
1656 case DRM_MODE_CONNECTOR_eDP:
1657 drm_connector_init(dev, &amdgpu_connector->base,
1658 &amdgpu_connector_edp_funcs, connector_type);
1659 drm_connector_helper_add(&amdgpu_connector->base,
1660 &amdgpu_connector_dp_helper_funcs);
1661 drm_object_attach_property(&amdgpu_connector->base.base,
1662 dev->mode_config.scaling_mode_property,
1663 DRM_MODE_SCALE_FULLSCREEN);
1664 subpixel_order = SubPixelHorizontalRGB;
1665 connector->interlace_allowed = false;
1666 connector->doublescan_allowed = false;
1667 break;
1668 }
1669 } else {
1670 switch (connector_type) {
1671 case DRM_MODE_CONNECTOR_VGA:
1672 drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_vga_funcs, connector_type);
1673 drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_vga_helper_funcs);
1674 if (i2c_bus->valid) {
1675 amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
1676 if (!amdgpu_connector->ddc_bus)
1677 DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1678 }
1679 amdgpu_connector->dac_load_detect = true;
1680 drm_object_attach_property(&amdgpu_connector->base.base,
1681 adev->mode_info.load_detect_property,
1682 1);
1683 drm_object_attach_property(&amdgpu_connector->base.base,
1684 dev->mode_config.scaling_mode_property,
1685 DRM_MODE_SCALE_NONE);
1686 /* no HPD on analog connectors */
1687 amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;
1688 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1689 connector->interlace_allowed = true;
1690 connector->doublescan_allowed = true;
1691 break;
1692 case DRM_MODE_CONNECTOR_DVIA:
1693 drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_vga_funcs, connector_type);
1694 drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_vga_helper_funcs);
1695 if (i2c_bus->valid) {
1696 amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
1697 if (!amdgpu_connector->ddc_bus)
1698 DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1699 }
1700 amdgpu_connector->dac_load_detect = true;
1701 drm_object_attach_property(&amdgpu_connector->base.base,
1702 adev->mode_info.load_detect_property,
1703 1);
1704 drm_object_attach_property(&amdgpu_connector->base.base,
1705 dev->mode_config.scaling_mode_property,
1706 DRM_MODE_SCALE_NONE);
1707 /* no HPD on analog connectors */
1708 amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;
1709 connector->interlace_allowed = true;
1710 connector->doublescan_allowed = true;
1711 break;
1712 case DRM_MODE_CONNECTOR_DVII:
1713 case DRM_MODE_CONNECTOR_DVID:
1714 amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);
1715 if (!amdgpu_dig_connector)
1716 goto failed;
1717 amdgpu_connector->con_priv = amdgpu_dig_connector;
1718 drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_dvi_funcs, connector_type);
1719 drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dvi_helper_funcs);
1720 if (i2c_bus->valid) {
1721 amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
1722 if (!amdgpu_connector->ddc_bus)
1723 DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1724 }
1725 subpixel_order = SubPixelHorizontalRGB;
1726 drm_object_attach_property(&amdgpu_connector->base.base,
1727 adev->mode_info.coherent_mode_property,
1728 1);
1729 drm_object_attach_property(&amdgpu_connector->base.base,
1730 adev->mode_info.underscan_property,
1731 UNDERSCAN_OFF);
1732 drm_object_attach_property(&amdgpu_connector->base.base,
1733 adev->mode_info.underscan_hborder_property,
1734 0);
1735 drm_object_attach_property(&amdgpu_connector->base.base,
1736 adev->mode_info.underscan_vborder_property,
1737 0);
1738 drm_object_attach_property(&amdgpu_connector->base.base,
1739 dev->mode_config.scaling_mode_property,
1740 DRM_MODE_SCALE_NONE);
1741
1742 if (amdgpu_audio != 0) {
1743 drm_object_attach_property(&amdgpu_connector->base.base,
1744 adev->mode_info.audio_property,
1745 AMDGPU_AUDIO_AUTO);
1746 }
1747 drm_object_attach_property(&amdgpu_connector->base.base,
1748 adev->mode_info.dither_property,
1749 AMDGPU_FMT_DITHER_DISABLE);
1750 if (connector_type == DRM_MODE_CONNECTOR_DVII) {
1751 amdgpu_connector->dac_load_detect = true;
1752 drm_object_attach_property(&amdgpu_connector->base.base,
1753 adev->mode_info.load_detect_property,
1754 1);
1755 }
1756 connector->interlace_allowed = true;
1757 if (connector_type == DRM_MODE_CONNECTOR_DVII)
1758 connector->doublescan_allowed = true;
1759 else
1760 connector->doublescan_allowed = false;
1761 break;
1762 case DRM_MODE_CONNECTOR_HDMIA:
1763 case DRM_MODE_CONNECTOR_HDMIB:
1764 amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);
1765 if (!amdgpu_dig_connector)
1766 goto failed;
1767 amdgpu_connector->con_priv = amdgpu_dig_connector;
1768 drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_dvi_funcs, connector_type);
1769 drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dvi_helper_funcs);
1770 if (i2c_bus->valid) {
1771 amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
1772 if (!amdgpu_connector->ddc_bus)
1773 DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1774 }
1775 drm_object_attach_property(&amdgpu_connector->base.base,
1776 adev->mode_info.coherent_mode_property,
1777 1);
1778 drm_object_attach_property(&amdgpu_connector->base.base,
1779 adev->mode_info.underscan_property,
1780 UNDERSCAN_OFF);
1781 drm_object_attach_property(&amdgpu_connector->base.base,
1782 adev->mode_info.underscan_hborder_property,
1783 0);
1784 drm_object_attach_property(&amdgpu_connector->base.base,
1785 adev->mode_info.underscan_vborder_property,
1786 0);
1787 drm_object_attach_property(&amdgpu_connector->base.base,
1788 dev->mode_config.scaling_mode_property,
1789 DRM_MODE_SCALE_NONE);
1790 if (amdgpu_audio != 0) {
1791 drm_object_attach_property(&amdgpu_connector->base.base,
1792 adev->mode_info.audio_property,
1793 AMDGPU_AUDIO_AUTO);
1794 }
1795 drm_object_attach_property(&amdgpu_connector->base.base,
1796 adev->mode_info.dither_property,
1797 AMDGPU_FMT_DITHER_DISABLE);
1798 subpixel_order = SubPixelHorizontalRGB;
1799 connector->interlace_allowed = true;
1800 if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
1801 connector->doublescan_allowed = true;
1802 else
1803 connector->doublescan_allowed = false;
1804 break;
1805 case DRM_MODE_CONNECTOR_DisplayPort:
1806 amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);
1807 if (!amdgpu_dig_connector)
1808 goto failed;
1809 amdgpu_connector->con_priv = amdgpu_dig_connector;
1810 drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_dp_funcs, connector_type);
1811 drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dp_helper_funcs);
1812 if (i2c_bus->valid) {
1813 amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
1814 if (amdgpu_connector->ddc_bus)
1815 has_aux = true;
1816 else
1817 DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1818 }
1819 subpixel_order = SubPixelHorizontalRGB;
1820 drm_object_attach_property(&amdgpu_connector->base.base,
1821 adev->mode_info.coherent_mode_property,
1822 1);
1823 drm_object_attach_property(&amdgpu_connector->base.base,
1824 adev->mode_info.underscan_property,
1825 UNDERSCAN_OFF);
1826 drm_object_attach_property(&amdgpu_connector->base.base,
1827 adev->mode_info.underscan_hborder_property,
1828 0);
1829 drm_object_attach_property(&amdgpu_connector->base.base,
1830 adev->mode_info.underscan_vborder_property,
1831 0);
1832 drm_object_attach_property(&amdgpu_connector->base.base,
1833 dev->mode_config.scaling_mode_property,
1834 DRM_MODE_SCALE_NONE);
1835 if (amdgpu_audio != 0) {
1836 drm_object_attach_property(&amdgpu_connector->base.base,
1837 adev->mode_info.audio_property,
1838 AMDGPU_AUDIO_AUTO);
1839 }
1840 drm_object_attach_property(&amdgpu_connector->base.base,
1841 adev->mode_info.dither_property,
1842 AMDGPU_FMT_DITHER_DISABLE);
1843 connector->interlace_allowed = true;
1844 /* in theory with a DP to VGA converter... */
1845 connector->doublescan_allowed = false;
1846 break;
1847 case DRM_MODE_CONNECTOR_eDP:
1848 amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);
1849 if (!amdgpu_dig_connector)
1850 goto failed;
1851 amdgpu_connector->con_priv = amdgpu_dig_connector;
1852 drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_edp_funcs, connector_type);
1853 drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dp_helper_funcs);
1854 if (i2c_bus->valid) {
1855 amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
1856 if (amdgpu_connector->ddc_bus)
1857 has_aux = true;
1858 else
1859 DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1860 }
1861 drm_object_attach_property(&amdgpu_connector->base.base,
1862 dev->mode_config.scaling_mode_property,
1863 DRM_MODE_SCALE_FULLSCREEN);
1864 subpixel_order = SubPixelHorizontalRGB;
1865 connector->interlace_allowed = false;
1866 connector->doublescan_allowed = false;
1867 break;
1868 case DRM_MODE_CONNECTOR_LVDS:
1869 amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);
1870 if (!amdgpu_dig_connector)
1871 goto failed;
1872 amdgpu_connector->con_priv = amdgpu_dig_connector;
1873 drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_lvds_funcs, connector_type);
1874 drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_lvds_helper_funcs);
1875 if (i2c_bus->valid) {
1876 amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);
1877 if (!amdgpu_connector->ddc_bus)
1878 DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1879 }
1880 drm_object_attach_property(&amdgpu_connector->base.base,
1881 dev->mode_config.scaling_mode_property,
1882 DRM_MODE_SCALE_FULLSCREEN);
1883 subpixel_order = SubPixelHorizontalRGB;
1884 connector->interlace_allowed = false;
1885 connector->doublescan_allowed = false;
1886 break;
1887 }
1888 }
1889
1890 if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE) {
1891 if (i2c_bus->valid)
1892 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1893 } else
1894 connector->polled = DRM_CONNECTOR_POLL_HPD;
1895
1896 connector->display_info.subpixel_order = subpixel_order;
1897 drm_connector_register(connector);
1898
1899 if (has_aux)
1900 amdgpu_atombios_dp_aux_init(amdgpu_connector);
1901
1902 return;
1903
1904failed:
1905 drm_connector_cleanup(connector);
1906 kfree(connector);
1907}
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h+42−0
@@ -0,0 +1,42 @@
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 __AMDGPU_CONNECTORS_H__
25#define __AMDGPU_CONNECTORS_H__
26
27struct edid *amdgpu_connector_edid(struct drm_connector *connector);
28void amdgpu_connector_hotplug(struct drm_connector *connector);
29int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector);
30u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector);
31bool amdgpu_connector_is_dp12_capable(struct drm_connector *connector);
32void
33amdgpu_connector_add(struct amdgpu_device *adev,
34 uint32_t connector_id,
35 uint32_t supported_device,
36 int connector_type,
37 struct amdgpu_i2c_bus_rec *i2c_bus,
38 uint16_t connector_object_id,
39 struct amdgpu_hpd *hpd,
40 struct amdgpu_router *router);
41
42#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+796−0
@@ -0,0 +1,796 @@
1/*
2 * Copyright 2008 Jerome Glisse.
3 * All Rights Reserved.
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 (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Jerome Glisse <glisse@freedesktop.org>
26 */
27#include <linux/list_sort.h>
28#include <drm/drmP.h>
29#include <drm/amdgpu_drm.h>
30#include "amdgpu.h"
31#include "amdgpu_trace.h"
32
33#define AMDGPU_CS_MAX_PRIORITY 32u
34#define AMDGPU_CS_NUM_BUCKETS (AMDGPU_CS_MAX_PRIORITY + 1)
35
36/* This is based on the bucket sort with O(n) time complexity.
37 * An item with priority "i" is added to bucket[i]. The lists are then
38 * concatenated in descending order.
39 */
40struct amdgpu_cs_buckets {
41 struct list_head bucket[AMDGPU_CS_NUM_BUCKETS];
42};
43
44static void amdgpu_cs_buckets_init(struct amdgpu_cs_buckets *b)
45{
46 unsigned i;
47
48 for (i = 0; i < AMDGPU_CS_NUM_BUCKETS; i++)
49 INIT_LIST_HEAD(&b->bucket[i]);
50}
51
52static void amdgpu_cs_buckets_add(struct amdgpu_cs_buckets *b,
53 struct list_head *item, unsigned priority)
54{
55 /* Since buffers which appear sooner in the relocation list are
56 * likely to be used more often than buffers which appear later
57 * in the list, the sort mustn't change the ordering of buffers
58 * with the same priority, i.e. it must be stable.
59 */
60 list_add_tail(item, &b->bucket[min(priority, AMDGPU_CS_MAX_PRIORITY)]);
61}
62
63static void amdgpu_cs_buckets_get_list(struct amdgpu_cs_buckets *b,
64 struct list_head *out_list)
65{
66 unsigned i;
67
68 /* Connect the sorted buckets in the output list. */
69 for (i = 0; i < AMDGPU_CS_NUM_BUCKETS; i++) {
70 list_splice(&b->bucket[i], out_list);
71 }
72}
73
74int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,
75 u32 ip_instance, u32 ring,
76 struct amdgpu_ring **out_ring)
77{
78 /* Right now all IPs have only one instance - multiple rings. */
79 if (ip_instance != 0) {
80 DRM_ERROR("invalid ip instance: %d\n", ip_instance);
81 return -EINVAL;
82 }
83
84 switch (ip_type) {
85 default:
86 DRM_ERROR("unknown ip type: %d\n", ip_type);
87 return -EINVAL;
88 case AMDGPU_HW_IP_GFX:
89 if (ring < adev->gfx.num_gfx_rings) {
90 *out_ring = &adev->gfx.gfx_ring[ring];
91 } else {
92 DRM_ERROR("only %d gfx rings are supported now\n",
93 adev->gfx.num_gfx_rings);
94 return -EINVAL;
95 }
96 break;
97 case AMDGPU_HW_IP_COMPUTE:
98 if (ring < adev->gfx.num_compute_rings) {
99 *out_ring = &adev->gfx.compute_ring[ring];
100 } else {
101 DRM_ERROR("only %d compute rings are supported now\n",
102 adev->gfx.num_compute_rings);
103 return -EINVAL;
104 }
105 break;
106 case AMDGPU_HW_IP_DMA:
107 if (ring < 2) {
108 *out_ring = &adev->sdma[ring].ring;
109 } else {
110 DRM_ERROR("only two SDMA rings are supported\n");
111 return -EINVAL;
112 }
113 break;
114 case AMDGPU_HW_IP_UVD:
115 *out_ring = &adev->uvd.ring;
116 break;
117 case AMDGPU_HW_IP_VCE:
118 if (ring < 2){
119 *out_ring = &adev->vce.ring[ring];
120 } else {
121 DRM_ERROR("only two VCE rings are supported\n");
122 return -EINVAL;
123 }
124 break;
125 }
126 return 0;
127}
128
129int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
130{
131 union drm_amdgpu_cs *cs = data;
132 uint64_t *chunk_array_user;
133 uint64_t *chunk_array = NULL;
134 struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
135 unsigned size, i;
136 int r = 0;
137
138 if (!cs->in.num_chunks)
139 goto out;
140
141 p->ctx = amdgpu_ctx_get(fpriv, cs->in.ctx_id);
142 if (!p->ctx) {
143 r = -EINVAL;
144 goto out;
145 }
146 p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle);
147
148 /* get chunks */
149 INIT_LIST_HEAD(&p->validated);
150 chunk_array = kcalloc(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL);
151 if (chunk_array == NULL) {
152 r = -ENOMEM;
153 goto out;
154 }
155
156 chunk_array_user = (uint64_t *)(unsigned long)(cs->in.chunks);
157 if (copy_from_user(chunk_array, chunk_array_user,
158 sizeof(uint64_t)*cs->in.num_chunks)) {
159 r = -EFAULT;
160 goto out;
161 }
162
163 p->nchunks = cs->in.num_chunks;
164 p->chunks = kcalloc(p->nchunks, sizeof(struct amdgpu_cs_chunk),
165 GFP_KERNEL);
166 if (p->chunks == NULL) {
167 r = -ENOMEM;
168 goto out;
169 }
170
171 for (i = 0; i < p->nchunks; i++) {
172 struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
173 struct drm_amdgpu_cs_chunk user_chunk;
174 uint32_t __user *cdata;
175
176 chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
177 if (copy_from_user(&user_chunk, chunk_ptr,
178 sizeof(struct drm_amdgpu_cs_chunk))) {
179 r = -EFAULT;
180 goto out;
181 }
182 p->chunks[i].chunk_id = user_chunk.chunk_id;
183 p->chunks[i].length_dw = user_chunk.length_dw;
184 if (p->chunks[i].chunk_id == AMDGPU_CHUNK_ID_IB)
185 p->num_ibs++;
186
187 size = p->chunks[i].length_dw;
188 cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
189 p->chunks[i].user_ptr = cdata;
190
191 p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
192 if (p->chunks[i].kdata == NULL) {
193 r = -ENOMEM;
194 goto out;
195 }
196 size *= sizeof(uint32_t);
197 if (copy_from_user(p->chunks[i].kdata, cdata, size)) {
198 r = -EFAULT;
199 goto out;
200 }
201
202 if (p->chunks[i].chunk_id == AMDGPU_CHUNK_ID_FENCE) {
203 size = sizeof(struct drm_amdgpu_cs_chunk_fence);
204 if (p->chunks[i].length_dw * sizeof(uint32_t) >= size) {
205 uint32_t handle;
206 struct drm_gem_object *gobj;
207 struct drm_amdgpu_cs_chunk_fence *fence_data;
208
209 fence_data = (void *)p->chunks[i].kdata;
210 handle = fence_data->handle;
211 gobj = drm_gem_object_lookup(p->adev->ddev,
212 p->filp, handle);
213 if (gobj == NULL) {
214 r = -EINVAL;
215 goto out;
216 }
217
218 p->uf.bo = gem_to_amdgpu_bo(gobj);
219 p->uf.offset = fence_data->offset;
220 } else {
221 r = -EINVAL;
222 goto out;
223 }
224 }
225 }
226
227 p->ibs = kcalloc(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL);
228 if (!p->ibs) {
229 r = -ENOMEM;
230 goto out;
231 }
232
233out:
234 kfree(chunk_array);
235 return r;
236}
237
238/* Returns how many bytes TTM can move per IB.
239 */
240static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
241{
242 u64 real_vram_size = adev->mc.real_vram_size;
243 u64 vram_usage = atomic64_read(&adev->vram_usage);
244
245 /* This function is based on the current VRAM usage.
246 *
247 * - If all of VRAM is free, allow relocating the number of bytes that
248 * is equal to 1/4 of the size of VRAM for this IB.
249
250 * - If more than one half of VRAM is occupied, only allow relocating
251 * 1 MB of data for this IB.
252 *
253 * - From 0 to one half of used VRAM, the threshold decreases
254 * linearly.
255 * __________________
256 * 1/4 of -|\ |
257 * VRAM | \ |
258 * | \ |
259 * | \ |
260 * | \ |
261 * | \ |
262 * | \ |
263 * | \________|1 MB
264 * |----------------|
265 * VRAM 0 % 100 %
266 * used used
267 *
268 * Note: It's a threshold, not a limit. The threshold must be crossed
269 * for buffer relocations to stop, so any buffer of an arbitrary size
270 * can be moved as long as the threshold isn't crossed before
271 * the relocation takes place. We don't want to disable buffer
272 * relocations completely.
273 *
274 * The idea is that buffers should be placed in VRAM at creation time
275 * and TTM should only do a minimum number of relocations during
276 * command submission. In practice, you need to submit at least
277 * a dozen IBs to move all buffers to VRAM if they are in GTT.
278 *
279 * Also, things can get pretty crazy under memory pressure and actual
280 * VRAM usage can change a lot, so playing safe even at 50% does
281 * consistently increase performance.
282 */
283
284 u64 half_vram = real_vram_size >> 1;
285 u64 half_free_vram = vram_usage >= half_vram ? 0 : half_vram - vram_usage;
286 u64 bytes_moved_threshold = half_free_vram >> 1;
287 return max(bytes_moved_threshold, 1024*1024ull);
288}
289
290int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p)
291{
292 struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
293 struct amdgpu_vm *vm = &fpriv->vm;
294 struct amdgpu_device *adev = p->adev;
295 struct amdgpu_bo_list_entry *lobj;
296 struct list_head duplicates;
297 struct amdgpu_bo *bo;
298 u64 bytes_moved = 0, initial_bytes_moved;
299 u64 bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(adev);
300 int r;
301
302 INIT_LIST_HEAD(&duplicates);
303 r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates);
304 if (unlikely(r != 0)) {
305 return r;
306 }
307
308 list_for_each_entry(lobj, &p->validated, tv.head) {
309 bo = lobj->robj;
310 if (!bo->pin_count) {
311 u32 domain = lobj->prefered_domains;
312 u32 current_domain =
313 amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
314
315 /* Check if this buffer will be moved and don't move it
316 * if we have moved too many buffers for this IB already.
317 *
318 * Note that this allows moving at least one buffer of
319 * any size, because it doesn't take the current "bo"
320 * into account. We don't want to disallow buffer moves
321 * completely.
322 */
323 if (current_domain != AMDGPU_GEM_DOMAIN_CPU &&
324 (domain & current_domain) == 0 && /* will be moved */
325 bytes_moved > bytes_moved_threshold) {
326 /* don't move it */
327 domain = current_domain;
328 }
329
330 retry:
331 amdgpu_ttm_placement_from_domain(bo, domain);
332 initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
333 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
334 bytes_moved += atomic64_read(&adev->num_bytes_moved) -
335 initial_bytes_moved;
336
337 if (unlikely(r)) {
338 if (r != -ERESTARTSYS && domain != lobj->allowed_domains) {
339 domain = lobj->allowed_domains;
340 goto retry;
341 }
342 ttm_eu_backoff_reservation(&p->ticket, &p->validated);
343 return r;
344 }
345 }
346 lobj->bo_va = amdgpu_vm_bo_find(vm, bo);
347 }
348 return 0;
349}
350
351static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)
352{
353 struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
354 struct amdgpu_cs_buckets buckets;
355 bool need_mmap_lock = false;
356 int i, r;
357
358 if (p->bo_list) {
359 need_mmap_lock = p->bo_list->has_userptr;
360 amdgpu_cs_buckets_init(&buckets);
361 for (i = 0; i < p->bo_list->num_entries; i++)
362 amdgpu_cs_buckets_add(&buckets, &p->bo_list->array[i].tv.head,
363 p->bo_list->array[i].priority);
364
365 amdgpu_cs_buckets_get_list(&buckets, &p->validated);
366 }
367
368 p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm,
369 &p->validated);
370
371 if (need_mmap_lock)
372 down_read(&current->mm->mmap_sem);
373
374 r = amdgpu_cs_list_validate(p);
375
376 if (need_mmap_lock)
377 up_read(&current->mm->mmap_sem);
378
379 return r;
380}
381
382static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
383{
384 struct amdgpu_bo_list_entry *e;
385 int r;
386
387 list_for_each_entry(e, &p->validated, tv.head) {
388 struct reservation_object *resv = e->robj->tbo.resv;
389 r = amdgpu_sync_resv(p->adev, &p->ibs[0].sync, resv, p->filp);
390
391 if (r)
392 return r;
393 }
394 return 0;
395}
396
397static int cmp_size_smaller_first(void *priv, struct list_head *a,
398 struct list_head *b)
399{
400 struct amdgpu_bo_list_entry *la = list_entry(a, struct amdgpu_bo_list_entry, tv.head);
401 struct amdgpu_bo_list_entry *lb = list_entry(b, struct amdgpu_bo_list_entry, tv.head);
402
403 /* Sort A before B if A is smaller. */
404 return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages;
405}
406
407/**
408 * cs_parser_fini() - clean parser states
409 * @parser: parser structure holding parsing context.
410 * @error: error number
411 *
412 * If error is set than unvalidate buffer, otherwise just free memory
413 * used by parsing context.
414 **/
415static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff)
416{
417 unsigned i;
418
419 if (!error) {
420 /* Sort the buffer list from the smallest to largest buffer,
421 * which affects the order of buffers in the LRU list.
422 * This assures that the smallest buffers are added first
423 * to the LRU list, so they are likely to be later evicted
424 * first, instead of large buffers whose eviction is more
425 * expensive.
426 *
427 * This slightly lowers the number of bytes moved by TTM
428 * per frame under memory pressure.
429 */
430 list_sort(NULL, &parser->validated, cmp_size_smaller_first);
431
432 ttm_eu_fence_buffer_objects(&parser->ticket,
433 &parser->validated,
434 &parser->ibs[parser->num_ibs-1].fence->base);
435 } else if (backoff) {
436 ttm_eu_backoff_reservation(&parser->ticket,
437 &parser->validated);
438 }
439
440 if (parser->ctx)
441 amdgpu_ctx_put(parser->ctx);
442 if (parser->bo_list)
443 amdgpu_bo_list_put(parser->bo_list);
444 drm_free_large(parser->vm_bos);
445 for (i = 0; i < parser->nchunks; i++)
446 drm_free_large(parser->chunks[i].kdata);
447 kfree(parser->chunks);
448 for (i = 0; i < parser->num_ibs; i++)
449 amdgpu_ib_free(parser->adev, &parser->ibs[i]);
450 kfree(parser->ibs);
451 if (parser->uf.bo)
452 drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base);
453}
454
455static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
456 struct amdgpu_vm *vm)
457{
458 struct amdgpu_device *adev = p->adev;
459 struct amdgpu_bo_va *bo_va;
460 struct amdgpu_bo *bo;
461 int i, r;
462
463 r = amdgpu_vm_update_page_directory(adev, vm);
464 if (r)
465 return r;
466
467 r = amdgpu_vm_clear_freed(adev, vm);
468 if (r)
469 return r;
470
471 if (p->bo_list) {
472 for (i = 0; i < p->bo_list->num_entries; i++) {
473 /* ignore duplicates */
474 bo = p->bo_list->array[i].robj;
475 if (!bo)
476 continue;
477
478 bo_va = p->bo_list->array[i].bo_va;
479 if (bo_va == NULL)
480 continue;
481
482 r = amdgpu_vm_bo_update(adev, bo_va, &bo->tbo.mem);
483 if (r)
484 return r;
485
486 amdgpu_sync_fence(&p->ibs[0].sync, bo_va->last_pt_update);
487 }
488 }
489
490 return amdgpu_vm_clear_invalids(adev, vm, &p->ibs[0].sync);
491}
492
493static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
494 struct amdgpu_cs_parser *parser)
495{
496 struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
497 struct amdgpu_vm *vm = &fpriv->vm;
498 struct amdgpu_ring *ring;
499 int i, r;
500
501 if (parser->num_ibs == 0)
502 return 0;
503
504 /* Only for UVD/VCE VM emulation */
505 for (i = 0; i < parser->num_ibs; i++) {
506 ring = parser->ibs[i].ring;
507 if (ring->funcs->parse_cs) {
508 r = amdgpu_ring_parse_cs(ring, parser, i);
509 if (r)
510 return r;
511 }
512 }
513
514 mutex_lock(&vm->mutex);
515 r = amdgpu_bo_vm_update_pte(parser, vm);
516 if (r) {
517 goto out;
518 }
519 amdgpu_cs_sync_rings(parser);
520
521 r = amdgpu_ib_schedule(adev, parser->num_ibs, parser->ibs,
522 parser->filp);
523
524out:
525 mutex_unlock(&vm->mutex);
526 return r;
527}
528
529static int amdgpu_cs_handle_lockup(struct amdgpu_device *adev, int r)
530{
531 if (r == -EDEADLK) {
532 r = amdgpu_gpu_reset(adev);
533 if (!r)
534 r = -EAGAIN;
535 }
536 return r;
537}
538
539static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
540 struct amdgpu_cs_parser *parser)
541{
542 struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
543 struct amdgpu_vm *vm = &fpriv->vm;
544 int i, j;
545 int r;
546
547 for (i = 0, j = 0; i < parser->nchunks && j < parser->num_ibs; i++) {
548 struct amdgpu_cs_chunk *chunk;
549 struct amdgpu_ib *ib;
550 struct drm_amdgpu_cs_chunk_ib *chunk_ib;
551 struct amdgpu_ring *ring;
552
553 chunk = &parser->chunks[i];
554 ib = &parser->ibs[j];
555 chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata;
556
557 if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB)
558 continue;
559
560 r = amdgpu_cs_get_ring(adev, chunk_ib->ip_type,
561 chunk_ib->ip_instance, chunk_ib->ring,
562 &ring);
563 if (r)
564 return r;
565
566 if (ring->funcs->parse_cs) {
567 struct amdgpu_bo_va_mapping *m;
568 struct amdgpu_bo *aobj = NULL;
569 uint64_t offset;
570 uint8_t *kptr;
571
572 m = amdgpu_cs_find_mapping(parser, chunk_ib->va_start,
573 &aobj);
574 if (!aobj) {
575 DRM_ERROR("IB va_start is invalid\n");
576 return -EINVAL;
577 }
578
579 if ((chunk_ib->va_start + chunk_ib->ib_bytes) >
580 (m->it.last + 1) * AMDGPU_GPU_PAGE_SIZE) {
581 DRM_ERROR("IB va_start+ib_bytes is invalid\n");
582 return -EINVAL;
583 }
584
585 /* the IB should be reserved at this point */
586 r = amdgpu_bo_kmap(aobj, (void **)&kptr);
587 if (r) {
588 return r;
589 }
590
591 offset = ((uint64_t)m->it.start) * AMDGPU_GPU_PAGE_SIZE;
592 kptr += chunk_ib->va_start - offset;
593
594 r = amdgpu_ib_get(ring, NULL, chunk_ib->ib_bytes, ib);
595 if (r) {
596 DRM_ERROR("Failed to get ib !\n");
597 return r;
598 }
599
600 memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
601 amdgpu_bo_kunmap(aobj);
602 } else {
603 r = amdgpu_ib_get(ring, vm, 0, ib);
604 if (r) {
605 DRM_ERROR("Failed to get ib !\n");
606 return r;
607 }
608
609 ib->gpu_addr = chunk_ib->va_start;
610 }
611
612 ib->length_dw = chunk_ib->ib_bytes / 4;
613 ib->flags = chunk_ib->flags;
614 ib->ctx = parser->ctx;
615 j++;
616 }
617
618 if (!parser->num_ibs)
619 return 0;
620
621 /* add GDS resources to first IB */
622 if (parser->bo_list) {
623 struct amdgpu_bo *gds = parser->bo_list->gds_obj;
624 struct amdgpu_bo *gws = parser->bo_list->gws_obj;
625 struct amdgpu_bo *oa = parser->bo_list->oa_obj;
626 struct amdgpu_ib *ib = &parser->ibs[0];
627
628 if (gds) {
629 ib->gds_base = amdgpu_bo_gpu_offset(gds);
630 ib->gds_size = amdgpu_bo_size(gds);
631 }
632 if (gws) {
633 ib->gws_base = amdgpu_bo_gpu_offset(gws);
634 ib->gws_size = amdgpu_bo_size(gws);
635 }
636 if (oa) {
637 ib->oa_base = amdgpu_bo_gpu_offset(oa);
638 ib->oa_size = amdgpu_bo_size(oa);
639 }
640 }
641
642 /* wrap the last IB with user fence */
643 if (parser->uf.bo) {
644 struct amdgpu_ib *ib = &parser->ibs[parser->num_ibs - 1];
645
646 /* UVD & VCE fw doesn't support user fences */
647 if (ib->ring->type == AMDGPU_RING_TYPE_UVD ||
648 ib->ring->type == AMDGPU_RING_TYPE_VCE)
649 return -EINVAL;
650
651 ib->user = &parser->uf;
652 }
653
654 return 0;
655}
656
657int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
658{
659 struct amdgpu_device *adev = dev->dev_private;
660 union drm_amdgpu_cs *cs = data;
661 struct amdgpu_cs_parser parser;
662 int r, i;
663 bool reserved_buffers = false;
664
665 down_read(&adev->exclusive_lock);
666 if (!adev->accel_working) {
667 up_read(&adev->exclusive_lock);
668 return -EBUSY;
669 }
670 /* initialize parser */
671 memset(&parser, 0, sizeof(struct amdgpu_cs_parser));
672 parser.filp = filp;
673 parser.adev = adev;
674 r = amdgpu_cs_parser_init(&parser, data);
675 if (r) {
676 DRM_ERROR("Failed to initialize parser !\n");
677 amdgpu_cs_parser_fini(&parser, r, false);
678 up_read(&adev->exclusive_lock);
679 r = amdgpu_cs_handle_lockup(adev, r);
680 return r;
681 }
682
683 r = amdgpu_cs_parser_relocs(&parser);
684 if (r) {
685 if (r != -ERESTARTSYS) {
686 if (r == -ENOMEM)
687 DRM_ERROR("Not enough memory for command submission!\n");
688 else
689 DRM_ERROR("Failed to process the buffer list %d!\n", r);
690 }
691 } else {
692 reserved_buffers = true;
693 r = amdgpu_cs_ib_fill(adev, &parser);
694 }
695
696 if (r) {
697 amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
698 up_read(&adev->exclusive_lock);
699 r = amdgpu_cs_handle_lockup(adev, r);
700 return r;
701 }
702
703 for (i = 0; i < parser.num_ibs; i++)
704 trace_amdgpu_cs(&parser, i);
705
706 r = amdgpu_cs_ib_vm_chunk(adev, &parser);
707 if (r) {
708 goto out;
709 }
710
711 cs->out.handle = parser.ibs[parser.num_ibs - 1].fence->seq;
712out:
713 amdgpu_cs_parser_fini(&parser, r, true);
714 up_read(&adev->exclusive_lock);
715 r = amdgpu_cs_handle_lockup(adev, r);
716 return r;
717}
718
719/**
720 * amdgpu_cs_wait_ioctl - wait for a command submission to finish
721 *
722 * @dev: drm device
723 * @data: data from userspace
724 * @filp: file private
725 *
726 * Wait for the command submission identified by handle to finish.
727 */
728int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
729 struct drm_file *filp)
730{
731 union drm_amdgpu_wait_cs *wait = data;
732 struct amdgpu_device *adev = dev->dev_private;
733 uint64_t seq[AMDGPU_MAX_RINGS] = {0};
734 struct amdgpu_ring *ring = NULL;
735 unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout);
736 struct amdgpu_ctx *ctx;
737 long r;
738
739 ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id);
740 if (ctx == NULL)
741 return -EINVAL;
742
743 r = amdgpu_cs_get_ring(adev, wait->in.ip_type, wait->in.ip_instance,
744 wait->in.ring, &ring);
745 if (r)
746 return r;
747
748 seq[ring->idx] = wait->in.handle;
749
750 r = amdgpu_fence_wait_seq_timeout(adev, seq, true, timeout);
751 amdgpu_ctx_put(ctx);
752 if (r < 0)
753 return r;
754
755 memset(wait, 0, sizeof(*wait));
756 wait->out.status = (r == 0);
757
758 return 0;
759}
760
761/**
762 * amdgpu_cs_find_bo_va - find bo_va for VM address
763 *
764 * @parser: command submission parser context
765 * @addr: VM address
766 * @bo: resulting BO of the mapping found
767 *
768 * Search the buffer objects in the command submission context for a certain
769 * virtual memory address. Returns allocation structure when found, NULL
770 * otherwise.
771 */
772struct amdgpu_bo_va_mapping *
773amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
774 uint64_t addr, struct amdgpu_bo **bo)
775{
776 struct amdgpu_bo_list_entry *reloc;
777 struct amdgpu_bo_va_mapping *mapping;
778
779 addr /= AMDGPU_GPU_PAGE_SIZE;
780
781 list_for_each_entry(reloc, &parser->validated, tv.head) {
782 if (!reloc->bo_va)
783 continue;
784
785 list_for_each_entry(mapping, &reloc->bo_va->mappings, list) {
786 if (mapping->it.start > addr ||
787 addr > mapping->it.last)
788 continue;
789
790 *bo = reloc->bo_va->bo;
791 return mapping;
792 }
793 }
794
795 return NULL;
796}
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c+193−0
@@ -0,0 +1,193 @@
1/*
2 * Copyright 2015 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 * Authors: monk liu <monk.liu@amd.com>
23 */
24
25#include <drm/drmP.h>
26#include "amdgpu.h"
27
28static void amdgpu_ctx_do_release(struct kref *ref)
29{
30 struct amdgpu_ctx *ctx;
31 struct amdgpu_ctx_mgr *mgr;
32
33 ctx = container_of(ref, struct amdgpu_ctx, refcount);
34 mgr = &ctx->fpriv->ctx_mgr;
35
36 idr_remove(&mgr->ctx_handles, ctx->id);
37 kfree(ctx);
38}
39
40int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t *id, uint32_t flags)
41{
42 int r;
43 struct amdgpu_ctx *ctx;
44 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
45
46 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
47 if (!ctx)
48 return -ENOMEM;
49
50 mutex_lock(&mgr->lock);
51 r = idr_alloc(&mgr->ctx_handles, ctx, 0, 0, GFP_KERNEL);
52 if (r < 0) {
53 mutex_unlock(&mgr->lock);
54 kfree(ctx);
55 return r;
56 }
57 *id = (uint32_t)r;
58
59 memset(ctx, 0, sizeof(*ctx));
60 ctx->id = *id;
61 ctx->fpriv = fpriv;
62 kref_init(&ctx->refcount);
63 mutex_unlock(&mgr->lock);
64
65 return 0;
66}
67
68int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id)
69{
70 struct amdgpu_ctx *ctx;
71 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
72
73 mutex_lock(&mgr->lock);
74 ctx = idr_find(&mgr->ctx_handles, id);
75 if (ctx) {
76 kref_put(&ctx->refcount, amdgpu_ctx_do_release);
77 mutex_unlock(&mgr->lock);
78 return 0;
79 }
80 mutex_unlock(&mgr->lock);
81 return -EINVAL;
82}
83
84static int amdgpu_ctx_query(struct amdgpu_device *adev,
85 struct amdgpu_fpriv *fpriv, uint32_t id,
86 union drm_amdgpu_ctx_out *out)
87{
88 struct amdgpu_ctx *ctx;
89 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
90 unsigned reset_counter;
91
92 mutex_lock(&mgr->lock);
93 ctx = idr_find(&mgr->ctx_handles, id);
94 if (!ctx) {
95 mutex_unlock(&mgr->lock);
96 return -EINVAL;
97 }
98
99 /* TODO: these two are always zero */
100 out->state.flags = ctx->state.flags;
101 out->state.hangs = ctx->state.hangs;
102
103 /* determine if a GPU reset has occured since the last call */
104 reset_counter = atomic_read(&adev->gpu_reset_counter);
105 /* TODO: this should ideally return NO, GUILTY, or INNOCENT. */
106 if (ctx->reset_counter == reset_counter)
107 out->state.reset_status = AMDGPU_CTX_NO_RESET;
108 else
109 out->state.reset_status = AMDGPU_CTX_UNKNOWN_RESET;
110 ctx->reset_counter = reset_counter;
111
112 mutex_unlock(&mgr->lock);
113 return 0;
114}
115
116void amdgpu_ctx_fini(struct amdgpu_fpriv *fpriv)
117{
118 struct idr *idp;
119 struct amdgpu_ctx *ctx;
120 uint32_t id;
121 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
122 idp = &mgr->ctx_handles;
123
124 idr_for_each_entry(idp,ctx,id) {
125 if (kref_put(&ctx->refcount, amdgpu_ctx_do_release) != 1)
126 DRM_ERROR("ctx (id=%ul) is still alive\n",ctx->id);
127 }
128
129 mutex_destroy(&mgr->lock);
130}
131
132int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
133 struct drm_file *filp)
134{
135 int r;
136 uint32_t id;
137 uint32_t flags;
138
139 union drm_amdgpu_ctx *args = data;
140 struct amdgpu_device *adev = dev->dev_private;
141 struct amdgpu_fpriv *fpriv = filp->driver_priv;
142
143 r = 0;
144 id = args->in.ctx_id;
145 flags = args->in.flags;
146
147 switch (args->in.op) {
148 case AMDGPU_CTX_OP_ALLOC_CTX:
149 r = amdgpu_ctx_alloc(adev, fpriv, &id, flags);
150 args->out.alloc.ctx_id = id;
151 break;
152 case AMDGPU_CTX_OP_FREE_CTX:
153 r = amdgpu_ctx_free(adev, fpriv, id);
154 break;
155 case AMDGPU_CTX_OP_QUERY_STATE:
156 r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
157 break;
158 default:
159 return -EINVAL;
160 }
161
162 return r;
163}
164
165struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
166{
167 struct amdgpu_ctx *ctx;
168 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
169
170 mutex_lock(&mgr->lock);
171 ctx = idr_find(&mgr->ctx_handles, id);
172 if (ctx)
173 kref_get(&ctx->refcount);
174 mutex_unlock(&mgr->lock);
175 return ctx;
176}
177
178int amdgpu_ctx_put(struct amdgpu_ctx *ctx)
179{
180 struct amdgpu_fpriv *fpriv;
181 struct amdgpu_ctx_mgr *mgr;
182
183 if (ctx == NULL)
184 return -EINVAL;
185
186 fpriv = ctx->fpriv;
187 mgr = &fpriv->ctx_mgr;
188 mutex_lock(&mgr->lock);
189 kref_put(&ctx->refcount, amdgpu_ctx_do_release);
190 mutex_unlock(&mgr->lock);
191
192 return 0;
193}
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c+2003−0
@@ -0,0 +1,2003 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include <linux/console.h>
29#include <linux/slab.h>
30#include <linux/debugfs.h>
31#include <drm/drmP.h>
32#include <drm/drm_crtc_helper.h>
33#include <drm/amdgpu_drm.h>
34#include <linux/vgaarb.h>
35#include <linux/vga_switcheroo.h>
36#include <linux/efi.h>
37#include "amdgpu.h"
38#include "amdgpu_i2c.h"
39#include "atom.h"
40#include "amdgpu_atombios.h"
41#ifdef CONFIG_DRM_AMDGPU_CIK
42#include "cik.h"
43#endif
44#include "vi.h"
45#include "bif/bif_4_1_d.h"
46
47static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
48static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev);
49
50static const char *amdgpu_asic_name[] = {
51 "BONAIRE",
52 "KAVERI",
53 "KABINI",
54 "HAWAII",
55 "MULLINS",
56 "TOPAZ",
57 "TONGA",
58 "CARRIZO",
59 "LAST",
60};
61
62bool amdgpu_device_is_px(struct drm_device *dev)
63{
64 struct amdgpu_device *adev = dev->dev_private;
65
66 if (adev->flags & AMDGPU_IS_PX)
67 return true;
68 return false;
69}
70
71/*
72 * MMIO register access helper functions.
73 */
74uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
75 bool always_indirect)
76{
77 if ((reg * 4) < adev->rmmio_size && !always_indirect)
78 return readl(((void __iomem *)adev->rmmio) + (reg * 4));
79 else {
80 unsigned long flags;
81 uint32_t ret;
82
83 spin_lock_irqsave(&adev->mmio_idx_lock, flags);
84 writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4));
85 ret = readl(((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
86 spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
87
88 return ret;
89 }
90}
91
92void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
93 bool always_indirect)
94{
95 if ((reg * 4) < adev->rmmio_size && !always_indirect)
96 writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
97 else {
98 unsigned long flags;
99
100 spin_lock_irqsave(&adev->mmio_idx_lock, flags);
101 writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4));
102 writel(v, ((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
103 spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
104 }
105}
106
107u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
108{
109 if ((reg * 4) < adev->rio_mem_size)
110 return ioread32(adev->rio_mem + (reg * 4));
111 else {
112 iowrite32((reg * 4), adev->rio_mem + (mmMM_INDEX * 4));
113 return ioread32(adev->rio_mem + (mmMM_DATA * 4));
114 }
115}
116
117void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
118{
119
120 if ((reg * 4) < adev->rio_mem_size)
121 iowrite32(v, adev->rio_mem + (reg * 4));
122 else {
123 iowrite32((reg * 4), adev->rio_mem + (mmMM_INDEX * 4));
124 iowrite32(v, adev->rio_mem + (mmMM_DATA * 4));
125 }
126}
127
128/**
129 * amdgpu_mm_rdoorbell - read a doorbell dword
130 *
131 * @adev: amdgpu_device pointer
132 * @index: doorbell index
133 *
134 * Returns the value in the doorbell aperture at the
135 * requested doorbell index (CIK).
136 */
137u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
138{
139 if (index < adev->doorbell.num_doorbells) {
140 return readl(adev->doorbell.ptr + index);
141 } else {
142 DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
143 return 0;
144 }
145}
146
147/**
148 * amdgpu_mm_wdoorbell - write a doorbell dword
149 *
150 * @adev: amdgpu_device pointer
151 * @index: doorbell index
152 * @v: value to write
153 *
154 * Writes @v to the doorbell aperture at the
155 * requested doorbell index (CIK).
156 */
157void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
158{
159 if (index < adev->doorbell.num_doorbells) {
160 writel(v, adev->doorbell.ptr + index);
161 } else {
162 DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
163 }
164}
165
166/**
167 * amdgpu_invalid_rreg - dummy reg read function
168 *
169 * @adev: amdgpu device pointer
170 * @reg: offset of register
171 *
172 * Dummy register read function. Used for register blocks
173 * that certain asics don't have (all asics).
174 * Returns the value in the register.
175 */
176static uint32_t amdgpu_invalid_rreg(struct amdgpu_device *adev, uint32_t reg)
177{
178 DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
179 BUG();
180 return 0;
181}
182
183/**
184 * amdgpu_invalid_wreg - dummy reg write function
185 *
186 * @adev: amdgpu device pointer
187 * @reg: offset of register
188 * @v: value to write to the register
189 *
190 * Dummy register read function. Used for register blocks
191 * that certain asics don't have (all asics).
192 */
193static void amdgpu_invalid_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
194{
195 DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
196 reg, v);
197 BUG();
198}
199
200/**
201 * amdgpu_block_invalid_rreg - dummy reg read function
202 *
203 * @adev: amdgpu device pointer
204 * @block: offset of instance
205 * @reg: offset of register
206 *
207 * Dummy register read function. Used for register blocks
208 * that certain asics don't have (all asics).
209 * Returns the value in the register.
210 */
211static uint32_t amdgpu_block_invalid_rreg(struct amdgpu_device *adev,
212 uint32_t block, uint32_t reg)
213{
214 DRM_ERROR("Invalid callback to read register 0x%04X in block 0x%04X\n",
215 reg, block);
216 BUG();
217 return 0;
218}
219
220/**
221 * amdgpu_block_invalid_wreg - dummy reg write function
222 *
223 * @adev: amdgpu device pointer
224 * @block: offset of instance
225 * @reg: offset of register
226 * @v: value to write to the register
227 *
228 * Dummy register read function. Used for register blocks
229 * that certain asics don't have (all asics).
230 */
231static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev,
232 uint32_t block,
233 uint32_t reg, uint32_t v)
234{
235 DRM_ERROR("Invalid block callback to write register 0x%04X in block 0x%04X with 0x%08X\n",
236 reg, block, v);
237 BUG();
238}
239
240static int amdgpu_vram_scratch_init(struct amdgpu_device *adev)
241{
242 int r;
243
244 if (adev->vram_scratch.robj == NULL) {
245 r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
246 PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, 0,
247 NULL, &adev->vram_scratch.robj);
248 if (r) {
249 return r;
250 }
251 }
252
253 r = amdgpu_bo_reserve(adev->vram_scratch.robj, false);
254 if (unlikely(r != 0))
255 return r;
256 r = amdgpu_bo_pin(adev->vram_scratch.robj,
257 AMDGPU_GEM_DOMAIN_VRAM, &adev->vram_scratch.gpu_addr);
258 if (r) {
259 amdgpu_bo_unreserve(adev->vram_scratch.robj);
260 return r;
261 }
262 r = amdgpu_bo_kmap(adev->vram_scratch.robj,
263 (void **)&adev->vram_scratch.ptr);
264 if (r)
265 amdgpu_bo_unpin(adev->vram_scratch.robj);
266 amdgpu_bo_unreserve(adev->vram_scratch.robj);
267
268 return r;
269}
270
271static void amdgpu_vram_scratch_fini(struct amdgpu_device *adev)
272{
273 int r;
274
275 if (adev->vram_scratch.robj == NULL) {
276 return;
277 }
278 r = amdgpu_bo_reserve(adev->vram_scratch.robj, false);
279 if (likely(r == 0)) {
280 amdgpu_bo_kunmap(adev->vram_scratch.robj);
281 amdgpu_bo_unpin(adev->vram_scratch.robj);
282 amdgpu_bo_unreserve(adev->vram_scratch.robj);
283 }
284 amdgpu_bo_unref(&adev->vram_scratch.robj);
285}
286
287/**
288 * amdgpu_program_register_sequence - program an array of registers.
289 *
290 * @adev: amdgpu_device pointer
291 * @registers: pointer to the register array
292 * @array_size: size of the register array
293 *
294 * Programs an array or registers with and and or masks.
295 * This is a helper for setting golden registers.
296 */
297void amdgpu_program_register_sequence(struct amdgpu_device *adev,
298 const u32 *registers,
299 const u32 array_size)
300{
301 u32 tmp, reg, and_mask, or_mask;
302 int i;
303
304 if (array_size % 3)
305 return;
306
307 for (i = 0; i < array_size; i +=3) {
308 reg = registers[i + 0];
309 and_mask = registers[i + 1];
310 or_mask = registers[i + 2];
311
312 if (and_mask == 0xffffffff) {
313 tmp = or_mask;
314 } else {
315 tmp = RREG32(reg);
316 tmp &= ~and_mask;
317 tmp |= or_mask;
318 }
319 WREG32(reg, tmp);
320 }
321}
322
323void amdgpu_pci_config_reset(struct amdgpu_device *adev)
324{
325 pci_write_config_dword(adev->pdev, 0x7c, AMDGPU_ASIC_RESET_DATA);
326}
327
328/*
329 * GPU doorbell aperture helpers function.
330 */
331/**
332 * amdgpu_doorbell_init - Init doorbell driver information.
333 *
334 * @adev: amdgpu_device pointer
335 *
336 * Init doorbell driver information (CIK)
337 * Returns 0 on success, error on failure.
338 */
339static int amdgpu_doorbell_init(struct amdgpu_device *adev)
340{
341 /* doorbell bar mapping */
342 adev->doorbell.base = pci_resource_start(adev->pdev, 2);
343 adev->doorbell.size = pci_resource_len(adev->pdev, 2);
344
345 adev->doorbell.num_doorbells = min_t(u32, adev->doorbell.size / sizeof(u32),
346 AMDGPU_DOORBELL_MAX_ASSIGNMENT+1);
347 if (adev->doorbell.num_doorbells == 0)
348 return -EINVAL;
349
350 adev->doorbell.ptr = ioremap(adev->doorbell.base, adev->doorbell.num_doorbells * sizeof(u32));
351 if (adev->doorbell.ptr == NULL) {
352 return -ENOMEM;
353 }
354 DRM_INFO("doorbell mmio base: 0x%08X\n", (uint32_t)adev->doorbell.base);
355 DRM_INFO("doorbell mmio size: %u\n", (unsigned)adev->doorbell.size);
356
357 return 0;
358}
359
360/**
361 * amdgpu_doorbell_fini - Tear down doorbell driver information.
362 *
363 * @adev: amdgpu_device pointer
364 *
365 * Tear down doorbell driver information (CIK)
366 */
367static void amdgpu_doorbell_fini(struct amdgpu_device *adev)
368{
369 iounmap(adev->doorbell.ptr);
370 adev->doorbell.ptr = NULL;
371}
372
373/**
374 * amdgpu_doorbell_get_kfd_info - Report doorbell configuration required to
375 * setup amdkfd
376 *
377 * @adev: amdgpu_device pointer
378 * @aperture_base: output returning doorbell aperture base physical address
379 * @aperture_size: output returning doorbell aperture size in bytes
380 * @start_offset: output returning # of doorbell bytes reserved for amdgpu.
381 *
382 * amdgpu and amdkfd share the doorbell aperture. amdgpu sets it up,
383 * takes doorbells required for its own rings and reports the setup to amdkfd.
384 * amdgpu reserved doorbells are at the start of the doorbell aperture.
385 */
386void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
387 phys_addr_t *aperture_base,
388 size_t *aperture_size,
389 size_t *start_offset)
390{
391 /*
392 * The first num_doorbells are used by amdgpu.
393 * amdkfd takes whatever's left in the aperture.
394 */
395 if (adev->doorbell.size > adev->doorbell.num_doorbells * sizeof(u32)) {
396 *aperture_base = adev->doorbell.base;
397 *aperture_size = adev->doorbell.size;
398 *start_offset = adev->doorbell.num_doorbells * sizeof(u32);
399 } else {
400 *aperture_base = 0;
401 *aperture_size = 0;
402 *start_offset = 0;
403 }
404}
405
406/*
407 * amdgpu_wb_*()
408 * Writeback is the the method by which the the GPU updates special pages
409 * in memory with the status of certain GPU events (fences, ring pointers,
410 * etc.).
411 */
412
413/**
414 * amdgpu_wb_fini - Disable Writeback and free memory
415 *
416 * @adev: amdgpu_device pointer
417 *
418 * Disables Writeback and frees the Writeback memory (all asics).
419 * Used at driver shutdown.
420 */
421static void amdgpu_wb_fini(struct amdgpu_device *adev)
422{
423 if (adev->wb.wb_obj) {
424 if (!amdgpu_bo_reserve(adev->wb.wb_obj, false)) {
425 amdgpu_bo_kunmap(adev->wb.wb_obj);
426 amdgpu_bo_unpin(adev->wb.wb_obj);
427 amdgpu_bo_unreserve(adev->wb.wb_obj);
428 }
429 amdgpu_bo_unref(&adev->wb.wb_obj);
430 adev->wb.wb = NULL;
431 adev->wb.wb_obj = NULL;
432 }
433}
434
435/**
436 * amdgpu_wb_init- Init Writeback driver info and allocate memory
437 *
438 * @adev: amdgpu_device pointer
439 *
440 * Disables Writeback and frees the Writeback memory (all asics).
441 * Used at driver startup.
442 * Returns 0 on success or an -error on failure.
443 */
444static int amdgpu_wb_init(struct amdgpu_device *adev)
445{
446 int r;
447
448 if (adev->wb.wb_obj == NULL) {
449 r = amdgpu_bo_create(adev, AMDGPU_MAX_WB * 4, PAGE_SIZE, true,
450 AMDGPU_GEM_DOMAIN_GTT, 0, NULL, &adev->wb.wb_obj);
451 if (r) {
452 dev_warn(adev->dev, "(%d) create WB bo failed\n", r);
453 return r;
454 }
455 r = amdgpu_bo_reserve(adev->wb.wb_obj, false);
456 if (unlikely(r != 0)) {
457 amdgpu_wb_fini(adev);
458 return r;
459 }
460 r = amdgpu_bo_pin(adev->wb.wb_obj, AMDGPU_GEM_DOMAIN_GTT,
461 &adev->wb.gpu_addr);
462 if (r) {
463 amdgpu_bo_unreserve(adev->wb.wb_obj);
464 dev_warn(adev->dev, "(%d) pin WB bo failed\n", r);
465 amdgpu_wb_fini(adev);
466 return r;
467 }
468 r = amdgpu_bo_kmap(adev->wb.wb_obj, (void **)&adev->wb.wb);
469 amdgpu_bo_unreserve(adev->wb.wb_obj);
470 if (r) {
471 dev_warn(adev->dev, "(%d) map WB bo failed\n", r);
472 amdgpu_wb_fini(adev);
473 return r;
474 }
475
476 adev->wb.num_wb = AMDGPU_MAX_WB;
477 memset(&adev->wb.used, 0, sizeof(adev->wb.used));
478
479 /* clear wb memory */
480 memset((char *)adev->wb.wb, 0, AMDGPU_GPU_PAGE_SIZE);
481 }
482
483 return 0;
484}
485
486/**
487 * amdgpu_wb_get - Allocate a wb entry
488 *
489 * @adev: amdgpu_device pointer
490 * @wb: wb index
491 *
492 * Allocate a wb slot for use by the driver (all asics).
493 * Returns 0 on success or -EINVAL on failure.
494 */
495int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb)
496{
497 unsigned long offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb);
498 if (offset < adev->wb.num_wb) {
499 __set_bit(offset, adev->wb.used);
500 *wb = offset;
501 return 0;
502 } else {
503 return -EINVAL;
504 }
505}
506
507/**
508 * amdgpu_wb_free - Free a wb entry
509 *
510 * @adev: amdgpu_device pointer
511 * @wb: wb index
512 *
513 * Free a wb slot allocated for use by the driver (all asics)
514 */
515void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb)
516{
517 if (wb < adev->wb.num_wb)
518 __clear_bit(wb, adev->wb.used);
519}
520
521/**
522 * amdgpu_vram_location - try to find VRAM location
523 * @adev: amdgpu device structure holding all necessary informations
524 * @mc: memory controller structure holding memory informations
525 * @base: base address at which to put VRAM
526 *
527 * Function will place try to place VRAM at base address provided
528 * as parameter (which is so far either PCI aperture address or
529 * for IGP TOM base address).
530 *
531 * If there is not enough space to fit the unvisible VRAM in the 32bits
532 * address space then we limit the VRAM size to the aperture.
533 *
534 * Note: We don't explicitly enforce VRAM start to be aligned on VRAM size,
535 * this shouldn't be a problem as we are using the PCI aperture as a reference.
536 * Otherwise this would be needed for rv280, all r3xx, and all r4xx, but
537 * not IGP.
538 *
539 * Note: we use mc_vram_size as on some board we need to program the mc to
540 * cover the whole aperture even if VRAM size is inferior to aperture size
541 * Novell bug 204882 + along with lots of ubuntu ones
542 *
543 * Note: when limiting vram it's safe to overwritte real_vram_size because
544 * we are not in case where real_vram_size is inferior to mc_vram_size (ie
545 * note afected by bogus hw of Novell bug 204882 + along with lots of ubuntu
546 * ones)
547 *
548 * Note: IGP TOM addr should be the same as the aperture addr, we don't
549 * explicitly check for that thought.
550 *
551 * FIXME: when reducing VRAM size align new size on power of 2.
552 */
553void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base)
554{
555 uint64_t limit = (uint64_t)amdgpu_vram_limit << 20;
556
557 mc->vram_start = base;
558 if (mc->mc_vram_size > (adev->mc.mc_mask - base + 1)) {
559 dev_warn(adev->dev, "limiting VRAM to PCI aperture size\n");
560 mc->real_vram_size = mc->aper_size;
561 mc->mc_vram_size = mc->aper_size;
562 }
563 mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
564 if (limit && limit < mc->real_vram_size)
565 mc->real_vram_size = limit;
566 dev_info(adev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
567 mc->mc_vram_size >> 20, mc->vram_start,
568 mc->vram_end, mc->real_vram_size >> 20);
569}
570
571/**
572 * amdgpu_gtt_location - try to find GTT location
573 * @adev: amdgpu device structure holding all necessary informations
574 * @mc: memory controller structure holding memory informations
575 *
576 * Function will place try to place GTT before or after VRAM.
577 *
578 * If GTT size is bigger than space left then we ajust GTT size.
579 * Thus function will never fails.
580 *
581 * FIXME: when reducing GTT size align new size on power of 2.
582 */
583void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc)
584{
585 u64 size_af, size_bf;
586
587 size_af = ((adev->mc.mc_mask - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align;
588 size_bf = mc->vram_start & ~mc->gtt_base_align;
589 if (size_bf > size_af) {
590 if (mc->gtt_size > size_bf) {
591 dev_warn(adev->dev, "limiting GTT\n");
592 mc->gtt_size = size_bf;
593 }
594 mc->gtt_start = (mc->vram_start & ~mc->gtt_base_align) - mc->gtt_size;
595 } else {
596 if (mc->gtt_size > size_af) {
597 dev_warn(adev->dev, "limiting GTT\n");
598 mc->gtt_size = size_af;
599 }
600 mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
601 }
602 mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
603 dev_info(adev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n",
604 mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
605}
606
607/*
608 * GPU helpers function.
609 */
610/**
611 * amdgpu_card_posted - check if the hw has already been initialized
612 *
613 * @adev: amdgpu_device pointer
614 *
615 * Check if the asic has been initialized (all asics).
616 * Used at driver startup.
617 * Returns true if initialized or false if not.
618 */
619bool amdgpu_card_posted(struct amdgpu_device *adev)
620{
621 uint32_t reg;
622
623 /* then check MEM_SIZE, in case the crtcs are off */
624 reg = RREG32(mmCONFIG_MEMSIZE);
625
626 if (reg)
627 return true;
628
629 return false;
630
631}
632
633/**
634 * amdgpu_boot_test_post_card - check and possibly initialize the hw
635 *
636 * @adev: amdgpu_device pointer
637 *
638 * Check if the asic is initialized and if not, attempt to initialize
639 * it (all asics).
640 * Returns true if initialized or false if not.
641 */
642bool amdgpu_boot_test_post_card(struct amdgpu_device *adev)
643{
644 if (amdgpu_card_posted(adev))
645 return true;
646
647 if (adev->bios) {
648 DRM_INFO("GPU not posted. posting now...\n");
649 if (adev->is_atom_bios)
650 amdgpu_atom_asic_init(adev->mode_info.atom_context);
651 return true;
652 } else {
653 dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
654 return false;
655 }
656}
657
658/**
659 * amdgpu_dummy_page_init - init dummy page used by the driver
660 *
661 * @adev: amdgpu_device pointer
662 *
663 * Allocate the dummy page used by the driver (all asics).
664 * This dummy page is used by the driver as a filler for gart entries
665 * when pages are taken out of the GART
666 * Returns 0 on sucess, -ENOMEM on failure.
667 */
668int amdgpu_dummy_page_init(struct amdgpu_device *adev)
669{
670 if (adev->dummy_page.page)
671 return 0;
672 adev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO);
673 if (adev->dummy_page.page == NULL)
674 return -ENOMEM;
675 adev->dummy_page.addr = pci_map_page(adev->pdev, adev->dummy_page.page,
676 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
677 if (pci_dma_mapping_error(adev->pdev, adev->dummy_page.addr)) {
678 dev_err(&adev->pdev->dev, "Failed to DMA MAP the dummy page\n");
679 __free_page(adev->dummy_page.page);
680 adev->dummy_page.page = NULL;
681 return -ENOMEM;
682 }
683 return 0;
684}
685
686/**
687 * amdgpu_dummy_page_fini - free dummy page used by the driver
688 *
689 * @adev: amdgpu_device pointer
690 *
691 * Frees the dummy page used by the driver (all asics).
692 */
693void amdgpu_dummy_page_fini(struct amdgpu_device *adev)
694{
695 if (adev->dummy_page.page == NULL)
696 return;
697 pci_unmap_page(adev->pdev, adev->dummy_page.addr,
698 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
699 __free_page(adev->dummy_page.page);
700 adev->dummy_page.page = NULL;
701}
702
703
704/* ATOM accessor methods */
705/*
706 * ATOM is an interpreted byte code stored in tables in the vbios. The
707 * driver registers callbacks to access registers and the interpreter
708 * in the driver parses the tables and executes then to program specific
709 * actions (set display modes, asic init, etc.). See amdgpu_atombios.c,
710 * atombios.h, and atom.c
711 */
712
713/**
714 * cail_pll_read - read PLL register
715 *
716 * @info: atom card_info pointer
717 * @reg: PLL register offset
718 *
719 * Provides a PLL register accessor for the atom interpreter (r4xx+).
720 * Returns the value of the PLL register.
721 */
722static uint32_t cail_pll_read(struct card_info *info, uint32_t reg)
723{
724 return 0;
725}
726
727/**
728 * cail_pll_write - write PLL register
729 *
730 * @info: atom card_info pointer
731 * @reg: PLL register offset
732 * @val: value to write to the pll register
733 *
734 * Provides a PLL register accessor for the atom interpreter (r4xx+).
735 */
736static void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val)
737{
738
739}
740
741/**
742 * cail_mc_read - read MC (Memory Controller) register
743 *
744 * @info: atom card_info pointer
745 * @reg: MC register offset
746 *
747 * Provides an MC register accessor for the atom interpreter (r4xx+).
748 * Returns the value of the MC register.
749 */
750static uint32_t cail_mc_read(struct card_info *info, uint32_t reg)
751{
752 return 0;
753}
754
755/**
756 * cail_mc_write - write MC (Memory Controller) register
757 *
758 * @info: atom card_info pointer
759 * @reg: MC register offset
760 * @val: value to write to the pll register
761 *
762 * Provides a MC register accessor for the atom interpreter (r4xx+).
763 */
764static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val)
765{
766
767}
768
769/**
770 * cail_reg_write - write MMIO register
771 *
772 * @info: atom card_info pointer
773 * @reg: MMIO register offset
774 * @val: value to write to the pll register
775 *
776 * Provides a MMIO register accessor for the atom interpreter (r4xx+).
777 */
778static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val)
779{
780 struct amdgpu_device *adev = info->dev->dev_private;
781
782 WREG32(reg, val);
783}
784
785/**
786 * cail_reg_read - read MMIO register
787 *
788 * @info: atom card_info pointer
789 * @reg: MMIO register offset
790 *
791 * Provides an MMIO register accessor for the atom interpreter (r4xx+).
792 * Returns the value of the MMIO register.
793 */
794static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
795{
796 struct amdgpu_device *adev = info->dev->dev_private;
797 uint32_t r;
798
799 r = RREG32(reg);
800 return r;
801}
802
803/**
804 * cail_ioreg_write - write IO register
805 *
806 * @info: atom card_info pointer
807 * @reg: IO register offset
808 * @val: value to write to the pll register
809 *
810 * Provides a IO register accessor for the atom interpreter (r4xx+).
811 */
812static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val)
813{
814 struct amdgpu_device *adev = info->dev->dev_private;
815
816 WREG32_IO(reg, val);
817}
818
819/**
820 * cail_ioreg_read - read IO register
821 *
822 * @info: atom card_info pointer
823 * @reg: IO register offset
824 *
825 * Provides an IO register accessor for the atom interpreter (r4xx+).
826 * Returns the value of the IO register.
827 */
828static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg)
829{
830 struct amdgpu_device *adev = info->dev->dev_private;
831 uint32_t r;
832
833 r = RREG32_IO(reg);
834 return r;
835}
836
837/**
838 * amdgpu_atombios_fini - free the driver info and callbacks for atombios
839 *
840 * @adev: amdgpu_device pointer
841 *
842 * Frees the driver info and register access callbacks for the ATOM
843 * interpreter (r4xx+).
844 * Called at driver shutdown.
845 */
846static void amdgpu_atombios_fini(struct amdgpu_device *adev)
847{
848 if (adev->mode_info.atom_context)
849 kfree(adev->mode_info.atom_context->scratch);
850 kfree(adev->mode_info.atom_context);
851 adev->mode_info.atom_context = NULL;
852 kfree(adev->mode_info.atom_card_info);
853 adev->mode_info.atom_card_info = NULL;
854}
855
856/**
857 * amdgpu_atombios_init - init the driver info and callbacks for atombios
858 *
859 * @adev: amdgpu_device pointer
860 *
861 * Initializes the driver info and register access callbacks for the
862 * ATOM interpreter (r4xx+).
863 * Returns 0 on sucess, -ENOMEM on failure.
864 * Called at driver startup.
865 */
866static int amdgpu_atombios_init(struct amdgpu_device *adev)
867{
868 struct card_info *atom_card_info =
869 kzalloc(sizeof(struct card_info), GFP_KERNEL);
870
871 if (!atom_card_info)
872 return -ENOMEM;
873
874 adev->mode_info.atom_card_info = atom_card_info;
875 atom_card_info->dev = adev->ddev;
876 atom_card_info->reg_read = cail_reg_read;
877 atom_card_info->reg_write = cail_reg_write;
878 /* needed for iio ops */
879 if (adev->rio_mem) {
880 atom_card_info->ioreg_read = cail_ioreg_read;
881 atom_card_info->ioreg_write = cail_ioreg_write;
882 } else {
883 DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n");
884 atom_card_info->ioreg_read = cail_reg_read;
885 atom_card_info->ioreg_write = cail_reg_write;
886 }
887 atom_card_info->mc_read = cail_mc_read;
888 atom_card_info->mc_write = cail_mc_write;
889 atom_card_info->pll_read = cail_pll_read;
890 atom_card_info->pll_write = cail_pll_write;
891
892 adev->mode_info.atom_context = amdgpu_atom_parse(atom_card_info, adev->bios);
893 if (!adev->mode_info.atom_context) {
894 amdgpu_atombios_fini(adev);
895 return -ENOMEM;
896 }
897
898 mutex_init(&adev->mode_info.atom_context->mutex);
899 amdgpu_atombios_scratch_regs_init(adev);
900 amdgpu_atom_allocate_fb_scratch(adev->mode_info.atom_context);
901 return 0;
902}
903
904/* if we get transitioned to only one device, take VGA back */
905/**
906 * amdgpu_vga_set_decode - enable/disable vga decode
907 *
908 * @cookie: amdgpu_device pointer
909 * @state: enable/disable vga decode
910 *
911 * Enable/disable vga decode (all asics).
912 * Returns VGA resource flags.
913 */
914static unsigned int amdgpu_vga_set_decode(void *cookie, bool state)
915{
916 struct amdgpu_device *adev = cookie;
917 amdgpu_asic_set_vga_state(adev, state);
918 if (state)
919 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
920 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
921 else
922 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
923}
924
925/**
926 * amdgpu_check_pot_argument - check that argument is a power of two
927 *
928 * @arg: value to check
929 *
930 * Validates that a certain argument is a power of two (all asics).
931 * Returns true if argument is valid.
932 */
933static bool amdgpu_check_pot_argument(int arg)
934{
935 return (arg & (arg - 1)) == 0;
936}
937
938/**
939 * amdgpu_check_arguments - validate module params
940 *
941 * @adev: amdgpu_device pointer
942 *
943 * Validates certain module parameters and updates
944 * the associated values used by the driver (all asics).
945 */
946static void amdgpu_check_arguments(struct amdgpu_device *adev)
947{
948 /* vramlimit must be a power of two */
949 if (!amdgpu_check_pot_argument(amdgpu_vram_limit)) {
950 dev_warn(adev->dev, "vram limit (%d) must be a power of 2\n",
951 amdgpu_vram_limit);
952 amdgpu_vram_limit = 0;
953 }
954
955 if (amdgpu_gart_size != -1) {
956 /* gtt size must be power of two and greater or equal to 32M */
957 if (amdgpu_gart_size < 32) {
958 dev_warn(adev->dev, "gart size (%d) too small\n",
959 amdgpu_gart_size);
960 amdgpu_gart_size = -1;
961 } else if (!amdgpu_check_pot_argument(amdgpu_gart_size)) {
962 dev_warn(adev->dev, "gart size (%d) must be a power of 2\n",
963 amdgpu_gart_size);
964 amdgpu_gart_size = -1;
965 }
966 }
967
968 if (!amdgpu_check_pot_argument(amdgpu_vm_size)) {
969 dev_warn(adev->dev, "VM size (%d) must be a power of 2\n",
970 amdgpu_vm_size);
971 amdgpu_vm_size = 8;
972 }
973
974 if (amdgpu_vm_size < 1) {
975 dev_warn(adev->dev, "VM size (%d) too small, min is 1GB\n",
976 amdgpu_vm_size);
977 amdgpu_vm_size = 8;
978 }
979
980 /*
981 * Max GPUVM size for Cayman, SI and CI are 40 bits.
982 */
983 if (amdgpu_vm_size > 1024) {
984 dev_warn(adev->dev, "VM size (%d) too large, max is 1TB\n",
985 amdgpu_vm_size);
986 amdgpu_vm_size = 8;
987 }
988
989 /* defines number of bits in page table versus page directory,
990 * a page is 4KB so we have 12 bits offset, minimum 9 bits in the
991 * page table and the remaining bits are in the page directory */
992 if (amdgpu_vm_block_size == -1) {
993
994 /* Total bits covered by PD + PTs */
995 unsigned bits = ilog2(amdgpu_vm_size) + 18;
996
997 /* Make sure the PD is 4K in size up to 8GB address space.
998 Above that split equal between PD and PTs */
999 if (amdgpu_vm_size <= 8)
1000 amdgpu_vm_block_size = bits - 9;
1001 else
1002 amdgpu_vm_block_size = (bits + 3) / 2;
1003
1004 } else if (amdgpu_vm_block_size < 9) {
1005 dev_warn(adev->dev, "VM page table size (%d) too small\n",
1006 amdgpu_vm_block_size);
1007 amdgpu_vm_block_size = 9;
1008 }
1009
1010 if (amdgpu_vm_block_size > 24 ||
1011 (amdgpu_vm_size * 1024) < (1ull << amdgpu_vm_block_size)) {
1012 dev_warn(adev->dev, "VM page table size (%d) too large\n",
1013 amdgpu_vm_block_size);
1014 amdgpu_vm_block_size = 9;
1015 }
1016}
1017
1018/**
1019 * amdgpu_switcheroo_set_state - set switcheroo state
1020 *
1021 * @pdev: pci dev pointer
1022 * @state: vga switcheroo state
1023 *
1024 * Callback for the switcheroo driver. Suspends or resumes the
1025 * the asics before or after it is powered up using ACPI methods.
1026 */
1027static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
1028{
1029 struct drm_device *dev = pci_get_drvdata(pdev);
1030
1031 if (amdgpu_device_is_px(dev) && state == VGA_SWITCHEROO_OFF)
1032 return;
1033
1034 if (state == VGA_SWITCHEROO_ON) {
1035 unsigned d3_delay = dev->pdev->d3_delay;
1036
1037 printk(KERN_INFO "amdgpu: switched on\n");
1038 /* don't suspend or resume card normally */
1039 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
1040
1041 amdgpu_resume_kms(dev, true, true);
1042
1043 dev->pdev->d3_delay = d3_delay;
1044
1045 dev->switch_power_state = DRM_SWITCH_POWER_ON;
1046 drm_kms_helper_poll_enable(dev);
1047 } else {
1048 printk(KERN_INFO "amdgpu: switched off\n");
1049 drm_kms_helper_poll_disable(dev);
1050 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
1051 amdgpu_suspend_kms(dev, true, true);
1052 dev->switch_power_state = DRM_SWITCH_POWER_OFF;
1053 }
1054}
1055
1056/**
1057 * amdgpu_switcheroo_can_switch - see if switcheroo state can change
1058 *
1059 * @pdev: pci dev pointer
1060 *
1061 * Callback for the switcheroo driver. Check of the switcheroo
1062 * state can be changed.
1063 * Returns true if the state can be changed, false if not.
1064 */
1065static bool amdgpu_switcheroo_can_switch(struct pci_dev *pdev)
1066{
1067 struct drm_device *dev = pci_get_drvdata(pdev);
1068
1069 /*
1070 * FIXME: open_count is protected by drm_global_mutex but that would lead to
1071 * locking inversion with the driver load path. And the access here is
1072 * completely racy anyway. So don't bother with locking for now.
1073 */
1074 return dev->open_count == 0;
1075}
1076
1077static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = {
1078 .set_gpu_state = amdgpu_switcheroo_set_state,
1079 .reprobe = NULL,
1080 .can_switch = amdgpu_switcheroo_can_switch,
1081};
1082
1083int amdgpu_set_clockgating_state(struct amdgpu_device *adev,
1084 enum amd_ip_block_type block_type,
1085 enum amd_clockgating_state state)
1086{
1087 int i, r = 0;
1088
1089 for (i = 0; i < adev->num_ip_blocks; i++) {
1090 if (adev->ip_blocks[i].type == block_type) {
1091 r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
1092 state);
1093 if (r)
1094 return r;
1095 }
1096 }
1097 return r;
1098}
1099
1100int amdgpu_set_powergating_state(struct amdgpu_device *adev,
1101 enum amd_ip_block_type block_type,
1102 enum amd_powergating_state state)
1103{
1104 int i, r = 0;
1105
1106 for (i = 0; i < adev->num_ip_blocks; i++) {
1107 if (adev->ip_blocks[i].type == block_type) {
1108 r = adev->ip_blocks[i].funcs->set_powergating_state((void *)adev,
1109 state);
1110 if (r)
1111 return r;
1112 }
1113 }
1114 return r;
1115}
1116
1117const struct amdgpu_ip_block_version * amdgpu_get_ip_block(
1118 struct amdgpu_device *adev,
1119 enum amd_ip_block_type type)
1120{
1121 int i;
1122
1123 for (i = 0; i < adev->num_ip_blocks; i++)
1124 if (adev->ip_blocks[i].type == type)
1125 return &adev->ip_blocks[i];
1126
1127 return NULL;
1128}
1129
1130/**
1131 * amdgpu_ip_block_version_cmp
1132 *
1133 * @adev: amdgpu_device pointer
1134 * @type: enum amd_ip_block_type
1135 * @major: major version
1136 * @minor: minor version
1137 *
1138 * return 0 if equal or greater
1139 * return 1 if smaller or the ip_block doesn't exist
1140 */
1141int amdgpu_ip_block_version_cmp(struct amdgpu_device *adev,
1142 enum amd_ip_block_type type,
1143 u32 major, u32 minor)
1144{
1145 const struct amdgpu_ip_block_version *ip_block;
1146 ip_block = amdgpu_get_ip_block(adev, type);
1147
1148 if (ip_block && ((ip_block->major > major) ||
1149 ((ip_block->major == major) &&
1150 (ip_block->minor >= minor))))
1151 return 0;
1152
1153 return 1;
1154}
1155
1156static int amdgpu_early_init(struct amdgpu_device *adev)
1157{
1158 int i, r;
1159
1160 switch (adev->asic_type) {
1161 case CHIP_TOPAZ:
1162 case CHIP_TONGA:
1163 case CHIP_CARRIZO:
1164 if (adev->asic_type == CHIP_CARRIZO)
1165 adev->family = AMDGPU_FAMILY_CZ;
1166 else
1167 adev->family = AMDGPU_FAMILY_VI;
1168
1169 r = vi_set_ip_blocks(adev);
1170 if (r)
1171 return r;
1172 break;
1173#ifdef CONFIG_DRM_AMDGPU_CIK
1174 case CHIP_BONAIRE:
1175 case CHIP_HAWAII:
1176 case CHIP_KAVERI:
1177 case CHIP_KABINI:
1178 case CHIP_MULLINS:
1179 if ((adev->asic_type == CHIP_BONAIRE) || (adev->asic_type == CHIP_HAWAII))
1180 adev->family = AMDGPU_FAMILY_CI;
1181 else
1182 adev->family = AMDGPU_FAMILY_KV;
1183
1184 r = cik_set_ip_blocks(adev);
1185 if (r)
1186 return r;
1187 break;
1188#endif
1189 default:
1190 /* FIXME: not supported yet */
1191 return -EINVAL;
1192 }
1193
1194
1195
1196 if (adev->ip_blocks == NULL) {
1197 DRM_ERROR("No IP blocks found!\n");
1198 return r;
1199 }
1200
1201 for (i = 0; i < adev->num_ip_blocks; i++) {
1202 if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
1203 DRM_ERROR("disabled ip block: %d\n", i);
1204 adev->ip_block_enabled[i] = false;
1205 } else {
1206 if (adev->ip_blocks[i].funcs->early_init) {
1207 r = adev->ip_blocks[i].funcs->early_init((void *)adev);
1208 if (r)
1209 return r;
1210 }
1211 adev->ip_block_enabled[i] = true;
1212 }
1213 }
1214
1215 return 0;
1216}
1217
1218static int amdgpu_init(struct amdgpu_device *adev)
1219{
1220 int i, r;
1221
1222 for (i = 0; i < adev->num_ip_blocks; i++) {
1223 if (!adev->ip_block_enabled[i])
1224 continue;
1225 r = adev->ip_blocks[i].funcs->sw_init((void *)adev);
1226 if (r)
1227 return r;
1228 /* need to do gmc hw init early so we can allocate gpu mem */
1229 if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
1230 r = amdgpu_vram_scratch_init(adev);
1231 if (r)
1232 return r;
1233 r = adev->ip_blocks[i].funcs->hw_init((void *)adev);
1234 if (r)
1235 return r;
1236 r = amdgpu_wb_init(adev);
1237 if (r)
1238 return r;
1239 }
1240 }
1241
1242 for (i = 0; i < adev->num_ip_blocks; i++) {
1243 if (!adev->ip_block_enabled[i])
1244 continue;
1245 /* gmc hw init is done early */
1246 if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC)
1247 continue;
1248 r = adev->ip_blocks[i].funcs->hw_init((void *)adev);
1249 if (r)
1250 return r;
1251 }
1252
1253 return 0;
1254}
1255
1256static int amdgpu_late_init(struct amdgpu_device *adev)
1257{
1258 int i = 0, r;
1259
1260 for (i = 0; i < adev->num_ip_blocks; i++) {
1261 if (!adev->ip_block_enabled[i])
1262 continue;
1263 /* enable clockgating to save power */
1264 r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
1265 AMD_CG_STATE_GATE);
1266 if (r)
1267 return r;
1268 if (adev->ip_blocks[i].funcs->late_init) {
1269 r = adev->ip_blocks[i].funcs->late_init((void *)adev);
1270 if (r)
1271 return r;
1272 }
1273 }
1274
1275 return 0;
1276}
1277
1278static int amdgpu_fini(struct amdgpu_device *adev)
1279{
1280 int i, r;
1281
1282 for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
1283 if (!adev->ip_block_enabled[i])
1284 continue;
1285 if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
1286 amdgpu_wb_fini(adev);
1287 amdgpu_vram_scratch_fini(adev);
1288 }
1289 /* ungate blocks before hw fini so that we can shutdown the blocks safely */
1290 r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
1291 AMD_CG_STATE_UNGATE);
1292 if (r)
1293 return r;
1294 r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
1295 /* XXX handle errors */
1296 }
1297
1298 for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
1299 if (!adev->ip_block_enabled[i])
1300 continue;
1301 r = adev->ip_blocks[i].funcs->sw_fini((void *)adev);
1302 /* XXX handle errors */
1303 adev->ip_block_enabled[i] = false;
1304 }
1305
1306 return 0;
1307}
1308
1309static int amdgpu_suspend(struct amdgpu_device *adev)
1310{
1311 int i, r;
1312
1313 for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
1314 if (!adev->ip_block_enabled[i])
1315 continue;
1316 /* ungate blocks so that suspend can properly shut them down */
1317 r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
1318 AMD_CG_STATE_UNGATE);
1319 /* XXX handle errors */
1320 r = adev->ip_blocks[i].funcs->suspend(adev);
1321 /* XXX handle errors */
1322 }
1323
1324 return 0;
1325}
1326
1327static int amdgpu_resume(struct amdgpu_device *adev)
1328{
1329 int i, r;
1330
1331 for (i = 0; i < adev->num_ip_blocks; i++) {
1332 if (!adev->ip_block_enabled[i])
1333 continue;
1334 r = adev->ip_blocks[i].funcs->resume(adev);
1335 if (r)
1336 return r;
1337 }
1338
1339 return 0;
1340}
1341
1342/**
1343 * amdgpu_device_init - initialize the driver
1344 *
1345 * @adev: amdgpu_device pointer
1346 * @pdev: drm dev pointer
1347 * @pdev: pci dev pointer
1348 * @flags: driver flags
1349 *
1350 * Initializes the driver info and hw (all asics).
1351 * Returns 0 for success or an error on failure.
1352 * Called at driver startup.
1353 */
1354int amdgpu_device_init(struct amdgpu_device *adev,
1355 struct drm_device *ddev,
1356 struct pci_dev *pdev,
1357 uint32_t flags)
1358{
1359 int r, i;
1360 bool runtime = false;
1361
1362 adev->shutdown = false;
1363 adev->dev = &pdev->dev;
1364 adev->ddev = ddev;
1365 adev->pdev = pdev;
1366 adev->flags = flags;
1367 adev->asic_type = flags & AMDGPU_ASIC_MASK;
1368 adev->is_atom_bios = false;
1369 adev->usec_timeout = AMDGPU_MAX_USEC_TIMEOUT;
1370 adev->mc.gtt_size = 512 * 1024 * 1024;
1371 adev->accel_working = false;
1372 adev->num_rings = 0;
1373 adev->mman.buffer_funcs = NULL;
1374 adev->mman.buffer_funcs_ring = NULL;
1375 adev->vm_manager.vm_pte_funcs = NULL;
1376 adev->vm_manager.vm_pte_funcs_ring = NULL;
1377 adev->gart.gart_funcs = NULL;
1378 adev->fence_context = fence_context_alloc(AMDGPU_MAX_RINGS);
1379
1380 adev->smc_rreg = &amdgpu_invalid_rreg;
1381 adev->smc_wreg = &amdgpu_invalid_wreg;
1382 adev->pcie_rreg = &amdgpu_invalid_rreg;
1383 adev->pcie_wreg = &amdgpu_invalid_wreg;
1384 adev->uvd_ctx_rreg = &amdgpu_invalid_rreg;
1385 adev->uvd_ctx_wreg = &amdgpu_invalid_wreg;
1386 adev->didt_rreg = &amdgpu_invalid_rreg;
1387 adev->didt_wreg = &amdgpu_invalid_wreg;
1388 adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg;
1389 adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg;
1390
1391 DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n",
1392 amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device,
1393 pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision);
1394
1395 /* mutex initialization are all done here so we
1396 * can recall function without having locking issues */
1397 mutex_init(&adev->ring_lock);
1398 atomic_set(&adev->irq.ih.lock, 0);
1399 mutex_init(&adev->gem.mutex);
1400 mutex_init(&adev->pm.mutex);
1401 mutex_init(&adev->gfx.gpu_clock_mutex);
1402 mutex_init(&adev->srbm_mutex);
1403 mutex_init(&adev->grbm_idx_mutex);
1404 init_rwsem(&adev->exclusive_lock);
1405 mutex_init(&adev->mn_lock);
1406 hash_init(adev->mn_hash);
1407
1408 amdgpu_check_arguments(adev);
1409
1410 /* Registers mapping */
1411 /* TODO: block userspace mapping of io register */
1412 spin_lock_init(&adev->mmio_idx_lock);
1413 spin_lock_init(&adev->smc_idx_lock);
1414 spin_lock_init(&adev->pcie_idx_lock);
1415 spin_lock_init(&adev->uvd_ctx_idx_lock);
1416 spin_lock_init(&adev->didt_idx_lock);
1417 spin_lock_init(&adev->audio_endpt_idx_lock);
1418
1419 adev->rmmio_base = pci_resource_start(adev->pdev, 5);
1420 adev->rmmio_size = pci_resource_len(adev->pdev, 5);
1421 adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size);
1422 if (adev->rmmio == NULL) {
1423 return -ENOMEM;
1424 }
1425 DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base);
1426 DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size);
1427
1428 /* doorbell bar mapping */
1429 amdgpu_doorbell_init(adev);
1430
1431 /* io port mapping */
1432 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
1433 if (pci_resource_flags(adev->pdev, i) & IORESOURCE_IO) {
1434 adev->rio_mem_size = pci_resource_len(adev->pdev, i);
1435 adev->rio_mem = pci_iomap(adev->pdev, i, adev->rio_mem_size);
1436 break;
1437 }
1438 }
1439 if (adev->rio_mem == NULL)
1440 DRM_ERROR("Unable to find PCI I/O BAR\n");
1441
1442 /* early init functions */
1443 r = amdgpu_early_init(adev);
1444 if (r)
1445 return r;
1446
1447 /* if we have > 1 VGA cards, then disable the amdgpu VGA resources */
1448 /* this will fail for cards that aren't VGA class devices, just
1449 * ignore it */
1450 vga_client_register(adev->pdev, adev, NULL, amdgpu_vga_set_decode);
1451
1452 if (amdgpu_runtime_pm == 1)
1453 runtime = true;
1454 if (amdgpu_device_is_px(ddev))
1455 runtime = true;
1456 vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime);
1457 if (runtime)
1458 vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
1459
1460 /* Read BIOS */
1461 if (!amdgpu_get_bios(adev))
1462 return -EINVAL;
1463 /* Must be an ATOMBIOS */
1464 if (!adev->is_atom_bios) {
1465 dev_err(adev->dev, "Expecting atombios for GPU\n");
1466 return -EINVAL;
1467 }
1468 r = amdgpu_atombios_init(adev);
1469 if (r)
1470 return r;
1471
1472 /* Post card if necessary */
1473 if (!amdgpu_card_posted(adev)) {
1474 if (!adev->bios) {
1475 dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
1476 return -EINVAL;
1477 }
1478 DRM_INFO("GPU not posted. posting now...\n");
1479 amdgpu_atom_asic_init(adev->mode_info.atom_context);
1480 }
1481
1482 /* Initialize clocks */
1483 r = amdgpu_atombios_get_clock_info(adev);
1484 if (r)
1485 return r;
1486 /* init i2c buses */
1487 amdgpu_atombios_i2c_init(adev);
1488
1489 /* Fence driver */
1490 r = amdgpu_fence_driver_init(adev);
1491 if (r)
1492 return r;
1493
1494 /* init the mode config */
1495 drm_mode_config_init(adev->ddev);
1496
1497 r = amdgpu_init(adev);
1498 if (r) {
1499 amdgpu_fini(adev);
1500 return r;
1501 }
1502
1503 adev->accel_working = true;
1504
1505 amdgpu_fbdev_init(adev);
1506
1507 r = amdgpu_ib_pool_init(adev);
1508 if (r) {
1509 dev_err(adev->dev, "IB initialization failed (%d).\n", r);
1510 return r;
1511 }
1512
1513 r = amdgpu_ib_ring_tests(adev);
1514 if (r)
1515 DRM_ERROR("ib ring test failed (%d).\n", r);
1516
1517 r = amdgpu_gem_debugfs_init(adev);
1518 if (r) {
1519 DRM_ERROR("registering gem debugfs failed (%d).\n", r);
1520 }
1521
1522 r = amdgpu_debugfs_regs_init(adev);
1523 if (r) {
1524 DRM_ERROR("registering register debugfs failed (%d).\n", r);
1525 }
1526
1527 if ((amdgpu_testing & 1)) {
1528 if (adev->accel_working)
1529 amdgpu_test_moves(adev);
1530 else
1531 DRM_INFO("amdgpu: acceleration disabled, skipping move tests\n");
1532 }
1533 if ((amdgpu_testing & 2)) {
1534 if (adev->accel_working)
1535 amdgpu_test_syncing(adev);
1536 else
1537 DRM_INFO("amdgpu: acceleration disabled, skipping sync tests\n");
1538 }
1539 if (amdgpu_benchmarking) {
1540 if (adev->accel_working)
1541 amdgpu_benchmark(adev, amdgpu_benchmarking);
1542 else
1543 DRM_INFO("amdgpu: acceleration disabled, skipping benchmarks\n");
1544 }
1545
1546 /* enable clockgating, etc. after ib tests, etc. since some blocks require
1547 * explicit gating rather than handling it automatically.
1548 */
1549 r = amdgpu_late_init(adev);
1550 if (r)
1551 return r;
1552
1553 return 0;
1554}
1555
1556static void amdgpu_debugfs_remove_files(struct amdgpu_device *adev);
1557
1558/**
1559 * amdgpu_device_fini - tear down the driver
1560 *
1561 * @adev: amdgpu_device pointer
1562 *
1563 * Tear down the driver info (all asics).
1564 * Called at driver shutdown.
1565 */
1566void amdgpu_device_fini(struct amdgpu_device *adev)
1567{
1568 int r;
1569
1570 DRM_INFO("amdgpu: finishing device.\n");
1571 adev->shutdown = true;
1572 /* evict vram memory */
1573 amdgpu_bo_evict_vram(adev);
1574 amdgpu_ib_pool_fini(adev);
1575 amdgpu_fence_driver_fini(adev);
1576 amdgpu_fbdev_fini(adev);
1577 r = amdgpu_fini(adev);
1578 if (adev->ip_block_enabled)
1579 kfree(adev->ip_block_enabled);
1580 adev->ip_block_enabled = NULL;
1581 adev->accel_working = false;
1582 /* free i2c buses */
1583 amdgpu_i2c_fini(adev);
1584 amdgpu_atombios_fini(adev);
1585 kfree(adev->bios);
1586 adev->bios = NULL;
1587 vga_switcheroo_unregister_client(adev->pdev);
1588 vga_client_register(adev->pdev, NULL, NULL, NULL);
1589 if (adev->rio_mem)
1590 pci_iounmap(adev->pdev, adev->rio_mem);
1591 adev->rio_mem = NULL;
1592 iounmap(adev->rmmio);
1593 adev->rmmio = NULL;
1594 amdgpu_doorbell_fini(adev);
1595 amdgpu_debugfs_regs_cleanup(adev);
1596 amdgpu_debugfs_remove_files(adev);
1597}
1598
1599
1600/*
1601 * Suspend & resume.
1602 */
1603/**
1604 * amdgpu_suspend_kms - initiate device suspend
1605 *
1606 * @pdev: drm dev pointer
1607 * @state: suspend state
1608 *
1609 * Puts the hw in the suspend state (all asics).
1610 * Returns 0 for success or an error on failure.
1611 * Called at driver suspend.
1612 */
1613int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
1614{
1615 struct amdgpu_device *adev;
1616 struct drm_crtc *crtc;
1617 struct drm_connector *connector;
1618 int i, r;
1619 bool force_completion = false;
1620
1621 if (dev == NULL || dev->dev_private == NULL) {
1622 return -ENODEV;
1623 }
1624
1625 adev = dev->dev_private;
1626
1627 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
1628 return 0;
1629
1630 drm_kms_helper_poll_disable(dev);
1631
1632 /* turn off display hw */
1633 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1634 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
1635 }
1636
1637 /* unpin the front buffers */
1638 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1639 struct amdgpu_framebuffer *rfb = to_amdgpu_framebuffer(crtc->primary->fb);
1640 struct amdgpu_bo *robj;
1641
1642 if (rfb == NULL || rfb->obj == NULL) {
1643 continue;
1644 }
1645 robj = gem_to_amdgpu_bo(rfb->obj);
1646 /* don't unpin kernel fb objects */
1647 if (!amdgpu_fbdev_robj_is_fb(adev, robj)) {
1648 r = amdgpu_bo_reserve(robj, false);
1649 if (r == 0) {
1650 amdgpu_bo_unpin(robj);
1651 amdgpu_bo_unreserve(robj);
1652 }
1653 }
1654 }
1655 /* evict vram memory */
1656 amdgpu_bo_evict_vram(adev);
1657
1658 /* wait for gpu to finish processing current batch */
1659 for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
1660 struct amdgpu_ring *ring = adev->rings[i];
1661 if (!ring)
1662 continue;
1663
1664 r = amdgpu_fence_wait_empty(ring);
1665 if (r) {
1666 /* delay GPU reset to resume */
1667 force_completion = true;
1668 }
1669 }
1670 if (force_completion) {
1671 amdgpu_fence_driver_force_completion(adev);
1672 }
1673
1674 r = amdgpu_suspend(adev);
1675
1676 /* evict remaining vram memory */
1677 amdgpu_bo_evict_vram(adev);
1678
1679 pci_save_state(dev->pdev);
1680 if (suspend) {
1681 /* Shut down the device */
1682 pci_disable_device(dev->pdev);
1683 pci_set_power_state(dev->pdev, PCI_D3hot);
1684 }
1685
1686 if (fbcon) {
1687 console_lock();
1688 amdgpu_fbdev_set_suspend(adev, 1);
1689 console_unlock();
1690 }
1691 return 0;
1692}
1693
1694/**
1695 * amdgpu_resume_kms - initiate device resume
1696 *
1697 * @pdev: drm dev pointer
1698 *
1699 * Bring the hw back to operating state (all asics).
1700 * Returns 0 for success or an error on failure.
1701 * Called at driver resume.
1702 */
1703int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
1704{
1705 struct drm_connector *connector;
1706 struct amdgpu_device *adev = dev->dev_private;
1707 int r;
1708
1709 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
1710 return 0;
1711
1712 if (fbcon) {
1713 console_lock();
1714 }
1715 if (resume) {
1716 pci_set_power_state(dev->pdev, PCI_D0);
1717 pci_restore_state(dev->pdev);
1718 if (pci_enable_device(dev->pdev)) {
1719 if (fbcon)
1720 console_unlock();
1721 return -1;
1722 }
1723 }
1724
1725 /* post card */
1726 amdgpu_atom_asic_init(adev->mode_info.atom_context);
1727
1728 r = amdgpu_resume(adev);
1729
1730 r = amdgpu_ib_ring_tests(adev);
1731 if (r)
1732 DRM_ERROR("ib ring test failed (%d).\n", r);
1733
1734 r = amdgpu_late_init(adev);
1735 if (r)
1736 return r;
1737
1738 /* blat the mode back in */
1739 if (fbcon) {
1740 drm_helper_resume_force_mode(dev);
1741 /* turn on display hw */
1742 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1743 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
1744 }
1745 }
1746
1747 drm_kms_helper_poll_enable(dev);
1748
1749 if (fbcon) {
1750 amdgpu_fbdev_set_suspend(adev, 0);
1751 console_unlock();
1752 }
1753
1754 return 0;
1755}
1756
1757/**
1758 * amdgpu_gpu_reset - reset the asic
1759 *
1760 * @adev: amdgpu device pointer
1761 *
1762 * Attempt the reset the GPU if it has hung (all asics).
1763 * Returns 0 for success or an error on failure.
1764 */
1765int amdgpu_gpu_reset(struct amdgpu_device *adev)
1766{
1767 unsigned ring_sizes[AMDGPU_MAX_RINGS];
1768 uint32_t *ring_data[AMDGPU_MAX_RINGS];
1769
1770 bool saved = false;
1771
1772 int i, r;
1773 int resched;
1774
1775 down_write(&adev->exclusive_lock);
1776
1777 if (!adev->needs_reset) {
1778 up_write(&adev->exclusive_lock);
1779 return 0;
1780 }
1781
1782 adev->needs_reset = false;
1783 atomic_inc(&adev->gpu_reset_counter);
1784
1785 /* block TTM */
1786 resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
1787
1788 r = amdgpu_suspend(adev);
1789
1790 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
1791 struct amdgpu_ring *ring = adev->rings[i];
1792 if (!ring)
1793 continue;
1794
1795 ring_sizes[i] = amdgpu_ring_backup(ring, &ring_data[i]);
1796 if (ring_sizes[i]) {
1797 saved = true;
1798 dev_info(adev->dev, "Saved %d dwords of commands "
1799 "on ring %d.\n", ring_sizes[i], i);
1800 }
1801 }
1802
1803retry:
1804 r = amdgpu_asic_reset(adev);
1805 if (!r) {
1806 dev_info(adev->dev, "GPU reset succeeded, trying to resume\n");
1807 r = amdgpu_resume(adev);
1808 }
1809
1810 if (!r) {
1811 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
1812 struct amdgpu_ring *ring = adev->rings[i];
1813 if (!ring)
1814 continue;
1815
1816 amdgpu_ring_restore(ring, ring_sizes[i], ring_data[i]);
1817 ring_sizes[i] = 0;
1818 ring_data[i] = NULL;
1819 }
1820
1821 r = amdgpu_ib_ring_tests(adev);
1822 if (r) {
1823 dev_err(adev->dev, "ib ring test failed (%d).\n", r);
1824 if (saved) {
1825 saved = false;
1826 r = amdgpu_suspend(adev);
1827 goto retry;
1828 }
1829 }
1830 } else {
1831 amdgpu_fence_driver_force_completion(adev);
1832 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
1833 if (adev->rings[i])
1834 kfree(ring_data[i]);
1835 }
1836 }
1837
1838 drm_helper_resume_force_mode(adev->ddev);
1839
1840 ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
1841 if (r) {
1842 /* bad news, how to tell it to userspace ? */
1843 dev_info(adev->dev, "GPU reset failed\n");
1844 }
1845
1846 up_write(&adev->exclusive_lock);
1847 return r;
1848}
1849
1850
1851/*
1852 * Debugfs
1853 */
1854int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
1855 struct drm_info_list *files,
1856 unsigned nfiles)
1857{
1858 unsigned i;
1859
1860 for (i = 0; i < adev->debugfs_count; i++) {
1861 if (adev->debugfs[i].files == files) {
1862 /* Already registered */
1863 return 0;
1864 }
1865 }
1866
1867 i = adev->debugfs_count + 1;
1868 if (i > AMDGPU_DEBUGFS_MAX_COMPONENTS) {
1869 DRM_ERROR("Reached maximum number of debugfs components.\n");
1870 DRM_ERROR("Report so we increase "
1871 "AMDGPU_DEBUGFS_MAX_COMPONENTS.\n");
1872 return -EINVAL;
1873 }
1874 adev->debugfs[adev->debugfs_count].files = files;
1875 adev->debugfs[adev->debugfs_count].num_files = nfiles;
1876 adev->debugfs_count = i;
1877#if defined(CONFIG_DEBUG_FS)
1878 drm_debugfs_create_files(files, nfiles,
1879 adev->ddev->control->debugfs_root,
1880 adev->ddev->control);
1881 drm_debugfs_create_files(files, nfiles,
1882 adev->ddev->primary->debugfs_root,
1883 adev->ddev->primary);
1884#endif
1885 return 0;
1886}
1887
1888static void amdgpu_debugfs_remove_files(struct amdgpu_device *adev)
1889{
1890#if defined(CONFIG_DEBUG_FS)
1891 unsigned i;
1892
1893 for (i = 0; i < adev->debugfs_count; i++) {
1894 drm_debugfs_remove_files(adev->debugfs[i].files,
1895 adev->debugfs[i].num_files,
1896 adev->ddev->control);
1897 drm_debugfs_remove_files(adev->debugfs[i].files,
1898 adev->debugfs[i].num_files,
1899 adev->ddev->primary);
1900 }
1901#endif
1902}
1903
1904#if defined(CONFIG_DEBUG_FS)
1905
1906static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
1907 size_t size, loff_t *pos)
1908{
1909 struct amdgpu_device *adev = f->f_inode->i_private;
1910 ssize_t result = 0;
1911 int r;
1912
1913 if (size & 0x3 || *pos & 0x3)
1914 return -EINVAL;
1915
1916 while (size) {
1917 uint32_t value;
1918
1919 if (*pos > adev->rmmio_size)
1920 return result;
1921
1922 value = RREG32(*pos >> 2);
1923 r = put_user(value, (uint32_t *)buf);
1924 if (r)
1925 return r;
1926
1927 result += 4;
1928 buf += 4;
1929 *pos += 4;
1930 size -= 4;
1931 }
1932
1933 return result;
1934}
1935
1936static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
1937 size_t size, loff_t *pos)
1938{
1939 struct amdgpu_device *adev = f->f_inode->i_private;
1940 ssize_t result = 0;
1941 int r;
1942
1943 if (size & 0x3 || *pos & 0x3)
1944 return -EINVAL;
1945
1946 while (size) {
1947 uint32_t value;
1948
1949 if (*pos > adev->rmmio_size)
1950 return result;
1951
1952 r = get_user(value, (uint32_t *)buf);
1953 if (r)
1954 return r;
1955
1956 WREG32(*pos >> 2, value);
1957
1958 result += 4;
1959 buf += 4;
1960 *pos += 4;
1961 size -= 4;
1962 }
1963
1964 return result;
1965}
1966
1967static const struct file_operations amdgpu_debugfs_regs_fops = {
1968 .owner = THIS_MODULE,
1969 .read = amdgpu_debugfs_regs_read,
1970 .write = amdgpu_debugfs_regs_write,
1971 .llseek = default_llseek
1972};
1973
1974static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
1975{
1976 struct drm_minor *minor = adev->ddev->primary;
1977 struct dentry *ent, *root = minor->debugfs_root;
1978
1979 ent = debugfs_create_file("amdgpu_regs", S_IFREG | S_IRUGO, root,
1980 adev, &amdgpu_debugfs_regs_fops);
1981 if (IS_ERR(ent))
1982 return PTR_ERR(ent);
1983 i_size_write(ent->d_inode, adev->rmmio_size);
1984 adev->debugfs_regs = ent;
1985
1986 return 0;
1987}
1988
1989static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev)
1990{
1991 debugfs_remove(adev->debugfs_regs);
1992 adev->debugfs_regs = NULL;
1993}
1994
1995int amdgpu_debugfs_init(struct drm_minor *minor)
1996{
1997 return 0;
1998}
1999
2000void amdgpu_debugfs_cleanup(struct drm_minor *minor)
2001{
2002}
2003#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c+832−0
@@ -0,0 +1,832 @@
1/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
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: Dave Airlie
24 * Alex Deucher
25 */
26#include <drm/drmP.h>
27#include <drm/amdgpu_drm.h>
28#include "amdgpu.h"
29#include "amdgpu_i2c.h"
30#include "atom.h"
31#include "amdgpu_connectors.h"
32#include <asm/div64.h>
33
34#include <linux/pm_runtime.h>
35#include <drm/drm_crtc_helper.h>
36#include <drm/drm_edid.h>
37
38
39static void amdgpu_flip_work_func(struct work_struct *__work)
40{
41 struct amdgpu_flip_work *work =
42 container_of(__work, struct amdgpu_flip_work, flip_work);
43 struct amdgpu_device *adev = work->adev;
44 struct amdgpu_crtc *amdgpuCrtc = adev->mode_info.crtcs[work->crtc_id];
45
46 struct drm_crtc *crtc = &amdgpuCrtc->base;
47 struct amdgpu_fence *fence;
48 unsigned long flags;
49 int r;
50
51 down_read(&adev->exclusive_lock);
52 if (work->fence) {
53 fence = to_amdgpu_fence(work->fence);
54 if (fence) {
55 r = amdgpu_fence_wait(fence, false);
56 if (r == -EDEADLK) {
57 up_read(&adev->exclusive_lock);
58 r = amdgpu_gpu_reset(adev);
59 down_read(&adev->exclusive_lock);
60 }
61 } else
62 r = fence_wait(work->fence, false);
63
64 if (r)
65 DRM_ERROR("failed to wait on page flip fence (%d)!\n", r);
66
67 /* We continue with the page flip even if we failed to wait on
68 * the fence, otherwise the DRM core and userspace will be
69 * confused about which BO the CRTC is scanning out
70 */
71
72 fence_put(work->fence);
73 work->fence = NULL;
74 }
75
76 /* We borrow the event spin lock for protecting flip_status */
77 spin_lock_irqsave(&crtc->dev->event_lock, flags);
78
79 /* set the proper interrupt */
80 amdgpu_irq_get(adev, &adev->pageflip_irq, work->crtc_id);
81 /* do the flip (mmio) */
82 adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);
83 /* set the flip status */
84 amdgpuCrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
85
86 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
87 up_read(&adev->exclusive_lock);
88}
89
90/*
91 * Handle unpin events outside the interrupt handler proper.
92 */
93static void amdgpu_unpin_work_func(struct work_struct *__work)
94{
95 struct amdgpu_flip_work *work =
96 container_of(__work, struct amdgpu_flip_work, unpin_work);
97 int r;
98
99 /* unpin of the old buffer */
100 r = amdgpu_bo_reserve(work->old_rbo, false);
101 if (likely(r == 0)) {
102 r = amdgpu_bo_unpin(work->old_rbo);
103 if (unlikely(r != 0)) {
104 DRM_ERROR("failed to unpin buffer after flip\n");
105 }
106 amdgpu_bo_unreserve(work->old_rbo);
107 } else
108 DRM_ERROR("failed to reserve buffer after flip\n");
109
110 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
111 kfree(work);
112}
113
114int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
115 struct drm_framebuffer *fb,
116 struct drm_pending_vblank_event *event,
117 uint32_t page_flip_flags)
118{
119 struct drm_device *dev = crtc->dev;
120 struct amdgpu_device *adev = dev->dev_private;
121 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
122 struct amdgpu_framebuffer *old_amdgpu_fb;
123 struct amdgpu_framebuffer *new_amdgpu_fb;
124 struct drm_gem_object *obj;
125 struct amdgpu_flip_work *work;
126 struct amdgpu_bo *new_rbo;
127 unsigned long flags;
128 u64 tiling_flags;
129 u64 base;
130 int r;
131
132 work = kzalloc(sizeof *work, GFP_KERNEL);
133 if (work == NULL)
134 return -ENOMEM;
135
136 INIT_WORK(&work->flip_work, amdgpu_flip_work_func);
137 INIT_WORK(&work->unpin_work, amdgpu_unpin_work_func);
138
139 work->event = event;
140 work->adev = adev;
141 work->crtc_id = amdgpu_crtc->crtc_id;
142
143 /* schedule unpin of the old buffer */
144 old_amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb);
145 obj = old_amdgpu_fb->obj;
146
147 /* take a reference to the old object */
148 drm_gem_object_reference(obj);
149 work->old_rbo = gem_to_amdgpu_bo(obj);
150
151 new_amdgpu_fb = to_amdgpu_framebuffer(fb);
152 obj = new_amdgpu_fb->obj;
153 new_rbo = gem_to_amdgpu_bo(obj);
154
155 /* pin the new buffer */
156 r = amdgpu_bo_reserve(new_rbo, false);
157 if (unlikely(r != 0)) {
158 DRM_ERROR("failed to reserve new rbo buffer before flip\n");
159 goto cleanup;
160 }
161
162 r = amdgpu_bo_pin_restricted(new_rbo, AMDGPU_GEM_DOMAIN_VRAM, 0, 0, &base);
163 if (unlikely(r != 0)) {
164 amdgpu_bo_unreserve(new_rbo);
165 r = -EINVAL;
166 DRM_ERROR("failed to pin new rbo buffer before flip\n");
167 goto cleanup;
168 }
169
170 work->fence = fence_get(reservation_object_get_excl(new_rbo->tbo.resv));
171 amdgpu_bo_get_tiling_flags(new_rbo, &tiling_flags);
172 amdgpu_bo_unreserve(new_rbo);
173
174 work->base = base;
175
176 r = drm_vblank_get(crtc->dev, amdgpu_crtc->crtc_id);
177 if (r) {
178 DRM_ERROR("failed to get vblank before flip\n");
179 goto pflip_cleanup;
180 }
181
182 /* we borrow the event spin lock for protecting flip_wrok */
183 spin_lock_irqsave(&crtc->dev->event_lock, flags);
184 if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_NONE) {
185 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
186 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
187 r = -EBUSY;
188 goto vblank_cleanup;
189 }
190
191 amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING;
192 amdgpu_crtc->pflip_works = work;
193
194 /* update crtc fb */
195 crtc->primary->fb = fb;
196 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
197 queue_work(amdgpu_crtc->pflip_queue, &work->flip_work);
198 return 0;
199
200vblank_cleanup:
201 drm_vblank_put(crtc->dev, amdgpu_crtc->crtc_id);
202
203pflip_cleanup:
204 if (unlikely(amdgpu_bo_reserve(new_rbo, false) != 0)) {
205 DRM_ERROR("failed to reserve new rbo in error path\n");
206 goto cleanup;
207 }
208 if (unlikely(amdgpu_bo_unpin(new_rbo) != 0)) {
209 DRM_ERROR("failed to unpin new rbo in error path\n");
210 }
211 amdgpu_bo_unreserve(new_rbo);
212
213cleanup:
214 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
215 fence_put(work->fence);
216 kfree(work);
217
218 return r;
219}
220
221int amdgpu_crtc_set_config(struct drm_mode_set *set)
222{
223 struct drm_device *dev;
224 struct amdgpu_device *adev;
225 struct drm_crtc *crtc;
226 bool active = false;
227 int ret;
228
229 if (!set || !set->crtc)
230 return -EINVAL;
231
232 dev = set->crtc->dev;
233
234 ret = pm_runtime_get_sync(dev->dev);
235 if (ret < 0)
236 return ret;
237
238 ret = drm_crtc_helper_set_config(set);
239
240 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
241 if (crtc->enabled)
242 active = true;
243
244 pm_runtime_mark_last_busy(dev->dev);
245
246 adev = dev->dev_private;
247 /* if we have active crtcs and we don't have a power ref,
248 take the current one */
249 if (active && !adev->have_disp_power_ref) {
250 adev->have_disp_power_ref = true;
251 return ret;
252 }
253 /* if we have no active crtcs, then drop the power ref
254 we got before */
255 if (!active && adev->have_disp_power_ref) {
256 pm_runtime_put_autosuspend(dev->dev);
257 adev->have_disp_power_ref = false;
258 }
259
260 /* drop the power reference we got coming in here */
261 pm_runtime_put_autosuspend(dev->dev);
262 return ret;
263}
264
265static const char *encoder_names[38] = {
266 "NONE",
267 "INTERNAL_LVDS",
268 "INTERNAL_TMDS1",
269 "INTERNAL_TMDS2",
270 "INTERNAL_DAC1",
271 "INTERNAL_DAC2",
272 "INTERNAL_SDVOA",
273 "INTERNAL_SDVOB",
274 "SI170B",
275 "CH7303",
276 "CH7301",
277 "INTERNAL_DVO1",
278 "EXTERNAL_SDVOA",
279 "EXTERNAL_SDVOB",
280 "TITFP513",
281 "INTERNAL_LVTM1",
282 "VT1623",
283 "HDMI_SI1930",
284 "HDMI_INTERNAL",
285 "INTERNAL_KLDSCP_TMDS1",
286 "INTERNAL_KLDSCP_DVO1",
287 "INTERNAL_KLDSCP_DAC1",
288 "INTERNAL_KLDSCP_DAC2",
289 "SI178",
290 "MVPU_FPGA",
291 "INTERNAL_DDI",
292 "VT1625",
293 "HDMI_SI1932",
294 "DP_AN9801",
295 "DP_DP501",
296 "INTERNAL_UNIPHY",
297 "INTERNAL_KLDSCP_LVTMA",
298 "INTERNAL_UNIPHY1",
299 "INTERNAL_UNIPHY2",
300 "NUTMEG",
301 "TRAVIS",
302 "INTERNAL_VCE",
303 "INTERNAL_UNIPHY3",
304};
305
306static const char *hpd_names[6] = {
307 "HPD1",
308 "HPD2",
309 "HPD3",
310 "HPD4",
311 "HPD5",
312 "HPD6",
313};
314
315void amdgpu_print_display_setup(struct drm_device *dev)
316{
317 struct drm_connector *connector;
318 struct amdgpu_connector *amdgpu_connector;
319 struct drm_encoder *encoder;
320 struct amdgpu_encoder *amdgpu_encoder;
321 uint32_t devices;
322 int i = 0;
323
324 DRM_INFO("AMDGPU Display Connectors\n");
325 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
326 amdgpu_connector = to_amdgpu_connector(connector);
327 DRM_INFO("Connector %d:\n", i);
328 DRM_INFO(" %s\n", connector->name);
329 if (amdgpu_connector->hpd.hpd != AMDGPU_HPD_NONE)
330 DRM_INFO(" %s\n", hpd_names[amdgpu_connector->hpd.hpd]);
331 if (amdgpu_connector->ddc_bus) {
332 DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
333 amdgpu_connector->ddc_bus->rec.mask_clk_reg,
334 amdgpu_connector->ddc_bus->rec.mask_data_reg,
335 amdgpu_connector->ddc_bus->rec.a_clk_reg,
336 amdgpu_connector->ddc_bus->rec.a_data_reg,
337 amdgpu_connector->ddc_bus->rec.en_clk_reg,
338 amdgpu_connector->ddc_bus->rec.en_data_reg,
339 amdgpu_connector->ddc_bus->rec.y_clk_reg,
340 amdgpu_connector->ddc_bus->rec.y_data_reg);
341 if (amdgpu_connector->router.ddc_valid)
342 DRM_INFO(" DDC Router 0x%x/0x%x\n",
343 amdgpu_connector->router.ddc_mux_control_pin,
344 amdgpu_connector->router.ddc_mux_state);
345 if (amdgpu_connector->router.cd_valid)
346 DRM_INFO(" Clock/Data Router 0x%x/0x%x\n",
347 amdgpu_connector->router.cd_mux_control_pin,
348 amdgpu_connector->router.cd_mux_state);
349 } else {
350 if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
351 connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
352 connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
353 connector->connector_type == DRM_MODE_CONNECTOR_DVIA ||
354 connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
355 connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
356 DRM_INFO(" DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n");
357 }
358 DRM_INFO(" Encoders:\n");
359 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
360 amdgpu_encoder = to_amdgpu_encoder(encoder);
361 devices = amdgpu_encoder->devices & amdgpu_connector->devices;
362 if (devices) {
363 if (devices & ATOM_DEVICE_CRT1_SUPPORT)
364 DRM_INFO(" CRT1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
365 if (devices & ATOM_DEVICE_CRT2_SUPPORT)
366 DRM_INFO(" CRT2: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
367 if (devices & ATOM_DEVICE_LCD1_SUPPORT)
368 DRM_INFO(" LCD1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
369 if (devices & ATOM_DEVICE_DFP1_SUPPORT)
370 DRM_INFO(" DFP1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
371 if (devices & ATOM_DEVICE_DFP2_SUPPORT)
372 DRM_INFO(" DFP2: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
373 if (devices & ATOM_DEVICE_DFP3_SUPPORT)
374 DRM_INFO(" DFP3: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
375 if (devices & ATOM_DEVICE_DFP4_SUPPORT)
376 DRM_INFO(" DFP4: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
377 if (devices & ATOM_DEVICE_DFP5_SUPPORT)
378 DRM_INFO(" DFP5: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
379 if (devices & ATOM_DEVICE_DFP6_SUPPORT)
380 DRM_INFO(" DFP6: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
381 if (devices & ATOM_DEVICE_TV1_SUPPORT)
382 DRM_INFO(" TV1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
383 if (devices & ATOM_DEVICE_CV_SUPPORT)
384 DRM_INFO(" CV: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
385 }
386 }
387 i++;
388 }
389}
390
391/**
392 * amdgpu_ddc_probe
393 *
394 */
395bool amdgpu_ddc_probe(struct amdgpu_connector *amdgpu_connector,
396 bool use_aux)
397{
398 u8 out = 0x0;
399 u8 buf[8];
400 int ret;
401 struct i2c_msg msgs[] = {
402 {
403 .addr = DDC_ADDR,
404 .flags = 0,
405 .len = 1,
406 .buf = &out,
407 },
408 {
409 .addr = DDC_ADDR,
410 .flags = I2C_M_RD,
411 .len = 8,
412 .buf = buf,
413 }
414 };
415
416 /* on hw with routers, select right port */
417 if (amdgpu_connector->router.ddc_valid)
418 amdgpu_i2c_router_select_ddc_port(amdgpu_connector);
419
420 if (use_aux) {
421 ret = i2c_transfer(&amdgpu_connector->ddc_bus->aux.ddc, msgs, 2);
422 } else {
423 ret = i2c_transfer(&amdgpu_connector->ddc_bus->adapter, msgs, 2);
424 }
425
426 if (ret != 2)
427 /* Couldn't find an accessible DDC on this connector */
428 return false;
429 /* Probe also for valid EDID header
430 * EDID header starts with:
431 * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00.
432 * Only the first 6 bytes must be valid as
433 * drm_edid_block_valid() can fix the last 2 bytes */
434 if (drm_edid_header_is_valid(buf) < 6) {
435 /* Couldn't find an accessible EDID on this
436 * connector */
437 return false;
438 }
439 return true;
440}
441
442static void amdgpu_user_framebuffer_destroy(struct drm_framebuffer *fb)
443{
444 struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
445
446 if (amdgpu_fb->obj) {
447 drm_gem_object_unreference_unlocked(amdgpu_fb->obj);
448 }
449 drm_framebuffer_cleanup(fb);
450 kfree(amdgpu_fb);
451}
452
453static int amdgpu_user_framebuffer_create_handle(struct drm_framebuffer *fb,
454 struct drm_file *file_priv,
455 unsigned int *handle)
456{
457 struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
458
459 return drm_gem_handle_create(file_priv, amdgpu_fb->obj, handle);
460}
461
462static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
463 .destroy = amdgpu_user_framebuffer_destroy,
464 .create_handle = amdgpu_user_framebuffer_create_handle,
465};
466
467int
468amdgpu_framebuffer_init(struct drm_device *dev,
469 struct amdgpu_framebuffer *rfb,
470 struct drm_mode_fb_cmd2 *mode_cmd,
471 struct drm_gem_object *obj)
472{
473 int ret;
474 rfb->obj = obj;
475 drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
476 ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
477 if (ret) {
478 rfb->obj = NULL;
479 return ret;
480 }
481 return 0;
482}
483
484static struct drm_framebuffer *
485amdgpu_user_framebuffer_create(struct drm_device *dev,
486 struct drm_file *file_priv,
487 struct drm_mode_fb_cmd2 *mode_cmd)
488{
489 struct drm_gem_object *obj;
490 struct amdgpu_framebuffer *amdgpu_fb;
491 int ret;
492
493 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
494 if (obj == NULL) {
495 dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, "
496 "can't create framebuffer\n", mode_cmd->handles[0]);
497 return ERR_PTR(-ENOENT);
498 }
499
500 amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL);
501 if (amdgpu_fb == NULL) {
502 drm_gem_object_unreference_unlocked(obj);
503 return ERR_PTR(-ENOMEM);
504 }
505
506 ret = amdgpu_framebuffer_init(dev, amdgpu_fb, mode_cmd, obj);
507 if (ret) {
508 kfree(amdgpu_fb);
509 drm_gem_object_unreference_unlocked(obj);
510 return ERR_PTR(ret);
511 }
512
513 return &amdgpu_fb->base;
514}
515
516static void amdgpu_output_poll_changed(struct drm_device *dev)
517{
518 struct amdgpu_device *adev = dev->dev_private;
519 amdgpu_fb_output_poll_changed(adev);
520}
521
522const struct drm_mode_config_funcs amdgpu_mode_funcs = {
523 .fb_create = amdgpu_user_framebuffer_create,
524 .output_poll_changed = amdgpu_output_poll_changed
525};
526
527static struct drm_prop_enum_list amdgpu_underscan_enum_list[] =
528{ { UNDERSCAN_OFF, "off" },
529 { UNDERSCAN_ON, "on" },
530 { UNDERSCAN_AUTO, "auto" },
531};
532
533static struct drm_prop_enum_list amdgpu_audio_enum_list[] =
534{ { AMDGPU_AUDIO_DISABLE, "off" },
535 { AMDGPU_AUDIO_ENABLE, "on" },
536 { AMDGPU_AUDIO_AUTO, "auto" },
537};
538
539/* XXX support different dither options? spatial, temporal, both, etc. */
540static struct drm_prop_enum_list amdgpu_dither_enum_list[] =
541{ { AMDGPU_FMT_DITHER_DISABLE, "off" },
542 { AMDGPU_FMT_DITHER_ENABLE, "on" },
543};
544
545int amdgpu_modeset_create_props(struct amdgpu_device *adev)
546{
547 int sz;
548
549 if (adev->is_atom_bios) {
550 adev->mode_info.coherent_mode_property =
551 drm_property_create_range(adev->ddev, 0 , "coherent", 0, 1);
552 if (!adev->mode_info.coherent_mode_property)
553 return -ENOMEM;
554 }
555
556 adev->mode_info.load_detect_property =
557 drm_property_create_range(adev->ddev, 0, "load detection", 0, 1);
558 if (!adev->mode_info.load_detect_property)
559 return -ENOMEM;
560
561 drm_mode_create_scaling_mode_property(adev->ddev);
562
563 sz = ARRAY_SIZE(amdgpu_underscan_enum_list);
564 adev->mode_info.underscan_property =
565 drm_property_create_enum(adev->ddev, 0,
566 "underscan",
567 amdgpu_underscan_enum_list, sz);
568
569 adev->mode_info.underscan_hborder_property =
570 drm_property_create_range(adev->ddev, 0,
571 "underscan hborder", 0, 128);
572 if (!adev->mode_info.underscan_hborder_property)
573 return -ENOMEM;
574
575 adev->mode_info.underscan_vborder_property =
576 drm_property_create_range(adev->ddev, 0,
577 "underscan vborder", 0, 128);
578 if (!adev->mode_info.underscan_vborder_property)
579 return -ENOMEM;
580
581 sz = ARRAY_SIZE(amdgpu_audio_enum_list);
582 adev->mode_info.audio_property =
583 drm_property_create_enum(adev->ddev, 0,
584 "audio",
585 amdgpu_audio_enum_list, sz);
586
587 sz = ARRAY_SIZE(amdgpu_dither_enum_list);
588 adev->mode_info.dither_property =
589 drm_property_create_enum(adev->ddev, 0,
590 "dither",
591 amdgpu_dither_enum_list, sz);
592
593 return 0;
594}
595
596void amdgpu_update_display_priority(struct amdgpu_device *adev)
597{
598 /* adjustment options for the display watermarks */
599 if ((amdgpu_disp_priority == 0) || (amdgpu_disp_priority > 2))
600 adev->mode_info.disp_priority = 0;
601 else
602 adev->mode_info.disp_priority = amdgpu_disp_priority;
603
604}
605
606static bool is_hdtv_mode(const struct drm_display_mode *mode)
607{
608 /* try and guess if this is a tv or a monitor */
609 if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */
610 (mode->vdisplay == 576) || /* 576p */
611 (mode->vdisplay == 720) || /* 720p */
612 (mode->vdisplay == 1080)) /* 1080p */
613 return true;
614 else
615 return false;
616}
617
618bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
619 const struct drm_display_mode *mode,
620 struct drm_display_mode *adjusted_mode)
621{
622 struct drm_device *dev = crtc->dev;
623 struct drm_encoder *encoder;
624 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
625 struct amdgpu_encoder *amdgpu_encoder;
626 struct drm_connector *connector;
627 struct amdgpu_connector *amdgpu_connector;
628 u32 src_v = 1, dst_v = 1;
629 u32 src_h = 1, dst_h = 1;
630
631 amdgpu_crtc->h_border = 0;
632 amdgpu_crtc->v_border = 0;
633
634 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
635 if (encoder->crtc != crtc)
636 continue;
637 amdgpu_encoder = to_amdgpu_encoder(encoder);
638 connector = amdgpu_get_connector_for_encoder(encoder);
639 amdgpu_connector = to_amdgpu_connector(connector);
640
641 /* set scaling */
642 if (amdgpu_encoder->rmx_type == RMX_OFF)
643 amdgpu_crtc->rmx_type = RMX_OFF;
644 else if (mode->hdisplay < amdgpu_encoder->native_mode.hdisplay ||
645 mode->vdisplay < amdgpu_encoder->native_mode.vdisplay)
646 amdgpu_crtc->rmx_type = amdgpu_encoder->rmx_type;
647 else
648 amdgpu_crtc->rmx_type = RMX_OFF;
649 /* copy native mode */
650 memcpy(&amdgpu_crtc->native_mode,
651 &amdgpu_encoder->native_mode,
652 sizeof(struct drm_display_mode));
653 src_v = crtc->mode.vdisplay;
654 dst_v = amdgpu_crtc->native_mode.vdisplay;
655 src_h = crtc->mode.hdisplay;
656 dst_h = amdgpu_crtc->native_mode.hdisplay;
657
658 /* fix up for overscan on hdmi */
659 if ((!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
660 ((amdgpu_encoder->underscan_type == UNDERSCAN_ON) ||
661 ((amdgpu_encoder->underscan_type == UNDERSCAN_AUTO) &&
662 drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) &&
663 is_hdtv_mode(mode)))) {
664 if (amdgpu_encoder->underscan_hborder != 0)
665 amdgpu_crtc->h_border = amdgpu_encoder->underscan_hborder;
666 else
667 amdgpu_crtc->h_border = (mode->hdisplay >> 5) + 16;
668 if (amdgpu_encoder->underscan_vborder != 0)
669 amdgpu_crtc->v_border = amdgpu_encoder->underscan_vborder;
670 else
671 amdgpu_crtc->v_border = (mode->vdisplay >> 5) + 16;
672 amdgpu_crtc->rmx_type = RMX_FULL;
673 src_v = crtc->mode.vdisplay;
674 dst_v = crtc->mode.vdisplay - (amdgpu_crtc->v_border * 2);
675 src_h = crtc->mode.hdisplay;
676 dst_h = crtc->mode.hdisplay - (amdgpu_crtc->h_border * 2);
677 }
678 }
679 if (amdgpu_crtc->rmx_type != RMX_OFF) {
680 fixed20_12 a, b;
681 a.full = dfixed_const(src_v);
682 b.full = dfixed_const(dst_v);
683 amdgpu_crtc->vsc.full = dfixed_div(a, b);
684 a.full = dfixed_const(src_h);
685 b.full = dfixed_const(dst_h);
686 amdgpu_crtc->hsc.full = dfixed_div(a, b);
687 } else {
688 amdgpu_crtc->vsc.full = dfixed_const(1);
689 amdgpu_crtc->hsc.full = dfixed_const(1);
690 }
691 return true;
692}
693
694/*
695 * Retrieve current video scanout position of crtc on a given gpu, and
696 * an optional accurate timestamp of when query happened.
697 *
698 * \param dev Device to query.
699 * \param crtc Crtc to query.
700 * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
701 * \param *vpos Location where vertical scanout position should be stored.
702 * \param *hpos Location where horizontal scanout position should go.
703 * \param *stime Target location for timestamp taken immediately before
704 * scanout position query. Can be NULL to skip timestamp.
705 * \param *etime Target location for timestamp taken immediately after
706 * scanout position query. Can be NULL to skip timestamp.
707 *
708 * Returns vpos as a positive number while in active scanout area.
709 * Returns vpos as a negative number inside vblank, counting the number
710 * of scanlines to go until end of vblank, e.g., -1 means "one scanline
711 * until start of active scanout / end of vblank."
712 *
713 * \return Flags, or'ed together as follows:
714 *
715 * DRM_SCANOUTPOS_VALID = Query successful.
716 * DRM_SCANOUTPOS_INVBL = Inside vblank.
717 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
718 * this flag means that returned position may be offset by a constant but
719 * unknown small number of scanlines wrt. real scanout position.
720 *
721 */
722int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags,
723 int *vpos, int *hpos, ktime_t *stime, ktime_t *etime)
724{
725 u32 vbl = 0, position = 0;
726 int vbl_start, vbl_end, vtotal, ret = 0;
727 bool in_vbl = true;
728
729 struct amdgpu_device *adev = dev->dev_private;
730
731 /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
732
733 /* Get optional system timestamp before query. */
734 if (stime)
735 *stime = ktime_get();
736
737 if (amdgpu_display_page_flip_get_scanoutpos(adev, crtc, &vbl, &position) == 0)
738 ret |= DRM_SCANOUTPOS_VALID;
739
740 /* Get optional system timestamp after query. */
741 if (etime)
742 *etime = ktime_get();
743
744 /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
745
746 /* Decode into vertical and horizontal scanout position. */
747 *vpos = position & 0x1fff;
748 *hpos = (position >> 16) & 0x1fff;
749
750 /* Valid vblank area boundaries from gpu retrieved? */
751 if (vbl > 0) {
752 /* Yes: Decode. */
753 ret |= DRM_SCANOUTPOS_ACCURATE;
754 vbl_start = vbl & 0x1fff;
755 vbl_end = (vbl >> 16) & 0x1fff;
756 }
757 else {
758 /* No: Fake something reasonable which gives at least ok results. */
759 vbl_start = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
760 vbl_end = 0;
761 }
762
763 /* Test scanout position against vblank region. */
764 if ((*vpos < vbl_start) && (*vpos >= vbl_end))
765 in_vbl = false;
766
767 /* Check if inside vblank area and apply corrective offsets:
768 * vpos will then be >=0 in video scanout area, but negative
769 * within vblank area, counting down the number of lines until
770 * start of scanout.
771 */
772
773 /* Inside "upper part" of vblank area? Apply corrective offset if so: */
774 if (in_vbl && (*vpos >= vbl_start)) {
775 vtotal = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
776 *vpos = *vpos - vtotal;
777 }
778
779 /* Correct for shifted end of vbl at vbl_end. */
780 *vpos = *vpos - vbl_end;
781
782 /* In vblank? */
783 if (in_vbl)
784 ret |= DRM_SCANOUTPOS_IN_VBLANK;
785
786 /* Is vpos outside nominal vblank area, but less than
787 * 1/100 of a frame height away from start of vblank?
788 * If so, assume this isn't a massively delayed vblank
789 * interrupt, but a vblank interrupt that fired a few
790 * microseconds before true start of vblank. Compensate
791 * by adding a full frame duration to the final timestamp.
792 * Happens, e.g., on ATI R500, R600.
793 *
794 * We only do this if DRM_CALLED_FROM_VBLIRQ.
795 */
796 if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
797 vbl_start = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
798 vtotal = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
799
800 if (vbl_start - *vpos < vtotal / 100) {
801 *vpos -= vtotal;
802
803 /* Signal this correction as "applied". */
804 ret |= 0x8;
805 }
806 }
807
808 return ret;
809}
810
811int amdgpu_crtc_idx_to_irq_type(struct amdgpu_device *adev, int crtc)
812{
813 if (crtc < 0 || crtc >= adev->mode_info.num_crtc)
814 return AMDGPU_CRTC_IRQ_NONE;
815
816 switch (crtc) {
817 case 0:
818 return AMDGPU_CRTC_IRQ_VBLANK1;
819 case 1:
820 return AMDGPU_CRTC_IRQ_VBLANK2;
821 case 2:
822 return AMDGPU_CRTC_IRQ_VBLANK3;
823 case 3:
824 return AMDGPU_CRTC_IRQ_VBLANK4;
825 case 4:
826 return AMDGPU_CRTC_IRQ_VBLANK5;
827 case 5:
828 return AMDGPU_CRTC_IRQ_VBLANK6;
829 default:
830 return AMDGPU_CRTC_IRQ_NONE;
831 }
832}
drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c+955−0
@@ -0,0 +1,955 @@
1/*
2 * Copyright 2011 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 * Authors: Alex Deucher
23 */
24
25#include "drmP.h"
26#include "amdgpu.h"
27#include "amdgpu_atombios.h"
28#include "amdgpu_i2c.h"
29#include "amdgpu_dpm.h"
30#include "atom.h"
31
32void amdgpu_dpm_print_class_info(u32 class, u32 class2)
33{
34 printk("\tui class: ");
35 switch (class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
36 case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
37 default:
38 printk("none\n");
39 break;
40 case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
41 printk("battery\n");
42 break;
43 case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
44 printk("balanced\n");
45 break;
46 case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
47 printk("performance\n");
48 break;
49 }
50 printk("\tinternal class: ");
51 if (((class & ~ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 0) &&
52 (class2 == 0))
53 printk("none");
54 else {
55 if (class & ATOM_PPLIB_CLASSIFICATION_BOOT)
56 printk("boot ");
57 if (class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
58 printk("thermal ");
59 if (class & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
60 printk("limited_pwr ");
61 if (class & ATOM_PPLIB_CLASSIFICATION_REST)
62 printk("rest ");
63 if (class & ATOM_PPLIB_CLASSIFICATION_FORCED)
64 printk("forced ");
65 if (class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
66 printk("3d_perf ");
67 if (class & ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE)
68 printk("ovrdrv ");
69 if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
70 printk("uvd ");
71 if (class & ATOM_PPLIB_CLASSIFICATION_3DLOW)
72 printk("3d_low ");
73 if (class & ATOM_PPLIB_CLASSIFICATION_ACPI)
74 printk("acpi ");
75 if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
76 printk("uvd_hd2 ");
77 if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
78 printk("uvd_hd ");
79 if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
80 printk("uvd_sd ");
81 if (class2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
82 printk("limited_pwr2 ");
83 if (class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
84 printk("ulv ");
85 if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
86 printk("uvd_mvc ");
87 }
88 printk("\n");
89}
90
91void amdgpu_dpm_print_cap_info(u32 caps)
92{
93 printk("\tcaps: ");
94 if (caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
95 printk("single_disp ");
96 if (caps & ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK)
97 printk("video ");
98 if (caps & ATOM_PPLIB_DISALLOW_ON_DC)
99 printk("no_dc ");
100 printk("\n");
101}
102
103void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
104 struct amdgpu_ps *rps)
105{
106 printk("\tstatus: ");
107 if (rps == adev->pm.dpm.current_ps)
108 printk("c ");
109 if (rps == adev->pm.dpm.requested_ps)
110 printk("r ");
111 if (rps == adev->pm.dpm.boot_ps)
112 printk("b ");
113 printk("\n");
114}
115
116u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
117{
118 struct drm_device *dev = adev->ddev;
119 struct drm_crtc *crtc;
120 struct amdgpu_crtc *amdgpu_crtc;
121 u32 line_time_us, vblank_lines;
122 u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
123
124 if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
125 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
126 amdgpu_crtc = to_amdgpu_crtc(crtc);
127 if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
128 line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
129 amdgpu_crtc->hw_mode.clock;
130 vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
131 amdgpu_crtc->hw_mode.crtc_vdisplay +
132 (amdgpu_crtc->v_border * 2);
133 vblank_time_us = vblank_lines * line_time_us;
134 break;
135 }
136 }
137 }
138
139 return vblank_time_us;
140}
141
142u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev)
143{
144 struct drm_device *dev = adev->ddev;
145 struct drm_crtc *crtc;
146 struct amdgpu_crtc *amdgpu_crtc;
147 u32 vrefresh = 0;
148
149 if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
150 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
151 amdgpu_crtc = to_amdgpu_crtc(crtc);
152 if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
153 vrefresh = amdgpu_crtc->hw_mode.vrefresh;
154 break;
155 }
156 }
157 }
158
159 return vrefresh;
160}
161
162void amdgpu_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
163 u32 *p, u32 *u)
164{
165 u32 b_c = 0;
166 u32 i_c;
167 u32 tmp;
168
169 i_c = (i * r_c) / 100;
170 tmp = i_c >> p_b;
171
172 while (tmp) {
173 b_c++;
174 tmp >>= 1;
175 }
176
177 *u = (b_c + 1) / 2;
178 *p = i_c / (1 << (2 * (*u)));
179}
180
181int amdgpu_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th)
182{
183 u32 k, a, ah, al;
184 u32 t1;
185
186 if ((fl == 0) || (fh == 0) || (fl > fh))
187 return -EINVAL;
188
189 k = (100 * fh) / fl;
190 t1 = (t * (k - 100));
191 a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100));
192 a = (a + 5) / 10;
193 ah = ((a * t) + 5000) / 10000;
194 al = a - ah;
195
196 *th = t - ah;
197 *tl = t + al;
198
199 return 0;
200}
201
202bool amdgpu_is_uvd_state(u32 class, u32 class2)
203{
204 if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
205 return true;
206 if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
207 return true;
208 if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
209 return true;
210 if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
211 return true;
212 if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
213 return true;
214 return false;
215}
216
217bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor)
218{
219 switch (sensor) {
220 case THERMAL_TYPE_RV6XX:
221 case THERMAL_TYPE_RV770:
222 case THERMAL_TYPE_EVERGREEN:
223 case THERMAL_TYPE_SUMO:
224 case THERMAL_TYPE_NI:
225 case THERMAL_TYPE_SI:
226 case THERMAL_TYPE_CI:
227 case THERMAL_TYPE_KV:
228 return true;
229 case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
230 case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
231 return false; /* need special handling */
232 case THERMAL_TYPE_NONE:
233 case THERMAL_TYPE_EXTERNAL:
234 case THERMAL_TYPE_EXTERNAL_GPIO:
235 default:
236 return false;
237 }
238}
239
240union power_info {
241 struct _ATOM_POWERPLAY_INFO info;
242 struct _ATOM_POWERPLAY_INFO_V2 info_2;
243 struct _ATOM_POWERPLAY_INFO_V3 info_3;
244 struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
245 struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
246 struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
247 struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;
248 struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;
249};
250
251union fan_info {
252 struct _ATOM_PPLIB_FANTABLE fan;
253 struct _ATOM_PPLIB_FANTABLE2 fan2;
254 struct _ATOM_PPLIB_FANTABLE3 fan3;
255};
256
257static int amdgpu_parse_clk_voltage_dep_table(struct amdgpu_clock_voltage_dependency_table *amdgpu_table,
258 ATOM_PPLIB_Clock_Voltage_Dependency_Table *atom_table)
259{
260 u32 size = atom_table->ucNumEntries *
261 sizeof(struct amdgpu_clock_voltage_dependency_entry);
262 int i;
263 ATOM_PPLIB_Clock_Voltage_Dependency_Record *entry;
264
265 amdgpu_table->entries = kzalloc(size, GFP_KERNEL);
266 if (!amdgpu_table->entries)
267 return -ENOMEM;
268
269 entry = &atom_table->entries[0];
270 for (i = 0; i < atom_table->ucNumEntries; i++) {
271 amdgpu_table->entries[i].clk = le16_to_cpu(entry->usClockLow) |
272 (entry->ucClockHigh << 16);
273 amdgpu_table->entries[i].v = le16_to_cpu(entry->usVoltage);
274 entry = (ATOM_PPLIB_Clock_Voltage_Dependency_Record *)
275 ((u8 *)entry + sizeof(ATOM_PPLIB_Clock_Voltage_Dependency_Record));
276 }
277 amdgpu_table->count = atom_table->ucNumEntries;
278
279 return 0;
280}
281
282int amdgpu_get_platform_caps(struct amdgpu_device *adev)
283{
284 struct amdgpu_mode_info *mode_info = &adev->mode_info;
285 union power_info *power_info;
286 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
287 u16 data_offset;
288 u8 frev, crev;
289
290 if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
291 &frev, &crev, &data_offset))
292 return -EINVAL;
293 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
294
295 adev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
296 adev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
297 adev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
298
299 return 0;
300}
301
302/* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
303#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
304#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
305#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
306#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
307#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
308#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
309#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8 24
310#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V9 26
311
312int amdgpu_parse_extended_power_table(struct amdgpu_device *adev)
313{
314 struct amdgpu_mode_info *mode_info = &adev->mode_info;
315 union power_info *power_info;
316 union fan_info *fan_info;
317 ATOM_PPLIB_Clock_Voltage_Dependency_Table *dep_table;
318 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
319 u16 data_offset;
320 u8 frev, crev;
321 int ret, i;
322
323 if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
324 &frev, &crev, &data_offset))
325 return -EINVAL;
326 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
327
328 /* fan table */
329 if (le16_to_cpu(power_info->pplib.usTableSize) >=
330 sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
331 if (power_info->pplib3.usFanTableOffset) {
332 fan_info = (union fan_info *)(mode_info->atom_context->bios + data_offset +
333 le16_to_cpu(power_info->pplib3.usFanTableOffset));
334 adev->pm.dpm.fan.t_hyst = fan_info->fan.ucTHyst;
335 adev->pm.dpm.fan.t_min = le16_to_cpu(fan_info->fan.usTMin);
336 adev->pm.dpm.fan.t_med = le16_to_cpu(fan_info->fan.usTMed);
337 adev->pm.dpm.fan.t_high = le16_to_cpu(fan_info->fan.usTHigh);
338 adev->pm.dpm.fan.pwm_min = le16_to_cpu(fan_info->fan.usPWMMin);
339 adev->pm.dpm.fan.pwm_med = le16_to_cpu(fan_info->fan.usPWMMed);
340 adev->pm.dpm.fan.pwm_high = le16_to_cpu(fan_info->fan.usPWMHigh);
341 if (fan_info->fan.ucFanTableFormat >= 2)
342 adev->pm.dpm.fan.t_max = le16_to_cpu(fan_info->fan2.usTMax);
343 else
344 adev->pm.dpm.fan.t_max = 10900;
345 adev->pm.dpm.fan.cycle_delay = 100000;
346 if (fan_info->fan.ucFanTableFormat >= 3) {
347 adev->pm.dpm.fan.control_mode = fan_info->fan3.ucFanControlMode;
348 adev->pm.dpm.fan.default_max_fan_pwm =
349 le16_to_cpu(fan_info->fan3.usFanPWMMax);
350 adev->pm.dpm.fan.default_fan_output_sensitivity = 4836;
351 adev->pm.dpm.fan.fan_output_sensitivity =
352 le16_to_cpu(fan_info->fan3.usFanOutputSensitivity);
353 }
354 adev->pm.dpm.fan.ucode_fan_control = true;
355 }
356 }
357
358 /* clock dependancy tables, shedding tables */
359 if (le16_to_cpu(power_info->pplib.usTableSize) >=
360 sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE4)) {
361 if (power_info->pplib4.usVddcDependencyOnSCLKOffset) {
362 dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
363 (mode_info->atom_context->bios + data_offset +
364 le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset));
365 ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
366 dep_table);
367 if (ret) {
368 amdgpu_free_extended_power_table(adev);
369 return ret;
370 }
371 }
372 if (power_info->pplib4.usVddciDependencyOnMCLKOffset) {
373 dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
374 (mode_info->atom_context->bios + data_offset +
375 le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset));
376 ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
377 dep_table);
378 if (ret) {
379 amdgpu_free_extended_power_table(adev);
380 return ret;
381 }
382 }
383 if (power_info->pplib4.usVddcDependencyOnMCLKOffset) {
384 dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
385 (mode_info->atom_context->bios + data_offset +
386 le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset));
387 ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
388 dep_table);
389 if (ret) {
390 amdgpu_free_extended_power_table(adev);
391 return ret;
392 }
393 }
394 if (power_info->pplib4.usMvddDependencyOnMCLKOffset) {
395 dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
396 (mode_info->atom_context->bios + data_offset +
397 le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset));
398 ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk,
399 dep_table);
400 if (ret) {
401 amdgpu_free_extended_power_table(adev);
402 return ret;
403 }
404 }
405 if (power_info->pplib4.usMaxClockVoltageOnDCOffset) {
406 ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v =
407 (ATOM_PPLIB_Clock_Voltage_Limit_Table *)
408 (mode_info->atom_context->bios + data_offset +
409 le16_to_cpu(power_info->pplib4.usMaxClockVoltageOnDCOffset));
410 if (clk_v->ucNumEntries) {
411 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk =
412 le16_to_cpu(clk_v->entries[0].usSclkLow) |
413 (clk_v->entries[0].ucSclkHigh << 16);
414 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk =
415 le16_to_cpu(clk_v->entries[0].usMclkLow) |
416 (clk_v->entries[0].ucMclkHigh << 16);
417 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc =
418 le16_to_cpu(clk_v->entries[0].usVddc);
419 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddci =
420 le16_to_cpu(clk_v->entries[0].usVddci);
421 }
422 }
423 if (power_info->pplib4.usVddcPhaseShedLimitsTableOffset) {
424 ATOM_PPLIB_PhaseSheddingLimits_Table *psl =
425 (ATOM_PPLIB_PhaseSheddingLimits_Table *)
426 (mode_info->atom_context->bios + data_offset +
427 le16_to_cpu(power_info->pplib4.usVddcPhaseShedLimitsTableOffset));
428 ATOM_PPLIB_PhaseSheddingLimits_Record *entry;
429
430 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries =
431 kzalloc(psl->ucNumEntries *
432 sizeof(struct amdgpu_phase_shedding_limits_entry),
433 GFP_KERNEL);
434 if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) {
435 amdgpu_free_extended_power_table(adev);
436 return -ENOMEM;
437 }
438
439 entry = &psl->entries[0];
440 for (i = 0; i < psl->ucNumEntries; i++) {
441 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].sclk =
442 le16_to_cpu(entry->usSclkLow) | (entry->ucSclkHigh << 16);
443 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].mclk =
444 le16_to_cpu(entry->usMclkLow) | (entry->ucMclkHigh << 16);
445 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].voltage =
446 le16_to_cpu(entry->usVoltage);
447 entry = (ATOM_PPLIB_PhaseSheddingLimits_Record *)
448 ((u8 *)entry + sizeof(ATOM_PPLIB_PhaseSheddingLimits_Record));
449 }
450 adev->pm.dpm.dyn_state.phase_shedding_limits_table.count =
451 psl->ucNumEntries;
452 }
453 }
454
455 /* cac data */
456 if (le16_to_cpu(power_info->pplib.usTableSize) >=
457 sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE5)) {
458 adev->pm.dpm.tdp_limit = le32_to_cpu(power_info->pplib5.ulTDPLimit);
459 adev->pm.dpm.near_tdp_limit = le32_to_cpu(power_info->pplib5.ulNearTDPLimit);
460 adev->pm.dpm.near_tdp_limit_adjusted = adev->pm.dpm.near_tdp_limit;
461 adev->pm.dpm.tdp_od_limit = le16_to_cpu(power_info->pplib5.usTDPODLimit);
462 if (adev->pm.dpm.tdp_od_limit)
463 adev->pm.dpm.power_control = true;
464 else
465 adev->pm.dpm.power_control = false;
466 adev->pm.dpm.tdp_adjustment = 0;
467 adev->pm.dpm.sq_ramping_threshold = le32_to_cpu(power_info->pplib5.ulSQRampingThreshold);
468 adev->pm.dpm.cac_leakage = le32_to_cpu(power_info->pplib5.ulCACLeakage);
469 adev->pm.dpm.load_line_slope = le16_to_cpu(power_info->pplib5.usLoadLineSlope);
470 if (power_info->pplib5.usCACLeakageTableOffset) {
471 ATOM_PPLIB_CAC_Leakage_Table *cac_table =
472 (ATOM_PPLIB_CAC_Leakage_Table *)
473 (mode_info->atom_context->bios + data_offset +
474 le16_to_cpu(power_info->pplib5.usCACLeakageTableOffset));
475 ATOM_PPLIB_CAC_Leakage_Record *entry;
476 u32 size = cac_table->ucNumEntries * sizeof(struct amdgpu_cac_leakage_table);
477 adev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL);
478 if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) {
479 amdgpu_free_extended_power_table(adev);
480 return -ENOMEM;
481 }
482 entry = &cac_table->entries[0];
483 for (i = 0; i < cac_table->ucNumEntries; i++) {
484 if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) {
485 adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc1 =
486 le16_to_cpu(entry->usVddc1);
487 adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc2 =
488 le16_to_cpu(entry->usVddc2);
489 adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc3 =
490 le16_to_cpu(entry->usVddc3);
491 } else {
492 adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc =
493 le16_to_cpu(entry->usVddc);
494 adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].leakage =
495 le32_to_cpu(entry->ulLeakageValue);
496 }
497 entry = (ATOM_PPLIB_CAC_Leakage_Record *)
498 ((u8 *)entry + sizeof(ATOM_PPLIB_CAC_Leakage_Record));
499 }
500 adev->pm.dpm.dyn_state.cac_leakage_table.count = cac_table->ucNumEntries;
501 }
502 }
503
504 /* ext tables */
505 if (le16_to_cpu(power_info->pplib.usTableSize) >=
506 sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
507 ATOM_PPLIB_EXTENDEDHEADER *ext_hdr = (ATOM_PPLIB_EXTENDEDHEADER *)
508 (mode_info->atom_context->bios + data_offset +
509 le16_to_cpu(power_info->pplib3.usExtendendedHeaderOffset));
510 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2) &&
511 ext_hdr->usVCETableOffset) {
512 VCEClockInfoArray *array = (VCEClockInfoArray *)
513 (mode_info->atom_context->bios + data_offset +
514 le16_to_cpu(ext_hdr->usVCETableOffset) + 1);
515 ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *limits =
516 (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *)
517 (mode_info->atom_context->bios + data_offset +
518 le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
519 1 + array->ucNumEntries * sizeof(VCEClockInfo));
520 ATOM_PPLIB_VCE_State_Table *states =
521 (ATOM_PPLIB_VCE_State_Table *)
522 (mode_info->atom_context->bios + data_offset +
523 le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
524 1 + (array->ucNumEntries * sizeof (VCEClockInfo)) +
525 1 + (limits->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)));
526 ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry;
527 ATOM_PPLIB_VCE_State_Record *state_entry;
528 VCEClockInfo *vce_clk;
529 u32 size = limits->numEntries *
530 sizeof(struct amdgpu_vce_clock_voltage_dependency_entry);
531 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries =
532 kzalloc(size, GFP_KERNEL);
533 if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) {
534 amdgpu_free_extended_power_table(adev);
535 return -ENOMEM;
536 }
537 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count =
538 limits->numEntries;
539 entry = &limits->entries[0];
540 state_entry = &states->entries[0];
541 for (i = 0; i < limits->numEntries; i++) {
542 vce_clk = (VCEClockInfo *)
543 ((u8 *)&array->entries[0] +
544 (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
545 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk =
546 le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
547 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].ecclk =
548 le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
549 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].v =
550 le16_to_cpu(entry->usVoltage);
551 entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *)
552 ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record));
553 }
554 for (i = 0; i < states->numEntries; i++) {
555 if (i >= AMDGPU_MAX_VCE_LEVELS)
556 break;
557 vce_clk = (VCEClockInfo *)
558 ((u8 *)&array->entries[0] +
559 (state_entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
560 adev->pm.dpm.vce_states[i].evclk =
561 le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
562 adev->pm.dpm.vce_states[i].ecclk =
563 le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
564 adev->pm.dpm.vce_states[i].clk_idx =
565 state_entry->ucClockInfoIndex & 0x3f;
566 adev->pm.dpm.vce_states[i].pstate =
567 (state_entry->ucClockInfoIndex & 0xc0) >> 6;
568 state_entry = (ATOM_PPLIB_VCE_State_Record *)
569 ((u8 *)state_entry + sizeof(ATOM_PPLIB_VCE_State_Record));
570 }
571 }
572 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) &&
573 ext_hdr->usUVDTableOffset) {
574 UVDClockInfoArray *array = (UVDClockInfoArray *)
575 (mode_info->atom_context->bios + data_offset +
576 le16_to_cpu(ext_hdr->usUVDTableOffset) + 1);
577 ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *limits =
578 (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *)
579 (mode_info->atom_context->bios + data_offset +
580 le16_to_cpu(ext_hdr->usUVDTableOffset) + 1 +
581 1 + (array->ucNumEntries * sizeof (UVDClockInfo)));
582 ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *entry;
583 u32 size = limits->numEntries *
584 sizeof(struct amdgpu_uvd_clock_voltage_dependency_entry);
585 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries =
586 kzalloc(size, GFP_KERNEL);
587 if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) {
588 amdgpu_free_extended_power_table(adev);
589 return -ENOMEM;
590 }
591 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count =
592 limits->numEntries;
593 entry = &limits->entries[0];
594 for (i = 0; i < limits->numEntries; i++) {
595 UVDClockInfo *uvd_clk = (UVDClockInfo *)
596 ((u8 *)&array->entries[0] +
597 (entry->ucUVDClockInfoIndex * sizeof(UVDClockInfo)));
598 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].vclk =
599 le16_to_cpu(uvd_clk->usVClkLow) | (uvd_clk->ucVClkHigh << 16);
600 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].dclk =
601 le16_to_cpu(uvd_clk->usDClkLow) | (uvd_clk->ucDClkHigh << 16);
602 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].v =
603 le16_to_cpu(entry->usVoltage);
604 entry = (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *)
605 ((u8 *)entry + sizeof(ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record));
606 }
607 }
608 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4) &&
609 ext_hdr->usSAMUTableOffset) {
610 ATOM_PPLIB_SAMClk_Voltage_Limit_Table *limits =
611 (ATOM_PPLIB_SAMClk_Voltage_Limit_Table *)
612 (mode_info->atom_context->bios + data_offset +
613 le16_to_cpu(ext_hdr->usSAMUTableOffset) + 1);
614 ATOM_PPLIB_SAMClk_Voltage_Limit_Record *entry;
615 u32 size = limits->numEntries *
616 sizeof(struct amdgpu_clock_voltage_dependency_entry);
617 adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries =
618 kzalloc(size, GFP_KERNEL);
619 if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) {
620 amdgpu_free_extended_power_table(adev);
621 return -ENOMEM;
622 }
623 adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count =
624 limits->numEntries;
625 entry = &limits->entries[0];
626 for (i = 0; i < limits->numEntries; i++) {
627 adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].clk =
628 le16_to_cpu(entry->usSAMClockLow) | (entry->ucSAMClockHigh << 16);
629 adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].v =
630 le16_to_cpu(entry->usVoltage);
631 entry = (ATOM_PPLIB_SAMClk_Voltage_Limit_Record *)
632 ((u8 *)entry + sizeof(ATOM_PPLIB_SAMClk_Voltage_Limit_Record));
633 }
634 }
635 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5) &&
636 ext_hdr->usPPMTableOffset) {
637 ATOM_PPLIB_PPM_Table *ppm = (ATOM_PPLIB_PPM_Table *)
638 (mode_info->atom_context->bios + data_offset +
639 le16_to_cpu(ext_hdr->usPPMTableOffset));
640 adev->pm.dpm.dyn_state.ppm_table =
641 kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL);
642 if (!adev->pm.dpm.dyn_state.ppm_table) {
643 amdgpu_free_extended_power_table(adev);
644 return -ENOMEM;
645 }
646 adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign;
647 adev->pm.dpm.dyn_state.ppm_table->cpu_core_number =
648 le16_to_cpu(ppm->usCpuCoreNumber);
649 adev->pm.dpm.dyn_state.ppm_table->platform_tdp =
650 le32_to_cpu(ppm->ulPlatformTDP);
651 adev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdp =
652 le32_to_cpu(ppm->ulSmallACPlatformTDP);
653 adev->pm.dpm.dyn_state.ppm_table->platform_tdc =
654 le32_to_cpu(ppm->ulPlatformTDC);
655 adev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdc =
656 le32_to_cpu(ppm->ulSmallACPlatformTDC);
657 adev->pm.dpm.dyn_state.ppm_table->apu_tdp =
658 le32_to_cpu(ppm->ulApuTDP);
659 adev->pm.dpm.dyn_state.ppm_table->dgpu_tdp =
660 le32_to_cpu(ppm->ulDGpuTDP);
661 adev->pm.dpm.dyn_state.ppm_table->dgpu_ulv_power =
662 le32_to_cpu(ppm->ulDGpuUlvPower);
663 adev->pm.dpm.dyn_state.ppm_table->tj_max =
664 le32_to_cpu(ppm->ulTjmax);
665 }
666 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6) &&
667 ext_hdr->usACPTableOffset) {
668 ATOM_PPLIB_ACPClk_Voltage_Limit_Table *limits =
669 (ATOM_PPLIB_ACPClk_Voltage_Limit_Table *)
670 (mode_info->atom_context->bios + data_offset +
671 le16_to_cpu(ext_hdr->usACPTableOffset) + 1);
672 ATOM_PPLIB_ACPClk_Voltage_Limit_Record *entry;
673 u32 size = limits->numEntries *
674 sizeof(struct amdgpu_clock_voltage_dependency_entry);
675 adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries =
676 kzalloc(size, GFP_KERNEL);
677 if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) {
678 amdgpu_free_extended_power_table(adev);
679 return -ENOMEM;
680 }
681 adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count =
682 limits->numEntries;
683 entry = &limits->entries[0];
684 for (i = 0; i < limits->numEntries; i++) {
685 adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].clk =
686 le16_to_cpu(entry->usACPClockLow) | (entry->ucACPClockHigh << 16);
687 adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].v =
688 le16_to_cpu(entry->usVoltage);
689 entry = (ATOM_PPLIB_ACPClk_Voltage_Limit_Record *)
690 ((u8 *)entry + sizeof(ATOM_PPLIB_ACPClk_Voltage_Limit_Record));
691 }
692 }
693 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7) &&
694 ext_hdr->usPowerTuneTableOffset) {
695 u8 rev = *(u8 *)(mode_info->atom_context->bios + data_offset +
696 le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
697 ATOM_PowerTune_Table *pt;
698 adev->pm.dpm.dyn_state.cac_tdp_table =
699 kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL);
700 if (!adev->pm.dpm.dyn_state.cac_tdp_table) {
701 amdgpu_free_extended_power_table(adev);
702 return -ENOMEM;
703 }
704 if (rev > 0) {
705 ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *)
706 (mode_info->atom_context->bios + data_offset +
707 le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
708 adev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit =
709 ppt->usMaximumPowerDeliveryLimit;
710 pt = &ppt->power_tune_table;
711 } else {
712 ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *)
713 (mode_info->atom_context->bios + data_offset +
714 le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
715 adev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = 255;
716 pt = &ppt->power_tune_table;
717 }
718 adev->pm.dpm.dyn_state.cac_tdp_table->tdp = le16_to_cpu(pt->usTDP);
719 adev->pm.dpm.dyn_state.cac_tdp_table->configurable_tdp =
720 le16_to_cpu(pt->usConfigurableTDP);
721 adev->pm.dpm.dyn_state.cac_tdp_table->tdc = le16_to_cpu(pt->usTDC);
722 adev->pm.dpm.dyn_state.cac_tdp_table->battery_power_limit =
723 le16_to_cpu(pt->usBatteryPowerLimit);
724 adev->pm.dpm.dyn_state.cac_tdp_table->small_power_limit =
725 le16_to_cpu(pt->usSmallPowerLimit);
726 adev->pm.dpm.dyn_state.cac_tdp_table->low_cac_leakage =
727 le16_to_cpu(pt->usLowCACLeakage);
728 adev->pm.dpm.dyn_state.cac_tdp_table->high_cac_leakage =
729 le16_to_cpu(pt->usHighCACLeakage);
730 }
731 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8) &&
732 ext_hdr->usSclkVddgfxTableOffset) {
733 dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
734 (mode_info->atom_context->bios + data_offset +
735 le16_to_cpu(ext_hdr->usSclkVddgfxTableOffset));
736 ret = amdgpu_parse_clk_voltage_dep_table(
737 &adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk,
738 dep_table);
739 if (ret) {
740 kfree(adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk.entries);
741 return ret;
742 }
743 }
744 }
745
746 return 0;
747}
748
749void amdgpu_free_extended_power_table(struct amdgpu_device *adev)
750{
751 struct amdgpu_dpm_dynamic_state *dyn_state = &adev->pm.dpm.dyn_state;
752
753 kfree(dyn_state->vddc_dependency_on_sclk.entries);
754 kfree(dyn_state->vddci_dependency_on_mclk.entries);
755 kfree(dyn_state->vddc_dependency_on_mclk.entries);
756 kfree(dyn_state->mvdd_dependency_on_mclk.entries);
757 kfree(dyn_state->cac_leakage_table.entries);
758 kfree(dyn_state->phase_shedding_limits_table.entries);
759 kfree(dyn_state->ppm_table);
760 kfree(dyn_state->cac_tdp_table);
761 kfree(dyn_state->vce_clock_voltage_dependency_table.entries);
762 kfree(dyn_state->uvd_clock_voltage_dependency_table.entries);
763 kfree(dyn_state->samu_clock_voltage_dependency_table.entries);
764 kfree(dyn_state->acp_clock_voltage_dependency_table.entries);
765 kfree(dyn_state->vddgfx_dependency_on_sclk.entries);
766}
767
768static const char *pp_lib_thermal_controller_names[] = {
769 "NONE",
770 "lm63",
771 "adm1032",
772 "adm1030",
773 "max6649",
774 "lm64",
775 "f75375",
776 "RV6xx",
777 "RV770",
778 "adt7473",
779 "NONE",
780 "External GPIO",
781 "Evergreen",
782 "emc2103",
783 "Sumo",
784 "Northern Islands",
785 "Southern Islands",
786 "lm96163",
787 "Sea Islands",
788 "Kaveri/Kabini",
789};
790
791void amdgpu_add_thermal_controller(struct amdgpu_device *adev)
792{
793 struct amdgpu_mode_info *mode_info = &adev->mode_info;
794 ATOM_PPLIB_POWERPLAYTABLE *power_table;
795 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
796 ATOM_PPLIB_THERMALCONTROLLER *controller;
797 struct amdgpu_i2c_bus_rec i2c_bus;
798 u16 data_offset;
799 u8 frev, crev;
800
801 if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
802 &frev, &crev, &data_offset))
803 return;
804 power_table = (ATOM_PPLIB_POWERPLAYTABLE *)
805 (mode_info->atom_context->bios + data_offset);
806 controller = &power_table->sThermalController;
807
808 /* add the i2c bus for thermal/fan chip */
809 if (controller->ucType > 0) {
810 if (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN)
811 adev->pm.no_fan = true;
812 adev->pm.fan_pulses_per_revolution =
813 controller->ucFanParameters & ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
814 if (adev->pm.fan_pulses_per_revolution) {
815 adev->pm.fan_min_rpm = controller->ucFanMinRPM;
816 adev->pm.fan_max_rpm = controller->ucFanMaxRPM;
817 }
818 if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
819 DRM_INFO("Internal thermal controller %s fan control\n",
820 (controller->ucFanParameters &
821 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
822 adev->pm.int_thermal_type = THERMAL_TYPE_RV6XX;
823 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {
824 DRM_INFO("Internal thermal controller %s fan control\n",
825 (controller->ucFanParameters &
826 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
827 adev->pm.int_thermal_type = THERMAL_TYPE_RV770;
828 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {
829 DRM_INFO("Internal thermal controller %s fan control\n",
830 (controller->ucFanParameters &
831 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
832 adev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;
833 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) {
834 DRM_INFO("Internal thermal controller %s fan control\n",
835 (controller->ucFanParameters &
836 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
837 adev->pm.int_thermal_type = THERMAL_TYPE_SUMO;
838 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) {
839 DRM_INFO("Internal thermal controller %s fan control\n",
840 (controller->ucFanParameters &
841 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
842 adev->pm.int_thermal_type = THERMAL_TYPE_NI;
843 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) {
844 DRM_INFO("Internal thermal controller %s fan control\n",
845 (controller->ucFanParameters &
846 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
847 adev->pm.int_thermal_type = THERMAL_TYPE_SI;
848 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) {
849 DRM_INFO("Internal thermal controller %s fan control\n",
850 (controller->ucFanParameters &
851 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
852 adev->pm.int_thermal_type = THERMAL_TYPE_CI;
853 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_KAVERI) {
854 DRM_INFO("Internal thermal controller %s fan control\n",
855 (controller->ucFanParameters &
856 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
857 adev->pm.int_thermal_type = THERMAL_TYPE_KV;
858 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) {
859 DRM_INFO("External GPIO thermal controller %s fan control\n",
860 (controller->ucFanParameters &
861 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
862 adev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL_GPIO;
863 } else if (controller->ucType ==
864 ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) {
865 DRM_INFO("ADT7473 with internal thermal controller %s fan control\n",
866 (controller->ucFanParameters &
867 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
868 adev->pm.int_thermal_type = THERMAL_TYPE_ADT7473_WITH_INTERNAL;
869 } else if (controller->ucType ==
870 ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL) {
871 DRM_INFO("EMC2103 with internal thermal controller %s fan control\n",
872 (controller->ucFanParameters &
873 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
874 adev->pm.int_thermal_type = THERMAL_TYPE_EMC2103_WITH_INTERNAL;
875 } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) {
876 DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
877 pp_lib_thermal_controller_names[controller->ucType],
878 controller->ucI2cAddress >> 1,
879 (controller->ucFanParameters &
880 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
881 adev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL;
882 i2c_bus = amdgpu_atombios_lookup_i2c_gpio(adev, controller->ucI2cLine);
883 adev->pm.i2c_bus = amdgpu_i2c_lookup(adev, &i2c_bus);
884 if (adev->pm.i2c_bus) {
885 struct i2c_board_info info = { };
886 const char *name = pp_lib_thermal_controller_names[controller->ucType];
887 info.addr = controller->ucI2cAddress >> 1;
888 strlcpy(info.type, name, sizeof(info.type));
889 i2c_new_device(&adev->pm.i2c_bus->adapter, &info);
890 }
891 } else {
892 DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
893 controller->ucType,
894 controller->ucI2cAddress >> 1,
895 (controller->ucFanParameters &
896 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
897 }
898 }
899}
900
901enum amdgpu_pcie_gen amdgpu_get_pcie_gen_support(struct amdgpu_device *adev,
902 u32 sys_mask,
903 enum amdgpu_pcie_gen asic_gen,
904 enum amdgpu_pcie_gen default_gen)
905{
906 switch (asic_gen) {
907 case AMDGPU_PCIE_GEN1:
908 return AMDGPU_PCIE_GEN1;
909 case AMDGPU_PCIE_GEN2:
910 return AMDGPU_PCIE_GEN2;
911 case AMDGPU_PCIE_GEN3:
912 return AMDGPU_PCIE_GEN3;
913 default:
914 if ((sys_mask & DRM_PCIE_SPEED_80) && (default_gen == AMDGPU_PCIE_GEN3))
915 return AMDGPU_PCIE_GEN3;
916 else if ((sys_mask & DRM_PCIE_SPEED_50) && (default_gen == AMDGPU_PCIE_GEN2))
917 return AMDGPU_PCIE_GEN2;
918 else
919 return AMDGPU_PCIE_GEN1;
920 }
921 return AMDGPU_PCIE_GEN1;
922}
923
924u16 amdgpu_get_pcie_lane_support(struct amdgpu_device *adev,
925 u16 asic_lanes,
926 u16 default_lanes)
927{
928 switch (asic_lanes) {
929 case 0:
930 default:
931 return default_lanes;
932 case 1:
933 return 1;
934 case 2:
935 return 2;
936 case 4:
937 return 4;
938 case 8:
939 return 8;
940 case 12:
941 return 12;
942 case 16:
943 return 16;
944 }
945}
946
947u8 amdgpu_encode_pci_lane_width(u32 lanes)
948{
949 u8 encoded_lanes[] = { 0, 1, 2, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6 };
950
951 if (lanes > 16)
952 return 0;
953
954 return encoded_lanes[lanes];
955}
drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h+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#ifndef __AMDGPU_DPM_H__
24#define __AMDGPU_DPM_H__
25
26#define R600_SSTU_DFLT 0
27#define R600_SST_DFLT 0x00C8
28
29/* XXX are these ok? */
30#define R600_TEMP_RANGE_MIN (90 * 1000)
31#define R600_TEMP_RANGE_MAX (120 * 1000)
32
33#define FDO_PWM_MODE_STATIC 1
34#define FDO_PWM_MODE_STATIC_RPM 5
35
36enum amdgpu_td {
37 AMDGPU_TD_AUTO,
38 AMDGPU_TD_UP,
39 AMDGPU_TD_DOWN,
40};
41
42enum amdgpu_display_watermark {
43 AMDGPU_DISPLAY_WATERMARK_LOW = 0,
44 AMDGPU_DISPLAY_WATERMARK_HIGH = 1,
45};
46
47enum amdgpu_display_gap
48{
49 AMDGPU_PM_DISPLAY_GAP_VBLANK_OR_WM = 0,
50 AMDGPU_PM_DISPLAY_GAP_VBLANK = 1,
51 AMDGPU_PM_DISPLAY_GAP_WATERMARK = 2,
52 AMDGPU_PM_DISPLAY_GAP_IGNORE = 3,
53};
54
55void amdgpu_dpm_print_class_info(u32 class, u32 class2);
56void amdgpu_dpm_print_cap_info(u32 caps);
57void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
58 struct amdgpu_ps *rps);
59u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev);
60u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev);
61bool amdgpu_is_uvd_state(u32 class, u32 class2);
62void amdgpu_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
63 u32 *p, u32 *u);
64int amdgpu_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th);
65
66bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor);
67
68int amdgpu_get_platform_caps(struct amdgpu_device *adev);
69
70int amdgpu_parse_extended_power_table(struct amdgpu_device *adev);
71void amdgpu_free_extended_power_table(struct amdgpu_device *adev);
72
73void amdgpu_add_thermal_controller(struct amdgpu_device *adev);
74
75enum amdgpu_pcie_gen amdgpu_get_pcie_gen_support(struct amdgpu_device *adev,
76 u32 sys_mask,
77 enum amdgpu_pcie_gen asic_gen,
78 enum amdgpu_pcie_gen default_gen);
79
80u16 amdgpu_get_pcie_lane_support(struct amdgpu_device *adev,
81 u16 asic_lanes,
82 u16 default_lanes);
83u8 amdgpu_encode_pci_lane_width(u32 lanes);
84
85#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+545−0
@@ -0,0 +1,545 @@
1/**
2 * \file amdgpu_drv.c
3 * AMD Amdgpu driver
4 *
5 * \author Gareth Hughes <gareth@valinux.com>
6 */
7
8/*
9 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
10 * All Rights Reserved.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice (including the next
20 * paragraph) shall be included in all copies or substantial portions of the
21 * Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 * OTHER DEALINGS IN THE SOFTWARE.
30 */
31
32#include <drm/drmP.h>
33#include <drm/amdgpu_drm.h>
34#include <drm/drm_gem.h>
35#include "amdgpu_drv.h"
36
37#include <drm/drm_pciids.h>
38#include <linux/console.h>
39#include <linux/module.h>
40#include <linux/pm_runtime.h>
41#include <linux/vga_switcheroo.h>
42#include "drm_crtc_helper.h"
43
44#include "amdgpu.h"
45#include "amdgpu_irq.h"
46
47/*
48 * KMS wrapper.
49 * - 3.0.0 - initial driver
50 */
51#define KMS_DRIVER_MAJOR 3
52#define KMS_DRIVER_MINOR 0
53#define KMS_DRIVER_PATCHLEVEL 0
54
55int amdgpu_vram_limit = 0;
56int amdgpu_gart_size = -1; /* auto */
57int amdgpu_benchmarking = 0;
58int amdgpu_testing = 0;
59int amdgpu_audio = -1;
60int amdgpu_disp_priority = 0;
61int amdgpu_hw_i2c = 0;
62int amdgpu_pcie_gen2 = -1;
63int amdgpu_msi = -1;
64int amdgpu_lockup_timeout = 10000;
65int amdgpu_dpm = -1;
66int amdgpu_smc_load_fw = 1;
67int amdgpu_aspm = -1;
68int amdgpu_runtime_pm = -1;
69int amdgpu_hard_reset = 0;
70unsigned amdgpu_ip_block_mask = 0xffffffff;
71int amdgpu_bapm = -1;
72int amdgpu_deep_color = 0;
73int amdgpu_vm_size = 8;
74int amdgpu_vm_block_size = -1;
75int amdgpu_exp_hw_support = 0;
76
77MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
78module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
79
80MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc., -1 = auto)");
81module_param_named(gartsize, amdgpu_gart_size, int, 0600);
82
83MODULE_PARM_DESC(benchmark, "Run benchmark");
84module_param_named(benchmark, amdgpu_benchmarking, int, 0444);
85
86MODULE_PARM_DESC(test, "Run tests");
87module_param_named(test, amdgpu_testing, int, 0444);
88
89MODULE_PARM_DESC(audio, "Audio enable (-1 = auto, 0 = disable, 1 = enable)");
90module_param_named(audio, amdgpu_audio, int, 0444);
91
92MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
93module_param_named(disp_priority, amdgpu_disp_priority, int, 0444);
94
95MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)");
96module_param_named(hw_i2c, amdgpu_hw_i2c, int, 0444);
97
98MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (-1 = auto, 0 = disable, 1 = enable)");
99module_param_named(pcie_gen2, amdgpu_pcie_gen2, int, 0444);
100
101MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)");
102module_param_named(msi, amdgpu_msi, int, 0444);
103
104MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (defaul 10000 = 10 seconds, 0 = disable)");
105module_param_named(lockup_timeout, amdgpu_lockup_timeout, int, 0444);
106
107MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)");
108module_param_named(dpm, amdgpu_dpm, int, 0444);
109
110MODULE_PARM_DESC(smc_load_fw, "SMC firmware loading(1 = enable, 0 = disable)");
111module_param_named(smc_load_fw, amdgpu_smc_load_fw, int, 0444);
112
113MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)");
114module_param_named(aspm, amdgpu_aspm, int, 0444);
115
116MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)");
117module_param_named(runpm, amdgpu_runtime_pm, int, 0444);
118
119MODULE_PARM_DESC(hard_reset, "PCI config reset (1 = force enable, 0 = disable (default))");
120module_param_named(hard_reset, amdgpu_hard_reset, int, 0444);
121
122MODULE_PARM_DESC(ip_block_mask, "IP Block Mask (all blocks enabled (default))");
123module_param_named(ip_block_mask, amdgpu_ip_block_mask, uint, 0444);
124
125MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)");
126module_param_named(bapm, amdgpu_bapm, int, 0444);
127
128MODULE_PARM_DESC(deep_color, "Deep Color support (1 = enable, 0 = disable (default))");
129module_param_named(deep_color, amdgpu_deep_color, int, 0444);
130
131MODULE_PARM_DESC(vm_size, "VM address space size in gigabytes (default 8GB)");
132module_param_named(vm_size, amdgpu_vm_size, int, 0444);
133
134MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)");
135module_param_named(vm_block_size, amdgpu_vm_block_size, int, 0444);
136
137MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
138module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
139
140static struct pci_device_id pciidlist[] = {
141#ifdef CONFIG_DRM_AMDGPU_CIK
142 /* Kaveri */
143 {0x1002, 0x1304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
144 {0x1002, 0x1305, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
145 {0x1002, 0x1306, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
146 {0x1002, 0x1307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
147 {0x1002, 0x1309, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
148 {0x1002, 0x130A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
149 {0x1002, 0x130B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
150 {0x1002, 0x130C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
151 {0x1002, 0x130D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
152 {0x1002, 0x130E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
153 {0x1002, 0x130F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
154 {0x1002, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
155 {0x1002, 0x1311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
156 {0x1002, 0x1312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
157 {0x1002, 0x1313, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
158 {0x1002, 0x1315, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
159 {0x1002, 0x1316, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
160 {0x1002, 0x1317, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
161 {0x1002, 0x1318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
162 {0x1002, 0x131B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
163 {0x1002, 0x131C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
164 {0x1002, 0x131D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMDGPU_IS_APU},
165 /* Bonaire */
166 {0x1002, 0x6640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|AMDGPU_IS_MOBILITY},
167 {0x1002, 0x6641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|AMDGPU_IS_MOBILITY},
168 {0x1002, 0x6646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|AMDGPU_IS_MOBILITY},
169 {0x1002, 0x6647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|AMDGPU_IS_MOBILITY},
170 {0x1002, 0x6649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE},
171 {0x1002, 0x6650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE},
172 {0x1002, 0x6651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE},
173 {0x1002, 0x6658, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE},
174 {0x1002, 0x665c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE},
175 {0x1002, 0x665d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE},
176 {0x1002, 0x665f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE},
177 /* Hawaii */
178 {0x1002, 0x67A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
179 {0x1002, 0x67A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
180 {0x1002, 0x67A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
181 {0x1002, 0x67A8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
182 {0x1002, 0x67A9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
183 {0x1002, 0x67AA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
184 {0x1002, 0x67B0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
185 {0x1002, 0x67B1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
186 {0x1002, 0x67B8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
187 {0x1002, 0x67B9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
188 {0x1002, 0x67BA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
189 {0x1002, 0x67BE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII},
190 /* Kabini */
191 {0x1002, 0x9830, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
192 {0x1002, 0x9831, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
193 {0x1002, 0x9832, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
194 {0x1002, 0x9833, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
195 {0x1002, 0x9834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
196 {0x1002, 0x9835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
197 {0x1002, 0x9836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
198 {0x1002, 0x9837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
199 {0x1002, 0x9838, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
200 {0x1002, 0x9839, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
201 {0x1002, 0x983a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
202 {0x1002, 0x983b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
203 {0x1002, 0x983c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
204 {0x1002, 0x983d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
205 {0x1002, 0x983e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
206 {0x1002, 0x983f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|AMDGPU_IS_APU},
207 /* mullins */
208 {0x1002, 0x9850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
209 {0x1002, 0x9851, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
210 {0x1002, 0x9852, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
211 {0x1002, 0x9853, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
212 {0x1002, 0x9854, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
213 {0x1002, 0x9855, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
214 {0x1002, 0x9856, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
215 {0x1002, 0x9857, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
216 {0x1002, 0x9858, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
217 {0x1002, 0x9859, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
218 {0x1002, 0x985A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
219 {0x1002, 0x985B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
220 {0x1002, 0x985C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
221 {0x1002, 0x985D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
222 {0x1002, 0x985E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
223 {0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMDGPU_IS_MOBILITY|AMDGPU_IS_APU},
224#endif
225 /* topaz */
226 {0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
227 {0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
228 {0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
229 {0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
230 {0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
231 /* tonga */
232 {0x1002, 0x6920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
233 {0x1002, 0x6921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
234 {0x1002, 0x6928, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
235 {0x1002, 0x6929, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
236 {0x1002, 0x692B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
237 {0x1002, 0x692F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
238 {0x1002, 0x6930, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
239 {0x1002, 0x6938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
240 {0x1002, 0x6939, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
241 /* carrizo */
242 {0x1002, 0x9870, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CARRIZO|AMDGPU_IS_APU},
243 {0x1002, 0x9874, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CARRIZO|AMDGPU_IS_APU},
244 {0x1002, 0x9875, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CARRIZO|AMDGPU_IS_APU},
245 {0x1002, 0x9876, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CARRIZO|AMDGPU_IS_APU},
246 {0x1002, 0x9877, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CARRIZO|AMDGPU_IS_APU},
247
248 {0, 0, 0}
249};
250
251MODULE_DEVICE_TABLE(pci, pciidlist);
252
253static struct drm_driver kms_driver;
254
255static int amdgpu_kick_out_firmware_fb(struct pci_dev *pdev)
256{
257 struct apertures_struct *ap;
258 bool primary = false;
259
260 ap = alloc_apertures(1);
261 if (!ap)
262 return -ENOMEM;
263
264 ap->ranges[0].base = pci_resource_start(pdev, 0);
265 ap->ranges[0].size = pci_resource_len(pdev, 0);
266
267#ifdef CONFIG_X86
268 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
269#endif
270 remove_conflicting_framebuffers(ap, "amdgpudrmfb", primary);
271 kfree(ap);
272
273 return 0;
274}
275
276static int amdgpu_pci_probe(struct pci_dev *pdev,
277 const struct pci_device_id *ent)
278{
279 unsigned long flags = ent->driver_data;
280 int ret;
281
282 if ((flags & AMDGPU_EXP_HW_SUPPORT) && !amdgpu_exp_hw_support) {
283 DRM_INFO("This hardware requires experimental hardware support.\n"
284 "See modparam exp_hw_support\n");
285 return -ENODEV;
286 }
287
288 /* Get rid of things like offb */
289 ret = amdgpu_kick_out_firmware_fb(pdev);
290 if (ret)
291 return ret;
292
293 return drm_get_pci_dev(pdev, ent, &kms_driver);
294}
295
296static void
297amdgpu_pci_remove(struct pci_dev *pdev)
298{
299 struct drm_device *dev = pci_get_drvdata(pdev);
300
301 drm_put_dev(dev);
302}
303
304static int amdgpu_pmops_suspend(struct device *dev)
305{
306 struct pci_dev *pdev = to_pci_dev(dev);
307 struct drm_device *drm_dev = pci_get_drvdata(pdev);
308 return amdgpu_suspend_kms(drm_dev, true, true);
309}
310
311static int amdgpu_pmops_resume(struct device *dev)
312{
313 struct pci_dev *pdev = to_pci_dev(dev);
314 struct drm_device *drm_dev = pci_get_drvdata(pdev);
315 return amdgpu_resume_kms(drm_dev, true, true);
316}
317
318static int amdgpu_pmops_freeze(struct device *dev)
319{
320 struct pci_dev *pdev = to_pci_dev(dev);
321 struct drm_device *drm_dev = pci_get_drvdata(pdev);
322 return amdgpu_suspend_kms(drm_dev, false, true);
323}
324
325static int amdgpu_pmops_thaw(struct device *dev)
326{
327 struct pci_dev *pdev = to_pci_dev(dev);
328 struct drm_device *drm_dev = pci_get_drvdata(pdev);
329 return amdgpu_resume_kms(drm_dev, false, true);
330}
331
332static int amdgpu_pmops_runtime_suspend(struct device *dev)
333{
334 struct pci_dev *pdev = to_pci_dev(dev);
335 struct drm_device *drm_dev = pci_get_drvdata(pdev);
336 int ret;
337
338 if (!amdgpu_device_is_px(drm_dev)) {
339 pm_runtime_forbid(dev);
340 return -EBUSY;
341 }
342
343 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
344 drm_kms_helper_poll_disable(drm_dev);
345 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
346
347 ret = amdgpu_suspend_kms(drm_dev, false, false);
348 pci_save_state(pdev);
349 pci_disable_device(pdev);
350 pci_ignore_hotplug(pdev);
351 pci_set_power_state(pdev, PCI_D3cold);
352 drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
353
354 return 0;
355}
356
357static int amdgpu_pmops_runtime_resume(struct device *dev)
358{
359 struct pci_dev *pdev = to_pci_dev(dev);
360 struct drm_device *drm_dev = pci_get_drvdata(pdev);
361 int ret;
362
363 if (!amdgpu_device_is_px(drm_dev))
364 return -EINVAL;
365
366 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
367
368 pci_set_power_state(pdev, PCI_D0);
369 pci_restore_state(pdev);
370 ret = pci_enable_device(pdev);
371 if (ret)
372 return ret;
373 pci_set_master(pdev);
374
375 ret = amdgpu_resume_kms(drm_dev, false, false);
376 drm_kms_helper_poll_enable(drm_dev);
377 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
378 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
379 return 0;
380}
381
382static int amdgpu_pmops_runtime_idle(struct device *dev)
383{
384 struct pci_dev *pdev = to_pci_dev(dev);
385 struct drm_device *drm_dev = pci_get_drvdata(pdev);
386 struct drm_crtc *crtc;
387
388 if (!amdgpu_device_is_px(drm_dev)) {
389 pm_runtime_forbid(dev);
390 return -EBUSY;
391 }
392
393 list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
394 if (crtc->enabled) {
395 DRM_DEBUG_DRIVER("failing to power off - crtc active\n");
396 return -EBUSY;
397 }
398 }
399
400 pm_runtime_mark_last_busy(dev);
401 pm_runtime_autosuspend(dev);
402 /* we don't want the main rpm_idle to call suspend - we want to autosuspend */
403 return 1;
404}
405
406long amdgpu_drm_ioctl(struct file *filp,
407 unsigned int cmd, unsigned long arg)
408{
409 struct drm_file *file_priv = filp->private_data;
410 struct drm_device *dev;
411 long ret;
412 dev = file_priv->minor->dev;
413 ret = pm_runtime_get_sync(dev->dev);
414 if (ret < 0)
415 return ret;
416
417 ret = drm_ioctl(filp, cmd, arg);
418
419 pm_runtime_mark_last_busy(dev->dev);
420 pm_runtime_put_autosuspend(dev->dev);
421 return ret;
422}
423
424static const struct dev_pm_ops amdgpu_pm_ops = {
425 .suspend = amdgpu_pmops_suspend,
426 .resume = amdgpu_pmops_resume,
427 .freeze = amdgpu_pmops_freeze,
428 .thaw = amdgpu_pmops_thaw,
429 .poweroff = amdgpu_pmops_freeze,
430 .restore = amdgpu_pmops_resume,
431 .runtime_suspend = amdgpu_pmops_runtime_suspend,
432 .runtime_resume = amdgpu_pmops_runtime_resume,
433 .runtime_idle = amdgpu_pmops_runtime_idle,
434};
435
436static const struct file_operations amdgpu_driver_kms_fops = {
437 .owner = THIS_MODULE,
438 .open = drm_open,
439 .release = drm_release,
440 .unlocked_ioctl = amdgpu_drm_ioctl,
441 .mmap = amdgpu_mmap,
442 .poll = drm_poll,
443 .read = drm_read,
444#ifdef CONFIG_COMPAT
445 .compat_ioctl = amdgpu_kms_compat_ioctl,
446#endif
447};
448
449static struct drm_driver kms_driver = {
450 .driver_features =
451 DRIVER_USE_AGP |
452 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
453 DRIVER_PRIME | DRIVER_RENDER,
454 .dev_priv_size = 0,
455 .load = amdgpu_driver_load_kms,
456 .open = amdgpu_driver_open_kms,
457 .preclose = amdgpu_driver_preclose_kms,
458 .postclose = amdgpu_driver_postclose_kms,
459 .lastclose = amdgpu_driver_lastclose_kms,
460 .set_busid = drm_pci_set_busid,
461 .unload = amdgpu_driver_unload_kms,
462 .get_vblank_counter = amdgpu_get_vblank_counter_kms,
463 .enable_vblank = amdgpu_enable_vblank_kms,
464 .disable_vblank = amdgpu_disable_vblank_kms,
465 .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms,
466 .get_scanout_position = amdgpu_get_crtc_scanoutpos,
467#if defined(CONFIG_DEBUG_FS)
468 .debugfs_init = amdgpu_debugfs_init,
469 .debugfs_cleanup = amdgpu_debugfs_cleanup,
470#endif
471 .irq_preinstall = amdgpu_irq_preinstall,
472 .irq_postinstall = amdgpu_irq_postinstall,
473 .irq_uninstall = amdgpu_irq_uninstall,
474 .irq_handler = amdgpu_irq_handler,
475 .ioctls = amdgpu_ioctls_kms,
476 .gem_free_object = amdgpu_gem_object_free,
477 .gem_open_object = amdgpu_gem_object_open,
478 .gem_close_object = amdgpu_gem_object_close,
479 .dumb_create = amdgpu_mode_dumb_create,
480 .dumb_map_offset = amdgpu_mode_dumb_mmap,
481 .dumb_destroy = drm_gem_dumb_destroy,
482 .fops = &amdgpu_driver_kms_fops,
483
484 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
485 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
486 .gem_prime_export = amdgpu_gem_prime_export,
487 .gem_prime_import = drm_gem_prime_import,
488 .gem_prime_pin = amdgpu_gem_prime_pin,
489 .gem_prime_unpin = amdgpu_gem_prime_unpin,
490 .gem_prime_res_obj = amdgpu_gem_prime_res_obj,
491 .gem_prime_get_sg_table = amdgpu_gem_prime_get_sg_table,
492 .gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table,
493 .gem_prime_vmap = amdgpu_gem_prime_vmap,
494 .gem_prime_vunmap = amdgpu_gem_prime_vunmap,
495
496 .name = DRIVER_NAME,
497 .desc = DRIVER_DESC,
498 .date = DRIVER_DATE,
499 .major = KMS_DRIVER_MAJOR,
500 .minor = KMS_DRIVER_MINOR,
501 .patchlevel = KMS_DRIVER_PATCHLEVEL,
502};
503
504static struct drm_driver *driver;
505static struct pci_driver *pdriver;
506
507static struct pci_driver amdgpu_kms_pci_driver = {
508 .name = DRIVER_NAME,
509 .id_table = pciidlist,
510 .probe = amdgpu_pci_probe,
511 .remove = amdgpu_pci_remove,
512 .driver.pm = &amdgpu_pm_ops,
513};
514
515static int __init amdgpu_init(void)
516{
517#ifdef CONFIG_VGA_CONSOLE
518 if (vgacon_text_force()) {
519 DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n");
520 return -EINVAL;
521 }
522#endif
523 DRM_INFO("amdgpu kernel modesetting enabled.\n");
524 driver = &kms_driver;
525 pdriver = &amdgpu_kms_pci_driver;
526 driver->driver_features |= DRIVER_MODESET;
527 driver->num_ioctls = amdgpu_max_kms_ioctl;
528 amdgpu_register_atpx_handler();
529
530 /* let modprobe override vga console setting */
531 return drm_pci_init(driver, pdriver);
532}
533
534static void __exit amdgpu_exit(void)
535{
536 drm_pci_exit(driver, pdriver);
537 amdgpu_unregister_atpx_handler();
538}
539
540module_init(amdgpu_init);
541module_exit(amdgpu_exit);
542
543MODULE_AUTHOR(DRIVER_AUTHOR);
544MODULE_DESCRIPTION(DRIVER_DESC);
545MODULE_LICENSE("GPL and additional rights");
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h+48−0
@@ -0,0 +1,48 @@
1/* amdgpu_drv.h -- Private header for amdgpu driver -*- linux-c -*-
2 *
3 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28#ifndef __AMDGPU_DRV_H__
29#define __AMDGPU_DRV_H__
30
31#include <linux/firmware.h>
32#include <linux/platform_device.h>
33
34#include "amdgpu_family.h"
35
36/* General customization:
37 */
38
39#define DRIVER_AUTHOR "AMD linux driver team"
40
41#define DRIVER_NAME "amdgpu"
42#define DRIVER_DESC "AMD GPU"
43#define DRIVER_DATE "20150101"
44
45long amdgpu_drm_ioctl(struct file *filp,
46 unsigned int cmd, unsigned long arg);
47
48#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c+245−0
@@ -0,0 +1,245 @@
1/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
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: Dave Airlie
24 * Alex Deucher
25 */
26#include <drm/drmP.h>
27#include <drm/drm_crtc_helper.h>
28#include <drm/amdgpu_drm.h>
29#include "amdgpu.h"
30#include "amdgpu_connectors.h"
31#include "atom.h"
32#include "atombios_encoders.h"
33
34void
35amdgpu_link_encoder_connector(struct drm_device *dev)
36{
37 struct amdgpu_device *adev = dev->dev_private;
38 struct drm_connector *connector;
39 struct amdgpu_connector *amdgpu_connector;
40 struct drm_encoder *encoder;
41 struct amdgpu_encoder *amdgpu_encoder;
42
43 /* walk the list and link encoders to connectors */
44 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
45 amdgpu_connector = to_amdgpu_connector(connector);
46 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
47 amdgpu_encoder = to_amdgpu_encoder(encoder);
48 if (amdgpu_encoder->devices & amdgpu_connector->devices) {
49 drm_mode_connector_attach_encoder(connector, encoder);
50 if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
51 amdgpu_atombios_encoder_init_backlight(amdgpu_encoder, connector);
52 adev->mode_info.bl_encoder = amdgpu_encoder;
53 }
54 }
55 }
56 }
57}
58
59void amdgpu_encoder_set_active_device(struct drm_encoder *encoder)
60{
61 struct drm_device *dev = encoder->dev;
62 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
63 struct drm_connector *connector;
64
65 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
66 if (connector->encoder == encoder) {
67 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
68 amdgpu_encoder->active_device = amdgpu_encoder->devices & amdgpu_connector->devices;
69 DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
70 amdgpu_encoder->active_device, amdgpu_encoder->devices,
71 amdgpu_connector->devices, encoder->encoder_type);
72 }
73 }
74}
75
76struct drm_connector *
77amdgpu_get_connector_for_encoder(struct drm_encoder *encoder)
78{
79 struct drm_device *dev = encoder->dev;
80 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
81 struct drm_connector *connector;
82 struct amdgpu_connector *amdgpu_connector;
83
84 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
85 amdgpu_connector = to_amdgpu_connector(connector);
86 if (amdgpu_encoder->active_device & amdgpu_connector->devices)
87 return connector;
88 }
89 return NULL;
90}
91
92struct drm_connector *
93amdgpu_get_connector_for_encoder_init(struct drm_encoder *encoder)
94{
95 struct drm_device *dev = encoder->dev;
96 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
97 struct drm_connector *connector;
98 struct amdgpu_connector *amdgpu_connector;
99
100 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
101 amdgpu_connector = to_amdgpu_connector(connector);
102 if (amdgpu_encoder->devices & amdgpu_connector->devices)
103 return connector;
104 }
105 return NULL;
106}
107
108struct drm_encoder *amdgpu_get_external_encoder(struct drm_encoder *encoder)
109{
110 struct drm_device *dev = encoder->dev;
111 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
112 struct drm_encoder *other_encoder;
113 struct amdgpu_encoder *other_amdgpu_encoder;
114
115 if (amdgpu_encoder->is_ext_encoder)
116 return NULL;
117
118 list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
119 if (other_encoder == encoder)
120 continue;
121 other_amdgpu_encoder = to_amdgpu_encoder(other_encoder);
122 if (other_amdgpu_encoder->is_ext_encoder &&
123 (amdgpu_encoder->devices & other_amdgpu_encoder->devices))
124 return other_encoder;
125 }
126 return NULL;
127}
128
129u16 amdgpu_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
130{
131 struct drm_encoder *other_encoder = amdgpu_get_external_encoder(encoder);
132
133 if (other_encoder) {
134 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(other_encoder);
135
136 switch (amdgpu_encoder->encoder_id) {
137 case ENCODER_OBJECT_ID_TRAVIS:
138 case ENCODER_OBJECT_ID_NUTMEG:
139 return amdgpu_encoder->encoder_id;
140 default:
141 return ENCODER_OBJECT_ID_NONE;
142 }
143 }
144 return ENCODER_OBJECT_ID_NONE;
145}
146
147void amdgpu_panel_mode_fixup(struct drm_encoder *encoder,
148 struct drm_display_mode *adjusted_mode)
149{
150 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
151 struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;
152 unsigned hblank = native_mode->htotal - native_mode->hdisplay;
153 unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
154 unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
155 unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
156 unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
157 unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
158
159 adjusted_mode->clock = native_mode->clock;
160 adjusted_mode->flags = native_mode->flags;
161
162 adjusted_mode->hdisplay = native_mode->hdisplay;
163 adjusted_mode->vdisplay = native_mode->vdisplay;
164
165 adjusted_mode->htotal = native_mode->hdisplay + hblank;
166 adjusted_mode->hsync_start = native_mode->hdisplay + hover;
167 adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
168
169 adjusted_mode->vtotal = native_mode->vdisplay + vblank;
170 adjusted_mode->vsync_start = native_mode->vdisplay + vover;
171 adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
172
173 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
174
175 adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
176 adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
177
178 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
179 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
180 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
181
182 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
183 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
184 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
185
186}
187
188bool amdgpu_dig_monitor_is_duallink(struct drm_encoder *encoder,
189 u32 pixel_clock)
190{
191 struct drm_connector *connector;
192 struct amdgpu_connector *amdgpu_connector;
193 struct amdgpu_connector_atom_dig *dig_connector;
194
195 connector = amdgpu_get_connector_for_encoder(encoder);
196 /* if we don't have an active device yet, just use one of
197 * the connectors tied to the encoder.
198 */
199 if (!connector)
200 connector = amdgpu_get_connector_for_encoder_init(encoder);
201 amdgpu_connector = to_amdgpu_connector(connector);
202
203 switch (connector->connector_type) {
204 case DRM_MODE_CONNECTOR_DVII:
205 case DRM_MODE_CONNECTOR_HDMIB:
206 if (amdgpu_connector->use_digital) {
207 /* HDMI 1.3 supports up to 340 Mhz over single link */
208 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
209 if (pixel_clock > 340000)
210 return true;
211 else
212 return false;
213 } else {
214 if (pixel_clock > 165000)
215 return true;
216 else
217 return false;
218 }
219 } else
220 return false;
221 case DRM_MODE_CONNECTOR_DVID:
222 case DRM_MODE_CONNECTOR_HDMIA:
223 case DRM_MODE_CONNECTOR_DisplayPort:
224 dig_connector = amdgpu_connector->con_priv;
225 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
226 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
227 return false;
228 else {
229 /* HDMI 1.3 supports up to 340 Mhz over single link */
230 if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
231 if (pixel_clock > 340000)
232 return true;
233 else
234 return false;
235 } else {
236 if (pixel_clock > 165000)
237 return true;
238 else
239 return false;
240 }
241 }
242 default:
243 return false;
244 }
245}
drivers/gpu/drm/amd/amdgpu/amdgpu_family.h+62−0
@@ -0,0 +1,62 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28
29/* this file defines the CHIP_ and family flags used in the pciids,
30 * its is common between kms and non-kms because duplicating it and
31 * changing one place is fail.
32 */
33#ifndef AMDGPU_FAMILY_H
34#define AMDGPU_FAMILY_H
35/*
36 * Supported ASIC types
37 */
38enum amdgpu_asic_type {
39 CHIP_BONAIRE = 0,
40 CHIP_KAVERI,
41 CHIP_KABINI,
42 CHIP_HAWAII,
43 CHIP_MULLINS,
44 CHIP_TOPAZ,
45 CHIP_TONGA,
46 CHIP_CARRIZO,
47 CHIP_LAST,
48};
49
50/*
51 * Chip flags
52 */
53enum amdgpu_chip_flags {
54 AMDGPU_ASIC_MASK = 0x0000ffffUL,
55 AMDGPU_FLAGS_MASK = 0xffff0000UL,
56 AMDGPU_IS_MOBILITY = 0x00010000UL,
57 AMDGPU_IS_APU = 0x00020000UL,
58 AMDGPU_IS_PX = 0x00040000UL,
59 AMDGPU_EXP_HW_SUPPORT = 0x00080000UL,
60};
61
62#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c+421−0
@@ -0,0 +1,421 @@
1/*
2 * Copyright © 2007 David Airlie
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 (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * David Airlie
25 */
26#include <linux/module.h>
27#include <linux/slab.h>
28#include <linux/fb.h>
29
30#include <drm/drmP.h>
31#include <drm/drm_crtc.h>
32#include <drm/drm_crtc_helper.h>
33#include <drm/amdgpu_drm.h>
34#include "amdgpu.h"
35#include "cikd.h"
36
37#include <drm/drm_fb_helper.h>
38
39#include <linux/vga_switcheroo.h>
40
41/* object hierarchy -
42 this contains a helper + a amdgpu fb
43 the helper contains a pointer to amdgpu framebuffer baseclass.
44*/
45struct amdgpu_fbdev {
46 struct drm_fb_helper helper;
47 struct amdgpu_framebuffer rfb;
48 struct list_head fbdev_list;
49 struct amdgpu_device *adev;
50};
51
52static struct fb_ops amdgpufb_ops = {
53 .owner = THIS_MODULE,
54 .fb_check_var = drm_fb_helper_check_var,
55 .fb_set_par = drm_fb_helper_set_par,
56 .fb_fillrect = cfb_fillrect,
57 .fb_copyarea = cfb_copyarea,
58 .fb_imageblit = cfb_imageblit,
59 .fb_pan_display = drm_fb_helper_pan_display,
60 .fb_blank = drm_fb_helper_blank,
61 .fb_setcmap = drm_fb_helper_setcmap,
62 .fb_debug_enter = drm_fb_helper_debug_enter,
63 .fb_debug_leave = drm_fb_helper_debug_leave,
64};
65
66
67int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tiled)
68{
69 int aligned = width;
70 int pitch_mask = 0;
71
72 switch (bpp / 8) {
73 case 1:
74 pitch_mask = 255;
75 break;
76 case 2:
77 pitch_mask = 127;
78 break;
79 case 3:
80 case 4:
81 pitch_mask = 63;
82 break;
83 }
84
85 aligned += pitch_mask;
86 aligned &= ~pitch_mask;
87 return aligned;
88}
89
90static void amdgpufb_destroy_pinned_object(struct drm_gem_object *gobj)
91{
92 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(gobj);
93 int ret;
94
95 ret = amdgpu_bo_reserve(rbo, false);
96 if (likely(ret == 0)) {
97 amdgpu_bo_kunmap(rbo);
98 amdgpu_bo_unpin(rbo);
99 amdgpu_bo_unreserve(rbo);
100 }
101 drm_gem_object_unreference_unlocked(gobj);
102}
103
104static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
105 struct drm_mode_fb_cmd2 *mode_cmd,
106 struct drm_gem_object **gobj_p)
107{
108 struct amdgpu_device *adev = rfbdev->adev;
109 struct drm_gem_object *gobj = NULL;
110 struct amdgpu_bo *rbo = NULL;
111 bool fb_tiled = false; /* useful for testing */
112 u32 tiling_flags = 0;
113 int ret;
114 int aligned_size, size;
115 int height = mode_cmd->height;
116 u32 bpp, depth;
117
118 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
119
120 /* need to align pitch with crtc limits */
121 mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, bpp,
122 fb_tiled) * ((bpp + 1) / 8);
123
124 height = ALIGN(mode_cmd->height, 8);
125 size = mode_cmd->pitches[0] * height;
126 aligned_size = ALIGN(size, PAGE_SIZE);
127 ret = amdgpu_gem_object_create(adev, aligned_size, 0,
128 AMDGPU_GEM_DOMAIN_VRAM,
129 0, true,
130 &gobj);
131 if (ret) {
132 printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
133 aligned_size);
134 return -ENOMEM;
135 }
136 rbo = gem_to_amdgpu_bo(gobj);
137
138 if (fb_tiled)
139 tiling_flags = AMDGPU_TILING_SET(ARRAY_MODE, GRPH_ARRAY_2D_TILED_THIN1);
140
141 ret = amdgpu_bo_reserve(rbo, false);
142 if (unlikely(ret != 0))
143 goto out_unref;
144
145 if (tiling_flags) {
146 ret = amdgpu_bo_set_tiling_flags(rbo,
147 tiling_flags);
148 if (ret)
149 dev_err(adev->dev, "FB failed to set tiling flags\n");
150 }
151
152
153 ret = amdgpu_bo_pin_restricted(rbo, AMDGPU_GEM_DOMAIN_VRAM, 0, 0, NULL);
154 if (ret) {
155 amdgpu_bo_unreserve(rbo);
156 goto out_unref;
157 }
158 ret = amdgpu_bo_kmap(rbo, NULL);
159 amdgpu_bo_unreserve(rbo);
160 if (ret) {
161 goto out_unref;
162 }
163
164 *gobj_p = gobj;
165 return 0;
166out_unref:
167 amdgpufb_destroy_pinned_object(gobj);
168 *gobj_p = NULL;
169 return ret;
170}
171
172static int amdgpufb_create(struct drm_fb_helper *helper,
173 struct drm_fb_helper_surface_size *sizes)
174{
175 struct amdgpu_fbdev *rfbdev = (struct amdgpu_fbdev *)helper;
176 struct amdgpu_device *adev = rfbdev->adev;
177 struct fb_info *info;
178 struct drm_framebuffer *fb = NULL;
179 struct drm_mode_fb_cmd2 mode_cmd;
180 struct drm_gem_object *gobj = NULL;
181 struct amdgpu_bo *rbo = NULL;
182 struct device *device = &adev->pdev->dev;
183 int ret;
184 unsigned long tmp;
185
186 mode_cmd.width = sizes->surface_width;
187 mode_cmd.height = sizes->surface_height;
188
189 if (sizes->surface_bpp == 24)
190 sizes->surface_bpp = 32;
191
192 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
193 sizes->surface_depth);
194
195 ret = amdgpufb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
196 if (ret) {
197 DRM_ERROR("failed to create fbcon object %d\n", ret);
198 return ret;
199 }
200
201 rbo = gem_to_amdgpu_bo(gobj);
202
203 /* okay we have an object now allocate the framebuffer */
204 info = framebuffer_alloc(0, device);
205 if (info == NULL) {
206 ret = -ENOMEM;
207 goto out_unref;
208 }
209
210 info->par = rfbdev;
211
212 ret = amdgpu_framebuffer_init(adev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
213 if (ret) {
214 DRM_ERROR("failed to initialize framebuffer %d\n", ret);
215 goto out_unref;
216 }
217
218 fb = &rfbdev->rfb.base;
219
220 /* setup helper */
221 rfbdev->helper.fb = fb;
222 rfbdev->helper.fbdev = info;
223
224 memset_io(rbo->kptr, 0x0, amdgpu_bo_size(rbo));
225
226 strcpy(info->fix.id, "amdgpudrmfb");
227
228 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
229
230 info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
231 info->fbops = &amdgpufb_ops;
232
233 tmp = amdgpu_bo_gpu_offset(rbo) - adev->mc.vram_start;
234 info->fix.smem_start = adev->mc.aper_base + tmp;
235 info->fix.smem_len = amdgpu_bo_size(rbo);
236 info->screen_base = rbo->kptr;
237 info->screen_size = amdgpu_bo_size(rbo);
238
239 drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
240
241 /* setup aperture base/size for vesafb takeover */
242 info->apertures = alloc_apertures(1);
243 if (!info->apertures) {
244 ret = -ENOMEM;
245 goto out_unref;
246 }
247 info->apertures->ranges[0].base = adev->ddev->mode_config.fb_base;
248 info->apertures->ranges[0].size = adev->mc.aper_size;
249
250 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
251
252 if (info->screen_base == NULL) {
253 ret = -ENOSPC;
254 goto out_unref;
255 }
256
257 ret = fb_alloc_cmap(&info->cmap, 256, 0);
258 if (ret) {
259 ret = -ENOMEM;
260 goto out_unref;
261 }
262
263 DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start);
264 DRM_INFO("vram apper at 0x%lX\n", (unsigned long)adev->mc.aper_base);
265 DRM_INFO("size %lu\n", (unsigned long)amdgpu_bo_size(rbo));
266 DRM_INFO("fb depth is %d\n", fb->depth);
267 DRM_INFO(" pitch is %d\n", fb->pitches[0]);
268
269 vga_switcheroo_client_fb_set(adev->ddev->pdev, info);
270 return 0;
271
272out_unref:
273 if (rbo) {
274
275 }
276 if (fb && ret) {
277 drm_gem_object_unreference(gobj);
278 drm_framebuffer_unregister_private(fb);
279 drm_framebuffer_cleanup(fb);
280 kfree(fb);
281 }
282 return ret;
283}
284
285void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev)
286{
287 if (adev->mode_info.rfbdev)
288 drm_fb_helper_hotplug_event(&adev->mode_info.rfbdev->helper);
289}
290
291static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfbdev)
292{
293 struct fb_info *info;
294 struct amdgpu_framebuffer *rfb = &rfbdev->rfb;
295
296 if (rfbdev->helper.fbdev) {
297 info = rfbdev->helper.fbdev;
298
299 unregister_framebuffer(info);
300 if (info->cmap.len)
301 fb_dealloc_cmap(&info->cmap);
302 framebuffer_release(info);
303 }
304
305 if (rfb->obj) {
306 amdgpufb_destroy_pinned_object(rfb->obj);
307 rfb->obj = NULL;
308 }
309 drm_fb_helper_fini(&rfbdev->helper);
310 drm_framebuffer_unregister_private(&rfb->base);
311 drm_framebuffer_cleanup(&rfb->base);
312
313 return 0;
314}
315
316/** Sets the color ramps on behalf of fbcon */
317static void amdgpu_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
318 u16 blue, int regno)
319{
320 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
321
322 amdgpu_crtc->lut_r[regno] = red >> 6;
323 amdgpu_crtc->lut_g[regno] = green >> 6;
324 amdgpu_crtc->lut_b[regno] = blue >> 6;
325}
326
327/** Gets the color ramps on behalf of fbcon */
328static void amdgpu_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
329 u16 *blue, int regno)
330{
331 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
332
333 *red = amdgpu_crtc->lut_r[regno] << 6;
334 *green = amdgpu_crtc->lut_g[regno] << 6;
335 *blue = amdgpu_crtc->lut_b[regno] << 6;
336}
337
338static const struct drm_fb_helper_funcs amdgpu_fb_helper_funcs = {
339 .gamma_set = amdgpu_crtc_fb_gamma_set,
340 .gamma_get = amdgpu_crtc_fb_gamma_get,
341 .fb_probe = amdgpufb_create,
342};
343
344int amdgpu_fbdev_init(struct amdgpu_device *adev)
345{
346 struct amdgpu_fbdev *rfbdev;
347 int bpp_sel = 32;
348 int ret;
349
350 /* don't init fbdev on hw without DCE */
351 if (!adev->mode_info.mode_config_initialized)
352 return 0;
353
354 /* select 8 bpp console on low vram cards */
355 if (adev->mc.real_vram_size <= (32*1024*1024))
356 bpp_sel = 8;
357
358 rfbdev = kzalloc(sizeof(struct amdgpu_fbdev), GFP_KERNEL);
359 if (!rfbdev)
360 return -ENOMEM;
361
362 rfbdev->adev = adev;
363 adev->mode_info.rfbdev = rfbdev;
364
365 drm_fb_helper_prepare(adev->ddev, &rfbdev->helper,
366 &amdgpu_fb_helper_funcs);
367
368 ret = drm_fb_helper_init(adev->ddev, &rfbdev->helper,
369 adev->mode_info.num_crtc,
370 AMDGPUFB_CONN_LIMIT);
371 if (ret) {
372 kfree(rfbdev);
373 return ret;
374 }
375
376 drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
377
378 /* disable all the possible outputs/crtcs before entering KMS mode */
379 drm_helper_disable_unused_functions(adev->ddev);
380
381 drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
382 return 0;
383}
384
385void amdgpu_fbdev_fini(struct amdgpu_device *adev)
386{
387 if (!adev->mode_info.rfbdev)
388 return;
389
390 amdgpu_fbdev_destroy(adev->ddev, adev->mode_info.rfbdev);
391 kfree(adev->mode_info.rfbdev);
392 adev->mode_info.rfbdev = NULL;
393}
394
395void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state)
396{
397 if (adev->mode_info.rfbdev)
398 fb_set_suspend(adev->mode_info.rfbdev->helper.fbdev, state);
399}
400
401int amdgpu_fbdev_total_size(struct amdgpu_device *adev)
402{
403 struct amdgpu_bo *robj;
404 int size = 0;
405
406 if (!adev->mode_info.rfbdev)
407 return 0;
408
409 robj = gem_to_amdgpu_bo(adev->mode_info.rfbdev->rfb.obj);
410 size += amdgpu_bo_size(robj);
411 return size;
412}
413
414bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
415{
416 if (!adev->mode_info.rfbdev)
417 return false;
418 if (robj == gem_to_amdgpu_bo(adev->mode_info.rfbdev->rfb.obj))
419 return true;
420 return false;
421}
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c+1133−0
@@ -0,0 +1,1133 @@
1/*
2 * Copyright 2009 Jerome Glisse.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 *
25 */
26/*
27 * Authors:
28 * Jerome Glisse <glisse@freedesktop.org>
29 * Dave Airlie
30 */
31#include <linux/seq_file.h>
32#include <linux/atomic.h>
33#include <linux/wait.h>
34#include <linux/kref.h>
35#include <linux/slab.h>
36#include <linux/firmware.h>
37#include <drm/drmP.h>
38#include "amdgpu.h"
39#include "amdgpu_trace.h"
40
41/*
42 * Fences
43 * Fences mark an event in the GPUs pipeline and are used
44 * for GPU/CPU synchronization. When the fence is written,
45 * it is expected that all buffers associated with that fence
46 * are no longer in use by the associated ring on the GPU and
47 * that the the relevant GPU caches have been flushed.
48 */
49
50/**
51 * amdgpu_fence_write - write a fence value
52 *
53 * @ring: ring the fence is associated with
54 * @seq: sequence number to write
55 *
56 * Writes a fence value to memory (all asics).
57 */
58static void amdgpu_fence_write(struct amdgpu_ring *ring, u32 seq)
59{
60 struct amdgpu_fence_driver *drv = &ring->fence_drv;
61
62 if (drv->cpu_addr)
63 *drv->cpu_addr = cpu_to_le32(seq);
64}
65
66/**
67 * amdgpu_fence_read - read a fence value
68 *
69 * @ring: ring the fence is associated with
70 *
71 * Reads a fence value from memory (all asics).
72 * Returns the value of the fence read from memory.
73 */
74static u32 amdgpu_fence_read(struct amdgpu_ring *ring)
75{
76 struct amdgpu_fence_driver *drv = &ring->fence_drv;
77 u32 seq = 0;
78
79 if (drv->cpu_addr)
80 seq = le32_to_cpu(*drv->cpu_addr);
81 else
82 seq = lower_32_bits(atomic64_read(&drv->last_seq));
83
84 return seq;
85}
86
87/**
88 * amdgpu_fence_schedule_check - schedule lockup check
89 *
90 * @ring: pointer to struct amdgpu_ring
91 *
92 * Queues a delayed work item to check for lockups.
93 */
94static void amdgpu_fence_schedule_check(struct amdgpu_ring *ring)
95{
96 /*
97 * Do not reset the timer here with mod_delayed_work,
98 * this can livelock in an interaction with TTM delayed destroy.
99 */
100 queue_delayed_work(system_power_efficient_wq,
101 &ring->fence_drv.lockup_work,
102 AMDGPU_FENCE_JIFFIES_TIMEOUT);
103}
104
105/**
106 * amdgpu_fence_emit - emit a fence on the requested ring
107 *
108 * @ring: ring the fence is associated with
109 * @owner: creator of the fence
110 * @fence: amdgpu fence object
111 *
112 * Emits a fence command on the requested ring (all asics).
113 * Returns 0 on success, -ENOMEM on failure.
114 */
115int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,
116 struct amdgpu_fence **fence)
117{
118 struct amdgpu_device *adev = ring->adev;
119
120 /* we are protected by the ring emission mutex */
121 *fence = kmalloc(sizeof(struct amdgpu_fence), GFP_KERNEL);
122 if ((*fence) == NULL) {
123 return -ENOMEM;
124 }
125 (*fence)->seq = ++ring->fence_drv.sync_seq[ring->idx];
126 (*fence)->ring = ring;
127 (*fence)->owner = owner;
128 fence_init(&(*fence)->base, &amdgpu_fence_ops,
129 &adev->fence_queue.lock, adev->fence_context + ring->idx,
130 (*fence)->seq);
131 amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
132 (*fence)->seq,
133 AMDGPU_FENCE_FLAG_INT);
134 trace_amdgpu_fence_emit(ring->adev->ddev, ring->idx, (*fence)->seq);
135 return 0;
136}
137
138/**
139 * amdgpu_fence_check_signaled - callback from fence_queue
140 *
141 * this function is called with fence_queue lock held, which is also used
142 * for the fence locking itself, so unlocked variants are used for
143 * fence_signal, and remove_wait_queue.
144 */
145static int amdgpu_fence_check_signaled(wait_queue_t *wait, unsigned mode, int flags, void *key)
146{
147 struct amdgpu_fence *fence;
148 struct amdgpu_device *adev;
149 u64 seq;
150 int ret;
151
152 fence = container_of(wait, struct amdgpu_fence, fence_wake);
153 adev = fence->ring->adev;
154
155 /*
156 * We cannot use amdgpu_fence_process here because we're already
157 * in the waitqueue, in a call from wake_up_all.
158 */
159 seq = atomic64_read(&fence->ring->fence_drv.last_seq);
160 if (seq >= fence->seq) {
161 ret = fence_signal_locked(&fence->base);
162 if (!ret)
163 FENCE_TRACE(&fence->base, "signaled from irq context\n");
164 else
165 FENCE_TRACE(&fence->base, "was already signaled\n");
166
167 amdgpu_irq_put(adev, fence->ring->fence_drv.irq_src,
168 fence->ring->fence_drv.irq_type);
169 __remove_wait_queue(&adev->fence_queue, &fence->fence_wake);
170 fence_put(&fence->base);
171 } else
172 FENCE_TRACE(&fence->base, "pending\n");
173 return 0;
174}
175
176/**
177 * amdgpu_fence_activity - check for fence activity
178 *
179 * @ring: pointer to struct amdgpu_ring
180 *
181 * Checks the current fence value and calculates the last
182 * signalled fence value. Returns true if activity occured
183 * on the ring, and the fence_queue should be waken up.
184 */
185static bool amdgpu_fence_activity(struct amdgpu_ring *ring)
186{
187 uint64_t seq, last_seq, last_emitted;
188 unsigned count_loop = 0;
189 bool wake = false;
190
191 /* Note there is a scenario here for an infinite loop but it's
192 * very unlikely to happen. For it to happen, the current polling
193 * process need to be interrupted by another process and another
194 * process needs to update the last_seq btw the atomic read and
195 * xchg of the current process.
196 *
197 * More over for this to go in infinite loop there need to be
198 * continuously new fence signaled ie amdgpu_fence_read needs
199 * to return a different value each time for both the currently
200 * polling process and the other process that xchg the last_seq
201 * btw atomic read and xchg of the current process. And the
202 * value the other process set as last seq must be higher than
203 * the seq value we just read. Which means that current process
204 * need to be interrupted after amdgpu_fence_read and before
205 * atomic xchg.
206 *
207 * To be even more safe we count the number of time we loop and
208 * we bail after 10 loop just accepting the fact that we might
209 * have temporarly set the last_seq not to the true real last
210 * seq but to an older one.
211 */
212 last_seq = atomic64_read(&ring->fence_drv.last_seq);
213 do {
214 last_emitted = ring->fence_drv.sync_seq[ring->idx];
215 seq = amdgpu_fence_read(ring);
216 seq |= last_seq & 0xffffffff00000000LL;
217 if (seq < last_seq) {
218 seq &= 0xffffffff;
219 seq |= last_emitted & 0xffffffff00000000LL;
220 }
221
222 if (seq <= last_seq || seq > last_emitted) {
223 break;
224 }
225 /* If we loop over we don't want to return without
226 * checking if a fence is signaled as it means that the
227 * seq we just read is different from the previous on.
228 */
229 wake = true;
230 last_seq = seq;
231 if ((count_loop++) > 10) {
232 /* We looped over too many time leave with the
233 * fact that we might have set an older fence
234 * seq then the current real last seq as signaled
235 * by the hw.
236 */
237 break;
238 }
239 } while (atomic64_xchg(&ring->fence_drv.last_seq, seq) > seq);
240
241 if (seq < last_emitted)
242 amdgpu_fence_schedule_check(ring);
243
244 return wake;
245}
246
247/**
248 * amdgpu_fence_check_lockup - check for hardware lockup
249 *
250 * @work: delayed work item
251 *
252 * Checks for fence activity and if there is none probe
253 * the hardware if a lockup occured.
254 */
255static void amdgpu_fence_check_lockup(struct work_struct *work)
256{
257 struct amdgpu_fence_driver *fence_drv;
258 struct amdgpu_ring *ring;
259
260 fence_drv = container_of(work, struct amdgpu_fence_driver,
261 lockup_work.work);
262 ring = fence_drv->ring;
263
264 if (!down_read_trylock(&ring->adev->exclusive_lock)) {
265 /* just reschedule the check if a reset is going on */
266 amdgpu_fence_schedule_check(ring);
267 return;
268 }
269
270 if (fence_drv->delayed_irq && ring->adev->ddev->irq_enabled) {
271 fence_drv->delayed_irq = false;
272 amdgpu_irq_update(ring->adev, fence_drv->irq_src,
273 fence_drv->irq_type);
274 }
275
276 if (amdgpu_fence_activity(ring))
277 wake_up_all(&ring->adev->fence_queue);
278 else if (amdgpu_ring_is_lockup(ring)) {
279 /* good news we believe it's a lockup */
280 dev_warn(ring->adev->dev, "GPU lockup (current fence id "
281 "0x%016llx last fence id 0x%016llx on ring %d)\n",
282 (uint64_t)atomic64_read(&fence_drv->last_seq),
283 fence_drv->sync_seq[ring->idx], ring->idx);
284
285 /* remember that we need an reset */
286 ring->adev->needs_reset = true;
287 wake_up_all(&ring->adev->fence_queue);
288 }
289 up_read(&ring->adev->exclusive_lock);
290}
291
292/**
293 * amdgpu_fence_process - process a fence
294 *
295 * @adev: amdgpu_device pointer
296 * @ring: ring index the fence is associated with
297 *
298 * Checks the current fence value and wakes the fence queue
299 * if the sequence number has increased (all asics).
300 */
301void amdgpu_fence_process(struct amdgpu_ring *ring)
302{
303 uint64_t seq, last_seq, last_emitted;
304 unsigned count_loop = 0;
305 bool wake = false;
306
307 /* Note there is a scenario here for an infinite loop but it's
308 * very unlikely to happen. For it to happen, the current polling
309 * process need to be interrupted by another process and another
310 * process needs to update the last_seq btw the atomic read and
311 * xchg of the current process.
312 *
313 * More over for this to go in infinite loop there need to be
314 * continuously new fence signaled ie amdgpu_fence_read needs
315 * to return a different value each time for both the currently
316 * polling process and the other process that xchg the last_seq
317 * btw atomic read and xchg of the current process. And the
318 * value the other process set as last seq must be higher than
319 * the seq value we just read. Which means that current process
320 * need to be interrupted after amdgpu_fence_read and before
321 * atomic xchg.
322 *
323 * To be even more safe we count the number of time we loop and
324 * we bail after 10 loop just accepting the fact that we might
325 * have temporarly set the last_seq not to the true real last
326 * seq but to an older one.
327 */
328 last_seq = atomic64_read(&ring->fence_drv.last_seq);
329 do {
330 last_emitted = ring->fence_drv.sync_seq[ring->idx];
331 seq = amdgpu_fence_read(ring);
332 seq |= last_seq & 0xffffffff00000000LL;
333 if (seq < last_seq) {
334 seq &= 0xffffffff;
335 seq |= last_emitted & 0xffffffff00000000LL;
336 }
337
338 if (seq <= last_seq || seq > last_emitted) {
339 break;
340 }
341 /* If we loop over we don't want to return without
342 * checking if a fence is signaled as it means that the
343 * seq we just read is different from the previous on.
344 */
345 wake = true;
346 last_seq = seq;
347 if ((count_loop++) > 10) {
348 /* We looped over too many time leave with the
349 * fact that we might have set an older fence
350 * seq then the current real last seq as signaled
351 * by the hw.
352 */
353 break;
354 }
355 } while (atomic64_xchg(&ring->fence_drv.last_seq, seq) > seq);
356
357 if (wake)
358 wake_up_all(&ring->adev->fence_queue);
359}
360
361/**
362 * amdgpu_fence_seq_signaled - check if a fence sequence number has signaled
363 *
364 * @ring: ring the fence is associated with
365 * @seq: sequence number
366 *
367 * Check if the last signaled fence sequnce number is >= the requested
368 * sequence number (all asics).
369 * Returns true if the fence has signaled (current fence value
370 * is >= requested value) or false if it has not (current fence
371 * value is < the requested value. Helper function for
372 * amdgpu_fence_signaled().
373 */
374static bool amdgpu_fence_seq_signaled(struct amdgpu_ring *ring, u64 seq)
375{
376 if (atomic64_read(&ring->fence_drv.last_seq) >= seq)
377 return true;
378
379 /* poll new last sequence at least once */
380 amdgpu_fence_process(ring);
381 if (atomic64_read(&ring->fence_drv.last_seq) >= seq)
382 return true;
383
384 return false;
385}
386
387static bool amdgpu_fence_is_signaled(struct fence *f)
388{
389 struct amdgpu_fence *fence = to_amdgpu_fence(f);
390 struct amdgpu_ring *ring = fence->ring;
391 struct amdgpu_device *adev = ring->adev;
392
393 if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq)
394 return true;
395
396 if (down_read_trylock(&adev->exclusive_lock)) {
397 amdgpu_fence_process(ring);
398 up_read(&adev->exclusive_lock);
399
400 if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq)
401 return true;
402 }
403 return false;
404}
405
406/**
407 * amdgpu_fence_enable_signaling - enable signalling on fence
408 * @fence: fence
409 *
410 * This function is called with fence_queue lock held, and adds a callback
411 * to fence_queue that checks if this fence is signaled, and if so it
412 * signals the fence and removes itself.
413 */
414static bool amdgpu_fence_enable_signaling(struct fence *f)
415{
416 struct amdgpu_fence *fence = to_amdgpu_fence(f);
417 struct amdgpu_ring *ring = fence->ring;
418 struct amdgpu_device *adev = ring->adev;
419
420 if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq)
421 return false;
422
423 if (down_read_trylock(&adev->exclusive_lock)) {
424 amdgpu_irq_get(adev, ring->fence_drv.irq_src,
425 ring->fence_drv.irq_type);
426 if (amdgpu_fence_activity(ring))
427 wake_up_all_locked(&adev->fence_queue);
428
429 /* did fence get signaled after we enabled the sw irq? */
430 if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq) {
431 amdgpu_irq_put(adev, ring->fence_drv.irq_src,
432 ring->fence_drv.irq_type);
433 up_read(&adev->exclusive_lock);
434 return false;
435 }
436
437 up_read(&adev->exclusive_lock);
438 } else {
439 /* we're probably in a lockup, lets not fiddle too much */
440 if (amdgpu_irq_get_delayed(adev, ring->fence_drv.irq_src,
441 ring->fence_drv.irq_type))
442 ring->fence_drv.delayed_irq = true;
443 amdgpu_fence_schedule_check(ring);
444 }
445
446 fence->fence_wake.flags = 0;
447 fence->fence_wake.private = NULL;
448 fence->fence_wake.func = amdgpu_fence_check_signaled;
449 __add_wait_queue(&adev->fence_queue, &fence->fence_wake);
450 fence_get(f);
451 FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx);
452 return true;
453}
454
455/**
456 * amdgpu_fence_signaled - check if a fence has signaled
457 *
458 * @fence: amdgpu fence object
459 *
460 * Check if the requested fence has signaled (all asics).
461 * Returns true if the fence has signaled or false if it has not.
462 */
463bool amdgpu_fence_signaled(struct amdgpu_fence *fence)
464{
465 if (!fence)
466 return true;
467
468 if (amdgpu_fence_seq_signaled(fence->ring, fence->seq)) {
469 if (!fence_signal(&fence->base))
470 FENCE_TRACE(&fence->base, "signaled from amdgpu_fence_signaled\n");
471 return true;
472 }
473
474 return false;
475}
476
477/**
478 * amdgpu_fence_any_seq_signaled - check if any sequence number is signaled
479 *
480 * @adev: amdgpu device pointer
481 * @seq: sequence numbers
482 *
483 * Check if the last signaled fence sequnce number is >= the requested
484 * sequence number (all asics).
485 * Returns true if any has signaled (current value is >= requested value)
486 * or false if it has not. Helper function for amdgpu_fence_wait_seq.
487 */
488static bool amdgpu_fence_any_seq_signaled(struct amdgpu_device *adev, u64 *seq)
489{
490 unsigned i;
491
492 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
493 if (!adev->rings[i] || !seq[i])
494 continue;
495
496 if (amdgpu_fence_seq_signaled(adev->rings[i], seq[i]))
497 return true;
498 }
499
500 return false;
501}
502
503/**
504 * amdgpu_fence_wait_seq_timeout - wait for a specific sequence numbers
505 *
506 * @adev: amdgpu device pointer
507 * @target_seq: sequence number(s) we want to wait for
508 * @intr: use interruptable sleep
509 * @timeout: maximum time to wait, or MAX_SCHEDULE_TIMEOUT for infinite wait
510 *
511 * Wait for the requested sequence number(s) to be written by any ring
512 * (all asics). Sequnce number array is indexed by ring id.
513 * @intr selects whether to use interruptable (true) or non-interruptable
514 * (false) sleep when waiting for the sequence number. Helper function
515 * for amdgpu_fence_wait_*().
516 * Returns remaining time if the sequence number has passed, 0 when
517 * the wait timeout, or an error for all other cases.
518 * -EDEADLK is returned when a GPU lockup has been detected.
519 */
520long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev, u64 *target_seq,
521 bool intr, long timeout)
522{
523 uint64_t last_seq[AMDGPU_MAX_RINGS];
524 bool signaled;
525 int i, r;
526
527 if (timeout == 0) {
528 return amdgpu_fence_any_seq_signaled(adev, target_seq);
529 }
530
531 while (!amdgpu_fence_any_seq_signaled(adev, target_seq)) {
532
533 /* Save current sequence values, used to check for GPU lockups */
534 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
535 struct amdgpu_ring *ring = adev->rings[i];
536
537 if (!ring || !target_seq[i])
538 continue;
539
540 last_seq[i] = atomic64_read(&ring->fence_drv.last_seq);
541 trace_amdgpu_fence_wait_begin(adev->ddev, i, target_seq[i]);
542 amdgpu_irq_get(adev, ring->fence_drv.irq_src,
543 ring->fence_drv.irq_type);
544 }
545
546 if (intr) {
547 r = wait_event_interruptible_timeout(adev->fence_queue, (
548 (signaled = amdgpu_fence_any_seq_signaled(adev, target_seq))
549 || adev->needs_reset), AMDGPU_FENCE_JIFFIES_TIMEOUT);
550 } else {
551 r = wait_event_timeout(adev->fence_queue, (
552 (signaled = amdgpu_fence_any_seq_signaled(adev, target_seq))
553 || adev->needs_reset), AMDGPU_FENCE_JIFFIES_TIMEOUT);
554 }
555
556 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
557 struct amdgpu_ring *ring = adev->rings[i];
558
559 if (!ring || !target_seq[i])
560 continue;
561
562 amdgpu_irq_put(adev, ring->fence_drv.irq_src,
563 ring->fence_drv.irq_type);
564 trace_amdgpu_fence_wait_end(adev->ddev, i, target_seq[i]);
565 }
566
567 if (unlikely(r < 0))
568 return r;
569
570 if (unlikely(!signaled)) {
571
572 if (adev->needs_reset)
573 return -EDEADLK;
574
575 /* we were interrupted for some reason and fence
576 * isn't signaled yet, resume waiting */
577 if (r)
578 continue;
579
580 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
581 struct amdgpu_ring *ring = adev->rings[i];
582
583 if (!ring || !target_seq[i])
584 continue;
585
586 if (last_seq[i] != atomic64_read(&ring->fence_drv.last_seq))
587 break;
588 }
589
590 if (i != AMDGPU_MAX_RINGS)
591 continue;
592
593 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
594 if (!adev->rings[i] || !target_seq[i])
595 continue;
596
597 if (amdgpu_ring_is_lockup(adev->rings[i]))
598 break;
599 }
600
601 if (i < AMDGPU_MAX_RINGS) {
602 /* good news we believe it's a lockup */
603 dev_warn(adev->dev, "GPU lockup (waiting for "
604 "0x%016llx last fence id 0x%016llx on"
605 " ring %d)\n",
606 target_seq[i], last_seq[i], i);
607
608 /* remember that we need an reset */
609 adev->needs_reset = true;
610 wake_up_all(&adev->fence_queue);
611 return -EDEADLK;
612 }
613
614 if (timeout < MAX_SCHEDULE_TIMEOUT) {
615 timeout -= AMDGPU_FENCE_JIFFIES_TIMEOUT;
616 if (timeout <= 0) {
617 return 0;
618 }
619 }
620 }
621 }
622 return timeout;
623}
624
625/**
626 * amdgpu_fence_wait - wait for a fence to signal
627 *
628 * @fence: amdgpu fence object
629 * @intr: use interruptable sleep
630 *
631 * Wait for the requested fence to signal (all asics).
632 * @intr selects whether to use interruptable (true) or non-interruptable
633 * (false) sleep when waiting for the fence.
634 * Returns 0 if the fence has passed, error for all other cases.
635 */
636int amdgpu_fence_wait(struct amdgpu_fence *fence, bool intr)
637{
638 uint64_t seq[AMDGPU_MAX_RINGS] = {};
639 long r;
640
641 seq[fence->ring->idx] = fence->seq;
642 r = amdgpu_fence_wait_seq_timeout(fence->ring->adev, seq, intr, MAX_SCHEDULE_TIMEOUT);
643 if (r < 0) {
644 return r;
645 }
646
647 r = fence_signal(&fence->base);
648 if (!r)
649 FENCE_TRACE(&fence->base, "signaled from fence_wait\n");
650 return 0;
651}
652
653/**
654 * amdgpu_fence_wait_any - wait for a fence to signal on any ring
655 *
656 * @adev: amdgpu device pointer
657 * @fences: amdgpu fence object(s)
658 * @intr: use interruptable sleep
659 *
660 * Wait for any requested fence to signal (all asics). Fence
661 * array is indexed by ring id. @intr selects whether to use
662 * interruptable (true) or non-interruptable (false) sleep when
663 * waiting for the fences. Used by the suballocator.
664 * Returns 0 if any fence has passed, error for all other cases.
665 */
666int amdgpu_fence_wait_any(struct amdgpu_device *adev,
667 struct amdgpu_fence **fences,
668 bool intr)
669{
670 uint64_t seq[AMDGPU_MAX_RINGS];
671 unsigned i, num_rings = 0;
672 long r;
673
674 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
675 seq[i] = 0;
676
677 if (!fences[i]) {
678 continue;
679 }
680
681 seq[i] = fences[i]->seq;
682 ++num_rings;
683 }
684
685 /* nothing to wait for ? */
686 if (num_rings == 0)
687 return -ENOENT;
688
689 r = amdgpu_fence_wait_seq_timeout(adev, seq, intr, MAX_SCHEDULE_TIMEOUT);
690 if (r < 0) {
691 return r;
692 }
693 return 0;
694}
695
696/**
697 * amdgpu_fence_wait_next - wait for the next fence to signal
698 *
699 * @adev: amdgpu device pointer
700 * @ring: ring index the fence is associated with
701 *
702 * Wait for the next fence on the requested ring to signal (all asics).
703 * Returns 0 if the next fence has passed, error for all other cases.
704 * Caller must hold ring lock.
705 */
706int amdgpu_fence_wait_next(struct amdgpu_ring *ring)
707{
708 uint64_t seq[AMDGPU_MAX_RINGS] = {};
709 long r;
710
711 seq[ring->idx] = atomic64_read(&ring->fence_drv.last_seq) + 1ULL;
712 if (seq[ring->idx] >= ring->fence_drv.sync_seq[ring->idx]) {
713 /* nothing to wait for, last_seq is
714 already the last emited fence */
715 return -ENOENT;
716 }
717 r = amdgpu_fence_wait_seq_timeout(ring->adev, seq, false, MAX_SCHEDULE_TIMEOUT);
718 if (r < 0)
719 return r;
720 return 0;
721}
722
723/**
724 * amdgpu_fence_wait_empty - wait for all fences to signal
725 *
726 * @adev: amdgpu device pointer
727 * @ring: ring index the fence is associated with
728 *
729 * Wait for all fences on the requested ring to signal (all asics).
730 * Returns 0 if the fences have passed, error for all other cases.
731 * Caller must hold ring lock.
732 */
733int amdgpu_fence_wait_empty(struct amdgpu_ring *ring)
734{
735 struct amdgpu_device *adev = ring->adev;
736 uint64_t seq[AMDGPU_MAX_RINGS] = {};
737 long r;
738
739 seq[ring->idx] = ring->fence_drv.sync_seq[ring->idx];
740 if (!seq[ring->idx])
741 return 0;
742
743 r = amdgpu_fence_wait_seq_timeout(adev, seq, false, MAX_SCHEDULE_TIMEOUT);
744 if (r < 0) {
745 if (r == -EDEADLK)
746 return -EDEADLK;
747
748 dev_err(adev->dev, "error waiting for ring[%d] to become idle (%ld)\n",
749 ring->idx, r);
750 }
751 return 0;
752}
753
754/**
755 * amdgpu_fence_ref - take a ref on a fence
756 *
757 * @fence: amdgpu fence object
758 *
759 * Take a reference on a fence (all asics).
760 * Returns the fence.
761 */
762struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence)
763{
764 fence_get(&fence->base);
765 return fence;
766}
767
768/**
769 * amdgpu_fence_unref - remove a ref on a fence
770 *
771 * @fence: amdgpu fence object
772 *
773 * Remove a reference on a fence (all asics).
774 */
775void amdgpu_fence_unref(struct amdgpu_fence **fence)
776{
777 struct amdgpu_fence *tmp = *fence;
778
779 *fence = NULL;
780 if (tmp)
781 fence_put(&tmp->base);
782}
783
784/**
785 * amdgpu_fence_count_emitted - get the count of emitted fences
786 *
787 * @ring: ring the fence is associated with
788 *
789 * Get the number of fences emitted on the requested ring (all asics).
790 * Returns the number of emitted fences on the ring. Used by the
791 * dynpm code to ring track activity.
792 */
793unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring)
794{
795 uint64_t emitted;
796
797 /* We are not protected by ring lock when reading the last sequence
798 * but it's ok to report slightly wrong fence count here.
799 */
800 amdgpu_fence_process(ring);
801 emitted = ring->fence_drv.sync_seq[ring->idx]
802 - atomic64_read(&ring->fence_drv.last_seq);
803 /* to avoid 32bits warp around */
804 if (emitted > 0x10000000)
805 emitted = 0x10000000;
806
807 return (unsigned)emitted;
808}
809
810/**
811 * amdgpu_fence_need_sync - do we need a semaphore
812 *
813 * @fence: amdgpu fence object
814 * @dst_ring: which ring to check against
815 *
816 * Check if the fence needs to be synced against another ring
817 * (all asics). If so, we need to emit a semaphore.
818 * Returns true if we need to sync with another ring, false if
819 * not.
820 */
821bool amdgpu_fence_need_sync(struct amdgpu_fence *fence,
822 struct amdgpu_ring *dst_ring)
823{
824 struct amdgpu_fence_driver *fdrv;
825
826 if (!fence)
827 return false;
828
829 if (fence->ring == dst_ring)
830 return false;
831
832 /* we are protected by the ring mutex */
833 fdrv = &dst_ring->fence_drv;
834 if (fence->seq <= fdrv->sync_seq[fence->ring->idx])
835 return false;
836
837 return true;
838}
839
840/**
841 * amdgpu_fence_note_sync - record the sync point
842 *
843 * @fence: amdgpu fence object
844 * @dst_ring: which ring to check against
845 *
846 * Note the sequence number at which point the fence will
847 * be synced with the requested ring (all asics).
848 */
849void amdgpu_fence_note_sync(struct amdgpu_fence *fence,
850 struct amdgpu_ring *dst_ring)
851{
852 struct amdgpu_fence_driver *dst, *src;
853 unsigned i;
854
855 if (!fence)
856 return;
857
858 if (fence->ring == dst_ring)
859 return;
860
861 /* we are protected by the ring mutex */
862 src = &fence->ring->fence_drv;
863 dst = &dst_ring->fence_drv;
864 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
865 if (i == dst_ring->idx)
866 continue;
867
868 dst->sync_seq[i] = max(dst->sync_seq[i], src->sync_seq[i]);
869 }
870}
871
872/**
873 * amdgpu_fence_driver_start_ring - make the fence driver
874 * ready for use on the requested ring.
875 *
876 * @ring: ring to start the fence driver on
877 * @irq_src: interrupt source to use for this ring
878 * @irq_type: interrupt type to use for this ring
879 *
880 * Make the fence driver ready for processing (all asics).
881 * Not all asics have all rings, so each asic will only
882 * start the fence driver on the rings it has.
883 * Returns 0 for success, errors for failure.
884 */
885int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
886 struct amdgpu_irq_src *irq_src,
887 unsigned irq_type)
888{
889 struct amdgpu_device *adev = ring->adev;
890 uint64_t index;
891
892 if (ring != &adev->uvd.ring) {
893 ring->fence_drv.cpu_addr = &adev->wb.wb[ring->fence_offs];
894 ring->fence_drv.gpu_addr = adev->wb.gpu_addr + (ring->fence_offs * 4);
895 } else {
896 /* put fence directly behind firmware */
897 index = ALIGN(adev->uvd.fw->size, 8);
898 ring->fence_drv.cpu_addr = adev->uvd.cpu_addr + index;
899 ring->fence_drv.gpu_addr = adev->uvd.gpu_addr + index;
900 }
901 amdgpu_fence_write(ring, atomic64_read(&ring->fence_drv.last_seq));
902 ring->fence_drv.initialized = true;
903 ring->fence_drv.irq_src = irq_src;
904 ring->fence_drv.irq_type = irq_type;
905 dev_info(adev->dev, "fence driver on ring %d use gpu addr 0x%016llx, "
906 "cpu addr 0x%p\n", ring->idx,
907 ring->fence_drv.gpu_addr, ring->fence_drv.cpu_addr);
908 return 0;
909}
910
911/**
912 * amdgpu_fence_driver_init_ring - init the fence driver
913 * for the requested ring.
914 *
915 * @ring: ring to init the fence driver on
916 *
917 * Init the fence driver for the requested ring (all asics).
918 * Helper function for amdgpu_fence_driver_init().
919 */
920void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring)
921{
922 int i;
923
924 ring->fence_drv.cpu_addr = NULL;
925 ring->fence_drv.gpu_addr = 0;
926 for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
927 ring->fence_drv.sync_seq[i] = 0;
928
929 atomic64_set(&ring->fence_drv.last_seq, 0);
930 ring->fence_drv.initialized = false;
931
932 INIT_DELAYED_WORK(&ring->fence_drv.lockup_work,
933 amdgpu_fence_check_lockup);
934 ring->fence_drv.ring = ring;
935}
936
937/**
938 * amdgpu_fence_driver_init - init the fence driver
939 * for all possible rings.
940 *
941 * @adev: amdgpu device pointer
942 *
943 * Init the fence driver for all possible rings (all asics).
944 * Not all asics have all rings, so each asic will only
945 * start the fence driver on the rings it has using
946 * amdgpu_fence_driver_start_ring().
947 * Returns 0 for success.
948 */
949int amdgpu_fence_driver_init(struct amdgpu_device *adev)
950{
951 init_waitqueue_head(&adev->fence_queue);
952 if (amdgpu_debugfs_fence_init(adev))
953 dev_err(adev->dev, "fence debugfs file creation failed\n");
954
955 return 0;
956}
957
958/**
959 * amdgpu_fence_driver_fini - tear down the fence driver
960 * for all possible rings.
961 *
962 * @adev: amdgpu device pointer
963 *
964 * Tear down the fence driver for all possible rings (all asics).
965 */
966void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
967{
968 int i, r;
969
970 mutex_lock(&adev->ring_lock);
971 for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
972 struct amdgpu_ring *ring = adev->rings[i];
973 if (!ring || !ring->fence_drv.initialized)
974 continue;
975 r = amdgpu_fence_wait_empty(ring);
976 if (r) {
977 /* no need to trigger GPU reset as we are unloading */
978 amdgpu_fence_driver_force_completion(adev);
979 }
980 wake_up_all(&adev->fence_queue);
981 ring->fence_drv.initialized = false;
982 }
983 mutex_unlock(&adev->ring_lock);
984}
985
986/**
987 * amdgpu_fence_driver_force_completion - force all fence waiter to complete
988 *
989 * @adev: amdgpu device pointer
990 *
991 * In case of GPU reset failure make sure no process keep waiting on fence
992 * that will never complete.
993 */
994void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev)
995{
996 int i;
997
998 for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
999 struct amdgpu_ring *ring = adev->rings[i];
1000 if (!ring || !ring->fence_drv.initialized)
1001 continue;
1002
1003 amdgpu_fence_write(ring, ring->fence_drv.sync_seq[i]);
1004 }
1005}
1006
1007
1008/*
1009 * Fence debugfs
1010 */
1011#if defined(CONFIG_DEBUG_FS)
1012static int amdgpu_debugfs_fence_info(struct seq_file *m, void *data)
1013{
1014 struct drm_info_node *node = (struct drm_info_node *)m->private;
1015 struct drm_device *dev = node->minor->dev;
1016 struct amdgpu_device *adev = dev->dev_private;
1017 int i, j;
1018
1019 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
1020 struct amdgpu_ring *ring = adev->rings[i];
1021 if (!ring || !ring->fence_drv.initialized)
1022 continue;
1023
1024 amdgpu_fence_process(ring);
1025
1026 seq_printf(m, "--- ring %d ---\n", i);
1027 seq_printf(m, "Last signaled fence 0x%016llx\n",
1028 (unsigned long long)atomic64_read(&ring->fence_drv.last_seq));
1029 seq_printf(m, "Last emitted 0x%016llx\n",
1030 ring->fence_drv.sync_seq[i]);
1031
1032 for (j = 0; j < AMDGPU_MAX_RINGS; ++j) {
1033 struct amdgpu_ring *other = adev->rings[j];
1034 if (i != j && other && other->fence_drv.initialized)
1035 seq_printf(m, "Last sync to ring %d 0x%016llx\n",
1036 j, ring->fence_drv.sync_seq[j]);
1037 }
1038 }
1039 return 0;
1040}
1041
1042static struct drm_info_list amdgpu_debugfs_fence_list[] = {
1043 {"amdgpu_fence_info", &amdgpu_debugfs_fence_info, 0, NULL},
1044};
1045#endif
1046
1047int amdgpu_debugfs_fence_init(struct amdgpu_device *adev)
1048{
1049#if defined(CONFIG_DEBUG_FS)
1050 return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_fence_list, 1);
1051#else
1052 return 0;
1053#endif
1054}
1055
1056static const char *amdgpu_fence_get_driver_name(struct fence *fence)
1057{
1058 return "amdgpu";
1059}
1060
1061static const char *amdgpu_fence_get_timeline_name(struct fence *f)
1062{
1063 struct amdgpu_fence *fence = to_amdgpu_fence(f);
1064 return (const char *)fence->ring->name;
1065}
1066
1067static inline bool amdgpu_test_signaled(struct amdgpu_fence *fence)
1068{
1069 return test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags);
1070}
1071
1072struct amdgpu_wait_cb {
1073 struct fence_cb base;
1074 struct task_struct *task;
1075};
1076
1077static void amdgpu_fence_wait_cb(struct fence *fence, struct fence_cb *cb)
1078{
1079 struct amdgpu_wait_cb *wait =
1080 container_of(cb, struct amdgpu_wait_cb, base);
1081 wake_up_process(wait->task);
1082}
1083
1084static signed long amdgpu_fence_default_wait(struct fence *f, bool intr,
1085 signed long t)
1086{
1087 struct amdgpu_fence *fence = to_amdgpu_fence(f);
1088 struct amdgpu_device *adev = fence->ring->adev;
1089 struct amdgpu_wait_cb cb;
1090
1091 cb.task = current;
1092
1093 if (fence_add_callback(f, &cb.base, amdgpu_fence_wait_cb))
1094 return t;
1095
1096 while (t > 0) {
1097 if (intr)
1098 set_current_state(TASK_INTERRUPTIBLE);
1099 else
1100 set_current_state(TASK_UNINTERRUPTIBLE);
1101
1102 /*
1103 * amdgpu_test_signaled must be called after
1104 * set_current_state to prevent a race with wake_up_process
1105 */
1106 if (amdgpu_test_signaled(fence))
1107 break;
1108
1109 if (adev->needs_reset) {
1110 t = -EDEADLK;
1111 break;
1112 }
1113
1114 t = schedule_timeout(t);
1115
1116 if (t > 0 && intr && signal_pending(current))
1117 t = -ERESTARTSYS;
1118 }
1119
1120 __set_current_state(TASK_RUNNING);
1121 fence_remove_callback(f, &cb.base);
1122
1123 return t;
1124}
1125
1126const struct fence_ops amdgpu_fence_ops = {
1127 .get_driver_name = amdgpu_fence_get_driver_name,
1128 .get_timeline_name = amdgpu_fence_get_timeline_name,
1129 .enable_signaling = amdgpu_fence_enable_signaling,
1130 .signaled = amdgpu_fence_is_signaled,
1131 .wait = amdgpu_fence_default_wait,
1132 .release = NULL,
1133};
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c+371−0
@@ -0,0 +1,371 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include <drm/drmP.h>
29#include <drm/amdgpu_drm.h>
30#include "amdgpu.h"
31
32/*
33 * GART
34 * The GART (Graphics Aperture Remapping Table) is an aperture
35 * in the GPU's address space. System pages can be mapped into
36 * the aperture and look like contiguous pages from the GPU's
37 * perspective. A page table maps the pages in the aperture
38 * to the actual backing pages in system memory.
39 *
40 * Radeon GPUs support both an internal GART, as described above,
41 * and AGP. AGP works similarly, but the GART table is configured
42 * and maintained by the northbridge rather than the driver.
43 * Radeon hw has a separate AGP aperture that is programmed to
44 * point to the AGP aperture provided by the northbridge and the
45 * requests are passed through to the northbridge aperture.
46 * Both AGP and internal GART can be used at the same time, however
47 * that is not currently supported by the driver.
48 *
49 * This file handles the common internal GART management.
50 */
51
52/*
53 * Common GART table functions.
54 */
55/**
56 * amdgpu_gart_table_ram_alloc - allocate system ram for gart page table
57 *
58 * @adev: amdgpu_device pointer
59 *
60 * Allocate system memory for GART page table
61 * (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the
62 * gart table to be in system memory.
63 * Returns 0 for success, -ENOMEM for failure.
64 */
65int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev)
66{
67 void *ptr;
68
69 ptr = pci_alloc_consistent(adev->pdev, adev->gart.table_size,
70 &adev->gart.table_addr);
71 if (ptr == NULL) {
72 return -ENOMEM;
73 }
74#ifdef CONFIG_X86
75 if (0) {
76 set_memory_uc((unsigned long)ptr,
77 adev->gart.table_size >> PAGE_SHIFT);
78 }
79#endif
80 adev->gart.ptr = ptr;
81 memset((void *)adev->gart.ptr, 0, adev->gart.table_size);
82 return 0;
83}
84
85/**
86 * amdgpu_gart_table_ram_free - free system ram for gart page table
87 *
88 * @adev: amdgpu_device pointer
89 *
90 * Free system memory for GART page table
91 * (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the
92 * gart table to be in system memory.
93 */
94void amdgpu_gart_table_ram_free(struct amdgpu_device *adev)
95{
96 if (adev->gart.ptr == NULL) {
97 return;
98 }
99#ifdef CONFIG_X86
100 if (0) {
101 set_memory_wb((unsigned long)adev->gart.ptr,
102 adev->gart.table_size >> PAGE_SHIFT);
103 }
104#endif
105 pci_free_consistent(adev->pdev, adev->gart.table_size,
106 (void *)adev->gart.ptr,
107 adev->gart.table_addr);
108 adev->gart.ptr = NULL;
109 adev->gart.table_addr = 0;
110}
111
112/**
113 * amdgpu_gart_table_vram_alloc - allocate vram for gart page table
114 *
115 * @adev: amdgpu_device pointer
116 *
117 * Allocate video memory for GART page table
118 * (pcie r4xx, r5xx+). These asics require the
119 * gart table to be in video memory.
120 * Returns 0 for success, error for failure.
121 */
122int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
123{
124 int r;
125
126 if (adev->gart.robj == NULL) {
127 r = amdgpu_bo_create(adev, adev->gart.table_size,
128 PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, 0,
129 NULL, &adev->gart.robj);
130 if (r) {
131 return r;
132 }
133 }
134 return 0;
135}
136
137/**
138 * amdgpu_gart_table_vram_pin - pin gart page table in vram
139 *
140 * @adev: amdgpu_device pointer
141 *
142 * Pin the GART page table in vram so it will not be moved
143 * by the memory manager (pcie r4xx, r5xx+). These asics require the
144 * gart table to be in video memory.
145 * Returns 0 for success, error for failure.
146 */
147int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev)
148{
149 uint64_t gpu_addr;
150 int r;
151
152 r = amdgpu_bo_reserve(adev->gart.robj, false);
153 if (unlikely(r != 0))
154 return r;
155 r = amdgpu_bo_pin(adev->gart.robj,
156 AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr);
157 if (r) {
158 amdgpu_bo_unreserve(adev->gart.robj);
159 return r;
160 }
161 r = amdgpu_bo_kmap(adev->gart.robj, &adev->gart.ptr);
162 if (r)
163 amdgpu_bo_unpin(adev->gart.robj);
164 amdgpu_bo_unreserve(adev->gart.robj);
165 adev->gart.table_addr = gpu_addr;
166 return r;
167}
168
169/**
170 * amdgpu_gart_table_vram_unpin - unpin gart page table in vram
171 *
172 * @adev: amdgpu_device pointer
173 *
174 * Unpin the GART page table in vram (pcie r4xx, r5xx+).
175 * These asics require the gart table to be in video memory.
176 */
177void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev)
178{
179 int r;
180
181 if (adev->gart.robj == NULL) {
182 return;
183 }
184 r = amdgpu_bo_reserve(adev->gart.robj, false);
185 if (likely(r == 0)) {
186 amdgpu_bo_kunmap(adev->gart.robj);
187 amdgpu_bo_unpin(adev->gart.robj);
188 amdgpu_bo_unreserve(adev->gart.robj);
189 adev->gart.ptr = NULL;
190 }
191}
192
193/**
194 * amdgpu_gart_table_vram_free - free gart page table vram
195 *
196 * @adev: amdgpu_device pointer
197 *
198 * Free the video memory used for the GART page table
199 * (pcie r4xx, r5xx+). These asics require the gart table to
200 * be in video memory.
201 */
202void amdgpu_gart_table_vram_free(struct amdgpu_device *adev)
203{
204 if (adev->gart.robj == NULL) {
205 return;
206 }
207 amdgpu_bo_unref(&adev->gart.robj);
208}
209
210/*
211 * Common gart functions.
212 */
213/**
214 * amdgpu_gart_unbind - unbind pages from the gart page table
215 *
216 * @adev: amdgpu_device pointer
217 * @offset: offset into the GPU's gart aperture
218 * @pages: number of pages to unbind
219 *
220 * Unbinds the requested pages from the gart page table and
221 * replaces them with the dummy page (all asics).
222 */
223void amdgpu_gart_unbind(struct amdgpu_device *adev, unsigned offset,
224 int pages)
225{
226 unsigned t;
227 unsigned p;
228 int i, j;
229 u64 page_base;
230 uint32_t flags = AMDGPU_PTE_SYSTEM;
231
232 if (!adev->gart.ready) {
233 WARN(1, "trying to unbind memory from uninitialized GART !\n");
234 return;
235 }
236
237 t = offset / AMDGPU_GPU_PAGE_SIZE;
238 p = t / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE);
239 for (i = 0; i < pages; i++, p++) {
240 if (adev->gart.pages[p]) {
241 adev->gart.pages[p] = NULL;
242 adev->gart.pages_addr[p] = adev->dummy_page.addr;
243 page_base = adev->gart.pages_addr[p];
244 if (!adev->gart.ptr)
245 continue;
246
247 for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
248 amdgpu_gart_set_pte_pde(adev, adev->gart.ptr,
249 t, page_base, flags);
250 page_base += AMDGPU_GPU_PAGE_SIZE;
251 }
252 }
253 }
254 mb();
255 amdgpu_gart_flush_gpu_tlb(adev, 0);
256}
257
258/**
259 * amdgpu_gart_bind - bind pages into the gart page table
260 *
261 * @adev: amdgpu_device pointer
262 * @offset: offset into the GPU's gart aperture
263 * @pages: number of pages to bind
264 * @pagelist: pages to bind
265 * @dma_addr: DMA addresses of pages
266 *
267 * Binds the requested pages to the gart page table
268 * (all asics).
269 * Returns 0 for success, -EINVAL for failure.
270 */
271int amdgpu_gart_bind(struct amdgpu_device *adev, unsigned offset,
272 int pages, struct page **pagelist, dma_addr_t *dma_addr,
273 uint32_t flags)
274{
275 unsigned t;
276 unsigned p;
277 uint64_t page_base;
278 int i, j;
279
280 if (!adev->gart.ready) {
281 WARN(1, "trying to bind memory to uninitialized GART !\n");
282 return -EINVAL;
283 }
284
285 t = offset / AMDGPU_GPU_PAGE_SIZE;
286 p = t / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE);
287
288 for (i = 0; i < pages; i++, p++) {
289 adev->gart.pages_addr[p] = dma_addr[i];
290 adev->gart.pages[p] = pagelist[i];
291 if (adev->gart.ptr) {
292 page_base = adev->gart.pages_addr[p];
293 for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
294 amdgpu_gart_set_pte_pde(adev, adev->gart.ptr, t, page_base, flags);
295 page_base += AMDGPU_GPU_PAGE_SIZE;
296 }
297 }
298 }
299 mb();
300 amdgpu_gart_flush_gpu_tlb(adev, 0);
301 return 0;
302}
303
304/**
305 * amdgpu_gart_init - init the driver info for managing the gart
306 *
307 * @adev: amdgpu_device pointer
308 *
309 * Allocate the dummy page and init the gart driver info (all asics).
310 * Returns 0 for success, error for failure.
311 */
312int amdgpu_gart_init(struct amdgpu_device *adev)
313{
314 int r, i;
315
316 if (adev->gart.pages) {
317 return 0;
318 }
319 /* We need PAGE_SIZE >= AMDGPU_GPU_PAGE_SIZE */
320 if (PAGE_SIZE < AMDGPU_GPU_PAGE_SIZE) {
321 DRM_ERROR("Page size is smaller than GPU page size!\n");
322 return -EINVAL;
323 }
324 r = amdgpu_dummy_page_init(adev);
325 if (r)
326 return r;
327 /* Compute table size */
328 adev->gart.num_cpu_pages = adev->mc.gtt_size / PAGE_SIZE;
329 adev->gart.num_gpu_pages = adev->mc.gtt_size / AMDGPU_GPU_PAGE_SIZE;
330 DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
331 adev->gart.num_cpu_pages, adev->gart.num_gpu_pages);
332 /* Allocate pages table */
333 adev->gart.pages = vzalloc(sizeof(void *) * adev->gart.num_cpu_pages);
334 if (adev->gart.pages == NULL) {
335 amdgpu_gart_fini(adev);
336 return -ENOMEM;
337 }
338 adev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) *
339 adev->gart.num_cpu_pages);
340 if (adev->gart.pages_addr == NULL) {
341 amdgpu_gart_fini(adev);
342 return -ENOMEM;
343 }
344 /* set GART entry to point to the dummy page by default */
345 for (i = 0; i < adev->gart.num_cpu_pages; i++) {
346 adev->gart.pages_addr[i] = adev->dummy_page.addr;
347 }
348 return 0;
349}
350
351/**
352 * amdgpu_gart_fini - tear down the driver info for managing the gart
353 *
354 * @adev: amdgpu_device pointer
355 *
356 * Tear down the gart driver info and free the dummy page (all asics).
357 */
358void amdgpu_gart_fini(struct amdgpu_device *adev)
359{
360 if (adev->gart.pages && adev->gart.pages_addr && adev->gart.ready) {
361 /* unbind pages */
362 amdgpu_gart_unbind(adev, 0, adev->gart.num_cpu_pages);
363 }
364 adev->gart.ready = false;
365 vfree(adev->gart.pages);
366 vfree(adev->gart.pages_addr);
367 adev->gart.pages = NULL;
368 adev->gart.pages_addr = NULL;
369
370 amdgpu_dummy_page_fini(adev);
371}
drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h+72−0
@@ -0,0 +1,72 @@
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 __AMDGPU_GDS_H__
25#define __AMDGPU_GDS_H__
26
27/* Because TTM request that alloacted buffer should be PAGE_SIZE aligned,
28 * we should report GDS/GWS/OA size as PAGE_SIZE aligned
29 * */
30#define AMDGPU_GDS_SHIFT 2
31#define AMDGPU_GWS_SHIFT PAGE_SHIFT
32#define AMDGPU_OA_SHIFT PAGE_SHIFT
33
34#define AMDGPU_PL_GDS TTM_PL_PRIV0
35#define AMDGPU_PL_GWS TTM_PL_PRIV1
36#define AMDGPU_PL_OA TTM_PL_PRIV2
37
38#define AMDGPU_PL_FLAG_GDS TTM_PL_FLAG_PRIV0
39#define AMDGPU_PL_FLAG_GWS TTM_PL_FLAG_PRIV1
40#define AMDGPU_PL_FLAG_OA TTM_PL_FLAG_PRIV2
41
42struct amdgpu_ring;
43struct amdgpu_bo;
44
45struct amdgpu_gds_asic_info {
46 uint32_t total_size;
47 uint32_t gfx_partition_size;
48 uint32_t cs_partition_size;
49};
50
51struct amdgpu_gds {
52 struct amdgpu_gds_asic_info mem;
53 struct amdgpu_gds_asic_info gws;
54 struct amdgpu_gds_asic_info oa;
55 /* At present, GDS, GWS and OA resources for gfx (graphics)
56 * is always pre-allocated and available for graphics operation.
57 * Such resource is shared between all gfx clients.
58 * TODO: move this operation to user space
59 * */
60 struct amdgpu_bo* gds_gfx_bo;
61 struct amdgpu_bo* gws_gfx_bo;
62 struct amdgpu_bo* oa_gfx_bo;
63};
64
65struct amdgpu_gds_reg_offset {
66 uint32_t mem_base;
67 uint32_t mem_size;
68 uint32_t gws;
69 uint32_t oa;
70};
71
72#endif /* __AMDGPU_GDS_H__ */
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c+716−0
@@ -0,0 +1,716 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include <linux/ktime.h>
29#include <drm/drmP.h>
30#include <drm/amdgpu_drm.h>
31#include "amdgpu.h"
32
33void amdgpu_gem_object_free(struct drm_gem_object *gobj)
34{
35 struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
36
37 if (robj) {
38 if (robj->gem_base.import_attach)
39 drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
40 amdgpu_mn_unregister(robj);
41 amdgpu_bo_unref(&robj);
42 }
43}
44
45int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
46 int alignment, u32 initial_domain,
47 u64 flags, bool kernel,
48 struct drm_gem_object **obj)
49{
50 struct amdgpu_bo *robj;
51 unsigned long max_size;
52 int r;
53
54 *obj = NULL;
55 /* At least align on page size */
56 if (alignment < PAGE_SIZE) {
57 alignment = PAGE_SIZE;
58 }
59
60 if (!(initial_domain & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA))) {
61 /* Maximum bo size is the unpinned gtt size since we use the gtt to
62 * handle vram to system pool migrations.
63 */
64 max_size = adev->mc.gtt_size - adev->gart_pin_size;
65 if (size > max_size) {
66 DRM_DEBUG("Allocation size %ldMb bigger than %ldMb limit\n",
67 size >> 20, max_size >> 20);
68 return -ENOMEM;
69 }
70 }
71retry:
72 r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, flags, NULL, &robj);
73 if (r) {
74 if (r != -ERESTARTSYS) {
75 if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
76 initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
77 goto retry;
78 }
79 DRM_ERROR("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
80 size, initial_domain, alignment, r);
81 }
82 return r;
83 }
84 *obj = &robj->gem_base;
85 robj->pid = task_pid_nr(current);
86
87 mutex_lock(&adev->gem.mutex);
88 list_add_tail(&robj->list, &adev->gem.objects);
89 mutex_unlock(&adev->gem.mutex);
90
91 return 0;
92}
93
94int amdgpu_gem_init(struct amdgpu_device *adev)
95{
96 INIT_LIST_HEAD(&adev->gem.objects);
97 return 0;
98}
99
100void amdgpu_gem_fini(struct amdgpu_device *adev)
101{
102 amdgpu_bo_force_delete(adev);
103}
104
105/*
106 * Call from drm_gem_handle_create which appear in both new and open ioctl
107 * case.
108 */
109int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv)
110{
111 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(obj);
112 struct amdgpu_device *adev = rbo->adev;
113 struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
114 struct amdgpu_vm *vm = &fpriv->vm;
115 struct amdgpu_bo_va *bo_va;
116 int r;
117
118 r = amdgpu_bo_reserve(rbo, false);
119 if (r) {
120 return r;
121 }
122
123 bo_va = amdgpu_vm_bo_find(vm, rbo);
124 if (!bo_va) {
125 bo_va = amdgpu_vm_bo_add(adev, vm, rbo);
126 } else {
127 ++bo_va->ref_count;
128 }
129 amdgpu_bo_unreserve(rbo);
130
131 return 0;
132}
133
134void amdgpu_gem_object_close(struct drm_gem_object *obj,
135 struct drm_file *file_priv)
136{
137 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(obj);
138 struct amdgpu_device *adev = rbo->adev;
139 struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
140 struct amdgpu_vm *vm = &fpriv->vm;
141 struct amdgpu_bo_va *bo_va;
142 int r;
143
144 r = amdgpu_bo_reserve(rbo, true);
145 if (r) {
146 dev_err(adev->dev, "leaking bo va because "
147 "we fail to reserve bo (%d)\n", r);
148 return;
149 }
150 bo_va = amdgpu_vm_bo_find(vm, rbo);
151 if (bo_va) {
152 if (--bo_va->ref_count == 0) {
153 amdgpu_vm_bo_rmv(adev, bo_va);
154 }
155 }
156 amdgpu_bo_unreserve(rbo);
157}
158
159static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r)
160{
161 if (r == -EDEADLK) {
162 r = amdgpu_gpu_reset(adev);
163 if (!r)
164 r = -EAGAIN;
165 }
166 return r;
167}
168
169/*
170 * GEM ioctls.
171 */
172int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
173 struct drm_file *filp)
174{
175 struct amdgpu_device *adev = dev->dev_private;
176 union drm_amdgpu_gem_create *args = data;
177 uint64_t size = args->in.bo_size;
178 struct drm_gem_object *gobj;
179 uint32_t handle;
180 bool kernel = false;
181 int r;
182
183 down_read(&adev->exclusive_lock);
184 /* create a gem object to contain this object in */
185 if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
186 AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
187 kernel = true;
188 if (args->in.domains == AMDGPU_GEM_DOMAIN_GDS)
189 size = size << AMDGPU_GDS_SHIFT;
190 else if (args->in.domains == AMDGPU_GEM_DOMAIN_GWS)
191 size = size << AMDGPU_GWS_SHIFT;
192 else if (args->in.domains == AMDGPU_GEM_DOMAIN_OA)
193 size = size << AMDGPU_OA_SHIFT;
194 else {
195 r = -EINVAL;
196 goto error_unlock;
197 }
198 }
199 size = roundup(size, PAGE_SIZE);
200
201 r = amdgpu_gem_object_create(adev, size, args->in.alignment,
202 (u32)(0xffffffff & args->in.domains),
203 args->in.domain_flags,
204 kernel, &gobj);
205 if (r)
206 goto error_unlock;
207
208 r = drm_gem_handle_create(filp, gobj, &handle);
209 /* drop reference from allocate - handle holds it now */
210 drm_gem_object_unreference_unlocked(gobj);
211 if (r)
212 goto error_unlock;
213
214 memset(args, 0, sizeof(*args));
215 args->out.handle = handle;
216 up_read(&adev->exclusive_lock);
217 return 0;
218
219error_unlock:
220 up_read(&adev->exclusive_lock);
221 r = amdgpu_gem_handle_lockup(adev, r);
222 return r;
223}
224
225int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
226 struct drm_file *filp)
227{
228 struct amdgpu_device *adev = dev->dev_private;
229 struct drm_amdgpu_gem_userptr *args = data;
230 struct drm_gem_object *gobj;
231 struct amdgpu_bo *bo;
232 uint32_t handle;
233 int r;
234
235 if (offset_in_page(args->addr | args->size))
236 return -EINVAL;
237
238 /* reject unknown flag values */
239 if (args->flags & ~(AMDGPU_GEM_USERPTR_READONLY |
240 AMDGPU_GEM_USERPTR_ANONONLY | AMDGPU_GEM_USERPTR_VALIDATE |
241 AMDGPU_GEM_USERPTR_REGISTER))
242 return -EINVAL;
243
244 if (!(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) ||
245 !(args->flags & AMDGPU_GEM_USERPTR_REGISTER)) {
246
247 /* if we want to write to it we must require anonymous
248 memory and install a MMU notifier */
249 return -EACCES;
250 }
251
252 down_read(&adev->exclusive_lock);
253
254 /* create a gem object to contain this object in */
255 r = amdgpu_gem_object_create(adev, args->size, 0,
256 AMDGPU_GEM_DOMAIN_CPU, 0,
257 0, &gobj);
258 if (r)
259 goto handle_lockup;
260
261 bo = gem_to_amdgpu_bo(gobj);
262 r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags);
263 if (r)
264 goto release_object;
265
266 if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) {
267 r = amdgpu_mn_register(bo, args->addr);
268 if (r)
269 goto release_object;
270 }
271
272 if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
273 down_read(&current->mm->mmap_sem);
274 r = amdgpu_bo_reserve(bo, true);
275 if (r) {
276 up_read(&current->mm->mmap_sem);
277 goto release_object;
278 }
279
280 amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
281 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
282 amdgpu_bo_unreserve(bo);
283 up_read(&current->mm->mmap_sem);
284 if (r)
285 goto release_object;
286 }
287
288 r = drm_gem_handle_create(filp, gobj, &handle);
289 /* drop reference from allocate - handle holds it now */
290 drm_gem_object_unreference_unlocked(gobj);
291 if (r)
292 goto handle_lockup;
293
294 args->handle = handle;
295 up_read(&adev->exclusive_lock);
296 return 0;
297
298release_object:
299 drm_gem_object_unreference_unlocked(gobj);
300
301handle_lockup:
302 up_read(&adev->exclusive_lock);
303 r = amdgpu_gem_handle_lockup(adev, r);
304
305 return r;
306}
307
308int amdgpu_mode_dumb_mmap(struct drm_file *filp,
309 struct drm_device *dev,
310 uint32_t handle, uint64_t *offset_p)
311{
312 struct drm_gem_object *gobj;
313 struct amdgpu_bo *robj;
314
315 gobj = drm_gem_object_lookup(dev, filp, handle);
316 if (gobj == NULL) {
317 return -ENOENT;
318 }
319 robj = gem_to_amdgpu_bo(gobj);
320 if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm) ||
321 (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) {
322 drm_gem_object_unreference_unlocked(gobj);
323 return -EPERM;
324 }
325 *offset_p = amdgpu_bo_mmap_offset(robj);
326 drm_gem_object_unreference_unlocked(gobj);
327 return 0;
328}
329
330int amdgpu_gem_mmap_ioctl(struct drm_device *dev, void *data,
331 struct drm_file *filp)
332{
333 union drm_amdgpu_gem_mmap *args = data;
334 uint32_t handle = args->in.handle;
335 memset(args, 0, sizeof(*args));
336 return amdgpu_mode_dumb_mmap(filp, dev, handle, &args->out.addr_ptr);
337}
338
339/**
340 * amdgpu_gem_timeout - calculate jiffies timeout from absolute value
341 *
342 * @timeout_ns: timeout in ns
343 *
344 * Calculate the timeout in jiffies from an absolute timeout in ns.
345 */
346unsigned long amdgpu_gem_timeout(uint64_t timeout_ns)
347{
348 unsigned long timeout_jiffies;
349 ktime_t timeout;
350
351 /* clamp timeout if it's to large */
352 if (((int64_t)timeout_ns) < 0)
353 return MAX_SCHEDULE_TIMEOUT;
354
355 timeout = ktime_sub_ns(ktime_get(), timeout_ns);
356 if (ktime_to_ns(timeout) < 0)
357 return 0;
358
359 timeout_jiffies = nsecs_to_jiffies(ktime_to_ns(timeout));
360 /* clamp timeout to avoid unsigned-> signed overflow */
361 if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT )
362 return MAX_SCHEDULE_TIMEOUT - 1;
363
364 return timeout_jiffies;
365}
366
367int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
368 struct drm_file *filp)
369{
370 struct amdgpu_device *adev = dev->dev_private;
371 union drm_amdgpu_gem_wait_idle *args = data;
372 struct drm_gem_object *gobj;
373 struct amdgpu_bo *robj;
374 uint32_t handle = args->in.handle;
375 unsigned long timeout = amdgpu_gem_timeout(args->in.timeout);
376 int r = 0;
377 long ret;
378
379 gobj = drm_gem_object_lookup(dev, filp, handle);
380 if (gobj == NULL) {
381 return -ENOENT;
382 }
383 robj = gem_to_amdgpu_bo(gobj);
384 if (timeout == 0)
385 ret = reservation_object_test_signaled_rcu(robj->tbo.resv, true);
386 else
387 ret = reservation_object_wait_timeout_rcu(robj->tbo.resv, true, true, timeout);
388
389 /* ret == 0 means not signaled,
390 * ret > 0 means signaled
391 * ret < 0 means interrupted before timeout
392 */
393 if (ret >= 0) {
394 memset(args, 0, sizeof(*args));
395 args->out.status = (ret == 0);
396 } else
397 r = ret;
398
399 drm_gem_object_unreference_unlocked(gobj);
400 r = amdgpu_gem_handle_lockup(adev, r);
401 return r;
402}
403
404int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
405 struct drm_file *filp)
406{
407 struct drm_amdgpu_gem_metadata *args = data;
408 struct drm_gem_object *gobj;
409 struct amdgpu_bo *robj;
410 int r = -1;
411
412 DRM_DEBUG("%d \n", args->handle);
413 gobj = drm_gem_object_lookup(dev, filp, args->handle);
414 if (gobj == NULL)
415 return -ENOENT;
416 robj = gem_to_amdgpu_bo(gobj);
417
418 r = amdgpu_bo_reserve(robj, false);
419 if (unlikely(r != 0))
420 goto out;
421
422 if (args->op == AMDGPU_GEM_METADATA_OP_GET_METADATA) {
423 amdgpu_bo_get_tiling_flags(robj, &args->data.tiling_info);
424 r = amdgpu_bo_get_metadata(robj, args->data.data,
425 sizeof(args->data.data),
426 &args->data.data_size_bytes,
427 &args->data.flags);
428 } else if (args->op == AMDGPU_GEM_METADATA_OP_SET_METADATA) {
429 r = amdgpu_bo_set_tiling_flags(robj, args->data.tiling_info);
430 if (!r)
431 r = amdgpu_bo_set_metadata(robj, args->data.data,
432 args->data.data_size_bytes,
433 args->data.flags);
434 }
435
436 amdgpu_bo_unreserve(robj);
437out:
438 drm_gem_object_unreference_unlocked(gobj);
439 return r;
440}
441
442/**
443 * amdgpu_gem_va_update_vm -update the bo_va in its VM
444 *
445 * @adev: amdgpu_device pointer
446 * @bo_va: bo_va to update
447 *
448 * Update the bo_va directly after setting it's address. Errors are not
449 * vital here, so they are not reported back to userspace.
450 */
451static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
452 struct amdgpu_bo_va *bo_va)
453{
454 struct ttm_validate_buffer tv, *entry;
455 struct amdgpu_bo_list_entry *vm_bos;
456 struct ww_acquire_ctx ticket;
457 struct list_head list;
458 unsigned domain;
459 int r;
460
461 INIT_LIST_HEAD(&list);
462
463 tv.bo = &bo_va->bo->tbo;
464 tv.shared = true;
465 list_add(&tv.head, &list);
466
467 vm_bos = amdgpu_vm_get_bos(adev, bo_va->vm, &list);
468 if (!vm_bos)
469 return;
470
471 r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
472 if (r)
473 goto error_free;
474
475 list_for_each_entry(entry, &list, head) {
476 domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type);
477 /* if anything is swapped out don't swap it in here,
478 just abort and wait for the next CS */
479 if (domain == AMDGPU_GEM_DOMAIN_CPU)
480 goto error_unreserve;
481 }
482
483 mutex_lock(&bo_va->vm->mutex);
484 r = amdgpu_vm_clear_freed(adev, bo_va->vm);
485 if (r)
486 goto error_unlock;
487
488 r = amdgpu_vm_bo_update(adev, bo_va, &bo_va->bo->tbo.mem);
489
490error_unlock:
491 mutex_unlock(&bo_va->vm->mutex);
492
493error_unreserve:
494 ttm_eu_backoff_reservation(&ticket, &list);
495
496error_free:
497 drm_free_large(vm_bos);
498
499 if (r)
500 DRM_ERROR("Couldn't update BO_VA (%d)\n", r);
501}
502
503
504
505int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
506 struct drm_file *filp)
507{
508 struct drm_amdgpu_gem_va *args = data;
509 struct drm_gem_object *gobj;
510 struct amdgpu_device *adev = dev->dev_private;
511 struct amdgpu_fpriv *fpriv = filp->driver_priv;
512 struct amdgpu_bo *rbo;
513 struct amdgpu_bo_va *bo_va;
514 uint32_t invalid_flags, va_flags = 0;
515 int r = 0;
516
517 if (!adev->vm_manager.enabled)
518 return -ENOTTY;
519
520 if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
521 dev_err(&dev->pdev->dev,
522 "va_address 0x%lX is in reserved area 0x%X\n",
523 (unsigned long)args->va_address,
524 AMDGPU_VA_RESERVED_SIZE);
525 return -EINVAL;
526 }
527
528 invalid_flags = ~(AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE |
529 AMDGPU_VM_PAGE_EXECUTABLE);
530 if ((args->flags & invalid_flags)) {
531 dev_err(&dev->pdev->dev, "invalid flags 0x%08X vs 0x%08X\n",
532 args->flags, invalid_flags);
533 return -EINVAL;
534 }
535
536 switch (args->operation) {
537 case AMDGPU_VA_OP_MAP:
538 case AMDGPU_VA_OP_UNMAP:
539 break;
540 default:
541 dev_err(&dev->pdev->dev, "unsupported operation %d\n",
542 args->operation);
543 return -EINVAL;
544 }
545
546 gobj = drm_gem_object_lookup(dev, filp, args->handle);
547 if (gobj == NULL)
548 return -ENOENT;
549
550 rbo = gem_to_amdgpu_bo(gobj);
551 r = amdgpu_bo_reserve(rbo, false);
552 if (r) {
553 drm_gem_object_unreference_unlocked(gobj);
554 return r;
555 }
556
557 bo_va = amdgpu_vm_bo_find(&fpriv->vm, rbo);
558 if (!bo_va) {
559 amdgpu_bo_unreserve(rbo);
560 return -ENOENT;
561 }
562
563 switch (args->operation) {
564 case AMDGPU_VA_OP_MAP:
565 if (args->flags & AMDGPU_VM_PAGE_READABLE)
566 va_flags |= AMDGPU_PTE_READABLE;
567 if (args->flags & AMDGPU_VM_PAGE_WRITEABLE)
568 va_flags |= AMDGPU_PTE_WRITEABLE;
569 if (args->flags & AMDGPU_VM_PAGE_EXECUTABLE)
570 va_flags |= AMDGPU_PTE_EXECUTABLE;
571 r = amdgpu_vm_bo_map(adev, bo_va, args->va_address,
572 args->offset_in_bo, args->map_size,
573 va_flags);
574 break;
575 case AMDGPU_VA_OP_UNMAP:
576 r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address);
577 break;
578 default:
579 break;
580 }
581
582 if (!r)
583 amdgpu_gem_va_update_vm(adev, bo_va);
584
585 drm_gem_object_unreference_unlocked(gobj);
586 return r;
587}
588
589int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
590 struct drm_file *filp)
591{
592 struct drm_amdgpu_gem_op *args = data;
593 struct drm_gem_object *gobj;
594 struct amdgpu_bo *robj;
595 int r;
596
597 gobj = drm_gem_object_lookup(dev, filp, args->handle);
598 if (gobj == NULL) {
599 return -ENOENT;
600 }
601 robj = gem_to_amdgpu_bo(gobj);
602
603 r = amdgpu_bo_reserve(robj, false);
604 if (unlikely(r))
605 goto out;
606
607 switch (args->op) {
608 case AMDGPU_GEM_OP_GET_GEM_CREATE_INFO: {
609 struct drm_amdgpu_gem_create_in info;
610 void __user *out = (void __user *)(long)args->value;
611
612 info.bo_size = robj->gem_base.size;
613 info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT;
614 info.domains = robj->initial_domain;
615 info.domain_flags = robj->flags;
616 if (copy_to_user(out, &info, sizeof(info)))
617 r = -EFAULT;
618 break;
619 }
620 case AMDGPU_GEM_OP_SET_PLACEMENT:
621 if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm)) {
622 r = -EPERM;
623 break;
624 }
625 robj->initial_domain = args->value & (AMDGPU_GEM_DOMAIN_VRAM |
626 AMDGPU_GEM_DOMAIN_GTT |
627 AMDGPU_GEM_DOMAIN_CPU);
628 break;
629 default:
630 r = -EINVAL;
631 }
632
633 amdgpu_bo_unreserve(robj);
634out:
635 drm_gem_object_unreference_unlocked(gobj);
636 return r;
637}
638
639int amdgpu_mode_dumb_create(struct drm_file *file_priv,
640 struct drm_device *dev,
641 struct drm_mode_create_dumb *args)
642{
643 struct amdgpu_device *adev = dev->dev_private;
644 struct drm_gem_object *gobj;
645 uint32_t handle;
646 int r;
647
648 args->pitch = amdgpu_align_pitch(adev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8);
649 args->size = args->pitch * args->height;
650 args->size = ALIGN(args->size, PAGE_SIZE);
651
652 r = amdgpu_gem_object_create(adev, args->size, 0,
653 AMDGPU_GEM_DOMAIN_VRAM,
654 0, ttm_bo_type_device,
655 &gobj);
656 if (r)
657 return -ENOMEM;
658
659 r = drm_gem_handle_create(file_priv, gobj, &handle);
660 /* drop reference from allocate - handle holds it now */
661 drm_gem_object_unreference_unlocked(gobj);
662 if (r) {
663 return r;
664 }
665 args->handle = handle;
666 return 0;
667}
668
669#if defined(CONFIG_DEBUG_FS)
670static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
671{
672 struct drm_info_node *node = (struct drm_info_node *)m->private;
673 struct drm_device *dev = node->minor->dev;
674 struct amdgpu_device *adev = dev->dev_private;
675 struct amdgpu_bo *rbo;
676 unsigned i = 0;
677
678 mutex_lock(&adev->gem.mutex);
679 list_for_each_entry(rbo, &adev->gem.objects, list) {
680 unsigned domain;
681 const char *placement;
682
683 domain = amdgpu_mem_type_to_domain(rbo->tbo.mem.mem_type);
684 switch (domain) {
685 case AMDGPU_GEM_DOMAIN_VRAM:
686 placement = "VRAM";
687 break;
688 case AMDGPU_GEM_DOMAIN_GTT:
689 placement = " GTT";
690 break;
691 case AMDGPU_GEM_DOMAIN_CPU:
692 default:
693 placement = " CPU";
694 break;
695 }
696 seq_printf(m, "bo[0x%08x] %8ldkB %8ldMB %s pid %8ld\n",
697 i, amdgpu_bo_size(rbo) >> 10, amdgpu_bo_size(rbo) >> 20,
698 placement, (unsigned long)rbo->pid);
699 i++;
700 }
701 mutex_unlock(&adev->gem.mutex);
702 return 0;
703}
704
705static struct drm_info_list amdgpu_debugfs_gem_list[] = {
706 {"amdgpu_gem_info", &amdgpu_debugfs_gem_info, 0, NULL},
707};
708#endif
709
710int amdgpu_gem_debugfs_init(struct amdgpu_device *adev)
711{
712#if defined(CONFIG_DEBUG_FS)
713 return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_gem_list, 1);
714#endif
715 return 0;
716}
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c+72−0
@@ -0,0 +1,72 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25#include <drm/drmP.h>
26#include "amdgpu.h"
27
28/*
29 * GPU scratch registers helpers function.
30 */
31/**
32 * amdgpu_gfx_scratch_get - Allocate a scratch register
33 *
34 * @adev: amdgpu_device pointer
35 * @reg: scratch register mmio offset
36 *
37 * Allocate a CP scratch register for use by the driver (all asics).
38 * Returns 0 on success or -EINVAL on failure.
39 */
40int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg)
41{
42 int i;
43
44 for (i = 0; i < adev->gfx.scratch.num_reg; i++) {
45 if (adev->gfx.scratch.free[i]) {
46 adev->gfx.scratch.free[i] = false;
47 *reg = adev->gfx.scratch.reg[i];
48 return 0;
49 }
50 }
51 return -EINVAL;
52}
53
54/**
55 * amdgpu_gfx_scratch_free - Free a scratch register
56 *
57 * @adev: amdgpu_device pointer
58 * @reg: scratch register mmio offset
59 *
60 * Free a CP scratch register allocated for use by the driver (all asics)
61 */
62void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg)
63{
64 int i;
65
66 for (i = 0; i < adev->gfx.scratch.num_reg; i++) {
67 if (adev->gfx.scratch.reg[i] == reg) {
68 adev->gfx.scratch.free[i] = true;
69 return;
70 }
71 }
72}
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h+30−0
@@ -0,0 +1,30 @@
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 __AMDGPU_GFX_H__
25#define __AMDGPU_GFX_H__
26
27int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg);
28void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg);
29
30#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c+395−0
@@ -0,0 +1,395 @@
1/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
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: Dave Airlie
24 * Alex Deucher
25 */
26#include <linux/export.h>
27
28#include <drm/drmP.h>
29#include <drm/drm_edid.h>
30#include <drm/amdgpu_drm.h>
31#include "amdgpu.h"
32#include "amdgpu_i2c.h"
33#include "amdgpu_atombios.h"
34#include "atom.h"
35#include "atombios_dp.h"
36#include "atombios_i2c.h"
37
38/* bit banging i2c */
39static int amdgpu_i2c_pre_xfer(struct i2c_adapter *i2c_adap)
40{
41 struct amdgpu_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
42 struct amdgpu_device *adev = i2c->dev->dev_private;
43 struct amdgpu_i2c_bus_rec *rec = &i2c->rec;
44 uint32_t temp;
45
46 mutex_lock(&i2c->mutex);
47
48 /* switch the pads to ddc mode */
49 if (rec->hw_capable) {
50 temp = RREG32(rec->mask_clk_reg);
51 temp &= ~(1 << 16);
52 WREG32(rec->mask_clk_reg, temp);
53 }
54
55 /* clear the output pin values */
56 temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask;
57 WREG32(rec->a_clk_reg, temp);
58
59 temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask;
60 WREG32(rec->a_data_reg, temp);
61
62 /* set the pins to input */
63 temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
64 WREG32(rec->en_clk_reg, temp);
65
66 temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
67 WREG32(rec->en_data_reg, temp);
68
69 /* mask the gpio pins for software use */
70 temp = RREG32(rec->mask_clk_reg) | rec->mask_clk_mask;
71 WREG32(rec->mask_clk_reg, temp);
72 temp = RREG32(rec->mask_clk_reg);
73
74 temp = RREG32(rec->mask_data_reg) | rec->mask_data_mask;
75 WREG32(rec->mask_data_reg, temp);
76 temp = RREG32(rec->mask_data_reg);
77
78 return 0;
79}
80
81static void amdgpu_i2c_post_xfer(struct i2c_adapter *i2c_adap)
82{
83 struct amdgpu_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
84 struct amdgpu_device *adev = i2c->dev->dev_private;
85 struct amdgpu_i2c_bus_rec *rec = &i2c->rec;
86 uint32_t temp;
87
88 /* unmask the gpio pins for software use */
89 temp = RREG32(rec->mask_clk_reg) & ~rec->mask_clk_mask;
90 WREG32(rec->mask_clk_reg, temp);
91 temp = RREG32(rec->mask_clk_reg);
92
93 temp = RREG32(rec->mask_data_reg) & ~rec->mask_data_mask;
94 WREG32(rec->mask_data_reg, temp);
95 temp = RREG32(rec->mask_data_reg);
96
97 mutex_unlock(&i2c->mutex);
98}
99
100static int amdgpu_i2c_get_clock(void *i2c_priv)
101{
102 struct amdgpu_i2c_chan *i2c = i2c_priv;
103 struct amdgpu_device *adev = i2c->dev->dev_private;
104 struct amdgpu_i2c_bus_rec *rec = &i2c->rec;
105 uint32_t val;
106
107 /* read the value off the pin */
108 val = RREG32(rec->y_clk_reg);
109 val &= rec->y_clk_mask;
110
111 return (val != 0);
112}
113
114
115static int amdgpu_i2c_get_data(void *i2c_priv)
116{
117 struct amdgpu_i2c_chan *i2c = i2c_priv;
118 struct amdgpu_device *adev = i2c->dev->dev_private;
119 struct amdgpu_i2c_bus_rec *rec = &i2c->rec;
120 uint32_t val;
121
122 /* read the value off the pin */
123 val = RREG32(rec->y_data_reg);
124 val &= rec->y_data_mask;
125
126 return (val != 0);
127}
128
129static void amdgpu_i2c_set_clock(void *i2c_priv, int clock)
130{
131 struct amdgpu_i2c_chan *i2c = i2c_priv;
132 struct amdgpu_device *adev = i2c->dev->dev_private;
133 struct amdgpu_i2c_bus_rec *rec = &i2c->rec;
134 uint32_t val;
135
136 /* set pin direction */
137 val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
138 val |= clock ? 0 : rec->en_clk_mask;
139 WREG32(rec->en_clk_reg, val);
140}
141
142static void amdgpu_i2c_set_data(void *i2c_priv, int data)
143{
144 struct amdgpu_i2c_chan *i2c = i2c_priv;
145 struct amdgpu_device *adev = i2c->dev->dev_private;
146 struct amdgpu_i2c_bus_rec *rec = &i2c->rec;
147 uint32_t val;
148
149 /* set pin direction */
150 val = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
151 val |= data ? 0 : rec->en_data_mask;
152 WREG32(rec->en_data_reg, val);
153}
154
155static const struct i2c_algorithm amdgpu_atombios_i2c_algo = {
156 .master_xfer = amdgpu_atombios_i2c_xfer,
157 .functionality = amdgpu_atombios_i2c_func,
158};
159
160struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev,
161 struct amdgpu_i2c_bus_rec *rec,
162 const char *name)
163{
164 struct amdgpu_i2c_chan *i2c;
165 int ret;
166
167 /* don't add the mm_i2c bus unless hw_i2c is enabled */
168 if (rec->mm_i2c && (amdgpu_hw_i2c == 0))
169 return NULL;
170
171 i2c = kzalloc(sizeof(struct amdgpu_i2c_chan), GFP_KERNEL);
172 if (i2c == NULL)
173 return NULL;
174
175 i2c->rec = *rec;
176 i2c->adapter.owner = THIS_MODULE;
177 i2c->adapter.class = I2C_CLASS_DDC;
178 i2c->adapter.dev.parent = &dev->pdev->dev;
179 i2c->dev = dev;
180 i2c_set_adapdata(&i2c->adapter, i2c);
181 mutex_init(&i2c->mutex);
182 if (rec->hw_capable &&
183 amdgpu_hw_i2c) {
184 /* hw i2c using atom */
185 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
186 "AMDGPU i2c hw bus %s", name);
187 i2c->adapter.algo = &amdgpu_atombios_i2c_algo;
188 ret = i2c_add_adapter(&i2c->adapter);
189 if (ret) {
190 DRM_ERROR("Failed to register hw i2c %s\n", name);
191 goto out_free;
192 }
193 } else {
194 /* set the amdgpu bit adapter */
195 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
196 "AMDGPU i2c bit bus %s", name);
197 i2c->adapter.algo_data = &i2c->bit;
198 i2c->bit.pre_xfer = amdgpu_i2c_pre_xfer;
199 i2c->bit.post_xfer = amdgpu_i2c_post_xfer;
200 i2c->bit.setsda = amdgpu_i2c_set_data;
201 i2c->bit.setscl = amdgpu_i2c_set_clock;
202 i2c->bit.getsda = amdgpu_i2c_get_data;
203 i2c->bit.getscl = amdgpu_i2c_get_clock;
204 i2c->bit.udelay = 10;
205 i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */
206 i2c->bit.data = i2c;
207 ret = i2c_bit_add_bus(&i2c->adapter);
208 if (ret) {
209 DRM_ERROR("Failed to register bit i2c %s\n", name);
210 goto out_free;
211 }
212 }
213
214 return i2c;
215out_free:
216 kfree(i2c);
217 return NULL;
218
219}
220
221void amdgpu_i2c_destroy(struct amdgpu_i2c_chan *i2c)
222{
223 if (!i2c)
224 return;
225 i2c_del_adapter(&i2c->adapter);
226 kfree(i2c);
227}
228
229/* Add the default buses */
230void amdgpu_i2c_init(struct amdgpu_device *adev)
231{
232 if (amdgpu_hw_i2c)
233 DRM_INFO("hw_i2c forced on, you may experience display detection problems!\n");
234
235 if (adev->is_atom_bios)
236 amdgpu_atombios_i2c_init(adev);
237}
238
239/* remove all the buses */
240void amdgpu_i2c_fini(struct amdgpu_device *adev)
241{
242 int i;
243
244 for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++) {
245 if (adev->i2c_bus[i]) {
246 amdgpu_i2c_destroy(adev->i2c_bus[i]);
247 adev->i2c_bus[i] = NULL;
248 }
249 }
250}
251
252/* Add additional buses */
253void amdgpu_i2c_add(struct amdgpu_device *adev,
254 struct amdgpu_i2c_bus_rec *rec,
255 const char *name)
256{
257 struct drm_device *dev = adev->ddev;
258 int i;
259
260 for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++) {
261 if (!adev->i2c_bus[i]) {
262 adev->i2c_bus[i] = amdgpu_i2c_create(dev, rec, name);
263 return;
264 }
265 }
266}
267
268/* looks up bus based on id */
269struct amdgpu_i2c_chan *
270amdgpu_i2c_lookup(struct amdgpu_device *adev,
271 struct amdgpu_i2c_bus_rec *i2c_bus)
272{
273 int i;
274
275 for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++) {
276 if (adev->i2c_bus[i] &&
277 (adev->i2c_bus[i]->rec.i2c_id == i2c_bus->i2c_id)) {
278 return adev->i2c_bus[i];
279 }
280 }
281 return NULL;
282}
283
284static void amdgpu_i2c_get_byte(struct amdgpu_i2c_chan *i2c_bus,
285 u8 slave_addr,
286 u8 addr,
287 u8 *val)
288{
289 u8 out_buf[2];
290 u8 in_buf[2];
291 struct i2c_msg msgs[] = {
292 {
293 .addr = slave_addr,
294 .flags = 0,
295 .len = 1,
296 .buf = out_buf,
297 },
298 {
299 .addr = slave_addr,
300 .flags = I2C_M_RD,
301 .len = 1,
302 .buf = in_buf,
303 }
304 };
305
306 out_buf[0] = addr;
307 out_buf[1] = 0;
308
309 if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) {
310 *val = in_buf[0];
311 DRM_DEBUG("val = 0x%02x\n", *val);
312 } else {
313 DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n",
314 addr, *val);
315 }
316}
317
318static void amdgpu_i2c_put_byte(struct amdgpu_i2c_chan *i2c_bus,
319 u8 slave_addr,
320 u8 addr,
321 u8 val)
322{
323 uint8_t out_buf[2];
324 struct i2c_msg msg = {
325 .addr = slave_addr,
326 .flags = 0,
327 .len = 2,
328 .buf = out_buf,
329 };
330
331 out_buf[0] = addr;
332 out_buf[1] = val;
333
334 if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
335 DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n",
336 addr, val);
337}
338
339/* ddc router switching */
340void
341amdgpu_i2c_router_select_ddc_port(struct amdgpu_connector *amdgpu_connector)
342{
343 u8 val;
344
345 if (!amdgpu_connector->router.ddc_valid)
346 return;
347
348 if (!amdgpu_connector->router_bus)
349 return;
350
351 amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
352 amdgpu_connector->router.i2c_addr,
353 0x3, &val);
354 val &= ~amdgpu_connector->router.ddc_mux_control_pin;
355 amdgpu_i2c_put_byte(amdgpu_connector->router_bus,
356 amdgpu_connector->router.i2c_addr,
357 0x3, val);
358 amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
359 amdgpu_connector->router.i2c_addr,
360 0x1, &val);
361 val &= ~amdgpu_connector->router.ddc_mux_control_pin;
362 val |= amdgpu_connector->router.ddc_mux_state;
363 amdgpu_i2c_put_byte(amdgpu_connector->router_bus,
364 amdgpu_connector->router.i2c_addr,
365 0x1, val);
366}
367
368/* clock/data router switching */
369void
370amdgpu_i2c_router_select_cd_port(struct amdgpu_connector *amdgpu_connector)
371{
372 u8 val;
373
374 if (!amdgpu_connector->router.cd_valid)
375 return;
376
377 if (!amdgpu_connector->router_bus)
378 return;
379
380 amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
381 amdgpu_connector->router.i2c_addr,
382 0x3, &val);
383 val &= ~amdgpu_connector->router.cd_mux_control_pin;
384 amdgpu_i2c_put_byte(amdgpu_connector->router_bus,
385 amdgpu_connector->router.i2c_addr,
386 0x3, val);
387 amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
388 amdgpu_connector->router.i2c_addr,
389 0x1, &val);
390 val &= ~amdgpu_connector->router.cd_mux_control_pin;
391 val |= amdgpu_connector->router.cd_mux_state;
392 amdgpu_i2c_put_byte(amdgpu_connector->router_bus,
393 amdgpu_connector->router.i2c_addr,
394 0x1, val);
395}
drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.h+44−0
@@ -0,0 +1,44 @@
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 __AMDGPU_I2C_H__
25#define __AMDGPU_I2C_H__
26
27struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev,
28 struct amdgpu_i2c_bus_rec *rec,
29 const char *name);
30void amdgpu_i2c_destroy(struct amdgpu_i2c_chan *i2c);
31void amdgpu_i2c_init(struct amdgpu_device *adev);
32void amdgpu_i2c_fini(struct amdgpu_device *adev);
33void amdgpu_i2c_add(struct amdgpu_device *adev,
34 struct amdgpu_i2c_bus_rec *rec,
35 const char *name);
36struct amdgpu_i2c_chan *
37amdgpu_i2c_lookup(struct amdgpu_device *adev,
38 struct amdgpu_i2c_bus_rec *i2c_bus);
39void
40amdgpu_i2c_router_select_ddc_port(struct amdgpu_connector *amdgpu_connector);
41void
42amdgpu_i2c_router_select_cd_port(struct amdgpu_connector *amdgpu_connector);
43
44#endif
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c+354−0
@@ -0,0 +1,354 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 * Christian König
28 */
29#include <linux/seq_file.h>
30#include <linux/slab.h>
31#include <drm/drmP.h>
32#include <drm/amdgpu_drm.h>
33#include "amdgpu.h"
34#include "atom.h"
35
36/*
37 * IB
38 * IBs (Indirect Buffers) and areas of GPU accessible memory where
39 * commands are stored. You can put a pointer to the IB in the
40 * command ring and the hw will fetch the commands from the IB
41 * and execute them. Generally userspace acceleration drivers
42 * produce command buffers which are send to the kernel and
43 * put in IBs for execution by the requested ring.
44 */
45static int amdgpu_debugfs_sa_init(struct amdgpu_device *adev);
46
47/**
48 * amdgpu_ib_get - request an IB (Indirect Buffer)
49 *
50 * @ring: ring index the IB is associated with
51 * @size: requested IB size
52 * @ib: IB object returned
53 *
54 * Request an IB (all asics). IBs are allocated using the
55 * suballocator.
56 * Returns 0 on success, error on failure.
57 */
58int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm,
59 unsigned size, struct amdgpu_ib *ib)
60{
61 struct amdgpu_device *adev = ring->adev;
62 int r;
63
64 if (size) {
65 r = amdgpu_sa_bo_new(adev, &adev->ring_tmp_bo,
66 &ib->sa_bo, size, 256);
67 if (r) {
68 dev_err(adev->dev, "failed to get a new IB (%d)\n", r);
69 return r;
70 }
71
72 ib->ptr = amdgpu_sa_bo_cpu_addr(ib->sa_bo);
73
74 if (!vm)
75 ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
76 else
77 ib->gpu_addr = 0;
78
79 } else {
80 ib->sa_bo = NULL;
81 ib->ptr = NULL;
82 ib->gpu_addr = 0;
83 }
84
85 amdgpu_sync_create(&ib->sync);
86
87 ib->ring = ring;
88 ib->fence = NULL;
89 ib->user = NULL;
90 ib->vm = vm;
91 ib->gds_base = 0;
92 ib->gds_size = 0;
93 ib->gws_base = 0;
94 ib->gws_size = 0;
95 ib->oa_base = 0;
96 ib->oa_size = 0;
97 ib->flags = 0;
98
99 return 0;
100}
101
102/**
103 * amdgpu_ib_free - free an IB (Indirect Buffer)
104 *
105 * @adev: amdgpu_device pointer
106 * @ib: IB object to free
107 *
108 * Free an IB (all asics).
109 */
110void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib)
111{
112 amdgpu_sync_free(adev, &ib->sync, ib->fence);
113 amdgpu_sa_bo_free(adev, &ib->sa_bo, ib->fence);
114 amdgpu_fence_unref(&ib->fence);
115}
116
117/**
118 * amdgpu_ib_schedule - schedule an IB (Indirect Buffer) on the ring
119 *
120 * @adev: amdgpu_device pointer
121 * @num_ibs: number of IBs to schedule
122 * @ibs: IB objects to schedule
123 * @owner: owner for creating the fences
124 *
125 * Schedule an IB on the associated ring (all asics).
126 * Returns 0 on success, error on failure.
127 *
128 * On SI, there are two parallel engines fed from the primary ring,
129 * the CE (Constant Engine) and the DE (Drawing Engine). Since
130 * resource descriptors have moved to memory, the CE allows you to
131 * prime the caches while the DE is updating register state so that
132 * the resource descriptors will be already in cache when the draw is
133 * processed. To accomplish this, the userspace driver submits two
134 * IBs, one for the CE and one for the DE. If there is a CE IB (called
135 * a CONST_IB), it will be put on the ring prior to the DE IB. Prior
136 * to SI there was just a DE IB.
137 */
138int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,
139 struct amdgpu_ib *ibs, void *owner)
140{
141 struct amdgpu_ib *ib = &ibs[0];
142 struct amdgpu_ring *ring;
143 struct amdgpu_ctx *ctx, *old_ctx;
144 struct amdgpu_vm *vm;
145 unsigned i;
146 int r = 0;
147
148 if (num_ibs == 0)
149 return -EINVAL;
150
151 ring = ibs->ring;
152 ctx = ibs->ctx;
153 vm = ibs->vm;
154
155 if (!ring->ready) {
156 dev_err(adev->dev, "couldn't schedule ib\n");
157 return -EINVAL;
158 }
159
160 r = amdgpu_ring_lock(ring, (256 + AMDGPU_NUM_SYNCS * 8) * num_ibs);
161 if (r) {
162 dev_err(adev->dev, "scheduling IB failed (%d).\n", r);
163 return r;
164 }
165
166 if (vm) {
167 /* grab a vm id if necessary */
168 struct amdgpu_fence *vm_id_fence = NULL;
169 vm_id_fence = amdgpu_vm_grab_id(ibs->ring, ibs->vm);
170 amdgpu_sync_fence(&ibs->sync, vm_id_fence);
171 }
172
173 r = amdgpu_sync_rings(&ibs->sync, ring);
174 if (r) {
175 amdgpu_ring_unlock_undo(ring);
176 dev_err(adev->dev, "failed to sync rings (%d)\n", r);
177 return r;
178 }
179
180 if (vm) {
181 /* do context switch */
182 amdgpu_vm_flush(ring, vm, ib->sync.last_vm_update);
183 }
184
185 if (vm && ring->funcs->emit_gds_switch)
186 amdgpu_ring_emit_gds_switch(ring, ib->vm->ids[ring->idx].id,
187 ib->gds_base, ib->gds_size,
188 ib->gws_base, ib->gws_size,
189 ib->oa_base, ib->oa_size);
190
191 if (ring->funcs->emit_hdp_flush)
192 amdgpu_ring_emit_hdp_flush(ring);
193
194 old_ctx = ring->current_ctx;
195 for (i = 0; i < num_ibs; ++i) {
196 ib = &ibs[i];
197
198 if (ib->ring != ring || ib->ctx != ctx || ib->vm != vm) {
199 ring->current_ctx = old_ctx;
200 amdgpu_ring_unlock_undo(ring);
201 return -EINVAL;
202 }
203 amdgpu_ring_emit_ib(ring, ib);
204 ring->current_ctx = ctx;
205 }
206
207 r = amdgpu_fence_emit(ring, owner, &ib->fence);
208 if (r) {
209 dev_err(adev->dev, "failed to emit fence (%d)\n", r);
210 ring->current_ctx = old_ctx;
211 amdgpu_ring_unlock_undo(ring);
212 return r;
213 }
214
215 /* wrap the last IB with fence */
216 if (ib->user) {
217 uint64_t addr = amdgpu_bo_gpu_offset(ib->user->bo);
218 addr += ib->user->offset;
219 amdgpu_ring_emit_fence(ring, addr, ib->fence->seq,
220 AMDGPU_FENCE_FLAG_64BIT);
221 }
222
223 if (ib->vm)
224 amdgpu_vm_fence(adev, ib->vm, ib->fence);
225
226 amdgpu_ring_unlock_commit(ring);
227 return 0;
228}
229
230/**
231 * amdgpu_ib_pool_init - Init the IB (Indirect Buffer) pool
232 *
233 * @adev: amdgpu_device pointer
234 *
235 * Initialize the suballocator to manage a pool of memory
236 * for use as IBs (all asics).
237 * Returns 0 on success, error on failure.
238 */
239int amdgpu_ib_pool_init(struct amdgpu_device *adev)
240{
241 int r;
242
243 if (adev->ib_pool_ready) {
244 return 0;
245 }
246 r = amdgpu_sa_bo_manager_init(adev, &adev->ring_tmp_bo,
247 AMDGPU_IB_POOL_SIZE*64*1024,
248 AMDGPU_GPU_PAGE_SIZE,
249 AMDGPU_GEM_DOMAIN_GTT);
250 if (r) {
251 return r;
252 }
253
254 r = amdgpu_sa_bo_manager_start(adev, &adev->ring_tmp_bo);
255 if (r) {
256 return r;
257 }
258
259 adev->ib_pool_ready = true;
260 if (amdgpu_debugfs_sa_init(adev)) {
261 dev_err(adev->dev, "failed to register debugfs file for SA\n");
262 }
263 return 0;
264}
265
266/**
267 * amdgpu_ib_pool_fini - Free the IB (Indirect Buffer) pool
268 *
269 * @adev: amdgpu_device pointer
270 *
271 * Tear down the suballocator managing the pool of memory
272 * for use as IBs (all asics).
273 */
274void amdgpu_ib_pool_fini(struct amdgpu_device *adev)
275{
276 if (adev->ib_pool_ready) {
277 amdgpu_sa_bo_manager_suspend(adev, &adev->ring_tmp_bo);
278 amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo);
279 adev->ib_pool_ready = false;
280 }
281}
282
283/**
284 * amdgpu_ib_ring_tests - test IBs on the rings
285 *
286 * @adev: amdgpu_device pointer
287 *
288 * Test an IB (Indirect Buffer) on each ring.
289 * If the test fails, disable the ring.
290 * Returns 0 on success, error if the primary GFX ring
291 * IB test fails.
292 */
293int amdgpu_ib_ring_tests(struct amdgpu_device *adev)
294{
295 unsigned i;
296 int r;
297
298 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
299 struct amdgpu_ring *ring = adev->rings[i];
300
301 if (!ring || !ring->ready)
302 continue;
303
304 r = amdgpu_ring_test_ib(ring);
305 if (r) {
306 ring->ready = false;
307 adev->needs_reset = false;
308
309 if (ring == &adev->gfx.gfx_ring[0]) {
310 /* oh, oh, that's really bad */
311 DRM_ERROR("amdgpu: failed testing IB on GFX ring (%d).\n", r);
312 adev->accel_working = false;
313 return r;
314
315 } else {
316 /* still not good, but we can live with it */
317 DRM_ERROR("amdgpu: failed testing IB on ring %d (%d).\n", i, r);
318 }
319 }
320 }
321 return 0;
322}
323
324/*
325 * Debugfs info
326 */
327#if defined(CONFIG_DEBUG_FS)
328
329static int amdgpu_debugfs_sa_info(struct seq_file *m, void *data)
330{
331 struct drm_info_node *node = (struct drm_info_node *) m->private;
332 struct drm_device *dev = node->minor->dev;
333 struct amdgpu_device *adev = dev->dev_private;
334
335 amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo, m);
336
337 return 0;
338
339}
340
341static struct drm_info_list amdgpu_debugfs_sa_list[] = {
342 {"amdgpu_sa_info", &amdgpu_debugfs_sa_info, 0, NULL},
343};
344
345#endif
346
347static int amdgpu_debugfs_sa_init(struct amdgpu_device *adev)
348{
349#if defined(CONFIG_DEBUG_FS)
350 return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_sa_list, 1);
351#else
352 return 0;
353#endif
354}
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c+216−0
@@ -0,0 +1,216 @@
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 <drm/drmP.h>
25#include "amdgpu.h"
26#include "amdgpu_ih.h"
27
28/**
29 * amdgpu_ih_ring_alloc - allocate memory for the IH ring
30 *
31 * @adev: amdgpu_device pointer
32 *
33 * Allocate a ring buffer for the interrupt controller.
34 * Returns 0 for success, errors for failure.
35 */
36static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev)
37{
38 int r;
39
40 /* Allocate ring buffer */
41 if (adev->irq.ih.ring_obj == NULL) {
42 r = amdgpu_bo_create(adev, adev->irq.ih.ring_size,
43 PAGE_SIZE, true,
44 AMDGPU_GEM_DOMAIN_GTT, 0,
45 NULL, &adev->irq.ih.ring_obj);
46 if (r) {
47 DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r);
48 return r;
49 }
50 r = amdgpu_bo_reserve(adev->irq.ih.ring_obj, false);
51 if (unlikely(r != 0))
52 return r;
53 r = amdgpu_bo_pin(adev->irq.ih.ring_obj,
54 AMDGPU_GEM_DOMAIN_GTT,
55 &adev->irq.ih.gpu_addr);
56 if (r) {
57 amdgpu_bo_unreserve(adev->irq.ih.ring_obj);
58 DRM_ERROR("amdgpu: failed to pin ih ring buffer (%d).\n", r);
59 return r;
60 }
61 r = amdgpu_bo_kmap(adev->irq.ih.ring_obj,
62 (void **)&adev->irq.ih.ring);
63 amdgpu_bo_unreserve(adev->irq.ih.ring_obj);
64 if (r) {
65 DRM_ERROR("amdgpu: failed to map ih ring buffer (%d).\n", r);
66 return r;
67 }
68 }
69 return 0;
70}
71
72/**
73 * amdgpu_ih_ring_init - initialize the IH state
74 *
75 * @adev: amdgpu_device pointer
76 *
77 * Initializes the IH state and allocates a buffer
78 * for the IH ring buffer.
79 * Returns 0 for success, errors for failure.
80 */
81int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size,
82 bool use_bus_addr)
83{
84 u32 rb_bufsz;
85 int r;
86
87 /* Align ring size */
88 rb_bufsz = order_base_2(ring_size / 4);
89 ring_size = (1 << rb_bufsz) * 4;
90 adev->irq.ih.ring_size = ring_size;
91 adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1;
92 adev->irq.ih.rptr = 0;
93 adev->irq.ih.use_bus_addr = use_bus_addr;
94
95 if (adev->irq.ih.use_bus_addr) {
96 if (!adev->irq.ih.ring) {
97 /* add 8 bytes for the rptr/wptr shadows and
98 * add them to the end of the ring allocation.
99 */
100 adev->irq.ih.ring = kzalloc(adev->irq.ih.ring_size + 8, GFP_KERNEL);
101 if (adev->irq.ih.ring == NULL)
102 return -ENOMEM;
103 adev->irq.ih.rb_dma_addr = pci_map_single(adev->pdev,
104 (void *)adev->irq.ih.ring,
105 adev->irq.ih.ring_size,
106 PCI_DMA_BIDIRECTIONAL);
107 if (pci_dma_mapping_error(adev->pdev, adev->irq.ih.rb_dma_addr)) {
108 dev_err(&adev->pdev->dev, "Failed to DMA MAP the IH RB page\n");
109 kfree((void *)adev->irq.ih.ring);
110 return -ENOMEM;
111 }
112 adev->irq.ih.wptr_offs = (adev->irq.ih.ring_size / 4) + 0;
113 adev->irq.ih.rptr_offs = (adev->irq.ih.ring_size / 4) + 1;
114 }
115 return 0;
116 } else {
117 r = amdgpu_wb_get(adev, &adev->irq.ih.wptr_offs);
118 if (r) {
119 dev_err(adev->dev, "(%d) ih wptr_offs wb alloc failed\n", r);
120 return r;
121 }
122
123 r = amdgpu_wb_get(adev, &adev->irq.ih.rptr_offs);
124 if (r) {
125 amdgpu_wb_free(adev, adev->irq.ih.wptr_offs);
126 dev_err(adev->dev, "(%d) ih rptr_offs wb alloc failed\n", r);
127 return r;
128 }
129
130 return amdgpu_ih_ring_alloc(adev);
131 }
132}
133
134/**
135 * amdgpu_ih_ring_fini - tear down the IH state
136 *
137 * @adev: amdgpu_device pointer
138 *
139 * Tears down the IH state and frees buffer
140 * used for the IH ring buffer.
141 */
142void amdgpu_ih_ring_fini(struct amdgpu_device *adev)
143{
144 int r;
145
146 if (adev->irq.ih.use_bus_addr) {
147 if (adev->irq.ih.ring) {
148 /* add 8 bytes for the rptr/wptr shadows and
149 * add them to the end of the ring allocation.
150 */
151 pci_unmap_single(adev->pdev, adev->irq.ih.rb_dma_addr,
152 adev->irq.ih.ring_size + 8, PCI_DMA_BIDIRECTIONAL);
153 kfree((void *)adev->irq.ih.ring);
154 adev->irq.ih.ring = NULL;
155 }
156 } else {
157 if (adev->irq.ih.ring_obj) {
158 r = amdgpu_bo_reserve(adev->irq.ih.ring_obj, false);
159 if (likely(r == 0)) {
160 amdgpu_bo_kunmap(adev->irq.ih.ring_obj);
161 amdgpu_bo_unpin(adev->irq.ih.ring_obj);
162 amdgpu_bo_unreserve(adev->irq.ih.ring_obj);
163 }
164 amdgpu_bo_unref(&adev->irq.ih.ring_obj);
165 adev->irq.ih.ring = NULL;
166 adev->irq.ih.ring_obj = NULL;
167 }
168 amdgpu_wb_free(adev, adev->irq.ih.wptr_offs);
169 amdgpu_wb_free(adev, adev->irq.ih.rptr_offs);
170 }
171}
172
173/**
174 * amdgpu_ih_process - interrupt handler
175 *
176 * @adev: amdgpu_device pointer
177 *
178 * Interrupt hander (VI), walk the IH ring.
179 * Returns irq process return code.
180 */
181int amdgpu_ih_process(struct amdgpu_device *adev)
182{
183 struct amdgpu_iv_entry entry;
184 u32 wptr;
185
186 if (!adev->irq.ih.enabled || adev->shutdown)
187 return IRQ_NONE;
188
189 wptr = amdgpu_ih_get_wptr(adev);
190
191restart_ih:
192 /* is somebody else already processing irqs? */
193 if (atomic_xchg(&adev->irq.ih.lock, 1))
194 return IRQ_NONE;
195
196 DRM_DEBUG("%s: rptr %d, wptr %d\n", __func__, adev->irq.ih.rptr, wptr);
197
198 /* Order reading of wptr vs. reading of IH ring data */
199 rmb();
200
201 while (adev->irq.ih.rptr != wptr) {
202 amdgpu_ih_decode_iv(adev, &entry);
203 adev->irq.ih.rptr &= adev->irq.ih.ptr_mask;
204
205 amdgpu_irq_dispatch(adev, &entry);
206 }
207 amdgpu_ih_set_rptr(adev);
208 atomic_set(&adev->irq.ih.lock, 0);
209
210 /* make sure wptr hasn't changed while processing */
211 wptr = amdgpu_ih_get_wptr(adev);
212 if (wptr != adev->irq.ih.rptr)
213 goto restart_ih;
214
215 return IRQ_HANDLED;
216}
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h+62−0
@@ -0,0 +1,62 @@
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

51 more lines aren’t shown here.

drivers/gpu/drm/amd/amdgpu/amdgpu_ioc32.c+47−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c+458−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h+92−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c+697−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c+322−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h+586−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_object.c+670−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_object.h+203−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_pll.c+350−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_pll.h+38−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c+807−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h+35−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c+125−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c+561−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c+419−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c+102−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c+234−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_test.c+552−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h+208−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c+9−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c+1215−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c+317−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h+176−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c+984−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h+39−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c+724−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h+47−0

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

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c+1269−0

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

drivers/gpu/drm/amd/amdgpu/atom-bits.h+48−0

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

drivers/gpu/drm/amd/amdgpu/atom-names.h+100−0

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

drivers/gpu/drm/amd/amdgpu/atom-types.h+42−0

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

drivers/gpu/drm/amd/amdgpu/atom.c+1408−0

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

drivers/gpu/drm/amd/amdgpu/atom.h+159−0

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

drivers/gpu/drm/amd/amdgpu/atombios.h+8555−0

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

drivers/gpu/drm/amd/amdgpu/atombios_crtc.c+807−0

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

drivers/gpu/drm/amd/amdgpu/atombios_crtc.h+58−0

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

drivers/gpu/drm/amd/amdgpu/atombios_dp.c+775−0

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

drivers/gpu/drm/amd/amdgpu/atombios_dp.h+42−0

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

drivers/gpu/drm/amd/amdgpu/atombios_encoders.c+2066−0

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

drivers/gpu/drm/amd/amdgpu/atombios_encoders.h+73−0

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

drivers/gpu/drm/amd/amdgpu/atombios_i2c.c+158−0

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

drivers/gpu/drm/amd/amdgpu/atombios_i2c.h+31−0

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

drivers/gpu/drm/amd/amdgpu/ci_dpm.c+6699−0

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

drivers/gpu/drm/amd/amdgpu/ci_dpm.h+348−0

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

drivers/gpu/drm/amd/amdgpu/ci_smc.c+279−0

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

drivers/gpu/drm/amd/amdgpu/cik.c+2513−0

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

drivers/gpu/drm/amd/amdgpu/cik.h+33−0

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

drivers/gpu/drm/amd/amdgpu/cik_dpm.h+30−0

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

drivers/gpu/drm/amd/amdgpu/cik_ih.c+471−0

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

drivers/gpu/drm/amd/amdgpu/cik_ih.h+29−0

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

drivers/gpu/drm/amd/amdgpu/cik_sdma.c+1407−0

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

drivers/gpu/drm/amd/amdgpu/cik_sdma.h+29−0

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

drivers/gpu/drm/amd/amdgpu/cikd.h+555−0

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

drivers/gpu/drm/amd/amdgpu/clearstate_ci.h+944−0

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

drivers/gpu/drm/amd/amdgpu/clearstate_defs.h+44−0

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

drivers/gpu/drm/amd/amdgpu/clearstate_vi.h+944−0

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

drivers/gpu/drm/amd/amdgpu/cz_dpm.c+1941−0

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

drivers/gpu/drm/amd/amdgpu/cz_dpm.h+237−0

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

drivers/gpu/drm/amd/amdgpu/cz_ih.c+452−0

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

drivers/gpu/drm/amd/amdgpu/cz_ih.h+29−0

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

drivers/gpu/drm/amd/amdgpu/cz_ppsmc.h+185−0

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

drivers/gpu/drm/amd/amdgpu/cz_smc.c+962−0

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

drivers/gpu/drm/amd/amdgpu/cz_smumgr.h+94−0

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

drivers/gpu/drm/amd/amdgpu/dce_v10_0.c+3802−0

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

drivers/gpu/drm/amd/amdgpu/dce_v10_0.h+29−0

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

drivers/gpu/drm/amd/amdgpu/dce_v11_0.c+3801−0

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

drivers/gpu/drm/amd/amdgpu/dce_v11_0.h+29−0

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

drivers/gpu/drm/amd/amdgpu/dce_v8_0.c+3753−0

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

drivers/gpu/drm/amd/amdgpu/dce_v8_0.h+29−0

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

drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c+5644−0

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

drivers/gpu/drm/amd/amdgpu/gfx_v7_0.h+37−0

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

drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c+4329−0

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

drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h+33−0

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

drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c+1339−0

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

drivers/gpu/drm/amd/amdgpu/gmc_v7_0.h+36−0

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

drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c+1301−0

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

drivers/gpu/drm/amd/amdgpu/gmc_v8_0.h+36−0

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

drivers/gpu/drm/amd/amdgpu/iceland_dpm.c+195−0

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

drivers/gpu/drm/amd/amdgpu/iceland_ih.c+450−0

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

drivers/gpu/drm/amd/amdgpu/iceland_ih.h+29−0

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

drivers/gpu/drm/amd/amdgpu/iceland_sdma_pkt_open.h+2167−0

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

drivers/gpu/drm/amd/amdgpu/iceland_smc.c+675−0

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

drivers/gpu/drm/amd/amdgpu/iceland_smumgr.h+41−0

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

drivers/gpu/drm/amd/amdgpu/kv_dpm.c+3343−0

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

drivers/gpu/drm/amd/amdgpu/kv_dpm.h+229−0

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

drivers/gpu/drm/amd/amdgpu/kv_smc.c+219−0

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

drivers/gpu/drm/amd/amdgpu/ppsmc.h+196−0

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

drivers/gpu/drm/amd/amdgpu/pptable.h+698−0

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

drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c+1417−0

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

drivers/gpu/drm/amd/amdgpu/sdma_v2_4.h+29−0

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

drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c+1483−0

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

drivers/gpu/drm/amd/amdgpu/sdma_v3_0.h+29−0

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

drivers/gpu/drm/amd/amdgpu/smu7.h+170−0

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

drivers/gpu/drm/amd/amdgpu/smu7_discrete.h+514−0

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

drivers/gpu/drm/amd/amdgpu/smu7_fusion.h+300−0

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

drivers/gpu/drm/amd/amdgpu/smu8.h+72−0

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

drivers/gpu/drm/amd/amdgpu/smu8_fusion.h+127−0

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

drivers/gpu/drm/amd/amdgpu/smu_ucode_xfer_cz.h+147−0

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

drivers/gpu/drm/amd/amdgpu/smu_ucode_xfer_vi.h+100−0

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

drivers/gpu/drm/amd/amdgpu/tonga_dpm.c+194−0

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

drivers/gpu/drm/amd/amdgpu/tonga_ih.c+473−0

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

drivers/gpu/drm/amd/amdgpu/tonga_ih.h+29−0

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

drivers/gpu/drm/amd/amdgpu/tonga_ppsmc.h+198−0

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

drivers/gpu/drm/amd/amdgpu/tonga_sdma_pkt_open.h+2240−0

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

drivers/gpu/drm/amd/amdgpu/tonga_smc.c+852−0

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

drivers/gpu/drm/amd/amdgpu/tonga_smumgr.h+42−0

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

drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c+905−0

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

drivers/gpu/drm/amd/amdgpu/uvd_v4_2.h+29−0

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

drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c+844−0

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

drivers/gpu/drm/amd/amdgpu/uvd_v5_0.h+29−0

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

drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c+824−0

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

drivers/gpu/drm/amd/amdgpu/uvd_v6_0.h+29−0

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

drivers/gpu/drm/amd/amdgpu/vce_v2_0.c+663−0

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

drivers/gpu/drm/amd/amdgpu/vce_v2_0.h+29−0

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

drivers/gpu/drm/amd/amdgpu/vce_v3_0.c+573−0

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

drivers/gpu/drm/amd/amdgpu/vce_v3_0.h+29−0

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

drivers/gpu/drm/amd/amdgpu/vi.c+1377−0

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

drivers/gpu/drm/amd/amdgpu/vi.h+33−0

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

drivers/gpu/drm/amd/amdgpu/vi_dpm.h+36−0

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

drivers/gpu/drm/amd/amdgpu/vid.h+368−0

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

drivers/gpu/drm/amd/amdkfd/Makefile+2−0

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

drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c+66−0

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

drivers/gpu/drm/amd/amdkfd/cik_int.h+41−0

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

drivers/gpu/drm/amd/amdkfd/cik_regs.h+13−164

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

drivers/gpu/drm/amd/amdkfd/kfd_chardev.c+393−2

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

drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c+886−0

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

drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h+193−0

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

drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c+168−0

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

drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h+294−0

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

drivers/gpu/drm/amd/amdkfd/kfd_device.c+59−1

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

drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c+57−25

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

drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h+24−3

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

drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c+17−1

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

drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c+9−1

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

drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c+7−8

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

drivers/gpu/drm/amd/amdkfd/kfd_events.c+969−0

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

drivers/gpu/drm/amd/amdkfd/kfd_events.h+84−0

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

drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c+188−0

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

drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c+3−2

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

drivers/gpu/drm/amd/amdkfd/kfd_module.c+7−2

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

drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c+36−10

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

drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h+4−2

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

drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h+290−0

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

drivers/gpu/drm/amd/amdkfd/kfd_priv.h+95−4

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

drivers/gpu/drm/amd/amdkfd/kfd_process.c+47−2

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

drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c+17−1

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

drivers/gpu/drm/amd/include/amd_shared.h+81−0

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

drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_d.h+921−0

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

drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_sh_mask.h+10250−0

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

drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_d.h+1068−0

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

drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_enum.h+1198−0

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

drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_sh_mask.h+11494−0

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

drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_1_d.h+3577−0

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

drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_1_enum.h+1068−0

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

drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_1_sh_mask.h+33080−0

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

This diff is larger than a page shows: the files after these aren’t listed. Clone the repository to see all of it.