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
24392439 <title>Tile group</title>
24402440 !Pdrivers/gpu/drm/drm_crtc.c Tile group
24412441 </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>
24422454 </sect1>
24432455
24442456 <!-- Internals: kms properties -->
@@ -2573,7 +2585,22 @@ void intel_crt_init(struct drm_device *dev) · 128 unmodified lines
25732585 <td valign="top" >Description/Restrictions</td>
25742586 </tr>
25752587 <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>
25772604 <td rowspan="5" valign="top" >Connector</td>
25782605 <td valign="top" >“EDID”</td>
25792606 <td valign="top" >BLOB | IMMUTABLE</td>
@@ -2834,7 +2861,7 @@ void intel_crt_init(struct drm_device *dev) · 254 unmodified lines
28342861 <td valign="top" >TBD</td>
28352862 </tr>
28362863 <tr>
2837− <td rowspan="21" valign="top" >i915</td>
2864+ <td rowspan="20" valign="top" >i915</td>
28382865 <td rowspan="2" valign="top" >Generic</td>
28392866 <td valign="top" >"Broadcast RGB"</td>
28402867 <td valign="top" >ENUM</td>
@@ -2850,14 +2877,6 @@ void intel_crt_init(struct drm_device *dev) · 9 unmodified lines
28502877 <td valign="top" >TBD</td>
28512878 </tr>
28522879 <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>
28612880 <td rowspan="17" valign="top" >SDVO-TV</td>
28622881 <td valign="top" >“mode”</td>
28632882 <td valign="top" >ENUM</td>
@@ -3365,19 +3384,7 @@ void intel_crt_init(struct drm_device *dev) · 501 unmodified lines
33653384 </tr>
33663385 <tr>
33673386 <td rowspan="2" valign="top" >omap</td>
3368− <td rowspan="2" 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>
3387+ <td valign="top" >Generic</td>
33813388 <td valign="top" >“zorder”</td>
33823389 <td valign="top" >RANGE</td>
33833390 <td valign="top" >Min=0, Max=3</td>
@@ -4067,7 +4074,7 @@ int num_ioctls;</synopsis> · 683 unmodified lines
40674074 <title>DPIO</title>
40684075 !Pdrivers/gpu/drm/i915/i915_reg.h DPIO
40694076 <table id="dpiox2">
4070− <title>Dual channel PHY (VLV/CHV)</title>
4077+ <title>Dual channel PHY (VLV/CHV/BXT)</title>
40714078 <tgroup cols="8">
40724079 <colspec colname="c0" />
40734080 <colspec colname="c1" />
@@ -4118,7 +4125,7 @@ int num_ioctls;</synopsis> · 44 unmodified lines
41184125 </tgroup>
41194126 </table>
41204127 <table id="dpiox1">
4121− <title>Single channel PHY (CHV)</title>
4128+ <title>Single channel PHY (CHV/BXT)</title>
41224129 <tgroup cols="4">
41234130 <colspec colname="c0" />
41244131 <colspec colname="c1" />
@@ -4153,6 +4160,12 @@ int num_ioctls;</synopsis> · 28 unmodified lines
41534160 </tgroup>
41544161 </table>
41554162 </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>
41564169 </sect1>
41574170
41584171 <sect1>
@@ -4204,7 +4217,6 @@ int num_ioctls;</synopsis> · 45 unmodified lines
42044217 !Idrivers/gpu/drm/i915/i915_gem_shrinker.c
42054218 </sect2>
42064219 </sect1>
4207−
42084220 <sect1>
42094221 <title> Tracing </title>
42104222 <para>
Documentation/devicetree/bindings/drm/msm/dsi.txt+120−0
@@ -0,0 +1,120 @@
1+Qualcomm Technologies Inc. adreno/snapdragon DSI output
2+
3+DSI Controller:
4+Required 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+
29+Optional 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+
42+DSI PHY:
43+Required 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+
62+Example:
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 @@
1+Qualcomm Technologies Inc. adreno/snapdragon eDP output
2+
3+Required 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+
28+Optional properties:
29+- interrupt-parent: phandle to the MDP block if the interrupt signal is routed
30+ through MDP block
31+
32+Example:
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
2020 Optional properties:
2121 - qcom,hdmi-tx-mux-en-gpio: hdmi mux enable pin
2222 - 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
2326
2427 Example:
2528
@@ -44,5 +47,8 @@ Example: · 18 unmodified lines
4447 qcom,hdmi-tx-hpd = <&msmgpio 72 GPIO_ACTIVE_HIGH>;
4548 core-vdda-supply = <&pm8921_hdmi_mvs>;
4649 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>;
4753 };
4854 };
Documentation/devicetree/bindings/drm/tilcdc/slave.txt+0−18
@@ -1,18 +0,0 @@
1−Device-Tree bindings for tilcdc DRM encoder slave output driver
2−
3−Required properties:
4− - compatible: value should be "ti,tilcdc,slave".
5− - i2c: the phandle for the i2c device the encoder slave is connected to
6−
7−Recommended properties:
8− - pinctrl-names, pinctrl-0: the pincontrol settings to configure
9− muxing properly for pins that connect to TFP410 device
10−
11−Example:
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
1818 - max-pixelclock: The maximum pixel clock that can be supported
1919 by the lcd controller in KHz.
2020
21+Optional 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+
2127 Example:
2228
2329 fb: fb@4830e000 {
@@ -26,4 +32,25 @@ Example: · 2 unmodified lines
2632 interrupt-parent = <&intc>;
2733 interrupts = <36>;
2834 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+ };
2956 };
Documentation/devicetree/bindings/panel/hannstar,hsd100pxn1.txt+7−0
@@ -0,0 +1,7 @@
1+HannStar Display Corp. HSD100PXN1 10.1" XGA LVDS panel
2+
3+Required properties:
4+- compatible: should be "hannstar,hsd100pxn1"
5+
6+This binding is compatible with the simple-panel binding, which is specified
7+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/lg,lb070wv8.txt+7−0
@@ -0,0 +1,7 @@
1+LG 7" (800x480 pixels) TFT LCD panel
2+
3+Required properties:
4+- compatible: should be "lg,lb070wv8"
5+
6+This binding is compatible with the simple-panel binding, which is specified
7+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/video/exynos-mic.txt+51−0
@@ -0,0 +1,51 @@
1+Device-Tree bindings for Samsung Exynos SoC mobile image compressor (MIC)
2+
3+MIC (mobile image compressor) resides between decon and mipi dsi. Mipi dsi is
4+not capable to transfer high resoltuion frame data as decon can send. MIC
5+solves this problem by compressing the frame data by 1/2 before it is
6+transferred through mipi dsi. The compressed frame data must be uncompressed in
7+the panel PCB.
8+
9+Required 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+
23+Example:
24+SoC specific DT entry:
25+mic: 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 @@
1+Device-Tree bindings for Samsung Exynos SoC display controller (DECON)
2+
3+DECON (Display and Enhancement Controller) is the Display Controller for the
4+Exynos series of SoCs which transfers the image data from a video memory
5+buffer to an external LCD interface.
6+
7+Required properties:
8+- compatible: value should be "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+
33+Example:
34+SoC specific DT entry:
35+decon: 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+
61+Board 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
66 "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
77 "samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
88 "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
9+ "samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
910 - reg: physical base address and length of the registers set for the device
1011 - interrupts: should contain DSI interrupt
1112 - clocks: list of clock specifiers, must contain an entry for each required
1213 entry in clock-names
13− - clock-names: should include "bus_clk"and "pll_clk" entries
14+ - clock-names: should include "bus_clk"and "sclk_mipi" entries
15+ the use of "pll_clk" is deprecated
1416 - phys: list of phy specifiers, must contain an entry for each required
1517 entry in phy-names
1618 - phy-names: should include "dsim" entry
1719 - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)
1820 - 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" clock
21+ - samsung,pll-clock-frequency: specifies frequency of the oscillator clock
2022 - #address-cells, #size-cells: should be set respectively to <1> and <0>
2123 according to DSI host bindings (see MIPI DSI bindings [1])
2224
@@ -30,10 +32,19 @@ Video interfaces: · 7 unmodified lines
3032 Device node can contain video interface port nodes according to [2].
3133 The following are properties specific to those nodes:
3234
33− port node:
34− - reg: (required) can be 0 for input RGB/I80 port or 1 for DSI port;
35+ port node inbound:
36+ - reg: (required) must be 0.
37+ port node outbound:
38+ - reg: (required) must be 1.
3539
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.
3748 - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
3849 mode
3950 - samsung,esc-clock-frequency: specifies DSI frequency in escape mode
@@ -48,7 +59,7 @@ Example: · 8 unmodified lines
4859 reg = <0x11C80000 0x10000>;
4960 interrupts = <0 79 0>;
5061 clocks = <&clock 286>, <&clock 143>;
51− clock-names = "bus_clk", "pll_clk";
62+ clock-names = "bus_clk", "sclk_mipi";
5263 phys = <&mipi_phy 1>;
5364 phy-names = "dsim";
5465 vddcore-supply = <&vusb_reg>;
@@ -72,7 +83,15 @@ Example: · 17 unmodified lines
7283 #address-cells = <1>;
7384 #size-cells = <0>;
7485
86+ port@0 {
87+ reg = <0>;
88+ decon_to_mic: endpoint {
89+ remote-endpoint = <&mic_to_decon>;
90+ };
91+ };
92+
7593 port@1 {
94+ reg = <1>;
7695 dsi_ep: endpoint {
7796 reg = <0>;
7897 samsung,burst-clock-frequency = <500000000>;
MAINTAINERS+10−1
@@ -632,7 +632,7 @@ F: drivers/iommu/amd_iommu*.[ch] · 631 unmodified lines
632632 F: include/linux/amd-iommu.h
633633
634634 AMD KFD
635−M: Oded Gabbay <oded.gabbay@amd.com>
635+M: Oded Gabbay <oded.gabbay@gmail.com>
636636 L: dri-devel@lists.freedesktop.org
637637 T: git git://people.freedesktop.org/~gabbayo/linux.git
638638 S: Supported
@@ -10777,6 +10777,15 @@ F: drivers/block/virtio_blk.c · 10138 unmodified lines
1077710777 F: include/linux/virtio_*.h
1077810778 F: include/uapi/linux/virtio_*.h
1077910779
10780+VIRTIO GPU DRIVER
10781+M: David Airlie <airlied@linux.ie>
10782+M: Gerd Hoffmann <kraxel@redhat.com>
10783+L: dri-devel@lists.freedesktop.org
10784+L: virtualization@lists.linux-foundation.org
10785+S: Maintained
10786+F: drivers/gpu/drm/virtio/
10787+F: include/uapi/linux/virtio_gpu.h
10788+
1078010789 VIRTIO HOST (VHOST)
1078110790 M: "Michael S. Tsirkin" <mst@redhat.com>
1078210791 L: kvm@vger.kernel.org
arch/arm/boot/dts/exynos4.dtsi+1−1
@@ -166,7 +166,7 @@ · 165 unmodified lines
166166 phys = <&mipi_phy 1>;
167167 phy-names = "dsim";
168168 clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
169− clock-names = "bus_clk", "pll_clk";
169+ clock-names = "bus_clk", "sclk_mipi";
170170 status = "disabled";
171171 #address-cells = <1>;
172172 #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
546546 INTEL_BDW_D_IDS(&gen8_stolen_funcs),
547547 INTEL_CHV_IDS(&chv_stolen_funcs),
548548 INTEL_SKL_IDS(&gen9_stolen_funcs),
549+ INTEL_BXT_IDS(&gen9_stolen_funcs),
549550 };
550551
551552 static 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
120120
121121 source "drivers/gpu/drm/radeon/Kconfig"
122122
123+config 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+
142+source "drivers/gpu/drm/amd/amdgpu/Kconfig"
143+
123144 source "drivers/gpu/drm/nouveau/Kconfig"
124145
125146 config DRM_I810
@@ -206,6 +227,8 @@ source "drivers/gpu/drm/qxl/Kconfig" · 80 unmodified lines
206227
207228 source "drivers/gpu/drm/bochs/Kconfig"
208229
230+source "drivers/gpu/drm/virtio/Kconfig"
231+
209232 source "drivers/gpu/drm/msm/Kconfig"
210233
211234 source "drivers/gpu/drm/tegra/Kconfig"
drivers/gpu/drm/Makefile+3−3
@@ -2,8 +2,6 @@ · 1 unmodified line
22 # Makefile for the drm device driver. This driver provides support for the
33 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
44
5−ccflags-y := -Iinclude/drm
6−
75 drm-y := drm_auth.o drm_bufs.o drm_cache.o \
86 drm_context.o drm_dma.o \
97 drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
@@ -39,6 +37,7 @@ obj-$(CONFIG_DRM_TDFX) += tdfx/ · 29 unmodified lines
3937 obj-$(CONFIG_DRM_R128) += r128/
4038 obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
4139 obj-$(CONFIG_DRM_RADEON)+= radeon/
40+obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/
4241 obj-$(CONFIG_DRM_MGA) += mga/
4342 obj-$(CONFIG_DRM_I810) += i810/
4443 obj-$(CONFIG_DRM_I915) += i915/
@@ -60,9 +59,10 @@ obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/ · 15 unmodified lines
6059 obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
6160 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
6261 obj-$(CONFIG_DRM_OMAP) += omapdrm/
63−obj-$(CONFIG_DRM_TILCDC) += tilcdc/
62+obj-y += tilcdc/
6463 obj-$(CONFIG_DRM_QXL) += qxl/
6564 obj-$(CONFIG_DRM_BOCHS) += bochs/
65+obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/
6666 obj-$(CONFIG_DRM_MSM) += msm/
6767 obj-$(CONFIG_DRM_TEGRA) += tegra/
6868 obj-$(CONFIG_DRM_STI) += sti/
drivers/gpu/drm/amd/amdgpu/Kconfig+17−0
@@ -0,0 +1,17 @@
1+config 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+
11+config 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+
5+ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/asic_reg \
6+ -Idrivers/gpu/drm/amd/include
7+
8+amdgpu-y := amdgpu_drv.o
9+
10+# add KMS driver
11+amdgpu-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
23+amdgpu-$(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+
26+amdgpu-y += \
27+ vi.o
28+
29+# add GMC block
30+amdgpu-y += \
31+ gmc_v8_0.o
32+
33+# add IH block
34+amdgpu-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
42+amdgpu-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
49+amdgpu-y += \
50+ dce_v10_0.o \
51+ dce_v11_0.o
52+
53+# add GFX block
54+amdgpu-y += \
55+ amdgpu_gfx.o \
56+ gfx_v8_0.o
57+
58+# add async DMA block
59+amdgpu-y += \
60+ sdma_v2_4.o \
61+ sdma_v3_0.o
62+
63+# add UVD block
64+amdgpu-y += \
65+ amdgpu_uvd.o \
66+ uvd_v5_0.o \
67+ uvd_v6_0.o
68+
69+# add VCE block
70+amdgpu-y += \
71+ amdgpu_vce.o \
72+ vce_v3_0.o
73+
74+amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
75+amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
76+amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
77+amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o
78+
79+obj-$(CONFIG_DRM_AMDGPU)+= amdgpu.o
80+
81+CFLAGS_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+ */
59+extern int amdgpu_modeset;
60+extern int amdgpu_vram_limit;
61+extern int amdgpu_gart_size;
62+extern int amdgpu_benchmarking;
63+extern int amdgpu_testing;
64+extern int amdgpu_audio;
65+extern int amdgpu_disp_priority;
66+extern int amdgpu_hw_i2c;
67+extern int amdgpu_pcie_gen2;
68+extern int amdgpu_msi;
69+extern int amdgpu_lockup_timeout;
70+extern int amdgpu_dpm;
71+extern int amdgpu_smc_load_fw;
72+extern int amdgpu_aspm;
73+extern int amdgpu_runtime_pm;
74+extern int amdgpu_hard_reset;
75+extern unsigned amdgpu_ip_block_mask;
76+extern int amdgpu_bapm;
77+extern int amdgpu_deep_color;
78+extern int amdgpu_vm_size;
79+extern 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+
173+struct amdgpu_device;
174+struct amdgpu_fence;
175+struct amdgpu_ib;
176+struct amdgpu_vm;
177+struct amdgpu_ring;
178+struct amdgpu_semaphore;
179+struct amdgpu_cs_parser;
180+struct amdgpu_irq_src;
181+
182+enum 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+
196+enum amdgpu_sdma_irq {
197+ AMDGPU_SDMA_IRQ_TRAP0 = 0,
198+ AMDGPU_SDMA_IRQ_TRAP1,
199+
200+ AMDGPU_SDMA_IRQ_LAST
201+};
202+
203+enum 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+
210+int amdgpu_set_clockgating_state(struct amdgpu_device *adev,
211+ enum amd_ip_block_type block_type,
212+ enum amd_clockgating_state state);
213+int amdgpu_set_powergating_state(struct amdgpu_device *adev,
214+ enum amd_ip_block_type block_type,
215+ enum amd_powergating_state state);
216+
217+struct 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+
225+int amdgpu_ip_block_version_cmp(struct amdgpu_device *adev,
226+ enum amd_ip_block_type type,
227+ u32 major, u32 minor);
228+
229+const 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 */
234+struct 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 */
267+struct 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 */
287+struct 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 */
300+struct 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 */
309+struct 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+ */
340+bool amdgpu_get_bios(struct amdgpu_device *adev);
341+bool amdgpu_read_bios(struct amdgpu_device *adev);
342+
343+/*
344+ * Dummy page
345+ */
346+struct amdgpu_dummy_page {
347+ struct page *page;
348+ dma_addr_t addr;
349+};
350+int amdgpu_dummy_page_init(struct amdgpu_device *adev);
351+void amdgpu_dummy_page_fini(struct amdgpu_device *adev);
352+
353+
354+/*
355+ * Clocks
356+ */
357+
358+#define AMDGPU_MAX_PPLL 3
359+
360+struct 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+ */
376+struct 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+
398+struct 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+
411+struct 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+
418+int amdgpu_fence_driver_init(struct amdgpu_device *adev);
419+void amdgpu_fence_driver_fini(struct amdgpu_device *adev);
420+void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev);
421+
422+void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
423+int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
424+ struct amdgpu_irq_src *irq_src,
425+ unsigned irq_type);
426+int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,
427+ struct amdgpu_fence **fence);
428+void amdgpu_fence_process(struct amdgpu_ring *ring);
429+int amdgpu_fence_wait_next(struct amdgpu_ring *ring);
430+int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
431+unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring);
432+
433+bool amdgpu_fence_signaled(struct amdgpu_fence *fence);
434+int amdgpu_fence_wait(struct amdgpu_fence *fence, bool interruptible);
435+int amdgpu_fence_wait_any(struct amdgpu_device *adev,
436+ struct amdgpu_fence **fences,
437+ bool intr);
438+long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev,
439+ u64 *target_seq, bool intr,
440+ long timeout);
441+struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence);
442+void amdgpu_fence_unref(struct amdgpu_fence **fence);
443+
444+bool amdgpu_fence_need_sync(struct amdgpu_fence *fence,
445+ struct amdgpu_ring *ring);
446+void amdgpu_fence_note_sync(struct amdgpu_fence *fence,
447+ struct amdgpu_ring *ring);
448+
449+static 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+
469+static 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+
485+int 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+ */
491+struct 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+
508+int 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);
514+int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
515+
516+struct 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+
525+struct 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 */
533+struct 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+
551+struct 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+
582+void amdgpu_gem_object_free(struct drm_gem_object *obj);
583+int amdgpu_gem_object_open(struct drm_gem_object *obj,
584+ struct drm_file *file_priv);
585+void amdgpu_gem_object_close(struct drm_gem_object *obj,
586+ struct drm_file *file_priv);
587+unsigned long amdgpu_gem_timeout(uint64_t timeout_ns);
588+struct sg_table *amdgpu_gem_prime_get_sg_table(struct drm_gem_object *obj);
589+struct drm_gem_object *amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
590+ struct dma_buf_attachment *attach,
591+ struct sg_table *sg);
592+struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev,
593+ struct drm_gem_object *gobj,
594+ int flags);
595+int amdgpu_gem_prime_pin(struct drm_gem_object *obj);
596+void amdgpu_gem_prime_unpin(struct drm_gem_object *obj);
597+struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *);
598+void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj);
599+void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
600+int 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+ */
625+struct 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+
638+struct amdgpu_sa_bo;
639+
640+/* sub-allocation buffer */
641+struct 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+ */
653+struct amdgpu_gem {
654+ struct mutex mutex;
655+ struct list_head objects;
656+};
657+
658+int amdgpu_gem_init(struct amdgpu_device *adev);
659+void amdgpu_gem_fini(struct amdgpu_device *adev);
660+int 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+
665+int amdgpu_mode_dumb_create(struct drm_file *file_priv,
666+ struct drm_device *dev,
667+ struct drm_mode_create_dumb *args);
668+int 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+ */
675+struct amdgpu_semaphore {
676+ struct amdgpu_sa_bo *sa_bo;
677+ signed waiters;
678+ uint64_t gpu_addr;
679+};
680+
681+int amdgpu_semaphore_create(struct amdgpu_device *adev,
682+ struct amdgpu_semaphore **semaphore);
683+bool amdgpu_semaphore_emit_signal(struct amdgpu_ring *ring,
684+ struct amdgpu_semaphore *semaphore);
685+bool amdgpu_semaphore_emit_wait(struct amdgpu_ring *ring,
686+ struct amdgpu_semaphore *semaphore);
687+void amdgpu_semaphore_free(struct amdgpu_device *adev,
688+ struct amdgpu_semaphore **semaphore,
689+ struct amdgpu_fence *fence);
690+
691+/*
692+ * Synchronization
693+ */
694+struct 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+
700+void amdgpu_sync_create(struct amdgpu_sync *sync);
701+void amdgpu_sync_fence(struct amdgpu_sync *sync,
702+ struct amdgpu_fence *fence);
703+int amdgpu_sync_resv(struct amdgpu_device *adev,
704+ struct amdgpu_sync *sync,
705+ struct reservation_object *resv,
706+ void *owner);
707+int amdgpu_sync_rings(struct amdgpu_sync *sync,
708+ struct amdgpu_ring *ring);
709+void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync,
710+ struct amdgpu_fence *fence);
711+
712+/*
713+ * GART structures, functions & helpers
714+ */
715+struct 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+
722+struct 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+
735+int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev);
736+void amdgpu_gart_table_ram_free(struct amdgpu_device *adev);
737+int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
738+void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
739+int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
740+void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
741+int amdgpu_gart_init(struct amdgpu_device *adev);
742+void amdgpu_gart_fini(struct amdgpu_device *adev);
743+void amdgpu_gart_unbind(struct amdgpu_device *adev, unsigned offset,
744+ int pages);
745+int 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+ */
752+struct 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+ */
779+typedef 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+
800+struct 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+
808+void 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+
817+struct 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+
833+struct 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+
850+enum 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+
858+struct 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+
928+struct amdgpu_vm_pt {
929+ struct amdgpu_bo *bo;
930+ uint64_t addr;
931+};
932+
933+struct 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+
942+struct 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+
967+struct 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+
987+struct amdgpu_ctx_state {
988+ uint64_t flags;
989+ uint32_t hangs;
990+};
991+
992+struct 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+
1001+struct 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+
1012+struct 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+
1023+struct 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+
1033+struct amdgpu_bo_list *
1034+amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id);
1035+void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
1036+void amdgpu_bo_list_free(struct amdgpu_bo_list *list);
1037+
1038+/*
1039+ * GFX stuff
1040+ */
1041+#include "clearstate_defs.h"
1042+
1043+struct 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+
1063+struct 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+ */
1074+struct 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+ */
1084+struct 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+
1113+struct 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+
1149+int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm,
1150+ unsigned size, struct amdgpu_ib *ib);
1151+void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib);
1152+int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,
1153+ struct amdgpu_ib *ib, void *owner);
1154+int amdgpu_ib_pool_init(struct amdgpu_device *adev);
1155+void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
1156+int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
1157+/* Ring access between begin & end cannot sleep */
1158+void amdgpu_ring_free_size(struct amdgpu_ring *ring);
1159+int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
1160+int amdgpu_ring_lock(struct amdgpu_ring *ring, unsigned ndw);
1161+void amdgpu_ring_commit(struct amdgpu_ring *ring);
1162+void amdgpu_ring_unlock_commit(struct amdgpu_ring *ring);
1163+void amdgpu_ring_undo(struct amdgpu_ring *ring);
1164+void amdgpu_ring_unlock_undo(struct amdgpu_ring *ring);
1165+void amdgpu_ring_lockup_update(struct amdgpu_ring *ring);
1166+bool amdgpu_ring_test_lockup(struct amdgpu_ring *ring);
1167+unsigned amdgpu_ring_backup(struct amdgpu_ring *ring,
1168+ uint32_t **data);
1169+int amdgpu_ring_restore(struct amdgpu_ring *ring,
1170+ unsigned size, uint32_t *data);
1171+int 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);
1175+void amdgpu_ring_fini(struct amdgpu_ring *ring);
1176+
1177+/*
1178+ * CS.
1179+ */
1180+struct amdgpu_cs_chunk {
1181+ uint32_t chunk_id;
1182+ uint32_t length_dw;
1183+ uint32_t *kdata;
1184+ void __user *user_ptr;
1185+};
1186+
1187+struct 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+
1208+static 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+
1218+struct 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+
1226+int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb);
1227+void 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+
1234+enum 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+
1255+enum 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+
1271+enum amdgpu_dpm_auto_throttle_src {
1272+ AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL,
1273+ AMDGPU_DPM_AUTO_THROTTLE_SRC_EXTERNAL
1274+};
1275+
1276+enum 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+
1286+enum 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+
1295+struct 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+
1311+struct 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+
1324+enum amdgpu_clk_action
1325+{
1326+ AMDGPU_SCLK_UP = 1,
1327+ AMDGPU_SCLK_DOWN
1328+};
1329+
1330+struct amdgpu_blacklist_clocks
1331+{
1332+ u32 sclk;
1333+ u32 mclk;
1334+ enum amdgpu_clk_action action;
1335+};
1336+
1337+struct amdgpu_clock_and_voltage_limits {
1338+ u32 sclk;
1339+ u32 mclk;
1340+ u16 vddc;
1341+ u16 vddci;
1342+};
1343+
1344+struct amdgpu_clock_array {
1345+ u32 count;
1346+ u32 *values;
1347+};
1348+
1349+struct amdgpu_clock_voltage_dependency_entry {
1350+ u32 clk;
1351+ u16 v;
1352+};
1353+
1354+struct amdgpu_clock_voltage_dependency_table {
1355+ u32 count;
1356+ struct amdgpu_clock_voltage_dependency_entry *entries;
1357+};
1358+
1359+union 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+
1371+struct amdgpu_cac_leakage_table {
1372+ u32 count;
1373+ union amdgpu_cac_leakage_entry *entries;
1374+};
1375+
1376+struct amdgpu_phase_shedding_limits_entry {
1377+ u16 voltage;
1378+ u32 sclk;
1379+ u32 mclk;
1380+};
1381+
1382+struct amdgpu_phase_shedding_limits_table {
1383+ u32 count;
1384+ struct amdgpu_phase_shedding_limits_entry *entries;
1385+};
1386+
1387+struct amdgpu_uvd_clock_voltage_dependency_entry {
1388+ u32 vclk;
1389+ u32 dclk;
1390+ u16 v;
1391+};
1392+
1393+struct amdgpu_uvd_clock_voltage_dependency_table {
1394+ u8 count;
1395+ struct amdgpu_uvd_clock_voltage_dependency_entry *entries;
1396+};
1397+
1398+struct amdgpu_vce_clock_voltage_dependency_entry {
1399+ u32 ecclk;
1400+ u32 evclk;
1401+ u16 v;
1402+};
1403+
1404+struct amdgpu_vce_clock_voltage_dependency_table {
1405+ u8 count;
1406+ struct amdgpu_vce_clock_voltage_dependency_entry *entries;
1407+};
1408+
1409+struct 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+
1422+struct 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+
1433+struct 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+
1458+struct 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+
1475+enum 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+
1482+enum 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+
1488+struct 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+
1499+struct 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+
1520+struct 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+
1567+struct 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+
1598+struct 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+
1618+struct 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+ */
1634+struct 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+ */
1645+struct 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+ */
1655+void amdgpu_benchmark(struct amdgpu_device *adev, int test_number);
1656+
1657+
1658+/*
1659+ * Testing
1660+ */
1661+void amdgpu_test_moves(struct amdgpu_device *adev);
1662+void amdgpu_test_ring_sync(struct amdgpu_device *adev,
1663+ struct amdgpu_ring *cpA,
1664+ struct amdgpu_ring *cpB);
1665+void amdgpu_test_syncing(struct amdgpu_device *adev);
1666+
1667+/*
1668+ * MMU Notifier
1669+ */
1670+#if defined(CONFIG_MMU_NOTIFIER)
1671+int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr);
1672+void amdgpu_mn_unregister(struct amdgpu_bo *bo);
1673+#else
1674+static int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
1675+{
1676+ return -ENODEV;
1677+}
1678+static void amdgpu_mn_unregister(struct amdgpu_bo *bo) {}
1679+#endif
1680+
1681+/*
1682+ * Debugfs
1683+ */
1684+struct amdgpu_debugfs {
1685+ struct drm_info_list *files;
1686+ unsigned num_files;
1687+};
1688+
1689+int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
1690+ struct drm_info_list *files,
1691+ unsigned nfiles);
1692+int amdgpu_debugfs_fence_init(struct amdgpu_device *adev);
1693+
1694+#if defined(CONFIG_DEBUG_FS)
1695+int amdgpu_debugfs_init(struct drm_minor *minor);
1696+void amdgpu_debugfs_cleanup(struct drm_minor *minor);
1697+#endif
1698+
1699+/*
1700+ * amdgpu smumgr functions
1701+ */
1702+struct 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+ */
1711+struct 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+ */
1726+struct amdgpu_allowed_register_entry {
1727+ uint32_t reg_offset;
1728+ bool untouched;
1729+ bool grbm_indexed;
1730+};
1731+
1732+struct 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+ */
1742+struct 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+ */
1763+int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
1764+ struct drm_file *filp);
1765+int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
1766+ struct drm_file *filp);
1767+
1768+int amdgpu_gem_info_ioctl(struct drm_device *dev, void *data,
1769+ struct drm_file *filp);
1770+int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
1771+ struct drm_file *filp);
1772+int amdgpu_gem_mmap_ioctl(struct drm_device *dev, void *data,
1773+ struct drm_file *filp);
1774+int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
1775+ struct drm_file *filp);
1776+int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
1777+ struct drm_file *filp);
1778+int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
1779+ struct drm_file *filp);
1780+int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
1781+int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
1782+
1783+int 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 */
1787+struct amdgpu_vram_scratch {
1788+ struct amdgpu_bo *robj;
1789+ volatile uint32_t *ptr;
1790+ u64 gpu_addr;
1791+};
1792+
1793+/*
1794+ * ACPI
1795+ */
1796+struct amdgpu_atif_notification_cfg {
1797+ bool enabled;
1798+ int command_code;
1799+};
1800+
1801+struct 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+
1813+struct 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+
1826+struct 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+
1833+struct 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+
1840+struct amdgpu_atcs {
1841+ struct amdgpu_atcs_functions functions;
1842+};
1843+
1844+int amdgpu_ctx_alloc(struct amdgpu_device *adev,struct amdgpu_fpriv *fpriv,
1845+ uint32_t *id,uint32_t flags);
1846+int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
1847+ uint32_t id);
1848+
1849+void amdgpu_ctx_fini(struct amdgpu_fpriv *fpriv);
1850+struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id);
1851+int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
1852+
1853+extern int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
1854+ struct drm_file *filp);
1855+
1856+/*
1857+ * Core structure, functions and helpers.
1858+ */
1859+typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device*, uint32_t);
1860+typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
1861+
1862+typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
1863+typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);
1864+
1865+struct 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+
2016+bool amdgpu_device_is_px(struct drm_device *dev);
2017+int amdgpu_device_init(struct amdgpu_device *adev,
2018+ struct drm_device *ddev,
2019+ struct pci_dev *pdev,
2020+ uint32_t flags);
2021+void amdgpu_device_fini(struct amdgpu_device *adev);
2022+int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
2023+
2024+uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
2025+ bool always_indirect);
2026+void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
2027+ bool always_indirect);
2028+u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg);
2029+void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v);
2030+
2031+u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index);
2032+void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
2033+
2034+/*
2035+ * Cast helper
2036+ */
2037+extern const struct fence_ops amdgpu_fence_ops;
2038+static 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+ */
2111+static 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 */
2196+int amdgpu_gpu_reset(struct amdgpu_device *adev);
2197+void amdgpu_pci_config_reset(struct amdgpu_device *adev);
2198+bool amdgpu_card_posted(struct amdgpu_device *adev);
2199+void amdgpu_update_display_priority(struct amdgpu_device *adev);
2200+bool amdgpu_boot_test_post_card(struct amdgpu_device *adev);
2201+int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data);
2202+int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,
2203+ u32 ip_instance, u32 ring,
2204+ struct amdgpu_ring **out_ring);
2205+void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain);
2206+bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
2207+int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
2208+ uint32_t flags);
2209+bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
2210+bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
2211+uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
2212+ struct ttm_mem_reg *mem);
2213+void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base);
2214+void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
2215+void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
2216+void amdgpu_program_register_sequence(struct amdgpu_device *adev,
2217+ const u32 *registers,
2218+ const u32 array_size);
2219+
2220+bool amdgpu_device_is_px(struct drm_device *dev);
2221+/* atpx handler */
2222+#if defined(CONFIG_VGA_SWITCHEROO)
2223+void amdgpu_register_atpx_handler(void);
2224+void amdgpu_unregister_atpx_handler(void);
2225+#else
2226+static inline void amdgpu_register_atpx_handler(void) {}
2227+static inline void amdgpu_unregister_atpx_handler(void) {}
2228+#endif
2229+
2230+/*
2231+ * KMS
2232+ */
2233+extern const struct drm_ioctl_desc amdgpu_ioctls_kms[];
2234+extern int amdgpu_max_kms_ioctl;
2235+
2236+int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags);
2237+int amdgpu_driver_unload_kms(struct drm_device *dev);
2238+void amdgpu_driver_lastclose_kms(struct drm_device *dev);
2239+int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv);
2240+void amdgpu_driver_postclose_kms(struct drm_device *dev,
2241+ struct drm_file *file_priv);
2242+void amdgpu_driver_preclose_kms(struct drm_device *dev,
2243+ struct drm_file *file_priv);
2244+int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon);
2245+int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
2246+u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, int crtc);
2247+int amdgpu_enable_vblank_kms(struct drm_device *dev, int crtc);
2248+void amdgpu_disable_vblank_kms(struct drm_device *dev, int crtc);
2249+int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
2250+ int *max_error,
2251+ struct timeval *vblank_time,
2252+ unsigned flags);
2253+long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd,
2254+ unsigned long arg);
2255+
2256+/*
2257+ * vm
2258+ */
2259+int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
2260+void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
2261+struct amdgpu_bo_list_entry *amdgpu_vm_get_bos(struct amdgpu_device *adev,
2262+ struct amdgpu_vm *vm,
2263+ struct list_head *head);
2264+struct amdgpu_fence *amdgpu_vm_grab_id(struct amdgpu_ring *ring,
2265+ struct amdgpu_vm *vm);
2266+void amdgpu_vm_flush(struct amdgpu_ring *ring,
2267+ struct amdgpu_vm *vm,
2268+ struct amdgpu_fence *updates);
2269+void amdgpu_vm_fence(struct amdgpu_device *adev,
2270+ struct amdgpu_vm *vm,
2271+ struct amdgpu_fence *fence);
2272+uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr);
2273+int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
2274+ struct amdgpu_vm *vm);
2275+int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
2276+ struct amdgpu_vm *vm);
2277+int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
2278+ struct amdgpu_vm *vm, struct amdgpu_sync *sync);
2279+int amdgpu_vm_bo_update(struct amdgpu_device *adev,
2280+ struct amdgpu_bo_va *bo_va,
2281+ struct ttm_mem_reg *mem);
2282+void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
2283+ struct amdgpu_bo *bo);
2284+struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
2285+ struct amdgpu_bo *bo);
2286+struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
2287+ struct amdgpu_vm *vm,
2288+ struct amdgpu_bo *bo);
2289+int 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);
2293+int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
2294+ struct amdgpu_bo_va *bo_va,
2295+ uint64_t addr);
2296+void 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+ */
2302+struct 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+
2316+struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock);
2317+
2318+/* amdgpu_acpi.c */
2319+#if defined(CONFIG_ACPI)
2320+int amdgpu_acpi_init(struct amdgpu_device *adev);
2321+void amdgpu_acpi_fini(struct amdgpu_device *adev);
2322+bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev);
2323+int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
2324+ u8 perf_req, bool advertise);
2325+int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
2326+#else
2327+static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; }
2328+static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
2329+#endif
2330+
2331+struct amdgpu_bo_va_mapping *
2332+amdgpu_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+
38+extern void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev);
39+
40+struct 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+
47+struct 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+
54+struct 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+
71+struct 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+
79+struct 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+
88+struct 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+ */
105+static 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+ */
152+static 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+ */
175+static 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+ */
200+static 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+
230+out:
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+ */
247+static 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+
290+out:
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+ */
309+static 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+
333+out:
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+ */
348+int 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+ */
415+static 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+ */
462+static 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+ */
481+static 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+
510+out:
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+ */
524+bool 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+ */
543+int 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+ */
577+int 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+ */
655+static 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+ */
685+int 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+
751+out:
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+ */
765+void 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+
27+struct amdgpu_device;
28+struct acpi_bus_event;
29+
30+int 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+
32+static 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+ */
51+static 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+
88+struct 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+
37+static void amdgpu_atombios_lookup_i2c_gpio_quirks(struct amdgpu_device *adev,
38+ ATOM_GPIO_I2C_ASSIGMENT *gpio,
39+ u8 index)
40+{
41+
42+}
43+
44+static 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+
87+struct 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+
124+void 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+
157+struct amdgpu_gpio_rec
158+amdgpu_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+
196+static struct amdgpu_hpd
197+amdgpu_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+
237+static 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+
247+static 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+
272+bool 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+
538+union 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+
547+int 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+
698+union 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+
707+static 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+
799+union 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+
805+union 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+
811+bool 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+
917+union 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+
927+int 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+
975+int 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+
1026+uint32_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+
1035+uint32_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+
1044+void 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+
1055+void 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+
1069+void 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+
1088+union 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+
1095+void 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+
1134+int 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+
1163+int 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+
1249+union 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+
1254+int 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+
1285+union 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+
1291+union 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+
1298+static 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+
1315+bool
1316+amdgpu_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+
1351+int 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+
1408+union 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+
1422+int 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+
1513+void 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+
1530+void 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+
1550+void 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+
1558+void 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+ */
1571+void 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+
27+struct 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+
53+struct 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+
85+struct atom_memory_info {
86+ u8 mem_vendor;
87+ u8 mem_type;
88+};
89+
90+#define MAX_AC_TIMING_ENTRIES 16
91+
92+struct 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+
102+struct atom_mc_reg_entry {
103+ u32 mclk_max;
104+ u32 mc_data[VBIOS_MC_REGISTER_ARRAY_SIZE];
105+};
106+
107+struct atom_mc_register_address {
108+ u16 s1;
109+ u8 pre_reg_data;
110+};
111+
112+struct 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+
121+struct atom_voltage_table_entry
122+{
123+ u16 value;
124+ u32 smio_low;
125+};
126+
127+struct 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+
135+struct amdgpu_gpio_rec
136+amdgpu_atombios_lookup_gpio(struct amdgpu_device *adev,
137+ u8 id);
138+
139+struct amdgpu_i2c_bus_rec amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device *adev,
140+ uint8_t id);
141+void amdgpu_atombios_i2c_init(struct amdgpu_device *adev);
142+
143+bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev);
144+
145+int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev);
146+
147+bool amdgpu_atombios_get_asic_ss_info(struct amdgpu_device *adev,
148+ struct amdgpu_atom_ss *ss,
149+ int id, u32 clock);
150+
151+int 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+
157+int 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+
162+uint32_t amdgpu_atombios_get_engine_clock(struct amdgpu_device *adev);
163+uint32_t amdgpu_atombios_get_memory_clock(struct amdgpu_device *adev);
164+void amdgpu_atombios_set_engine_clock(struct amdgpu_device *adev,
165+ uint32_t eng_clock);
166+void amdgpu_atombios_set_memory_clock(struct amdgpu_device *adev,
167+ uint32_t mem_clock);
168+void amdgpu_atombios_set_voltage(struct amdgpu_device *adev,
169+ u16 voltage_level,
170+ u8 voltage_type);
171+
172+void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
173+ u32 eng_clock, u32 mem_clock);
174+
175+int amdgpu_atombios_get_leakage_id_from_vbios(struct amdgpu_device *adev,
176+ u16 *leakage_id);
177+
178+int 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+
183+int amdgpu_atombios_get_voltage_evv(struct amdgpu_device *adev,
184+ u16 virtual_voltage_id,
185+ u16 *voltage);
186+
187+bool
188+amdgpu_atombios_is_voltage_gpio(struct amdgpu_device *adev,
189+ u8 voltage_type, u8 voltage_mode);
190+
191+int amdgpu_atombios_get_voltage_table(struct amdgpu_device *adev,
192+ u8 voltage_type, u8 voltage_mode,
193+ struct atom_voltage_table *voltage_table);
194+
195+int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
196+ u8 module_index,
197+ struct atom_mc_reg_table *reg_table);
198+
199+void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock);
200+void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev);
201+void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev);
202+void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev);
203+
204+void 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+
16+struct 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+
27+struct amdgpu_atpx {
28+ acpi_handle handle;
29+ struct amdgpu_atpx_functions functions;
30+};
31+
32+static 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+
40+struct 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+
46+struct 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+
52+struct atpx_power_control {
53+ u16 size;
54+ u8 dgpu_state;
55+} __packed;
56+
57+struct atpx_mux {
58+ u16 size;
59+ u16 mux;
60+} __packed;
61+
62+bool 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+ */
76+static 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+ */
123+static 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+ */
143+static 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+ */
198+static 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+
227+out:
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+ */
242+static 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+ */
274+static 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+ */
306+static 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+ */
338+static 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+ */
370+static 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+ */
400+static 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+ */
427+static 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+ */
446+static 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+ */
471+static 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+ */
496+static 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+
504+static 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+ */
517+static 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+ */
552+void 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+ */
569+void 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+
31+static 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+
53+exit_do_move:
54+ if (fence)
55+ amdgpu_fence_unref(&fence);
56+ return r;
57+}
58+
59+
60+static 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+
72+static 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+
116+out_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+
139+void 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+ */
45+static 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+
76+bool 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+
105+static 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+ */
146+static 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+
176+static 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
241+static inline bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
242+{
243+ return false;
244+}
245+#endif
246+
247+static 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
256+static 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+
301+out_unmap:
302+ return ret;
303+}
304+#else
305+static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
306+{
307+ return false;
308+}
309+#endif
310+
311+bool 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;
359+free_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+
34+static 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+
64+static 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+
79+static 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+
143+error_free:
144+ drm_free_large(array);
145+ return -ENOENT;
146+}
147+
148+struct amdgpu_bo_list *
149+amdgpu_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+
161+void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
162+{
163+ mutex_unlock(&list->lock);
164+}
165+
166+void 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+
178+int 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+
265+error_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+
40+void 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+
90+static 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+
100+int 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+
213+static void
214+amdgpu_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+
244+static struct drm_encoder *
245+amdgpu_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+
265+struct 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+
280+static struct edid *
281+amdgpu_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+
297+static 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+
340+static 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+
350+static 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+
365+static struct drm_encoder *
366+amdgpu_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+
376+static 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+
397+static struct drm_display_mode *
398+amdgpu_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+
429+static 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+
481+static 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+
626+static void
627+amdgpu_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+
662+static 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+
699+static 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+
729+static enum drm_connector_status
730+amdgpu_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+
763+static 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+
776+static 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+
812+static 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+
818+static 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+
826+static 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+
836+static 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+
850+static enum drm_connector_status
851+amdgpu_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+
915+out:
916+ pm_runtime_mark_last_busy(connector->dev->dev);
917+ pm_runtime_put_autosuspend(connector->dev->dev);
918+
919+ return ret;
920+}
921+
922+static 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+
928+static 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+
936+static bool
937+amdgpu_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+ */
967+static enum drm_connector_status
968+amdgpu_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+
1101+out:
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+
1105+exit:
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 */
1113+static struct drm_encoder *
1114+amdgpu_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+
1147+static 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+
1156+static 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+
1188+static 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+
1194+static 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+
1203+static 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+
1273+u16 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+
1302+static 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+
1325+bool 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+
1338+static enum drm_connector_status
1339+amdgpu_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);
1418+out:
1419+ pm_runtime_mark_last_busy(connector->dev->dev);
1420+ pm_runtime_put_autosuspend(connector->dev->dev);
1421+
1422+ return ret;
1423+}
1424+
1425+static 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+
1478+static 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+
1484+static 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+
1493+static 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+
1502+void
1503+amdgpu_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+
1904+failed:
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+
27+struct edid *amdgpu_connector_edid(struct drm_connector *connector);
28+void amdgpu_connector_hotplug(struct drm_connector *connector);
29+int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector);
30+u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector);
31+bool amdgpu_connector_is_dp12_capable(struct drm_connector *connector);
32+void
33+amdgpu_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+ */
40+struct amdgpu_cs_buckets {
41+ struct list_head bucket[AMDGPU_CS_NUM_BUCKETS];
42+};
43+
44+static 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+
52+static 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+
63+static 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+
74+int 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+
129+int 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+
233+out:
234+ kfree(chunk_array);
235+ return r;
236+}
237+
238+/* Returns how many bytes TTM can move per IB.
239+ */
240+static 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+
290+int 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+
351+static 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+
382+static 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+
397+static 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+ **/
415+static 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+
455+static 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+
493+static 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+
524+out:
525+ mutex_unlock(&vm->mutex);
526+ return r;
527+}
528+
529+static 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+
539+static 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+
657+int 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;
712+out:
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+ */
728+int 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+ */
772+struct amdgpu_bo_va_mapping *
773+amdgpu_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+
28+static 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+
40+int 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+
68+int 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+
84+static 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+
116+void 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+
132+int 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+
165+struct 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+
178+int 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+
47+static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
48+static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev);
49+
50+static 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+
62+bool 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+ */
74+uint32_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+
92+void 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+
107+u32 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+
117+void 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+ */
137+u32 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+ */
157+void 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+ */
176+static 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+ */
193+static 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+ */
211+static 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+ */
231+static 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+
240+static 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+
271+static 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+ */
297+void 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+
323+void 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+ */
339+static 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+ */
367+static 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+ */
386+void 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+ */
421+static 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+ */
444+static 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+ */
495+int 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+ */
515+void 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+ */
553+void 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+ */
583+void 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+ */
619+bool 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+ */
642+bool 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+ */
668+int 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+ */
693+void 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+ */
722+static 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+ */
736+static 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+ */
750+static 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+ */
764+static 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+ */
778+static 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+ */
794+static 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+ */
812+static 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+ */
828+static 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+ */
846+static 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+ */
866+static 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+ */
914+static 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+ */
933+static 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+ */
946+static 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+ */
1027+static 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+ */
1065+static 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+
1077+static 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+
1083+int 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+
1100+int 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+
1117+const 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+ */
1141+int 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+
1156+static 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+
1218+static 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+
1256+static 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+
1278+static 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+
1309+static 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+
1327+static 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+ */
1354+int 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+
1556+static 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+ */
1566+void 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+ */
1613+int 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+ */
1703+int 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+ */
1765+int 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+
1803+retry:
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+ */
1854+int 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+
1888+static 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+
1906+static 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+
1936+static 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+
1967+static 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+
1974+static 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+
1989+static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev)
1990+{
1991+ debugfs_remove(adev->debugfs_regs);
1992+ adev->debugfs_regs = NULL;
1993+}
1994+
1995+int amdgpu_debugfs_init(struct drm_minor *minor)
1996+{
1997+ return 0;
1998+}
1999+
2000+void 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+
39+static 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+ */
93+static 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+
114+int 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+
200+vblank_cleanup:
201+ drm_vblank_put(crtc->dev, amdgpu_crtc->crtc_id);
202+
203+pflip_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+
213+cleanup:
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+
221+int 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+
265+static 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+
306+static const char *hpd_names[6] = {
307+ "HPD1",
308+ "HPD2",
309+ "HPD3",
310+ "HPD4",
311+ "HPD5",
312+ "HPD6",
313+};
314+
315+void 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+ */
395+bool 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+
442+static 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+
453+static 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+
462+static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
463+ .destroy = amdgpu_user_framebuffer_destroy,
464+ .create_handle = amdgpu_user_framebuffer_create_handle,
465+};
466+
467+int
468+amdgpu_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+
484+static struct drm_framebuffer *
485+amdgpu_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+
516+static 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+
522+const 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+
527+static struct drm_prop_enum_list amdgpu_underscan_enum_list[] =
528+{ { UNDERSCAN_OFF, "off" },
529+ { UNDERSCAN_ON, "on" },
530+ { UNDERSCAN_AUTO, "auto" },
531+};
532+
533+static 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. */
540+static struct drm_prop_enum_list amdgpu_dither_enum_list[] =
541+{ { AMDGPU_FMT_DITHER_DISABLE, "off" },
542+ { AMDGPU_FMT_DITHER_ENABLE, "on" },
543+};
544+
545+int 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+
596+void 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+
606+static 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+
618+bool 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+ */
722+int 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+
811+int 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+
32+void 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+
91+void 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+
103+void 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+
116+u32 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+
142+u32 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+
162+void 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+
181+int 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+
202+bool 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+
217+bool 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+
240+union 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+
251+union fan_info {
252+ struct _ATOM_PPLIB_FANTABLE fan;
253+ struct _ATOM_PPLIB_FANTABLE2 fan2;
254+ struct _ATOM_PPLIB_FANTABLE3 fan3;
255+};
256+
257+static 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+
282+int 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+
312+int 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+
749+void 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+
768+static 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+
791+void 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+
901+enum 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+
924+u16 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+
947+u8 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+
36+enum amdgpu_td {
37+ AMDGPU_TD_AUTO,
38+ AMDGPU_TD_UP,
39+ AMDGPU_TD_DOWN,
40+};
41+
42+enum amdgpu_display_watermark {
43+ AMDGPU_DISPLAY_WATERMARK_LOW = 0,
44+ AMDGPU_DISPLAY_WATERMARK_HIGH = 1,
45+};
46+
47+enum 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+
55+void amdgpu_dpm_print_class_info(u32 class, u32 class2);
56+void amdgpu_dpm_print_cap_info(u32 caps);
57+void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
58+ struct amdgpu_ps *rps);
59+u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev);
60+u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev);
61+bool amdgpu_is_uvd_state(u32 class, u32 class2);
62+void amdgpu_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
63+ u32 *p, u32 *u);
64+int amdgpu_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th);
65+
66+bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor);
67+
68+int amdgpu_get_platform_caps(struct amdgpu_device *adev);
69+
70+int amdgpu_parse_extended_power_table(struct amdgpu_device *adev);
71+void amdgpu_free_extended_power_table(struct amdgpu_device *adev);
72+
73+void amdgpu_add_thermal_controller(struct amdgpu_device *adev);
74+
75+enum 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+
80+u16 amdgpu_get_pcie_lane_support(struct amdgpu_device *adev,
81+ u16 asic_lanes,
82+ u16 default_lanes);
83+u8 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+
55+int amdgpu_vram_limit = 0;
56+int amdgpu_gart_size = -1; /* auto */
57+int amdgpu_benchmarking = 0;
58+int amdgpu_testing = 0;
59+int amdgpu_audio = -1;
60+int amdgpu_disp_priority = 0;
61+int amdgpu_hw_i2c = 0;
62+int amdgpu_pcie_gen2 = -1;
63+int amdgpu_msi = -1;
64+int amdgpu_lockup_timeout = 10000;
65+int amdgpu_dpm = -1;
66+int amdgpu_smc_load_fw = 1;
67+int amdgpu_aspm = -1;
68+int amdgpu_runtime_pm = -1;
69+int amdgpu_hard_reset = 0;
70+unsigned amdgpu_ip_block_mask = 0xffffffff;
71+int amdgpu_bapm = -1;
72+int amdgpu_deep_color = 0;
73+int amdgpu_vm_size = 8;
74+int amdgpu_vm_block_size = -1;
75+int amdgpu_exp_hw_support = 0;
76+
77+MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
78+module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
79+
80+MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc., -1 = auto)");
81+module_param_named(gartsize, amdgpu_gart_size, int, 0600);
82+
83+MODULE_PARM_DESC(benchmark, "Run benchmark");
84+module_param_named(benchmark, amdgpu_benchmarking, int, 0444);
85+
86+MODULE_PARM_DESC(test, "Run tests");
87+module_param_named(test, amdgpu_testing, int, 0444);
88+
89+MODULE_PARM_DESC(audio, "Audio enable (-1 = auto, 0 = disable, 1 = enable)");
90+module_param_named(audio, amdgpu_audio, int, 0444);
91+
92+MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
93+module_param_named(disp_priority, amdgpu_disp_priority, int, 0444);
94+
95+MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)");
96+module_param_named(hw_i2c, amdgpu_hw_i2c, int, 0444);
97+
98+MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (-1 = auto, 0 = disable, 1 = enable)");
99+module_param_named(pcie_gen2, amdgpu_pcie_gen2, int, 0444);
100+
101+MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)");
102+module_param_named(msi, amdgpu_msi, int, 0444);
103+
104+MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (defaul 10000 = 10 seconds, 0 = disable)");
105+module_param_named(lockup_timeout, amdgpu_lockup_timeout, int, 0444);
106+
107+MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)");
108+module_param_named(dpm, amdgpu_dpm, int, 0444);
109+
110+MODULE_PARM_DESC(smc_load_fw, "SMC firmware loading(1 = enable, 0 = disable)");
111+module_param_named(smc_load_fw, amdgpu_smc_load_fw, int, 0444);
112+
113+MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)");
114+module_param_named(aspm, amdgpu_aspm, int, 0444);
115+
116+MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)");
117+module_param_named(runpm, amdgpu_runtime_pm, int, 0444);
118+
119+MODULE_PARM_DESC(hard_reset, "PCI config reset (1 = force enable, 0 = disable (default))");
120+module_param_named(hard_reset, amdgpu_hard_reset, int, 0444);
121+
122+MODULE_PARM_DESC(ip_block_mask, "IP Block Mask (all blocks enabled (default))");
123+module_param_named(ip_block_mask, amdgpu_ip_block_mask, uint, 0444);
124+
125+MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)");
126+module_param_named(bapm, amdgpu_bapm, int, 0444);
127+
128+MODULE_PARM_DESC(deep_color, "Deep Color support (1 = enable, 0 = disable (default))");
129+module_param_named(deep_color, amdgpu_deep_color, int, 0444);
130+
131+MODULE_PARM_DESC(vm_size, "VM address space size in gigabytes (default 8GB)");
132+module_param_named(vm_size, amdgpu_vm_size, int, 0444);
133+
134+MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)");
135+module_param_named(vm_block_size, amdgpu_vm_block_size, int, 0444);
136+
137+MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
138+module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
139+
140+static 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+
251+MODULE_DEVICE_TABLE(pci, pciidlist);
252+
253+static struct drm_driver kms_driver;
254+
255+static 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+
276+static 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+
296+static void
297+amdgpu_pci_remove(struct pci_dev *pdev)
298+{
299+ struct drm_device *dev = pci_get_drvdata(pdev);
300+
301+ drm_put_dev(dev);
302+}
303+
304+static 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+
311+static 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+
318+static 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+
325+static 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+
332+static 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+
357+static 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+
382+static 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+
406+long 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+
424+static 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+
436+static 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+
449+static 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+
504+static struct drm_driver *driver;
505+static struct pci_driver *pdriver;
506+
507+static 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+
515+static 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+
534+static void __exit amdgpu_exit(void)
535+{
536+ drm_pci_exit(driver, pdriver);
537+ amdgpu_unregister_atpx_handler();
538+}
539+
540+module_init(amdgpu_init);
541+module_exit(amdgpu_exit);
542+
543+MODULE_AUTHOR(DRIVER_AUTHOR);
544+MODULE_DESCRIPTION(DRIVER_DESC);
545+MODULE_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+
45+long 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+
34+void
35+amdgpu_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+
59+void 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+
76+struct drm_connector *
77+amdgpu_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+
92+struct drm_connector *
93+amdgpu_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+
108+struct 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+
129+u16 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+
147+void 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+
188+bool 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+ */
38+enum 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+ */
53+enum 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+*/
45+struct 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+
52+static 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+
67+int 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+
90+static 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+
104+static 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;
166+out_unref:
167+ amdgpufb_destroy_pinned_object(gobj);
168+ *gobj_p = NULL;
169+ return ret;
170+}
171+
172+static 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+
272+out_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+
285+void 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+
291+static 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 */
317+static 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 */
328+static 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+
338+static 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+
344+int 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+
385+void 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+
395+void 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+
401+int 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+
414+bool 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+ */
58+static 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+ */
74+static 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+ */
94+static 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+ */
115+int 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+ */
145+static 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+ */
185+static 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+ */
255+static 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+ */
301+void 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+ */
374+static 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+
387+static 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+ */
414+static 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+ */
463+bool 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+ */
488+static 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+ */
520+long 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+ */
636+int 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+ */
666+int 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+ */
706+int 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+ */
733+int 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+ */
762+struct 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+ */
775+void 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+ */
793+unsigned 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+ */
821+bool 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+ */
849+void 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+ */
885+int 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+ */
920+void 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+ */
949+int 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+ */
966+void 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+ */
994+void 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)
1012+static 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+
1042+static struct drm_info_list amdgpu_debugfs_fence_list[] = {
1043+ {"amdgpu_fence_info", &amdgpu_debugfs_fence_info, 0, NULL},
1044+};
1045+#endif
1046+
1047+int 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+
1056+static const char *amdgpu_fence_get_driver_name(struct fence *fence)
1057+{
1058+ return "amdgpu";
1059+}
1060+
1061+static 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+
1067+static inline bool amdgpu_test_signaled(struct amdgpu_fence *fence)
1068+{
1069+ return test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags);
1070+}
1071+
1072+struct amdgpu_wait_cb {
1073+ struct fence_cb base;
1074+ struct task_struct *task;
1075+};
1076+
1077+static 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+
1084+static 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+
1126+const 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+ */
65+int 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+ */
94+void 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+ */
122+int 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+ */
147+int 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+ */
177+void 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+ */
202+void 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+ */
223+void 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+ */
271+int 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+ */
312+int 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+ */
358+void 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+
42+struct amdgpu_ring;
43+struct amdgpu_bo;
44+
45+struct amdgpu_gds_asic_info {
46+ uint32_t total_size;
47+ uint32_t gfx_partition_size;
48+ uint32_t cs_partition_size;
49+};
50+
51+struct 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+
65+struct 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+
33+void 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+
45+int 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+ }
71+retry:
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+
94+int amdgpu_gem_init(struct amdgpu_device *adev)
95+{
96+ INIT_LIST_HEAD(&adev->gem.objects);
97+ return 0;
98+}
99+
100+void 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+ */
109+int 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+
134+void 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+
159+static 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+ */
172+int 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+
219+error_unlock:
220+ up_read(&adev->exclusive_lock);
221+ r = amdgpu_gem_handle_lockup(adev, r);
222+ return r;
223+}
224+
225+int 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+
298+release_object:
299+ drm_gem_object_unreference_unlocked(gobj);
300+
301+handle_lockup:
302+ up_read(&adev->exclusive_lock);
303+ r = amdgpu_gem_handle_lockup(adev, r);
304+
305+ return r;
306+}
307+
308+int 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+
330+int 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+ */
346+unsigned 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+
367+int 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+
404+int 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);
437+out:
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+ */
451+static 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+
490+error_unlock:
491+ mutex_unlock(&bo_va->vm->mutex);
492+
493+error_unreserve:
494+ ttm_eu_backoff_reservation(&ticket, &list);
495+
496+error_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+
505+int 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+
589+int 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);
634+out:
635+ drm_gem_object_unreference_unlocked(gobj);
636+ return r;
637+}
638+
639+int 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)
670+static 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+
705+static struct drm_info_list amdgpu_debugfs_gem_list[] = {
706+ {"amdgpu_gem_info", &amdgpu_debugfs_gem_info, 0, NULL},
707+};
708+#endif
709+
710+int 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+ */
40+int 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+ */
62+void 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+
27+int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg);
28+void 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 */
39+static 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+
81+static 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+
100+static 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+
115+static 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+
129+static 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+
142+static 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+
155+static const struct i2c_algorithm amdgpu_atombios_i2c_algo = {
156+ .master_xfer = amdgpu_atombios_i2c_xfer,
157+ .functionality = amdgpu_atombios_i2c_func,
158+};
159+
160+struct 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;
215+out_free:
216+ kfree(i2c);
217+ return NULL;
218+
219+}
220+
221+void 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 */
230+void 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 */
240+void 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 */
253+void 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 */
269+struct amdgpu_i2c_chan *
270+amdgpu_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+
284+static 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+
318+static 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 */
340+void
341+amdgpu_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 */
369+void
370+amdgpu_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+
27+struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev,
28+ struct amdgpu_i2c_bus_rec *rec,
29+ const char *name);
30+void amdgpu_i2c_destroy(struct amdgpu_i2c_chan *i2c);
31+void amdgpu_i2c_init(struct amdgpu_device *adev);
32+void amdgpu_i2c_fini(struct amdgpu_device *adev);
33+void amdgpu_i2c_add(struct amdgpu_device *adev,
34+ struct amdgpu_i2c_bus_rec *rec,
35+ const char *name);
36+struct amdgpu_i2c_chan *
37+amdgpu_i2c_lookup(struct amdgpu_device *adev,
38+ struct amdgpu_i2c_bus_rec *i2c_bus);
39+void
40+amdgpu_i2c_router_select_ddc_port(struct amdgpu_connector *amdgpu_connector);
41+void
42+amdgpu_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+ */
45+static 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+ */
58+int 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+ */
110+void 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+ */
138+int 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+ */
239+int 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+ */
274+void 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+ */
293+int 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+
329+static 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+
341+static struct drm_info_list amdgpu_debugfs_sa_list[] = {
342+ {"amdgpu_sa_info", &amdgpu_debugfs_sa_info, 0, NULL},
343+};
344+
345+#endif
346+
347+static 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+ */
36+static 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+ */
81+int 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+ */
142+void 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+ */
181+int 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+
191+restart_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.