History

Merge drm/drm-next into drm-misc-next

Biju Das needs a patch for rz-du merged in 7.0-rc3

Maxime Ripard committed 8 months ago

Commit f08ceb72 parents f66d6cc 58351f4735 files · +112973 −6958Browse files

Unified · Split

309 files
  1. .mailmap +3 −0
  2. CREDITS +8 −0
  3. Documentation/ABI/testing/sysfs-driver-uniwill-laptop +5 −5
  4. Documentation/admin-guide/kernel-parameters.txt +13 −0
  5. Documentation/admin-guide/laptops/uniwill-laptop.rst +1 −1
  6. Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml +0 −1
  7. Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml +1 −0
  8. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml +1 −0
  9. Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml +1 −0
  10. Documentation/hwmon/emc1403.rst +1 −1
  11. Documentation/hwmon/index.rst +0 −1
  12. Documentation/hwmon/sa67.rst +0 −41
  13. Documentation/netlink/specs/nfsd.yaml +2 −2
  14. Documentation/sound/alsa-configuration.rst +4 −0
  15. MAINTAINERS +10 −27
  16. Makefile +5 −5
  17. arch/alpha/kernel/vmlinux.lds.S +1 −0
  18. arch/arc/kernel/vmlinux.lds.S +1 −0
  19. arch/arm/boot/compressed/vmlinux.lds.S +1 −0
  20. arch/arm/kernel/vmlinux-xip.lds.S +1 −0
  21. arch/arm/kernel/vmlinux.lds.S +1 −0
  22. arch/arm64/include/asm/cmpxchg.h +7 −5
  23. arch/arm64/include/asm/pgtable-prot.h +5 −5
  24. arch/arm64/include/asm/runtime-const.h +4 −0
  25. arch/arm64/kernel/vmlinux.lds.S +1 −0
  26. arch/arm64/mm/contpte.c +49 −4
  27. arch/csky/kernel/vmlinux.lds.S +1 −0
  28. arch/hexagon/kernel/vmlinux.lds.S +1 −0
  29. arch/loongarch/kernel/vmlinux.lds.S +1 −0
  30. arch/m68k/kernel/vmlinux-nommu.lds +1 −0
  31. arch/m68k/kernel/vmlinux-std.lds +1 −0
  32. arch/m68k/kernel/vmlinux-sun3.lds +1 −0
  33. arch/mips/kernel/vmlinux.lds.S +1 −0
  34. arch/nios2/kernel/vmlinux.lds.S +1 −0
  35. arch/openrisc/kernel/vmlinux.lds.S +1 −0
  36. arch/parisc/boot/compressed/vmlinux.lds.S +1 −0
  37. arch/parisc/include/asm/pgtable.h +1 −1
  38. arch/parisc/kernel/head.S +6 −1
  39. arch/parisc/kernel/setup.c +12 −8
  40. arch/parisc/kernel/vmlinux.lds.S +1 −0
  41. arch/powerpc/kernel/pci_of_scan.c +7 −0
  42. arch/powerpc/kernel/vmlinux.lds.S +1 −0
  43. arch/riscv/kernel/vmlinux.lds.S +1 −0
  44. arch/s390/include/asm/processor.h +1 −1
  45. arch/s390/kernel/vmlinux.lds.S +1 −0
  46. arch/s390/lib/xor.c +5 −6
  47. arch/sh/kernel/vmlinux.lds.S +1 −0
  48. arch/sparc/kernel/pci.c +7 −0
  49. arch/sparc/kernel/vmlinux.lds.S +1 −0
  50. arch/um/kernel/dyn.lds.S +1 −0
  51. arch/um/kernel/uml.lds.S +1 −0
  52. arch/x86/boot/compressed/Makefile +1 −0
  53. arch/x86/boot/compressed/sev.c +5 −4
  54. arch/x86/boot/compressed/vmlinux.lds.S +1 −1
  55. arch/x86/boot/startup/sev-shared.c +1 −1
  56. arch/x86/coco/sev/core.c +1 −0
  57. arch/x86/entry/vdso/vdso32/sigreturn.S +30 −0
  58. arch/x86/include/asm/efi.h +1 −1
  59. arch/x86/include/asm/msr-index.h +4 −1
  60. arch/x86/include/asm/numa.h +6 −0
  61. arch/x86/include/asm/pgtable_64.h +0 −2
  62. arch/x86/include/asm/topology.h +6 −0
  63. arch/x86/kernel/cpu/common.c +3 −0
  64. arch/x86/kernel/cpu/resctrl/monitor.c +5 −31
  65. arch/x86/kernel/cpu/topology.c +11 −2
  66. arch/x86/kernel/head_64.S +0 −28
  67. arch/x86/kernel/smpboot.c +145 −56
  68. arch/x86/kernel/vmlinux.lds.S +1 −0
  69. arch/x86/mm/numa.c +8 −0
  70. arch/x86/mm/srat.c +2 −0
  71. arch/x86/platform/efi/efi.c +1 −1
  72. arch/x86/platform/efi/quirks.c +52 −3
  73. arch/x86/platform/pvh/enlighten.c +1 −6
  74. arch/x86/xen/enlighten_pv.c +1 −1
  75. arch/x86/xen/mmu_pv.c +9 −0
  76. block/blk-map.c +1 −2
  77. block/blk-mq.c +30 −15
  78. block/blk-sysfs.c +7 −1
  79. block/elevator.c +11 −1
  80. crypto/Kconfig +0 −9
  81. crypto/testmgr.c +2 −2
  82. drivers/accel/amdxdna/aie2_ctx.c +8 −15
  83. drivers/accel/amdxdna/aie2_message.c +28 −8
  84. drivers/accel/amdxdna/aie2_pci.c +37 −29
  85. drivers/accel/amdxdna/aie2_pci.h +1 −0
  86. drivers/accel/amdxdna/amdxdna_ctx.c +27 −0
  87. drivers/accel/amdxdna/amdxdna_ctx.h +3 −0
  88. drivers/accel/amdxdna/amdxdna_mailbox.c +45 −46
  89. drivers/accel/amdxdna/amdxdna_mailbox.h +17 −14
  90. drivers/accel/amdxdna/npu1_regs.c +1 −1
  91. drivers/accel/ethosu/ethosu_gem.c +9 −3
  92. drivers/accel/ethosu/ethosu_job.c +18 −8
  93. drivers/acpi/acpica/acpredef.h +3 −2
  94. drivers/acpi/device_pm.c +0 −9
  95. drivers/ata/libata-core.c +2 −0
  96. drivers/ata/libata-eh.c +2 −1
  97. drivers/ata/libata-scsi.c +1 −0
  98. drivers/base/base.h +1 −10
  99. drivers/base/dd.c +1 −1
  100. drivers/crypto/atmel-sha204a.c +3 −2
  101. drivers/crypto/ccp/sev-dev-tsm.c +1 −1
  102. drivers/crypto/ccp/sev-dev.c +4 −6
  103. drivers/firmware/efi/mokvar-table.c +1 −1
  104. drivers/gpu/drm/amd/amdgpu/Makefile +1 −1
  105. drivers/gpu/drm/amd/amdgpu/amdgpu.h +39 −115
  106. drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +5 −1
  107. drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c +2 −0
  108. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +0 −7
  109. drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +7 −2
  110. drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h +6 −7
  111. drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +4 −4
  112. drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +7 −807
  113. drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +1 −0
  114. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +0 −20
  115. drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +45 −71
  116. drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +49 −0
  117. drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +2 −0
  118. drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +3 −3
  119. drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +1 −5
  120. drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +27 −29
  121. drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +2 −4
  122. drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +35 −15
  123. drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +3 −0
  124. drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c +959 −0
  125. drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h +163 −0
  126. drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +9 −37
  127. drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +24 −18
  128. drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +106 −51
  129. drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +27 −4
  130. drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +81 −35
  131. drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +6 −0
  132. drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +70 −152
  133. drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +0 −18
  134. drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +1 −1
  135. drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +33 −12
  136. drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +1 −1
  137. drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +11 −4
  138. drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h +19 −6
  139. drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +1 −20
  140. drivers/gpu/drm/amd/amdgpu/atom.c +26 −2
  141. drivers/gpu/drm/amd/amdgpu/cik.c +26 −26
  142. drivers/gpu/drm/amd/amdgpu/cik_sdma.c +9 −22
  143. drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +6 −6
  144. drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +6 −6
  145. drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +6 −6
  146. drivers/gpu/drm/amd/amdgpu/df_v3_6.c +10 −10
  147. drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +33 −0
  148. drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +33 −0
  149. drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c +1 −1
  150. drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +8 −2
  151. drivers/gpu/drm/amd/amdgpu/gmc_v12_1.c +0 −2
  152. drivers/gpu/drm/amd/amdgpu/nv.c +13 −19
  153. drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +1 −1
  154. drivers/gpu/drm/amd/amdgpu/psp_v15_0.c +10 −10
  155. drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +9 −22
  156. drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +9 −22
  157. drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +25 −29
  158. drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +11 −28
  159. drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +8 −23
  160. drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +10 −25
  161. drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +10 −23
  162. drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +10 −23
  163. drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c +10 −23
  164. drivers/gpu/drm/amd/amdgpu/si.c +32 −34
  165. drivers/gpu/drm/amd/amdgpu/si_dma.c +9 −22
  166. drivers/gpu/drm/amd/amdgpu/soc15.c +33 −35
  167. drivers/gpu/drm/amd/amdgpu/soc15.h +0 −1
  168. drivers/gpu/drm/amd/amdgpu/soc15_common.h +17 −14
  169. drivers/gpu/drm/amd/amdgpu/soc21.c +16 −20
  170. drivers/gpu/drm/amd/amdgpu/soc24.c +6 −12
  171. drivers/gpu/drm/amd/amdgpu/soc_v1_0.c +10 −16
  172. drivers/gpu/drm/amd/amdgpu/vce_v1_0.c +17 −16
  173. drivers/gpu/drm/amd/amdgpu/vi.c +38 −38
  174. drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx12.asm +0 −3
  175. drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +25 −10
  176. drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +6 −6
  177. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +0 −1
  178. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c +0 −1
  179. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c +0 −1
  180. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c +0 −1
  181. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c +0 −1
  182. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +0 −1
  183. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c +0 −1
  184. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +79 −140
  185. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +4 −2
  186. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c +2 −1
  187. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +8 −8
  188. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +6 −3
  189. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +10 −1
  190. drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +33 −13
  191. drivers/gpu/drm/amd/display/dc/bios/command_table.c +37 −87
  192. drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c +1 −0
  193. drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +10 −13
  194. drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +1 −13
  195. drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c +51 −13
  196. drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +0 −166
  197. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c +7 −7
  198. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c +1152 −0
  199. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h +79 −0
  200. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_smu.c +431 −0
  201. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_smu.h +190 −0
  202. drivers/gpu/drm/amd/display/dc/core/dc.c +85 −72
  203. drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +59 −1
  204. drivers/gpu/drm/amd/display/dc/core/dc_resource.c +7 −0
  205. drivers/gpu/drm/amd/display/dc/dc.h +15 −2
  206. drivers/gpu/drm/amd/display/dc/dc_bios_types.h +4 −2
  207. drivers/gpu/drm/amd/display/dc/dc_dp_types.h +2 −2
  208. drivers/gpu/drm/amd/display/dc/dc_helper.c +2 −0
  209. drivers/gpu/drm/amd/display/dc/dc_hw_types.h +73 −0
  210. drivers/gpu/drm/amd/display/dc/dc_types.h +5 −1
  211. drivers/gpu/drm/amd/display/dc/dccg/Makefile +10 −1
  212. drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h +14 −1
  213. drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.c +278 −0
  214. drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.h +263 −0
  215. drivers/gpu/drm/amd/display/dc/dce/dce_abm.h +59 −1
  216. drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +0 −131
  217. drivers/gpu/drm/amd/display/dc/dce/dce_audio.h +0 −9
  218. drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c +0 −966
  219. drivers/gpu/drm/amd/display/dc/dio/Makefile +10 −1
  220. drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_stream_encoder.h +9 −1
  221. drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_link_encoder.c +205 −0
  222. drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_link_encoder.h +140 −0
  223. drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_stream_encoder.c +522 −0
  224. drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_stream_encoder.h +206 −0
  225. drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c +6 −2
  226. drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c +106 −99
  227. drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.h +1 −0
  228. drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h +2 −0
  229. drivers/gpu/drm/amd/display/dc/dml2_0/dml2_dc_resource_mgmt.c +3 −3
  230. drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.h +1 −0
  231. drivers/gpu/drm/amd/display/dc/dpp/Makefile +9 −1
  232. drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h +4 −1
  233. drivers/gpu/drm/amd/display/dc/dpp/dcn42/dcn42_dpp.c +333 −0
  234. drivers/gpu/drm/amd/display/dc/dpp/dcn42/dcn42_dpp.h +469 −0
  235. drivers/gpu/drm/amd/display/dc/gpio/Makefile +12 −1
  236. drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_factory_dcn42.c +254 −0
  237. drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_factory_dcn42.h +31 −0
  238. drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.c +205 −0
  239. drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.h +36 −0
  240. drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +4 −0
  241. drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c +4 −0
  242. drivers/gpu/drm/amd/display/dc/hpo/Makefile +10 −1
  243. drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.h +8 −2
  244. drivers/gpu/drm/amd/display/dc/hpo/dcn42/dcn42_hpo_dp_link_encoder.c +93 −0
  245. drivers/gpu/drm/amd/display/dc/hpo/dcn42/dcn42_hpo_dp_link_encoder.h +17 −0
  246. drivers/gpu/drm/amd/display/dc/hubbub/Makefile +9 −1
  247. drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h +5 −1
  248. drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.c +539 −0
  249. drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.h +268 −0
  250. drivers/gpu/drm/amd/display/dc/hubp/Makefile +9 −1
  251. drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h +7 −1
  252. drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c +643 −0
  253. drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h +79 −0
  254. drivers/gpu/drm/amd/display/dc/hwss/Makefile +10 −2
  255. drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h +12 −1
  256. drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +66 −0
  257. drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +26 −3
  258. drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c +1472 −0
  259. drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h +53 −0
  260. drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c +167 −0
  261. drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.h +11 −0
  262. drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +22 −1
  263. drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h +4 −1
  264. drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +23 −1
  265. drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h +47 −16
  266. drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +9 −1
  267. drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +19 −1
  268. drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +3 −1
  269. drivers/gpu/drm/amd/display/dc/irq/Makefile +9 −0
  270. drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.c +412 −0
  271. drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.h +15 −0
  272. drivers/gpu/drm/amd/display/dc/link/link_detection.c +27 −31
  273. drivers/gpu/drm/amd/display/dc/link/link_dpms.c +249 −391
  274. drivers/gpu/drm/amd/display/dc/link/link_factory.c +28 −1
  275. drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +2 −0
  276. drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c +1 −1
  277. drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c +1 −1
  278. drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +2 −6
  279. drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile +9 −1
  280. drivers/gpu/drm/amd/display/dc/mmhubbub/dcn42/dcn42_mmhubbub.c +25 −0
  281. drivers/gpu/drm/amd/display/dc/mmhubbub/dcn42/dcn42_mmhubbub.h +13 −0
  282. drivers/gpu/drm/amd/display/dc/mpc/Makefile +9 −1
  283. drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c +12 −1
  284. drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h +9 −1
  285. drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c +1121 −0
  286. drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h +1006 −0
  287. drivers/gpu/drm/amd/display/dc/optc/Makefile +9 −1
  288. drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h +19 −1
  289. drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.c +198 −0
  290. drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.h +211 −0
  291. drivers/gpu/drm/amd/display/dc/pg/Makefile +9 −1
  292. drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c +648 −0
  293. drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.h +175 −0
  294. drivers/gpu/drm/amd/display/dc/resource/Makefile +18 −0
  295. drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +1 −1
  296. drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c +2337 −0
  297. drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.h +588 −0
  298. drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource_fpu.c +47 −0
  299. drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource_fpu.h +7 −10
  300. drivers/gpu/drm/amd/display/dmub/dmub_srv.h +4 −1
  301. drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +54 −0
  302. drivers/gpu/drm/amd/display/dmub/src/Makefile +2 −1
  303. drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.c +752 −0
  304. drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.h +171 −0
  305. drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +62 −2
  306. drivers/gpu/drm/amd/display/include/bios_parser_types.h +2 −0
  307. drivers/gpu/drm/amd/display/include/dal_asic_id.h +1 −0
  308. drivers/gpu/drm/amd/display/include/dal_types.h +1 −0
  309. drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_2_0_offset.h +17872 −0
.mailmap+3−0
@@ -219,6 +219,7 @@ Daniele Alessandrelli <daniele.alessandrelli@gmail.com> <daniele.alessandrelli@i · 218 unmodified lines
219Danilo Krummrich <dakr@kernel.org> <dakr@redhat.com>219Danilo Krummrich <dakr@kernel.org> <dakr@redhat.com>
220David Brownell <david-b@pacbell.net>220David Brownell <david-b@pacbell.net>
221David Collins <quic_collinsd@quicinc.com> <collinsd@codeaurora.org>221David Collins <quic_collinsd@quicinc.com> <collinsd@codeaurora.org>
222David Gow <david@davidgow.net> <davidgow@google.com>
222David Heidelberg <david@ixit.cz> <d.okias@gmail.com>223David Heidelberg <david@ixit.cz> <d.okias@gmail.com>
223David Hildenbrand <david@kernel.org> <david@redhat.com>224David Hildenbrand <david@kernel.org> <david@redhat.com>
224David Rheinsberg <david@readahead.eu> <dh.herrmann@gmail.com>225David Rheinsberg <david@readahead.eu> <dh.herrmann@gmail.com>
@@ -353,6 +354,7 @@ Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@opinsys.com> · 128 unmodified lines
353Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com>354Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com>
354Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com>355Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com>
355Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>356Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
357Jason Xing <kerneljasonxing@gmail.com> <kernelxing@tencent.com>
356<javier@osg.samsung.com> <javier.martinez@collabora.co.uk>358<javier@osg.samsung.com> <javier.martinez@collabora.co.uk>
357Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>359Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>
358Jayachandran C <c.jayachandran@gmail.com> <jayachandranc@netlogicmicro.com>360Jayachandran C <c.jayachandran@gmail.com> <jayachandranc@netlogicmicro.com>
@@ -401,6 +403,7 @@ Jiri Slaby <jirislaby@kernel.org> <xslaby@fi.muni.cz> · 42 unmodified lines
401Jisheng Zhang <jszhang@kernel.org> <jszhang@marvell.com>403Jisheng Zhang <jszhang@kernel.org> <jszhang@marvell.com>
402Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com>404Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com>
403Jishnu Prakash <quic_jprakash@quicinc.com> <jprakash@codeaurora.org>405Jishnu Prakash <quic_jprakash@quicinc.com> <jprakash@codeaurora.org>
406Joe Damato <joe@dama.to> <jdamato@fastly.com>
404Joel Granados <joel.granados@kernel.org> <j.granados@samsung.com>407Joel Granados <joel.granados@kernel.org> <j.granados@samsung.com>
405Johan Hovold <johan@kernel.org> <jhovold@gmail.com>408Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
406Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>409Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
CREDITS+8−0
@@ -1242,6 +1242,10 @@ N: Veaceslav Falico · 1241 unmodified lines
1242E: vfalico@gmail.com1242E: vfalico@gmail.com
1243D: Co-maintainer and co-author of the network bonding driver.1243D: Co-maintainer and co-author of the network bonding driver.
1244 1244
1245N: Thomas Falcon
1246E: tlfalcon@linux.ibm.com
1247D: Initial author of the IBM ibmvnic network driver
1248
1245N: János Farkas1249N: János Farkas
1246E: chexum@shadow.banki.hu1250E: chexum@shadow.banki.hu
1247D: romfs, various (mostly networking) fixes1251D: romfs, various (mostly networking) fixes
@@ -2415,6 +2419,10 @@ S: Am Muehlenweg 38 · 1167 unmodified lines
2415S: D53424 Remagen2419S: D53424 Remagen
2416S: Germany2420S: Germany
2417 2421
2422N: Jonathan Lemon
2423E: jonathan.lemon@gmail.com
2424D: OpenCompute PTP clock driver (ptp_ocp)
2425
2418N: Colin Leroy2426N: Colin Leroy
2419E: colin@colino.net2427E: colin@colino.net
2420W: http://www.geekounet.org/2428W: http://www.geekounet.org/
Documentation/ABI/testing/sysfs-driver-uniwill-laptop+5−5
@@ -1,4 +1,4 @@
1What: /sys/bus/platform/devices/INOU0000:XX/fn_lock_toggle_enable1What: /sys/bus/platform/devices/INOU0000:XX/fn_lock
2Date: November 20252Date: November 2025
3KernelVersion: 6.193KernelVersion: 6.19
4Contact: Armin Wolf <W_Armin@gmx.de>4Contact: Armin Wolf <W_Armin@gmx.de>
@@ -8,15 +8,15 @@ Description: · 3 unmodified lines
8 8
9 Reading this file returns the current enable status of the FN lock functionality.9 Reading this file returns the current enable status of the FN lock functionality.
10 10
11What: /sys/bus/platform/devices/INOU0000:XX/super_key_toggle_enable11What: /sys/bus/platform/devices/INOU0000:XX/super_key_enable
12Date: November 202512Date: November 2025
13KernelVersion: 6.1913KernelVersion: 6.19
14Contact: Armin Wolf <W_Armin@gmx.de>14Contact: Armin Wolf <W_Armin@gmx.de>
15Description:15Description:
16 Allows userspace applications to enable/disable the super key functionality16 Allows userspace applications to enable/disable the super key of the integrated
17 of the integrated keyboard by writing "1"/"0" into this file.17 keyboard by writing "1"/"0" into this file.
18 18
19 Reading this file returns the current enable status of the super key functionality.19 Reading this file returns the current enable status of the super key.
20 20
21What: /sys/bus/platform/devices/INOU0000:XX/touchpad_toggle_enable21What: /sys/bus/platform/devices/INOU0000:XX/touchpad_toggle_enable
22Date: November 202522Date: November 2025
Documentation/admin-guide/kernel-parameters.txt+13−0
@@ -74,6 +74,7 @@ · 73 unmodified lines
74 TPM TPM drivers are enabled.74 TPM TPM drivers are enabled.
75 UMS USB Mass Storage support is enabled.75 UMS USB Mass Storage support is enabled.
76 USB USB support is enabled.76 USB USB support is enabled.
77 NVME NVMe support is enabled
77 USBHID USB Human Interface Device support is enabled.78 USBHID USB Human Interface Device support is enabled.
78 V4L Video For Linux support is enabled.79 V4L Video For Linux support is enabled.
79 VGA The VGA console has been enabled.80 VGA The VGA console has been enabled.
@@ -4787,6 +4788,18 @@ Kernel parameters · 4707 unmodified lines
4787 This can be set from sysctl after boot.4788 This can be set from sysctl after boot.
4788 See Documentation/admin-guide/sysctl/vm.rst for details.4789 See Documentation/admin-guide/sysctl/vm.rst for details.
4789 4790
4791 nvme.quirks= [NVME] A list of quirk entries to augment the built-in
4792 nvme quirk list. List entries are separated by a
4793 '-' character.
4794 Each entry has the form VendorID:ProductID:quirk_names.
4795 The IDs are 4-digits hex numbers and quirk_names is a
4796 list of quirk names separated by commas. A quirk name
4797 can be prefixed by '^', meaning that the specified
4798 quirk must be disabled.
4799
4800 Example:
4801 nvme.quirks=7710:2267:bogus_nid,^identify_cns-9900:7711:broken_msi
4802
4790 ohci1394_dma=early [HW,EARLY] enable debugging via the ohci1394 driver.4803 ohci1394_dma=early [HW,EARLY] enable debugging via the ohci1394 driver.
4791 See Documentation/core-api/debugging-via-ohci1394.rst for more4804 See Documentation/core-api/debugging-via-ohci1394.rst for more
4792 info.4805 info.
Documentation/admin-guide/laptops/uniwill-laptop.rst+1−1
@@ -24,7 +24,7 @@ Keyboard settings · 23 unmodified lines
24 24
25The ``uniwill-laptop`` driver allows the user to enable/disable:25The ``uniwill-laptop`` driver allows the user to enable/disable:
26 26
27 - the FN and super key lock functionality of the integrated keyboard27 - the FN lock and super key of the integrated keyboard
28 - the touchpad toggle functionality of the integrated touchpad28 - the touchpad toggle functionality of the integrated touchpad
29 29
30See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details.30See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details.
Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml+0−1
@@ -16,7 +16,6 @@ description: | · 15 unmodified lines
16properties:16properties:
17 compatible:17 compatible:
18 enum:18 enum:
19 - kontron,sa67mcu-hwmon
20 - kontron,sl28cpld-fan19 - kontron,sl28cpld-fan
21 20
22 reg:21 reg:
Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml+1−0
@@ -87,6 +87,7 @@ required: · 86 unmodified lines
87 87
88allOf:88allOf:
89 - $ref: can-controller.yaml#89 - $ref: can-controller.yaml#
90 - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml
90 - if:91 - if:
91 properties:92 properties:
92 compatible:93 compatible:
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml+1−0
@@ -23,6 +23,7 @@ properties: · 22 unmodified lines
23 enum:23 enum:
24 - nvidia,tegra210-audio-graph-card24 - nvidia,tegra210-audio-graph-card
25 - nvidia,tegra186-audio-graph-card25 - nvidia,tegra186-audio-graph-card
26 - nvidia,tegra238-audio-graph-card
26 - nvidia,tegra264-audio-graph-card27 - nvidia,tegra264-audio-graph-card
27 28
28 clocks:29 clocks:
Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml+1−0
@@ -20,6 +20,7 @@ properties: · 19 unmodified lines
20 - renesas,r9a07g044-ssi # RZ/G2{L,LC}20 - renesas,r9a07g044-ssi # RZ/G2{L,LC}
21 - renesas,r9a07g054-ssi # RZ/V2L21 - renesas,r9a07g054-ssi # RZ/V2L
22 - renesas,r9a08g045-ssi # RZ/G3S22 - renesas,r9a08g045-ssi # RZ/G3S
23 - renesas,r9a08g046-ssi # RZ/G3L
23 - const: renesas,rz-ssi24 - const: renesas,rz-ssi
24 25
25 reg:26 reg:
Documentation/hwmon/emc1403.rst+1−1
@@ -57,7 +57,7 @@ Supported chips: · 56 unmodified lines
57 - https://ww1.microchip.com/downloads/en/DeviceDoc/EMC1438%20DS%20Rev.%201.0%20(04-29-10).pdf57 - https://ww1.microchip.com/downloads/en/DeviceDoc/EMC1438%20DS%20Rev.%201.0%20(04-29-10).pdf
58 58
59Author:59Author:
60 Kalhan Trisal <kalhan.trisal@intel.com60 Kalhan Trisal <kalhan.trisal@intel.com>
61 61
62 62
63Description63Description
Documentation/hwmon/index.rst+0−1
@@ -220,7 +220,6 @@ Hardware Monitoring Kernel Drivers · 219 unmodified lines
220 q54sj108a2220 q54sj108a2
221 qnap-mcu-hwmon221 qnap-mcu-hwmon
222 raspberrypi-hwmon222 raspberrypi-hwmon
223 sa67
224 sbrmi223 sbrmi
225 sbtsi_temp224 sbtsi_temp
226 sch5627225 sch5627
Documentation/hwmon/sa67.rst+0−41
@@ -1,41 +0,0 @@
1.. SPDX-License-Identifier: GPL-2.0-only
2
3Kernel driver sa67mcu
4=====================
5
6Supported chips:
7
8 * Kontron sa67mcu
9
10 Prefix: 'sa67mcu'
11
12 Datasheet: not available
13
14Authors: Michael Walle <mwalle@kernel.org>
15
16Description
17-----------
18
19The sa67mcu is a board management controller which also exposes a hardware
20monitoring controller.
21
22The controller has two voltage and one temperature sensor. The values are
23hold in two 8 bit registers to form one 16 bit value. Reading the lower byte
24will also capture the high byte to make the access atomic. The unit of the
25volatge sensors are 1mV and the unit of the temperature sensor is 0.1degC.
26
27Sysfs entries
28-------------
29
30The following attributes are supported.
31
32======================= ========================================================
33in0_label "VDDIN"
34in0_input Measured VDDIN voltage.
35
36in1_label "VDD_RTC"
37in1_input Measured VDD_RTC voltage.
38
39temp1_input MCU temperature. Roughly the board temperature.
40======================= ========================================================
41
Documentation/netlink/specs/nfsd.yaml+2−2
@@ -152,7 +152,7 @@ operations: · 151 unmodified lines
152 - compound-ops152 - compound-ops
153 -153 -
154 name: threads-set154 name: threads-set
155 doc: set the number of running threads155 doc: set the maximum number of running threads
156 attribute-set: server156 attribute-set: server
157 flags: [admin-perm]157 flags: [admin-perm]
158 do:158 do:
@@ -165,7 +165,7 @@ operations: · 6 unmodified lines
165 - min-threads165 - min-threads
166 -166 -
167 name: threads-get167 name: threads-get
168 doc: get the number of running threads168 doc: get the maximum number of running threads
169 attribute-set: server169 attribute-set: server
170 do:170 do:
171 reply:171 reply:
Documentation/sound/alsa-configuration.rst+4−0
@@ -2372,6 +2372,10 @@ quirk_flags · 2371 unmodified lines
2372 audible volume2372 audible volume
2373 * bit 25: ``mixer_capture_min_mute``2373 * bit 25: ``mixer_capture_min_mute``
2374 Similar to bit 24 but for capture streams2374 Similar to bit 24 but for capture streams
2375 * bit 26: ``skip_iface_setup``
2376 Skip the probe-time interface setup (usb_set_interface,
2377 init_pitch, init_sample_rate); redundant with
2378 snd_usb_endpoint_prepare() at stream-open time
2375 2379
2376This module supports multiple devices, autoprobe and hotplugging.2380This module supports multiple devices, autoprobe and hotplugging.
2377 2381
MAINTAINERS+10−27
@@ -993,10 +993,8 @@ F: Documentation/devicetree/bindings/thermal/amazon,al-thermal.yaml · 992 unmodified lines
993F: drivers/thermal/thermal_mmio.c993F: drivers/thermal/thermal_mmio.c
994 994
995AMAZON ETHERNET DRIVERS995AMAZON ETHERNET DRIVERS
996M: Shay Agroskin <shayagr@amazon.com>
997M: Arthur Kiyanovski <akiyano@amazon.com>996M: Arthur Kiyanovski <akiyano@amazon.com>
998R: David Arinzon <darinzon@amazon.com>997M: David Arinzon <darinzon@amazon.com>
999R: Saeed Bishara <saeedb@amazon.com>
1000L: netdev@vger.kernel.org998L: netdev@vger.kernel.org
1001S: Maintained999S: Maintained
1002F: Documentation/networking/device_drivers/ethernet/amazon/ena.rst1000F: Documentation/networking/device_drivers/ethernet/amazon/ena.rst
@@ -4617,7 +4615,6 @@ F: drivers/bluetooth/ · 3614 unmodified lines
4617 4615
4618BLUETOOTH SUBSYSTEM4616BLUETOOTH SUBSYSTEM
4619M: Marcel Holtmann <marcel@holtmann.org>4617M: Marcel Holtmann <marcel@holtmann.org>
4620M: Johan Hedberg <johan.hedberg@gmail.com>
4621M: Luiz Augusto von Dentz <luiz.dentz@gmail.com>4618M: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
4622L: linux-bluetooth@vger.kernel.org4619L: linux-bluetooth@vger.kernel.org
4623S: Supported4620S: Supported
@@ -10187,8 +10184,8 @@ F: drivers/i2c/busses/i2c-cpm.c · 5563 unmodified lines
10187 10184
10188FREESCALE IMX / MXC FEC DRIVER10185FREESCALE IMX / MXC FEC DRIVER
10189M: Wei Fang <wei.fang@nxp.com>10186M: Wei Fang <wei.fang@nxp.com>
10187R: Frank Li <frank.li@nxp.com>
10190R: Shenwei Wang <shenwei.wang@nxp.com>10188R: Shenwei Wang <shenwei.wang@nxp.com>
10191R: Clark Wang <xiaoning.wang@nxp.com>
10192L: imx@lists.linux.dev10189L: imx@lists.linux.dev
10193L: netdev@vger.kernel.org10190L: netdev@vger.kernel.org
10194S: Maintained10191S: Maintained
@@ -10500,7 +10497,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git · 305 unmodified lines
10500F: Documentation/trace/ftrace*10497F: Documentation/trace/ftrace*
10501F: arch/*/*/*/*ftrace*10498F: arch/*/*/*/*ftrace*
10502F: arch/*/*/*ftrace*10499F: arch/*/*/*ftrace*
10503F: include/*/ftrace.h10500F: include/*/*ftrace*
10504F: kernel/trace/fgraph.c10501F: kernel/trace/fgraph.c
10505F: kernel/trace/ftrace*10502F: kernel/trace/ftrace*
10506F: samples/ftrace10503F: samples/ftrace
@@ -12233,7 +12230,6 @@ IBM Power SRIOV Virtual NIC Device Driver · 1726 unmodified lines
12233M: Haren Myneni <haren@linux.ibm.com>12230M: Haren Myneni <haren@linux.ibm.com>
12234M: Rick Lindsley <ricklind@linux.ibm.com>12231M: Rick Lindsley <ricklind@linux.ibm.com>
12235R: Nick Child <nnac123@linux.ibm.com>12232R: Nick Child <nnac123@linux.ibm.com>
12236R: Thomas Falcon <tlfalcon@linux.ibm.com>
12237L: netdev@vger.kernel.org12233L: netdev@vger.kernel.org
12238S: Maintained12234S: Maintained
12239F: drivers/net/ethernet/ibm/ibmvnic.*12235F: drivers/net/ethernet/ibm/ibmvnic.*
@@ -13958,7 +13954,7 @@ F: fs/smb/server/ · 1718 unmodified lines
13958 13954
13959KERNEL UNIT TESTING FRAMEWORK (KUnit)13955KERNEL UNIT TESTING FRAMEWORK (KUnit)
13960M: Brendan Higgins <brendan.higgins@linux.dev>13956M: Brendan Higgins <brendan.higgins@linux.dev>
13961M: David Gow <davidgow@google.com>13957M: David Gow <david@davidgow.net>
13962R: Rae Moar <raemoar63@gmail.com>13958R: Rae Moar <raemoar63@gmail.com>
13963L: linux-kselftest@vger.kernel.org13959L: linux-kselftest@vger.kernel.org
13964L: kunit-dev@googlegroups.com13960L: kunit-dev@googlegroups.com
@@ -14778,7 +14774,7 @@ F: drivers/misc/lis3lv02d/ · 813 unmodified lines
14778F: drivers/platform/x86/hp/hp_accel.c14774F: drivers/platform/x86/hp/hp_accel.c
14779 14775
14780LIST KUNIT TEST14776LIST KUNIT TEST
14781M: David Gow <davidgow@google.com>14777M: David Gow <david@davidgow.net>
14782L: linux-kselftest@vger.kernel.org14778L: linux-kselftest@vger.kernel.org
14783L: kunit-dev@googlegroups.com14779L: kunit-dev@googlegroups.com
14784S: Maintained14780S: Maintained
@@ -15391,10 +15387,8 @@ F: drivers/crypto/marvell/ · 606 unmodified lines
15391F: include/linux/soc/marvell/octeontx2/15387F: include/linux/soc/marvell/octeontx2/
15392 15388
15393MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)15389MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)
15394M: Mirko Lindner <mlindner@marvell.com>
15395M: Stephen Hemminger <stephen@networkplumber.org>
15396L: netdev@vger.kernel.org15390L: netdev@vger.kernel.org
15397S: Odd fixes15391S: Orphan
15398F: drivers/net/ethernet/marvell/sk*15392F: drivers/net/ethernet/marvell/sk*
15399 15393
15400MARVELL LIBERTAS WIRELESS DRIVER15394MARVELL LIBERTAS WIRELESS DRIVER
@@ -15491,7 +15485,6 @@ MARVELL OCTEONTX2 RVU ADMIN FUNCTION DRIVER · 90 unmodified lines
15491M: Sunil Goutham <sgoutham@marvell.com>15485M: Sunil Goutham <sgoutham@marvell.com>
15492M: Linu Cherian <lcherian@marvell.com>15486M: Linu Cherian <lcherian@marvell.com>
15493M: Geetha sowjanya <gakula@marvell.com>15487M: Geetha sowjanya <gakula@marvell.com>
15494M: Jerin Jacob <jerinj@marvell.com>
15495M: hariprasad <hkelam@marvell.com>15488M: hariprasad <hkelam@marvell.com>
15496M: Subbaraya Sundeep <sbhatta@marvell.com>15489M: Subbaraya Sundeep <sbhatta@marvell.com>
15497L: netdev@vger.kernel.org15490L: netdev@vger.kernel.org
@@ -15506,7 +15499,7 @@ S: Supported · 8 unmodified lines
15506F: drivers/perf/marvell_pem_pmu.c15499F: drivers/perf/marvell_pem_pmu.c
15507 15500
15508MARVELL PRESTERA ETHERNET SWITCH DRIVER15501MARVELL PRESTERA ETHERNET SWITCH DRIVER
15509M: Taras Chornyi <taras.chornyi@plvision.eu>15502M: Elad Nachman <enachman@marvell.com>
15510S: Supported15503S: Supported
15511W: https://github.com/Marvell-switching/switchdev-prestera15504W: https://github.com/Marvell-switching/switchdev-prestera
15512F: drivers/net/ethernet/marvell/prestera/15505F: drivers/net/ethernet/marvell/prestera/
@@ -16180,7 +16173,6 @@ F: drivers/dma/mediatek/ · 667 unmodified lines
16180 16173
16181MEDIATEK ETHERNET DRIVER16174MEDIATEK ETHERNET DRIVER
16182M: Felix Fietkau <nbd@nbd.name>16175M: Felix Fietkau <nbd@nbd.name>
16183M: Sean Wang <sean.wang@mediatek.com>
16184M: Lorenzo Bianconi <lorenzo@kernel.org>16176M: Lorenzo Bianconi <lorenzo@kernel.org>
16185L: netdev@vger.kernel.org16177L: netdev@vger.kernel.org
16186S: Maintained16178S: Maintained
@@ -16373,8 +16365,6 @@ F: include/soc/mediatek/smi.h · 186 unmodified lines
16373MEDIATEK SWITCH DRIVER16365MEDIATEK SWITCH DRIVER
16374M: Chester A. Unal <chester.a.unal@arinc9.com>16366M: Chester A. Unal <chester.a.unal@arinc9.com>
16375M: Daniel Golle <daniel@makrotopia.org>16367M: Daniel Golle <daniel@makrotopia.org>
16376M: DENG Qingfang <dqfext@gmail.com>
16377M: Sean Wang <sean.wang@mediatek.com>
16378L: netdev@vger.kernel.org16368L: netdev@vger.kernel.org
16379S: Maintained16369S: Maintained
16380F: drivers/net/dsa/mt7530-mdio.c16370F: drivers/net/dsa/mt7530-mdio.c
@@ -19242,8 +19232,6 @@ F: tools/objtool/ · 2861 unmodified lines
19242 19232
19243OCELOT ETHERNET SWITCH DRIVER19233OCELOT ETHERNET SWITCH DRIVER
19244M: Vladimir Oltean <vladimir.oltean@nxp.com>19234M: Vladimir Oltean <vladimir.oltean@nxp.com>
19245M: Claudiu Manoil <claudiu.manoil@nxp.com>
19246M: Alexandre Belloni <alexandre.belloni@bootlin.com>
19247M: UNGLinuxDriver@microchip.com19235M: UNGLinuxDriver@microchip.com
19248L: netdev@vger.kernel.org19236L: netdev@vger.kernel.org
19249S: Supported19237S: Supported
@@ -19829,7 +19817,6 @@ F: arch/*/boot/dts/ · 579 unmodified lines
19829F: include/dt-bindings/19817F: include/dt-bindings/
19830 19818
19831OPENCOMPUTE PTP CLOCK DRIVER19819OPENCOMPUTE PTP CLOCK DRIVER
19832M: Jonathan Lemon <jonathan.lemon@gmail.com>
19833M: Vadim Fedorenko <vadim.fedorenko@linux.dev>19820M: Vadim Fedorenko <vadim.fedorenko@linux.dev>
19834L: netdev@vger.kernel.org19821L: netdev@vger.kernel.org
19835S: Maintained19822S: Maintained
@@ -20137,9 +20124,8 @@ F: Documentation/devicetree/bindings/pci/marvell,armada-3700-pcie.yaml · 301 unmodified lines
20137F: drivers/pci/controller/pci-aardvark.c20124F: drivers/pci/controller/pci-aardvark.c
20138 20125
20139PCI DRIVER FOR ALTERA PCIE IP20126PCI DRIVER FOR ALTERA PCIE IP
20140M: Joyce Ooi <joyce.ooi@intel.com>
20141L: linux-pci@vger.kernel.org20127L: linux-pci@vger.kernel.org
20142S: Supported20128S: Orphan
20143F: Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml20129F: Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml
20144F: drivers/pci/controller/pcie-altera.c20130F: drivers/pci/controller/pcie-altera.c
20145 20131
@@ -20384,9 +20370,8 @@ S: Supported · 238 unmodified lines
20384F: Documentation/PCI/pci-error-recovery.rst20370F: Documentation/PCI/pci-error-recovery.rst
20385 20371
20386PCI MSI DRIVER FOR ALTERA MSI IP20372PCI MSI DRIVER FOR ALTERA MSI IP
20387M: Joyce Ooi <joyce.ooi@intel.com>
20388L: linux-pci@vger.kernel.org20373L: linux-pci@vger.kernel.org
20389S: Supported20374S: Orphan
20390F: Documentation/devicetree/bindings/interrupt-controller/altr,msi-controller.yaml20375F: Documentation/devicetree/bindings/interrupt-controller/altr,msi-controller.yaml
20391F: drivers/pci/controller/pcie-altera-msi.c20376F: drivers/pci/controller/pcie-altera-msi.c
20392 20377
@@ -21473,9 +21458,8 @@ S: Supported · 1080 unmodified lines
21473F: drivers/scsi/qedi/21458F: drivers/scsi/qedi/
21474 21459
21475QLOGIC QL4xxx ETHERNET DRIVER21460QLOGIC QL4xxx ETHERNET DRIVER
21476M: Manish Chopra <manishc@marvell.com>
21477L: netdev@vger.kernel.org21461L: netdev@vger.kernel.org
21478S: Maintained21462S: Orphan
21479F: drivers/net/ethernet/qlogic/qed/21463F: drivers/net/ethernet/qlogic/qed/
21480F: drivers/net/ethernet/qlogic/qede/21464F: drivers/net/ethernet/qlogic/qede/
21481F: include/linux/qed/21465F: include/linux/qed/
@@ -24353,7 +24337,6 @@ F: Documentation/devicetree/bindings/interrupt-controller/kontron,sl28cpld-intc. · 2871 unmodified lines
24353F: Documentation/devicetree/bindings/pwm/kontron,sl28cpld-pwm.yaml24337F: Documentation/devicetree/bindings/pwm/kontron,sl28cpld-pwm.yaml
24354F: Documentation/devicetree/bindings/watchdog/kontron,sl28cpld-wdt.yaml24338F: Documentation/devicetree/bindings/watchdog/kontron,sl28cpld-wdt.yaml
24355F: drivers/gpio/gpio-sl28cpld.c24339F: drivers/gpio/gpio-sl28cpld.c
24356F: drivers/hwmon/sa67mcu-hwmon.c
24357F: drivers/hwmon/sl28cpld-hwmon.c24340F: drivers/hwmon/sl28cpld-hwmon.c
24358F: drivers/irqchip/irq-sl28cpld.c24341F: drivers/irqchip/irq-sl28cpld.c
24359F: drivers/pwm/pwm-sl28cpld.c24342F: drivers/pwm/pwm-sl28cpld.c
Makefile+5−5
@@ -2,7 +2,7 @@ · 1 unmodified line
2VERSION = 72VERSION = 7
3PATCHLEVEL = 03PATCHLEVEL = 0
4SUBLEVEL = 04SUBLEVEL = 0
5EXTRAVERSION = -rc25EXTRAVERSION = -rc3
6NAME = Baby Opossum Posse6NAME = Baby Opossum Posse
7 7
8# *DOCUMENTATION*8# *DOCUMENTATION*
@@ -1497,13 +1497,13 @@ ifneq ($(wildcard $(resolve_btfids_O)),) · 1488 unmodified lines
1497 $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean1497 $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean
1498endif1498endif
1499 1499
1500PHONY += objtool_clean1500PHONY += objtool_clean objtool_mrproper
1501 1501
1502objtool_O = $(abspath $(objtree))/tools/objtool1502objtool_O = $(abspath $(objtree))/tools/objtool
1503 1503
1504objtool_clean:1504objtool_clean objtool_mrproper:
1505ifneq ($(wildcard $(objtool_O)),)1505ifneq ($(wildcard $(objtool_O)),)
1506 $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean1506 $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) $(patsubst objtool_%,%,$@)
1507endif1507endif
1508 1508
1509tools/: FORCE1509tools/: FORCE
@@ -1686,7 +1686,7 @@ PHONY += $(mrproper-dirs) mrproper · 176 unmodified lines
1686$(mrproper-dirs):1686$(mrproper-dirs):
1687 $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)1687 $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
1688 1688
1689mrproper: clean $(mrproper-dirs)1689mrproper: clean objtool_mrproper $(mrproper-dirs)
1690 $(call cmd,rmfiles)1690 $(call cmd,rmfiles)
1691 @find . $(RCS_FIND_IGNORE) \1691 @find . $(RCS_FIND_IGNORE) \
1692 \( -name '*.rmeta' \) \1692 \( -name '*.rmeta' \) \
arch/alpha/kernel/vmlinux.lds.S+1−0
@@ -71,6 +71,7 @@ SECTIONS · 70 unmodified lines
71 71
72 STABS_DEBUG72 STABS_DEBUG
73 DWARF_DEBUG73 DWARF_DEBUG
74 MODINFO
74 ELF_DETAILS75 ELF_DETAILS
75 76
76 DISCARDS77 DISCARDS
arch/arc/kernel/vmlinux.lds.S+1−0
@@ -123,6 +123,7 @@ SECTIONS · 122 unmodified lines
123 _end = . ;123 _end = . ;
124 124
125 STABS_DEBUG125 STABS_DEBUG
126 MODINFO
126 ELF_DETAILS127 ELF_DETAILS
127 DISCARDS128 DISCARDS
128 129
arch/arm/boot/compressed/vmlinux.lds.S+1−0
@@ -21,6 +21,7 @@ SECTIONS · 20 unmodified lines
21 COMMON_DISCARDS21 COMMON_DISCARDS
22 *(.ARM.exidx*)22 *(.ARM.exidx*)
23 *(.ARM.extab*)23 *(.ARM.extab*)
24 *(.modinfo)
24 *(.note.*)25 *(.note.*)
25 *(.rel.*)26 *(.rel.*)
26 *(.printk_index)27 *(.printk_index)
arch/arm/kernel/vmlinux-xip.lds.S+1−0
@@ -154,6 +154,7 @@ SECTIONS · 153 unmodified lines
154 154
155 STABS_DEBUG155 STABS_DEBUG
156 DWARF_DEBUG156 DWARF_DEBUG
157 MODINFO
157 ARM_DETAILS158 ARM_DETAILS
158 159
159 ARM_ASSERTS160 ARM_ASSERTS
arch/arm/kernel/vmlinux.lds.S+1−0
@@ -153,6 +153,7 @@ SECTIONS · 152 unmodified lines
153 153
154 STABS_DEBUG154 STABS_DEBUG
155 DWARF_DEBUG155 DWARF_DEBUG
156 MODINFO
156 ARM_DETAILS157 ARM_DETAILS
157 158
158 ARM_ASSERTS159 ARM_ASSERTS
arch/arm64/include/asm/cmpxchg.h+7−5
@@ -91,8 +91,9 @@ __XCHG_GEN(_mb) · 90 unmodified lines
91#define __xchg_wrapper(sfx, ptr, x) \91#define __xchg_wrapper(sfx, ptr, x) \
92({ \92({ \
93 __typeof__(*(ptr)) __ret; \93 __typeof__(*(ptr)) __ret; \
94 __ret = (__typeof__(*(ptr))) \94 __ret = (__force __typeof__(*(ptr))) \
95 __arch_xchg##sfx((unsigned long)(x), (ptr), sizeof(*(ptr))); \95 __arch_xchg##sfx((__force unsigned long)(x), (ptr), \
96 sizeof(*(ptr))); \
96 __ret; \97 __ret; \
97})98})
98 99
@@ -175,9 +176,10 @@ __CMPXCHG_GEN(_mb) · 76 unmodified lines
175#define __cmpxchg_wrapper(sfx, ptr, o, n) \176#define __cmpxchg_wrapper(sfx, ptr, o, n) \
176({ \177({ \
177 __typeof__(*(ptr)) __ret; \178 __typeof__(*(ptr)) __ret; \
178 __ret = (__typeof__(*(ptr))) \179 __ret = (__force __typeof__(*(ptr))) \
179 __cmpxchg##sfx((ptr), (unsigned long)(o), \180 __cmpxchg##sfx((ptr), (__force unsigned long)(o), \
180 (unsigned long)(n), sizeof(*(ptr))); \181 (__force unsigned long)(n), \
182 sizeof(*(ptr))); \
181 __ret; \183 __ret; \
182})184})
183 185
arch/arm64/include/asm/pgtable-prot.h+5−5
@@ -50,11 +50,11 @@ · 49 unmodified lines
50 50
51#define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))51#define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
52 52
53#define _PAGE_KERNEL (PROT_NORMAL)53#define _PAGE_KERNEL (PROT_NORMAL | PTE_DIRTY)
54#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)54#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY | PTE_DIRTY)
55#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)55#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY | PTE_DIRTY)
56#define _PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN)56#define _PAGE_KERNEL_EXEC ((PROT_NORMAL & ~PTE_PXN) | PTE_DIRTY)
57#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)57#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT | PTE_DIRTY)
58 58
59#define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)59#define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
60#define _PAGE_SHARED_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)60#define _PAGE_SHARED_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
arch/arm64/include/asm/runtime-const.h+4−0
@@ -2,6 +2,10 @@ · 1 unmodified line
2#ifndef _ASM_RUNTIME_CONST_H2#ifndef _ASM_RUNTIME_CONST_H
3#define _ASM_RUNTIME_CONST_H3#define _ASM_RUNTIME_CONST_H
4 4
5#ifdef MODULE
6 #error "Cannot use runtime-const infrastructure from modules"
7#endif
8
5#include <asm/cacheflush.h>9#include <asm/cacheflush.h>
6 10
7/* Sigh. You can still run arm64 in BE mode */11/* Sigh. You can still run arm64 in BE mode */
arch/arm64/kernel/vmlinux.lds.S+1−0
@@ -349,6 +349,7 @@ SECTIONS · 348 unmodified lines
349 349
350 STABS_DEBUG350 STABS_DEBUG
351 DWARF_DEBUG351 DWARF_DEBUG
352 MODINFO
352 ELF_DETAILS353 ELF_DETAILS
353 354
354 HEAD_SYMBOLS355 HEAD_SYMBOLS
arch/arm64/mm/contpte.c+49−4
@@ -599,6 +599,27 @@ void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma, · 598 unmodified lines
599}599}
600EXPORT_SYMBOL_GPL(contpte_clear_young_dirty_ptes);600EXPORT_SYMBOL_GPL(contpte_clear_young_dirty_ptes);
601 601
602static bool contpte_all_subptes_match_access_flags(pte_t *ptep, pte_t entry)
603{
604 pte_t *cont_ptep = contpte_align_down(ptep);
605 /*
606 * PFNs differ per sub-PTE. Match only bits consumed by
607 * __ptep_set_access_flags(): AF, DIRTY and write permission.
608 */
609 const pteval_t cmp_mask = PTE_RDONLY | PTE_AF | PTE_WRITE | PTE_DIRTY;
610 pteval_t entry_cmp = pte_val(entry) & cmp_mask;
611 int i;
612
613 for (i = 0; i < CONT_PTES; i++) {
614 pteval_t pte_cmp = pte_val(__ptep_get(cont_ptep + i)) & cmp_mask;
615
616 if (pte_cmp != entry_cmp)
617 return false;
618 }
619
620 return true;
621}
622
602int contpte_ptep_set_access_flags(struct vm_area_struct *vma,623int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
603 unsigned long addr, pte_t *ptep,624 unsigned long addr, pte_t *ptep,
604 pte_t entry, int dirty)625 pte_t entry, int dirty)
@@ -608,13 +629,37 @@ int contpte_ptep_set_access_flags(struct vm_area_struct *vma, · 3 unmodified lines
608 int i;629 int i;
609 630
610 /*631 /*
611 * Gather the access/dirty bits for the contiguous range. If nothing has632 * Check whether all sub-PTEs in the CONT block already match the
612 * changed, its a noop.633 * requested access flags/write permission, using raw per-PTE values
634 * rather than the gathered ptep_get() view.
635 *
636 * __ptep_set_access_flags() can update AF, dirty and write
637 * permission, but only to make the mapping more permissive.
638 *
639 * ptep_get() gathers AF/dirty state across the whole CONT block,
640 * which is correct for a CPU with FEAT_HAFDBS. But page-table
641 * walkers that evaluate each descriptor individually (e.g. a CPU
642 * without DBM support, or an SMMU without HTTU, or with HA/HD
643 * disabled in CD.TCR) can keep faulting on the target sub-PTE if
644 * only a sibling has been updated. Gathering can therefore cause
645 * false no-ops when only a sibling has been updated:
646 * - write faults: target still has PTE_RDONLY (needs PTE_RDONLY cleared)
647 * - read faults: target still lacks PTE_AF
648 *
649 * Per Arm ARM (DDI 0487) D8.7.1, any sub-PTE in a CONT range may
650 * become the effective cached translation, so all entries must have
651 * consistent attributes. Check the full CONT block before returning
652 * no-op, and when any sub-PTE mismatches, proceed to update the whole
653 * range.
613 */654 */
614 orig_pte = pte_mknoncont(ptep_get(ptep));655 if (contpte_all_subptes_match_access_flags(ptep, entry))
615 if (pte_val(orig_pte) == pte_val(entry))
616 return 0;656 return 0;
617 657
658 /*
659 * Use raw target pte (not gathered) for write-bit unfold decision.
660 */
661 orig_pte = pte_mknoncont(__ptep_get(ptep));
662
618 /*663 /*
619 * We can fix up access/dirty bits without having to unfold the contig664 * We can fix up access/dirty bits without having to unfold the contig
620 * range. But if the write bit is changing, we must unfold.665 * range. But if the write bit is changing, we must unfold.
arch/csky/kernel/vmlinux.lds.S+1−0
@@ -109,6 +109,7 @@ SECTIONS · 108 unmodified lines
109 109
110 STABS_DEBUG110 STABS_DEBUG
111 DWARF_DEBUG111 DWARF_DEBUG
112 MODINFO
112 ELF_DETAILS113 ELF_DETAILS
113 114
114 DISCARDS115 DISCARDS
arch/hexagon/kernel/vmlinux.lds.S+1−0
@@ -62,6 +62,7 @@ SECTIONS · 61 unmodified lines
62 62
63 STABS_DEBUG63 STABS_DEBUG
64 DWARF_DEBUG64 DWARF_DEBUG
65 MODINFO
65 ELF_DETAILS66 ELF_DETAILS
66 .hexagon.attributes 0 : { *(.hexagon.attributes) }67 .hexagon.attributes 0 : { *(.hexagon.attributes) }
67 68
arch/loongarch/kernel/vmlinux.lds.S+1−0
@@ -147,6 +147,7 @@ SECTIONS · 146 unmodified lines
147 147
148 STABS_DEBUG148 STABS_DEBUG
149 DWARF_DEBUG149 DWARF_DEBUG
150 MODINFO
150 ELF_DETAILS151 ELF_DETAILS
151 152
152#ifdef CONFIG_EFI_STUB153#ifdef CONFIG_EFI_STUB
arch/m68k/kernel/vmlinux-nommu.lds+1−0
@@ -85,6 +85,7 @@ SECTIONS { · 84 unmodified lines
85 _end = .;85 _end = .;
86 86
87 STABS_DEBUG87 STABS_DEBUG
88 MODINFO
88 ELF_DETAILS89 ELF_DETAILS
89 90
90 /* Sections to be discarded */91 /* Sections to be discarded */
arch/m68k/kernel/vmlinux-std.lds+1−0
@@ -58,6 +58,7 @@ SECTIONS · 57 unmodified lines
58 _end = . ;58 _end = . ;
59 59
60 STABS_DEBUG60 STABS_DEBUG
61 MODINFO
61 ELF_DETAILS62 ELF_DETAILS
62 63
63 /* Sections to be discarded */64 /* Sections to be discarded */
arch/m68k/kernel/vmlinux-sun3.lds+1−0
@@ -51,6 +51,7 @@ __init_begin = .; · 50 unmodified lines
51 _end = . ;51 _end = . ;
52 52
53 STABS_DEBUG53 STABS_DEBUG
54 MODINFO
54 ELF_DETAILS55 ELF_DETAILS
55 56
56 /* Sections to be discarded */57 /* Sections to be discarded */
arch/mips/kernel/vmlinux.lds.S+1−0
@@ -217,6 +217,7 @@ SECTIONS · 216 unmodified lines
217 217
218 STABS_DEBUG218 STABS_DEBUG
219 DWARF_DEBUG219 DWARF_DEBUG
220 MODINFO
220 ELF_DETAILS221 ELF_DETAILS
221 222
222 /* These must appear regardless of . */223 /* These must appear regardless of . */
arch/nios2/kernel/vmlinux.lds.S+1−0
@@ -57,6 +57,7 @@ SECTIONS · 56 unmodified lines
57 57
58 STABS_DEBUG58 STABS_DEBUG
59 DWARF_DEBUG59 DWARF_DEBUG
60 MODINFO
60 ELF_DETAILS61 ELF_DETAILS
61 62
62 DISCARDS63 DISCARDS
arch/openrisc/kernel/vmlinux.lds.S+1−0
@@ -101,6 +101,7 @@ SECTIONS · 100 unmodified lines
101 /* Throw in the debugging sections */101 /* Throw in the debugging sections */
102 STABS_DEBUG102 STABS_DEBUG
103 DWARF_DEBUG103 DWARF_DEBUG
104 MODINFO
104 ELF_DETAILS105 ELF_DETAILS
105 106
106 /* Sections to be discarded -- must be last */107 /* Sections to be discarded -- must be last */
arch/parisc/boot/compressed/vmlinux.lds.S+1−0
@@ -90,6 +90,7 @@ SECTIONS · 89 unmodified lines
90 /* Sections to be discarded */90 /* Sections to be discarded */
91 DISCARDS91 DISCARDS
92 /DISCARD/ : {92 /DISCARD/ : {
93 *(.modinfo)
93#ifdef CONFIG_64BIT94#ifdef CONFIG_64BIT
94 /* temporary hack until binutils is fixed to not emit these95 /* temporary hack until binutils is fixed to not emit these
95 * for static binaries96 * for static binaries
arch/parisc/include/asm/pgtable.h+1−1
@@ -85,7 +85,7 @@ extern void __update_cache(pte_t pte); · 84 unmodified lines
85 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))85 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
86 86
87/* This is the size of the initially mapped kernel memory */87/* This is the size of the initially mapped kernel memory */
88#if defined(CONFIG_64BIT)88#if defined(CONFIG_64BIT) || defined(CONFIG_KALLSYMS)
89#define KERNEL_INITIAL_ORDER 26 /* 1<<26 = 64MB */89#define KERNEL_INITIAL_ORDER 26 /* 1<<26 = 64MB */
90#else90#else
91#define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */91#define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */
arch/parisc/kernel/head.S+6−1
@@ -56,6 +56,7 @@ ENTRY(parisc_kernel_start) · 55 unmodified lines
56 56
57 .import __bss_start,data57 .import __bss_start,data
58 .import __bss_stop,data58 .import __bss_stop,data
59 .import __end,data
59 60
60 load32 PA(__bss_start),%r361 load32 PA(__bss_start),%r3
61 load32 PA(__bss_stop),%r462 load32 PA(__bss_stop),%r4
@@ -149,7 +150,11 @@ $cpu_ok: · 87 unmodified lines
149 * everything ... it will get remapped correctly later */150 * everything ... it will get remapped correctly later */
150 ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */151 ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
151 load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */152 load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
152 load32 PA(pg0),%r1153 load32 PA(_end),%r1
154 SHRREG %r1,PAGE_SHIFT,%r1 /* %r1 is PFN count for _end symbol */
155 cmpb,<<,n %r11,%r1,1f
156 copy %r1,%r11 /* %r1 PFN count smaller than %r11 */
1571: load32 PA(pg0),%r1
153 158
154$pgt_fill_loop:159$pgt_fill_loop:
155 STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1)160 STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1)
arch/parisc/kernel/setup.c+12−8
@@ -120,14 +120,6 @@ void __init setup_arch(char **cmdline_p) · 119 unmodified lines
120#endif120#endif
121 printk(KERN_CONT ".\n");121 printk(KERN_CONT ".\n");
122 122
123 /*
124 * Check if initial kernel page mappings are sufficient.
125 * panic early if not, else we may access kernel functions
126 * and variables which can't be reached.
127 */
128 if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
129 panic("KERNEL_INITIAL_ORDER too small!");
130
131#ifdef CONFIG_64BIT123#ifdef CONFIG_64BIT
132 if(parisc_narrow_firmware) {124 if(parisc_narrow_firmware) {
133 printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");125 printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
@@ -279,6 +271,18 @@ void __init start_parisc(void) · 145 unmodified lines
279 int ret, cpunum;271 int ret, cpunum;
280 struct pdc_coproc_cfg coproc_cfg;272 struct pdc_coproc_cfg coproc_cfg;
281 273
274 /*
275 * Check if initial kernel page mapping is sufficient.
276 * Print warning if not, because we may access kernel functions and
277 * variables which can't be reached yet through the initial mappings.
278 * Note that the panic() and printk() functions are not functional
279 * yet, so we need to use direct iodc() firmware calls instead.
280 */
281 const char warn1[] = "CRITICAL: Kernel may crash because "
282 "KERNEL_INITIAL_ORDER is too small.\n";
283 if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
284 pdc_iodc_print(warn1, sizeof(warn1) - 1);
285
282 /* check QEMU/SeaBIOS marker in PAGE0 */286 /* check QEMU/SeaBIOS marker in PAGE0 */
283 running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0);287 running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0);
284 288
arch/parisc/kernel/vmlinux.lds.S+1−0
@@ -165,6 +165,7 @@ SECTIONS · 164 unmodified lines
165 _end = . ;165 _end = . ;
166 166
167 STABS_DEBUG167 STABS_DEBUG
168 MODINFO
168 ELF_DETAILS169 ELF_DETAILS
169 .note 0 : { *(.note) }170 .note 0 : { *(.note) }
170 171
arch/powerpc/kernel/pci_of_scan.c+7−0
@@ -212,6 +212,13 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, · 211 unmodified lines
212 dev->error_state = pci_channel_io_normal;212 dev->error_state = pci_channel_io_normal;
213 dev->dma_mask = 0xffffffff;213 dev->dma_mask = 0xffffffff;
214 214
215 /*
216 * Assume 64-bit addresses for MSI initially. Will be changed to 32-bit
217 * if MSI (rather than MSI-X) capability does not have
218 * PCI_MSI_FLAGS_64BIT. Can also be overridden by driver.
219 */
220 dev->msi_addr_mask = DMA_BIT_MASK(64);
221
215 /* Early fixups, before probing the BARs */222 /* Early fixups, before probing the BARs */
216 pci_fixup_device(pci_fixup_early, dev);223 pci_fixup_device(pci_fixup_early, dev);
217 224
arch/powerpc/kernel/vmlinux.lds.S+1−0
@@ -397,6 +397,7 @@ SECTIONS · 396 unmodified lines
397 _end = . ;397 _end = . ;
398 398
399 DWARF_DEBUG399 DWARF_DEBUG
400 MODINFO
400 ELF_DETAILS401 ELF_DETAILS
401 402
402 DISCARDS403 DISCARDS
arch/riscv/kernel/vmlinux.lds.S+1−0
@@ -170,6 +170,7 @@ SECTIONS · 169 unmodified lines
170 170
171 STABS_DEBUG171 STABS_DEBUG
172 DWARF_DEBUG172 DWARF_DEBUG
173 MODINFO
173 ELF_DETAILS174 ELF_DETAILS
174 .riscv.attributes 0 : { *(.riscv.attributes) }175 .riscv.attributes 0 : { *(.riscv.attributes) }
175 176
arch/s390/include/asm/processor.h+1−1
@@ -159,7 +159,7 @@ static __always_inline void __stackleak_poison(unsigned long erase_low, · 158 unmodified lines
159 " j 4f\n"159 " j 4f\n"
160 "3: mvc 8(1,%[addr]),0(%[addr])\n"160 "3: mvc 8(1,%[addr]),0(%[addr])\n"
161 "4:"161 "4:"
162 : [addr] "+&a" (erase_low), [count] "+&d" (count), [tmp] "=&a" (tmp)162 : [addr] "+&a" (erase_low), [count] "+&a" (count), [tmp] "=&a" (tmp)
163 : [poison] "d" (poison)163 : [poison] "d" (poison)
164 : "memory", "cc"164 : "memory", "cc"
165 );165 );
arch/s390/kernel/vmlinux.lds.S+1−0
@@ -221,6 +221,7 @@ SECTIONS · 220 unmodified lines
221 /* Debugging sections. */221 /* Debugging sections. */
222 STABS_DEBUG222 STABS_DEBUG
223 DWARF_DEBUG223 DWARF_DEBUG
224 MODINFO
224 ELF_DETAILS225 ELF_DETAILS
225 226
226 /*227 /*
arch/s390/lib/xor.c+5−6
@@ -28,8 +28,8 @@ static void xor_xc_2(unsigned long bytes, unsigned long * __restrict p1, · 27 unmodified lines
28 " j 3f\n"28 " j 3f\n"
29 "2: xc 0(1,%1),0(%2)\n"29 "2: xc 0(1,%1),0(%2)\n"
30 "3:"30 "3:"
31 : : "d" (bytes), "a" (p1), "a" (p2)31 : "+a" (bytes), "+a" (p1), "+a" (p2)
32 : "0", "cc", "memory");32 : : "0", "cc", "memory");
33}33}
34 34
35static void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1,35static void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1,
@@ -54,7 +54,7 @@ static void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1, · 18 unmodified lines
54 "2: xc 0(1,%1),0(%2)\n"54 "2: xc 0(1,%1),0(%2)\n"
55 "3: xc 0(1,%1),0(%3)\n"55 "3: xc 0(1,%1),0(%3)\n"
56 "4:"56 "4:"
57 : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)57 : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
58 : : "0", "cc", "memory");58 : : "0", "cc", "memory");
59}59}
60 60
@@ -85,7 +85,7 @@ static void xor_xc_4(unsigned long bytes, unsigned long * __restrict p1, · 24 unmodified lines
85 "3: xc 0(1,%1),0(%3)\n"85 "3: xc 0(1,%1),0(%3)\n"
86 "4: xc 0(1,%1),0(%4)\n"86 "4: xc 0(1,%1),0(%4)\n"
87 "5:"87 "5:"
88 : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)88 : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
89 : : "0", "cc", "memory");89 : : "0", "cc", "memory");
90}90}
91 91
@@ -96,7 +96,6 @@ static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1, · 4 unmodified lines
96 const unsigned long * __restrict p5)96 const unsigned long * __restrict p5)
97{97{
98 asm volatile(98 asm volatile(
99 " larl 1,2f\n"
100 " aghi %0,-1\n"99 " aghi %0,-1\n"
101 " jm 6f\n"100 " jm 6f\n"
102 " srlg 0,%0,8\n"101 " srlg 0,%0,8\n"
@@ -122,7 +121,7 @@ static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1, · 19 unmodified lines
122 "4: xc 0(1,%1),0(%4)\n"121 "4: xc 0(1,%1),0(%4)\n"
123 "5: xc 0(1,%1),0(%5)\n"122 "5: xc 0(1,%1),0(%5)\n"
124 "6:"123 "6:"
125 : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),124 : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
126 "+a" (p5)125 "+a" (p5)
127 : : "0", "cc", "memory");126 : : "0", "cc", "memory");
128}127}
arch/sh/kernel/vmlinux.lds.S+1−0
@@ -89,6 +89,7 @@ SECTIONS · 88 unmodified lines
89 89
90 STABS_DEBUG90 STABS_DEBUG
91 DWARF_DEBUG91 DWARF_DEBUG
92 MODINFO
92 ELF_DETAILS93 ELF_DETAILS
93 94
94 DISCARDS95 DISCARDS
arch/sparc/kernel/pci.c+7−0
@@ -355,6 +355,13 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, · 354 unmodified lines
355 dev->error_state = pci_channel_io_normal;355 dev->error_state = pci_channel_io_normal;
356 dev->dma_mask = 0xffffffff;356 dev->dma_mask = 0xffffffff;
357 357
358 /*
359 * Assume 64-bit addresses for MSI initially. Will be changed to 32-bit
360 * if MSI (rather than MSI-X) capability does not have
361 * PCI_MSI_FLAGS_64BIT. Can also be overridden by driver.
362 */
363 dev->msi_addr_mask = DMA_BIT_MASK(64);
364
358 if (of_node_name_eq(node, "pci")) {365 if (of_node_name_eq(node, "pci")) {
359 /* a PCI-PCI bridge */366 /* a PCI-PCI bridge */
360 dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;367 dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
arch/sparc/kernel/vmlinux.lds.S+1−0
@@ -191,6 +191,7 @@ SECTIONS · 190 unmodified lines
191 191
192 STABS_DEBUG192 STABS_DEBUG
193 DWARF_DEBUG193 DWARF_DEBUG
194 MODINFO
194 ELF_DETAILS195 ELF_DETAILS
195 196
196 DISCARDS197 DISCARDS
arch/um/kernel/dyn.lds.S+1−0
@@ -172,6 +172,7 @@ SECTIONS · 171 unmodified lines
172 172
173 STABS_DEBUG173 STABS_DEBUG
174 DWARF_DEBUG174 DWARF_DEBUG
175 MODINFO
175 ELF_DETAILS176 ELF_DETAILS
176 177
177 DISCARDS178 DISCARDS
arch/um/kernel/uml.lds.S+1−0
@@ -113,6 +113,7 @@ SECTIONS · 112 unmodified lines
113 113
114 STABS_DEBUG114 STABS_DEBUG
115 DWARF_DEBUG115 DWARF_DEBUG
116 MODINFO
116 ELF_DETAILS117 ELF_DETAILS
117 118
118 DISCARDS119 DISCARDS
arch/x86/boot/compressed/Makefile+1−0
@@ -113,6 +113,7 @@ vmlinux-objs-$(CONFIG_EFI_SBAT) += $(obj)/sbat.o · 112 unmodified lines
113 113
114ifdef CONFIG_EFI_SBAT114ifdef CONFIG_EFI_SBAT
115$(obj)/sbat.o: $(CONFIG_EFI_SBAT_FILE)115$(obj)/sbat.o: $(CONFIG_EFI_SBAT_FILE)
116AFLAGS_sbat.o += -I $(srctree)
116endif117endif
117 118
118$(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE119$(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE
arch/x86/boot/compressed/sev.c+5−4
@@ -28,17 +28,17 @@ · 27 unmodified lines
28#include "sev.h"28#include "sev.h"
29 29
30static struct ghcb boot_ghcb_page __aligned(PAGE_SIZE);30static struct ghcb boot_ghcb_page __aligned(PAGE_SIZE);
31struct ghcb *boot_ghcb;31struct ghcb *boot_ghcb __section(".data");
32 32
33#undef __init33#undef __init
34#define __init34#define __init
35 35
36#define __BOOT_COMPRESSED36#define __BOOT_COMPRESSED
37 37
38u8 snp_vmpl;38u8 snp_vmpl __section(".data");
39u16 ghcb_version;39u16 ghcb_version __section(".data");
40 40
41u64 boot_svsm_caa_pa;41u64 boot_svsm_caa_pa __section(".data");
42 42
43/* Include code for early handlers */43/* Include code for early handlers */
44#include "../../boot/startup/sev-shared.c"44#include "../../boot/startup/sev-shared.c"
@@ -188,6 +188,7 @@ bool sev_es_check_ghcb_fault(unsigned long address) · 143 unmodified lines
188 MSR_AMD64_SNP_RESERVED_BIT13 | \188 MSR_AMD64_SNP_RESERVED_BIT13 | \
189 MSR_AMD64_SNP_RESERVED_BIT15 | \189 MSR_AMD64_SNP_RESERVED_BIT15 | \
190 MSR_AMD64_SNP_SECURE_AVIC | \190 MSR_AMD64_SNP_SECURE_AVIC | \
191 MSR_AMD64_SNP_RESERVED_BITS19_22 | \
191 MSR_AMD64_SNP_RESERVED_MASK)192 MSR_AMD64_SNP_RESERVED_MASK)
192 193
193#ifdef CONFIG_AMD_SECURE_AVIC194#ifdef CONFIG_AMD_SECURE_AVIC
arch/x86/boot/compressed/vmlinux.lds.S+1−1
@@ -88,7 +88,7 @@ SECTIONS · 87 unmodified lines
88 /DISCARD/ : {88 /DISCARD/ : {
89 *(.dynamic) *(.dynsym) *(.dynstr) *(.dynbss)89 *(.dynamic) *(.dynsym) *(.dynstr) *(.dynbss)
90 *(.hash) *(.gnu.hash)90 *(.hash) *(.gnu.hash)
91 *(.note.*)91 *(.note.*) *(.modinfo)
92 }92 }
93 93
94 .got.plt (INFO) : {94 .got.plt (INFO) : {
arch/x86/boot/startup/sev-shared.c+1−1
@@ -31,7 +31,7 @@ static u32 cpuid_std_range_max __ro_after_init; · 30 unmodified lines
31static u32 cpuid_hyp_range_max __ro_after_init;31static u32 cpuid_hyp_range_max __ro_after_init;
32static u32 cpuid_ext_range_max __ro_after_init;32static u32 cpuid_ext_range_max __ro_after_init;
33 33
34bool sev_snp_needs_sfw;34bool sev_snp_needs_sfw __section(".data");
35 35
36void __noreturn36void __noreturn
37sev_es_terminate(unsigned int set, unsigned int reason)37sev_es_terminate(unsigned int set, unsigned int reason)
arch/x86/coco/sev/core.c+1−0
@@ -89,6 +89,7 @@ static const char * const sev_status_feat_names[] = { · 88 unmodified lines
89 [MSR_AMD64_SNP_VMSA_REG_PROT_BIT] = "VMSARegProt",89 [MSR_AMD64_SNP_VMSA_REG_PROT_BIT] = "VMSARegProt",
90 [MSR_AMD64_SNP_SMT_PROT_BIT] = "SMTProt",90 [MSR_AMD64_SNP_SMT_PROT_BIT] = "SMTProt",
91 [MSR_AMD64_SNP_SECURE_AVIC_BIT] = "SecureAVIC",91 [MSR_AMD64_SNP_SECURE_AVIC_BIT] = "SecureAVIC",
92 [MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT] = "IBPBOnEntry",
92};93};
93 94
94/*95/*
arch/x86/entry/vdso/vdso32/sigreturn.S+30−0
@@ -35,9 +35,38 @@ · 34 unmodified lines
35#endif35#endif
36.endm36.endm
37 37
38/*
39 * WARNING:
40 *
41 * A bug in the libgcc unwinder as of at least gcc 15.2 (2026) means that
42 * the unwinder fails to recognize the signal frame flag.
43 *
44 * There is a hacky legacy fallback path in libgcc which ends up
45 * getting invoked instead. It happens to work as long as BOTH of the
46 * following conditions are true:
47 *
48 * 1. There is at least one byte before the each of the sigreturn
49 * functions which falls outside any function. This is enforced by
50 * an explicit nop instruction before the ALIGN.
51 * 2. The code sequences between the entry point up to and including
52 * the int $0x80 below need to match EXACTLY. Do not change them
53 * in any way. The exact byte sequences are:
54 *
55 * __kernel_sigreturn:
56 * 0: 58 pop %eax
57 * 1: b8 77 00 00 00 mov $0x77,%eax
58 * 6: cd 80 int $0x80
59 *
60 * __kernel_rt_sigreturn:
61 * 0: b8 ad 00 00 00 mov $0xad,%eax
62 * 5: cd 80 int $0x80
63 *
64 * For details, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124050
65 */
38 .text66 .text
39 .globl __kernel_sigreturn67 .globl __kernel_sigreturn
40 .type __kernel_sigreturn,@function68 .type __kernel_sigreturn,@function
69 nop /* libgcc hack: see comment above */
41 ALIGN70 ALIGN
42__kernel_sigreturn:71__kernel_sigreturn:
43 STARTPROC_SIGNAL_FRAME IA32_SIGFRAME_sigcontext72 STARTPROC_SIGNAL_FRAME IA32_SIGFRAME_sigcontext
@@ -52,6 +81,7 @@ SYM_INNER_LABEL(vdso32_sigreturn_landing_pad, SYM_L_GLOBAL) · 8 unmodified lines
52 81
53 .globl __kernel_rt_sigreturn82 .globl __kernel_rt_sigreturn
54 .type __kernel_rt_sigreturn,@function83 .type __kernel_rt_sigreturn,@function
84 nop /* libgcc hack: see comment above */
55 ALIGN85 ALIGN
56__kernel_rt_sigreturn:86__kernel_rt_sigreturn:
57 STARTPROC_SIGNAL_FRAME IA32_RT_SIGFRAME_sigcontext87 STARTPROC_SIGNAL_FRAME IA32_RT_SIGFRAME_sigcontext
arch/x86/include/asm/efi.h+1−1
@@ -138,7 +138,7 @@ extern void __init efi_apply_memmap_quirks(void); · 137 unmodified lines
138extern int __init efi_reuse_config(u64 tables, int nr_tables);138extern int __init efi_reuse_config(u64 tables, int nr_tables);
139extern void efi_delete_dummy_variable(void);139extern void efi_delete_dummy_variable(void);
140extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr);140extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr);
141extern void efi_free_boot_services(void);141extern void efi_unmap_boot_services(void);
142 142
143void arch_efi_call_virt_setup(void);143void arch_efi_call_virt_setup(void);
144void arch_efi_call_virt_teardown(void);144void arch_efi_call_virt_teardown(void);
arch/x86/include/asm/msr-index.h+4−1
@@ -740,7 +740,10 @@ · 739 unmodified lines
740#define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)740#define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
741#define MSR_AMD64_SNP_SECURE_AVIC_BIT 18741#define MSR_AMD64_SNP_SECURE_AVIC_BIT 18
742#define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)742#define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
743#define MSR_AMD64_SNP_RESV_BIT 19743#define MSR_AMD64_SNP_RESERVED_BITS19_22 GENMASK_ULL(22, 19)
744#define MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT 23
745#define MSR_AMD64_SNP_IBPB_ON_ENTRY BIT_ULL(MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT)
746#define MSR_AMD64_SNP_RESV_BIT 24
744#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)747#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
745#define MSR_AMD64_SAVIC_CONTROL 0xc0010138748#define MSR_AMD64_SAVIC_CONTROL 0xc0010138
746#define MSR_AMD64_SAVIC_EN_BIT 0749#define MSR_AMD64_SAVIC_EN_BIT 0
arch/x86/include/asm/numa.h+6−0
@@ -22,6 +22,7 @@ extern int numa_off; · 21 unmodified lines
22 */22 */
23extern s16 __apicid_to_node[MAX_LOCAL_APIC];23extern s16 __apicid_to_node[MAX_LOCAL_APIC];
24extern nodemask_t numa_nodes_parsed __initdata;24extern nodemask_t numa_nodes_parsed __initdata;
25extern nodemask_t numa_phys_nodes_parsed __initdata;
25 26
26static inline void set_apicid_to_node(int apicid, s16 node)27static inline void set_apicid_to_node(int apicid, s16 node)
27{28{
@@ -48,6 +49,7 @@ extern void __init init_cpu_to_node(void); · 20 unmodified lines
48extern void numa_add_cpu(unsigned int cpu);49extern void numa_add_cpu(unsigned int cpu);
49extern void numa_remove_cpu(unsigned int cpu);50extern void numa_remove_cpu(unsigned int cpu);
50extern void init_gi_nodes(void);51extern void init_gi_nodes(void);
52extern int num_phys_nodes(void);
51#else /* CONFIG_NUMA */53#else /* CONFIG_NUMA */
52static inline void numa_set_node(int cpu, int node) { }54static inline void numa_set_node(int cpu, int node) { }
53static inline void numa_clear_node(int cpu) { }55static inline void numa_clear_node(int cpu) { }
@@ -55,6 +57,10 @@ static inline void init_cpu_to_node(void) { } · 1 unmodified line
55static inline void numa_add_cpu(unsigned int cpu) { }57static inline void numa_add_cpu(unsigned int cpu) { }
56static inline void numa_remove_cpu(unsigned int cpu) { }58static inline void numa_remove_cpu(unsigned int cpu) { }
57static inline void init_gi_nodes(void) { }59static inline void init_gi_nodes(void) { }
60static inline int num_phys_nodes(void)
61{
62 return 1;
63}
58#endif /* CONFIG_NUMA */64#endif /* CONFIG_NUMA */
59 65
60#ifdef CONFIG_DEBUG_PER_CPU_MAPS66#ifdef CONFIG_DEBUG_PER_CPU_MAPS
arch/x86/include/asm/pgtable_64.h+0−2
@@ -19,10 +19,8 @@ · 18 unmodified lines
19extern p4d_t level4_kernel_pgt[512];19extern p4d_t level4_kernel_pgt[512];
20extern p4d_t level4_ident_pgt[512];20extern p4d_t level4_ident_pgt[512];
21extern pud_t level3_kernel_pgt[512];21extern pud_t level3_kernel_pgt[512];
22extern pud_t level3_ident_pgt[512];
23extern pmd_t level2_kernel_pgt[512];22extern pmd_t level2_kernel_pgt[512];
24extern pmd_t level2_fixmap_pgt[512];23extern pmd_t level2_fixmap_pgt[512];
25extern pmd_t level2_ident_pgt[512];
26extern pte_t level1_fixmap_pgt[512 * FIXMAP_PMD_NUM];24extern pte_t level1_fixmap_pgt[512 * FIXMAP_PMD_NUM];
27extern pgd_t init_top_pgt[];25extern pgd_t init_top_pgt[];
28 26
arch/x86/include/asm/topology.h+6−0
@@ -155,6 +155,7 @@ extern unsigned int __max_logical_packages; · 154 unmodified lines
155extern unsigned int __max_threads_per_core;155extern unsigned int __max_threads_per_core;
156extern unsigned int __num_threads_per_package;156extern unsigned int __num_threads_per_package;
157extern unsigned int __num_cores_per_package;157extern unsigned int __num_cores_per_package;
158extern unsigned int __num_nodes_per_package;
158 159
159const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c);160const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c);
160enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c);161enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c);
@@ -179,6 +180,11 @@ static inline unsigned int topology_num_threads_per_package(void) · 18 unmodified lines
179 return __num_threads_per_package;180 return __num_threads_per_package;
180}181}
181 182
183static inline unsigned int topology_num_nodes_per_package(void)
184{
185 return __num_nodes_per_package;
186}
187
182#ifdef CONFIG_X86_LOCAL_APIC188#ifdef CONFIG_X86_LOCAL_APIC
183int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level);189int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level);
184#else190#else
arch/x86/kernel/cpu/common.c+3−0
@@ -95,6 +95,9 @@ EXPORT_SYMBOL(__max_dies_per_package); · 94 unmodified lines
95unsigned int __max_logical_packages __ro_after_init = 1;95unsigned int __max_logical_packages __ro_after_init = 1;
96EXPORT_SYMBOL(__max_logical_packages);96EXPORT_SYMBOL(__max_logical_packages);
97 97
98unsigned int __num_nodes_per_package __ro_after_init = 1;
99EXPORT_SYMBOL(__num_nodes_per_package);
100
98unsigned int __num_cores_per_package __ro_after_init = 1;101unsigned int __num_cores_per_package __ro_after_init = 1;
99EXPORT_SYMBOL(__num_cores_per_package);102EXPORT_SYMBOL(__num_cores_per_package);
100 103
arch/x86/kernel/cpu/resctrl/monitor.c+5−31
@@ -364,7 +364,7 @@ void arch_mon_domain_online(struct rdt_resource *r, struct rdt_l3_mon_domain *d) · 363 unmodified lines
364 msr_clear_bit(MSR_RMID_SNC_CONFIG, 0);364 msr_clear_bit(MSR_RMID_SNC_CONFIG, 0);
365}365}
366 366
367/* CPU models that support MSR_RMID_SNC_CONFIG */367/* CPU models that support SNC and MSR_RMID_SNC_CONFIG */
368static const struct x86_cpu_id snc_cpu_ids[] __initconst = {368static const struct x86_cpu_id snc_cpu_ids[] __initconst = {
369 X86_MATCH_VFM(INTEL_ICELAKE_X, 0),369 X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
370 X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0),370 X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0),
@@ -375,40 +375,14 @@ static const struct x86_cpu_id snc_cpu_ids[] __initconst = { · 4 unmodified lines
375 {}375 {}
376};376};
377 377
378/*
379 * There isn't a simple hardware bit that indicates whether a CPU is running
380 * in Sub-NUMA Cluster (SNC) mode. Infer the state by comparing the
381 * number of CPUs sharing the L3 cache with CPU0 to the number of CPUs in
382 * the same NUMA node as CPU0.
383 * It is not possible to accurately determine SNC state if the system is
384 * booted with a maxcpus=N parameter. That distorts the ratio of SNC nodes
385 * to L3 caches. It will be OK if system is booted with hyperthreading
386 * disabled (since this doesn't affect the ratio).
387 */
388static __init int snc_get_config(void)378static __init int snc_get_config(void)
389{379{
390 struct cacheinfo *ci = get_cpu_cacheinfo_level(0, RESCTRL_L3_CACHE);380 int ret = topology_num_nodes_per_package();
391 const cpumask_t *node0_cpumask;
392 int cpus_per_node, cpus_per_l3;
393 int ret;
394
395 if (!x86_match_cpu(snc_cpu_ids) || !ci)
396 return 1;
397 381
398 cpus_read_lock();382 if (ret > 1 && !x86_match_cpu(snc_cpu_ids)) {
399 if (num_online_cpus() != num_present_cpus())383 pr_warn("CoD enabled system? Resctrl not supported\n");
400 pr_warn("Some CPUs offline, SNC detection may be incorrect\n");
401 cpus_read_unlock();
402
403 node0_cpumask = cpumask_of_node(cpu_to_node(0));
404
405 cpus_per_node = cpumask_weight(node0_cpumask);
406 cpus_per_l3 = cpumask_weight(&ci->shared_cpu_map);
407
408 if (!cpus_per_node || !cpus_per_l3)
409 return 1;384 return 1;
410 385 }
411 ret = cpus_per_l3 / cpus_per_node;
412 386
413 /* sanity check: Only valid results are 1, 2, 3, 4, 6 */387 /* sanity check: Only valid results are 1, 2, 3, 4, 6 */
414 switch (ret) {388 switch (ret) {
arch/x86/kernel/cpu/topology.c+11−2
@@ -31,6 +31,7 @@ · 30 unmodified lines
31#include <asm/mpspec.h>31#include <asm/mpspec.h>
32#include <asm/msr.h>32#include <asm/msr.h>
33#include <asm/smp.h>33#include <asm/smp.h>
34#include <asm/numa.h>
34 35
35#include "cpu.h"36#include "cpu.h"
36 37
@@ -492,11 +493,19 @@ void __init topology_init_possible_cpus(void) · 455 unmodified lines
492 set_nr_cpu_ids(allowed);493 set_nr_cpu_ids(allowed);
493 494
494 cnta = domain_weight(TOPO_PKG_DOMAIN);495 cnta = domain_weight(TOPO_PKG_DOMAIN);
495 cntb = domain_weight(TOPO_DIE_DOMAIN);
496 __max_logical_packages = cnta;496 __max_logical_packages = cnta;
497
498 pr_info("Max. logical packages: %3u\n", __max_logical_packages);
499
500 cntb = num_phys_nodes();
501 __num_nodes_per_package = DIV_ROUND_UP(cntb, cnta);
502
503 pr_info("Max. logical nodes: %3u\n", cntb);
504 pr_info("Num. nodes per package:%3u\n", __num_nodes_per_package);
505
506 cntb = domain_weight(TOPO_DIE_DOMAIN);
497 __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta));507 __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta));
498 508
499 pr_info("Max. logical packages: %3u\n", cnta);
500 pr_info("Max. logical dies: %3u\n", cntb);509 pr_info("Max. logical dies: %3u\n", cntb);
501 pr_info("Max. dies per package: %3u\n", __max_dies_per_package);510 pr_info("Max. dies per package: %3u\n", __max_dies_per_package);
502 511
arch/x86/kernel/head_64.S+0−28
@@ -616,38 +616,10 @@ SYM_DATA(early_recursion_flag, .long 0) · 615 unmodified lines
616 616
617 .data617 .data
618 618
619#if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH)
620SYM_DATA_START_PTI_ALIGNED(init_top_pgt)
621 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
622 .org init_top_pgt + L4_PAGE_OFFSET*8, 0
623 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
624 .org init_top_pgt + L4_START_KERNEL*8, 0
625 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
626 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
627 .fill PTI_USER_PGD_FILL,8,0
628SYM_DATA_END(init_top_pgt)
629
630SYM_DATA_START_PAGE_ALIGNED(level3_ident_pgt)
631 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
632 .fill 511, 8, 0
633SYM_DATA_END(level3_ident_pgt)
634SYM_DATA_START_PAGE_ALIGNED(level2_ident_pgt)
635 /*
636 * Since I easily can, map the first 1G.
637 * Don't set NX because code runs from these pages.
638 *
639 * Note: This sets _PAGE_GLOBAL despite whether
640 * the CPU supports it or it is enabled. But,
641 * the CPU should ignore the bit.
642 */
643 PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
644SYM_DATA_END(level2_ident_pgt)
645#else
646SYM_DATA_START_PTI_ALIGNED(init_top_pgt)619SYM_DATA_START_PTI_ALIGNED(init_top_pgt)
647 .fill 512,8,0620 .fill 512,8,0
648 .fill PTI_USER_PGD_FILL,8,0621 .fill PTI_USER_PGD_FILL,8,0
649SYM_DATA_END(init_top_pgt)622SYM_DATA_END(init_top_pgt)
650#endif
651 623
652SYM_DATA_START_PAGE_ALIGNED(level4_kernel_pgt)624SYM_DATA_START_PAGE_ALIGNED(level4_kernel_pgt)
653 .fill 511,8,0625 .fill 511,8,0
arch/x86/kernel/smpboot.c+145−56
@@ -468,13 +468,6 @@ static int x86_cluster_flags(void) · 467 unmodified lines
468}468}
469#endif469#endif
470 470
471/*
472 * Set if a package/die has multiple NUMA nodes inside.
473 * AMD Magny-Cours, Intel Cluster-on-Die, and Intel
474 * Sub-NUMA Clustering have this.
475 */
476static bool x86_has_numa_in_package;
477
478static struct sched_domain_topology_level x86_topology[] = {471static struct sched_domain_topology_level x86_topology[] = {
479 SDTL_INIT(tl_smt_mask, cpu_smt_flags, SMT),472 SDTL_INIT(tl_smt_mask, cpu_smt_flags, SMT),
480#ifdef CONFIG_SCHED_CLUSTER473#ifdef CONFIG_SCHED_CLUSTER
@@ -496,7 +489,7 @@ static void __init build_sched_topology(void) · 15 unmodified lines
496 * PKG domain since the NUMA domains will auto-magically create the489 * PKG domain since the NUMA domains will auto-magically create the
497 * right spanning domains based on the SLIT.490 * right spanning domains based on the SLIT.
498 */491 */
499 if (x86_has_numa_in_package) {492 if (topology_num_nodes_per_package() > 1) {
500 unsigned int pkgdom = ARRAY_SIZE(x86_topology) - 2;493 unsigned int pkgdom = ARRAY_SIZE(x86_topology) - 2;
501 494
502 memset(&x86_topology[pkgdom], 0, sizeof(x86_topology[pkgdom]));495 memset(&x86_topology[pkgdom], 0, sizeof(x86_topology[pkgdom]));
@@ -513,33 +506,149 @@ static void __init build_sched_topology(void) · 10 unmodified lines
513}506}
514 507
515#ifdef CONFIG_NUMA508#ifdef CONFIG_NUMA
516static int sched_avg_remote_distance;509/*
517static int avg_remote_numa_distance(void)510 * Test if the on-trace cluster at (N,N) is symmetric.
511 * Uses upper triangle iteration to avoid obvious duplicates.
512 */
513static bool slit_cluster_symmetric(int N)
518{514{
519 int i, j;515 int u = topology_num_nodes_per_package();
520 int distance, nr_remote, total_distance;516
521 517 for (int k = 0; k < u; k++) {
522 if (sched_avg_remote_distance > 0)518 for (int l = k; l < u; l++) {
523 return sched_avg_remote_distance;519 if (node_distance(N + k, N + l) !=
524 520 node_distance(N + l, N + k))
525 nr_remote = 0;521 return false;
526 total_distance = 0;
527 for_each_node_state(i, N_CPU) {
528 for_each_node_state(j, N_CPU) {
529 distance = node_distance(i, j);
530
531 if (distance >= REMOTE_DISTANCE) {
532 nr_remote++;
533 total_distance += distance;
534 }
535 }522 }
536 }523 }
537 if (nr_remote)
538 sched_avg_remote_distance = total_distance / nr_remote;
539 else
540 sched_avg_remote_distance = REMOTE_DISTANCE;
541 524
542 return sched_avg_remote_distance;525 return true;
526}
527
528/*
529 * Return the package-id of the cluster, or ~0 if indeterminate.
530 * Each node in the on-trace cluster should have the same package-id.
531 */
532static u32 slit_cluster_package(int N)
533{
534 int u = topology_num_nodes_per_package();
535 u32 pkg_id = ~0;
536
537 for (int n = 0; n < u; n++) {
538 const struct cpumask *cpus = cpumask_of_node(N + n);
539 int cpu;
540
541 for_each_cpu(cpu, cpus) {
542 u32 id = topology_logical_package_id(cpu);
543
544 if (pkg_id == ~0)
545 pkg_id = id;
546 if (pkg_id != id)
547 return ~0;
548 }
549 }
550
551 return pkg_id;
552}
553
554/*
555 * Validate the SLIT table is of the form expected for SNC, specifically:
556 *
557 * - each on-trace cluster should be symmetric,
558 * - each on-trace cluster should have a unique package-id.
559 *
560 * If you NUMA_EMU on top of SNC, you get to keep the pieces.
561 */
562static bool slit_validate(void)
563{
564 int u = topology_num_nodes_per_package();
565 u32 pkg_id, prev_pkg_id = ~0;
566
567 for (int pkg = 0; pkg < topology_max_packages(); pkg++) {
568 int n = pkg * u;
569
570 /*
571 * Ensure the on-trace cluster is symmetric and each cluster
572 * has a different package id.
573 */
574 if (!slit_cluster_symmetric(n))
575 return false;
576 pkg_id = slit_cluster_package(n);
577 if (pkg_id == ~0)
578 return false;
579 if (pkg && pkg_id == prev_pkg_id)
580 return false;
581
582 prev_pkg_id = pkg_id;
583 }
584
585 return true;
586}
587
588/*
589 * Compute a sanitized SLIT table for SNC; notably SNC-3 can end up with
590 * asymmetric off-trace clusters, reflecting physical assymmetries. However
591 * this leads to 'unfortunate' sched_domain configurations.
592 *
593 * For example dual socket GNR with SNC-3:
594 *
595 * node distances:
596 * node 0 1 2 3 4 5
597 * 0: 10 15 17 21 28 26
598 * 1: 15 10 15 23 26 23
599 * 2: 17 15 10 26 23 21
600 * 3: 21 28 26 10 15 17
601 * 4: 23 26 23 15 10 15
602 * 5: 26 23 21 17 15 10
603 *
604 * Fix things up by averaging out the off-trace clusters; resulting in:
605 *
606 * node 0 1 2 3 4 5
607 * 0: 10 15 17 24 24 24
608 * 1: 15 10 15 24 24 24
609 * 2: 17 15 10 24 24 24
610 * 3: 24 24 24 10 15 17
611 * 4: 24 24 24 15 10 15
612 * 5: 24 24 24 17 15 10
613 */
614static int slit_cluster_distance(int i, int j)
615{
616 static int slit_valid = -1;
617 int u = topology_num_nodes_per_package();
618 long d = 0;
619 int x, y;
620
621 if (slit_valid < 0) {
622 slit_valid = slit_validate();
623 if (!slit_valid)
624 pr_err(FW_BUG "SLIT table doesn't have the expected form for SNC -- fixup disabled!\n");
625 else
626 pr_info("Fixing up SNC SLIT table.\n");
627 }
628
629 /*
630 * Is this a unit cluster on the trace?
631 */
632 if ((i / u) == (j / u) || !slit_valid)
633 return node_distance(i, j);
634
635 /*
636 * Off-trace cluster.
637 *
638 * Notably average out the symmetric pair of off-trace clusters to
639 * ensure the resulting SLIT table is symmetric.
640 */
641 x = i - (i % u);
642 y = j - (j % u);
643
644 for (i = x; i < x + u; i++) {
645 for (j = y; j < y + u; j++) {
646 d += node_distance(i, j);
647 d += node_distance(j, i);
648 }
649 }
650
651 return d / (2*u*u);
543}652}
544 653
545int arch_sched_node_distance(int from, int to)654int arch_sched_node_distance(int from, int to)
@@ -549,34 +658,14 @@ int arch_sched_node_distance(int from, int to) · 3 unmodified lines
549 switch (boot_cpu_data.x86_vfm) {658 switch (boot_cpu_data.x86_vfm) {
550 case INTEL_GRANITERAPIDS_X:659 case INTEL_GRANITERAPIDS_X:
551 case INTEL_ATOM_DARKMONT_X:660 case INTEL_ATOM_DARKMONT_X:
552 661 if (topology_max_packages() == 1 ||
553 if (!x86_has_numa_in_package || topology_max_packages() == 1 ||662 topology_num_nodes_per_package() < 3)
554 d < REMOTE_DISTANCE)
555 return d;663 return d;
556 664
557 /*665 /*
558 * With SNC enabled, there could be too many levels of remote666 * Handle SNC-3 asymmetries.
559 * NUMA node distances, creating NUMA domain levels
560 * including local nodes and partial remote nodes.
561 *
562 * Trim finer distance tuning for NUMA nodes in remote package
563 * for the purpose of building sched domains. Group NUMA nodes
564 * in the remote package in the same sched group.
565 * Simplify NUMA domains and avoid extra NUMA levels including
566 * different remote NUMA nodes and local nodes.
567 *
568 * GNR and CWF don't expect systems with more than 2 packages
569 * and more than 2 hops between packages. Single average remote
570 * distance won't be appropriate if there are more than 2
571 * packages as average distance to different remote packages
572 * could be different.
573 */667 */
574 WARN_ONCE(topology_max_packages() > 2,668 return slit_cluster_distance(from, to);
575 "sched: Expect only up to 2 packages for GNR or CWF, "
576 "but saw %d packages when building sched domains.",
577 topology_max_packages());
578
579 d = avg_remote_numa_distance();
580 }669 }
581 return d;670 return d;
582}671}
@@ -606,7 +695,7 @@ void set_cpu_sibling_map(int cpu) · 23 unmodified lines
606 o = &cpu_data(i);695 o = &cpu_data(i);
607 696
608 if (match_pkg(c, o) && !topology_same_node(c, o))697 if (match_pkg(c, o) && !topology_same_node(c, o))
609 x86_has_numa_in_package = true;698 WARN_ON_ONCE(topology_num_nodes_per_package() == 1);
610 699
611 if ((i == cpu) || (has_smt && match_smt(c, o)))700 if ((i == cpu) || (has_smt && match_smt(c, o)))
612 link_mask(topology_sibling_cpumask, cpu, i);701 link_mask(topology_sibling_cpumask, cpu, i);
arch/x86/kernel/vmlinux.lds.S+1−0
@@ -427,6 +427,7 @@ SECTIONS · 426 unmodified lines
427 .llvm_bb_addr_map : { *(.llvm_bb_addr_map) }427 .llvm_bb_addr_map : { *(.llvm_bb_addr_map) }
428#endif428#endif
429 429
430 MODINFO
430 ELF_DETAILS431 ELF_DETAILS
431 432
432 DISCARDS433 DISCARDS
arch/x86/mm/numa.c+8−0
@@ -48,6 +48,8 @@ s16 __apicid_to_node[MAX_LOCAL_APIC] = { · 47 unmodified lines
48 [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE48 [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
49};49};
50 50
51nodemask_t numa_phys_nodes_parsed __initdata;
52
51int numa_cpu_node(int cpu)53int numa_cpu_node(int cpu)
52{54{
53 u32 apicid = early_per_cpu(x86_cpu_to_apicid, cpu);55 u32 apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
@@ -57,6 +59,11 @@ int numa_cpu_node(int cpu) · 3 unmodified lines
57 return NUMA_NO_NODE;59 return NUMA_NO_NODE;
58}60}
59 61
62int __init num_phys_nodes(void)
63{
64 return bitmap_weight(numa_phys_nodes_parsed.bits, MAX_NUMNODES);
65}
66
60cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];67cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
61EXPORT_SYMBOL(node_to_cpumask_map);68EXPORT_SYMBOL(node_to_cpumask_map);
62 69
@@ -210,6 +217,7 @@ static int __init dummy_numa_init(void) · 147 unmodified lines
210 0LLU, PFN_PHYS(max_pfn) - 1);217 0LLU, PFN_PHYS(max_pfn) - 1);
211 218
212 node_set(0, numa_nodes_parsed);219 node_set(0, numa_nodes_parsed);
220 node_set(0, numa_phys_nodes_parsed);
213 numa_add_memblk(0, 0, PFN_PHYS(max_pfn));221 numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
214 222
215 return 0;223 return 0;
arch/x86/mm/srat.c+2−0
@@ -57,6 +57,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) · 56 unmodified lines
57 }57 }
58 set_apicid_to_node(apic_id, node);58 set_apicid_to_node(apic_id, node);
59 node_set(node, numa_nodes_parsed);59 node_set(node, numa_nodes_parsed);
60 node_set(node, numa_phys_nodes_parsed);
60 pr_debug("SRAT: PXM %u -> APIC 0x%04x -> Node %u\n", pxm, apic_id, node);61 pr_debug("SRAT: PXM %u -> APIC 0x%04x -> Node %u\n", pxm, apic_id, node);
61}62}
62 63
@@ -97,6 +98,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) · 34 unmodified lines
97 98
98 set_apicid_to_node(apic_id, node);99 set_apicid_to_node(apic_id, node);
99 node_set(node, numa_nodes_parsed);100 node_set(node, numa_nodes_parsed);
101 node_set(node, numa_phys_nodes_parsed);
100 pr_debug("SRAT: PXM %u -> APIC 0x%02x -> Node %u\n", pxm, apic_id, node);102 pr_debug("SRAT: PXM %u -> APIC 0x%02x -> Node %u\n", pxm, apic_id, node);
101}103}
102 104
arch/x86/platform/efi/efi.c+1−1
@@ -836,7 +836,7 @@ static void __init __efi_enter_virtual_mode(void) · 835 unmodified lines
836 }836 }
837 837
838 efi_check_for_embedded_firmwares();838 efi_check_for_embedded_firmwares();
839 efi_free_boot_services();839 efi_unmap_boot_services();
840 840
841 if (!efi_is_mixed())841 if (!efi_is_mixed())
842 efi_native_runtime_setup();842 efi_native_runtime_setup();
arch/x86/platform/efi/quirks.c+52−3
@@ -341,7 +341,7 @@ void __init efi_reserve_boot_services(void) · 340 unmodified lines
341 341
342 /*342 /*
343 * Because the following memblock_reserve() is paired343 * Because the following memblock_reserve() is paired
344 * with memblock_free_late() for this region in344 * with free_reserved_area() for this region in
345 * efi_free_boot_services(), we must be extremely345 * efi_free_boot_services(), we must be extremely
346 * careful not to reserve, and subsequently free,346 * careful not to reserve, and subsequently free,
347 * critical regions of memory (like the kernel image) or347 * critical regions of memory (like the kernel image) or
@@ -404,17 +404,33 @@ static void __init efi_unmap_pages(efi_memory_desc_t *md) · 56 unmodified lines
404 pr_err("Failed to unmap VA mapping for 0x%llx\n", va);404 pr_err("Failed to unmap VA mapping for 0x%llx\n", va);
405}405}
406 406
407void __init efi_free_boot_services(void)407struct efi_freeable_range {
408 u64 start;
409 u64 end;
410};
411
412static struct efi_freeable_range *ranges_to_free;
413
414void __init efi_unmap_boot_services(void)
408{415{
409 struct efi_memory_map_data data = { 0 };416 struct efi_memory_map_data data = { 0 };
410 efi_memory_desc_t *md;417 efi_memory_desc_t *md;
411 int num_entries = 0;418 int num_entries = 0;
419 int idx = 0;
420 size_t sz;
412 void *new, *new_md;421 void *new, *new_md;
413 422
414 /* Keep all regions for /sys/kernel/debug/efi */423 /* Keep all regions for /sys/kernel/debug/efi */
415 if (efi_enabled(EFI_DBG))424 if (efi_enabled(EFI_DBG))
416 return;425 return;
417 426
427 sz = sizeof(*ranges_to_free) * efi.memmap.nr_map + 1;
428 ranges_to_free = kzalloc(sz, GFP_KERNEL);
429 if (!ranges_to_free) {
430 pr_err("Failed to allocate storage for freeable EFI regions\n");
431 return;
432 }
433
418 for_each_efi_memory_desc(md) {434 for_each_efi_memory_desc(md) {
419 unsigned long long start = md->phys_addr;435 unsigned long long start = md->phys_addr;
420 unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;436 unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
@@ -471,7 +487,15 @@ void __init efi_free_boot_services(void) · 50 unmodified lines
471 start = SZ_1M;487 start = SZ_1M;
472 }488 }
473 489
474 memblock_free_late(start, size);490 /*
491 * With CONFIG_DEFERRED_STRUCT_PAGE_INIT parts of the memory
492 * map are still not initialized and we can't reliably free
493 * memory here.
494 * Queue the ranges to free at a later point.
495 */
496 ranges_to_free[idx].start = start;
497 ranges_to_free[idx].end = start + size;
498 idx++;
475 }499 }
476 500
477 if (!num_entries)501 if (!num_entries)
@@ -512,6 +536,31 @@ void __init efi_free_boot_services(void) · 34 unmodified lines
512 }536 }
513}537}
514 538
539static int __init efi_free_boot_services(void)
540{
541 struct efi_freeable_range *range = ranges_to_free;
542 unsigned long freed = 0;
543
544 if (!ranges_to_free)
545 return 0;
546
547 while (range->start) {
548 void *start = phys_to_virt(range->start);
549 void *end = phys_to_virt(range->end);
550
551 free_reserved_area(start, end, -1, NULL);
552 freed += (end - start);
553 range++;
554 }
555 kfree(ranges_to_free);
556
557 if (freed)
558 pr_info("Freeing EFI boot services memory: %ldK\n", freed / SZ_1K);
559
560 return 0;
561}
562arch_initcall(efi_free_boot_services);
563
515/*564/*
516 * A number of config table entries get remapped to virtual addresses565 * A number of config table entries get remapped to virtual addresses
517 * after entering EFI virtual mode. However, the kexec kernel requires566 * after entering EFI virtual mode. However, the kexec kernel requires
arch/x86/platform/pvh/enlighten.c+1−6
@@ -25,11 +25,6 @@ struct hvm_start_info __initdata pvh_start_info; · 24 unmodified lines
25 25
26const unsigned int __initconst pvh_start_info_sz = sizeof(pvh_start_info);26const unsigned int __initconst pvh_start_info_sz = sizeof(pvh_start_info);
27 27
28static u64 __init pvh_get_root_pointer(void)
29{
30 return pvh_start_info.rsdp_paddr;
31}
32
33/*28/*
34 * Xen guests are able to obtain the memory map from the hypervisor via the29 * Xen guests are able to obtain the memory map from the hypervisor via the
35 * HYPERVISOR_memory_op hypercall.30 * HYPERVISOR_memory_op hypercall.
@@ -95,7 +90,7 @@ static void __init init_pvh_bootparams(bool xen_guest) · 59 unmodified lines
95 pvh_bootparams.hdr.version = (2 << 8) | 12;90 pvh_bootparams.hdr.version = (2 << 8) | 12;
96 pvh_bootparams.hdr.type_of_loader = ((xen_guest ? 0x9 : 0xb) << 4) | 0;91 pvh_bootparams.hdr.type_of_loader = ((xen_guest ? 0x9 : 0xb) << 4) | 0;
97 92
98 x86_init.acpi.get_root_pointer = pvh_get_root_pointer;93 pvh_bootparams.acpi_rsdp_addr = pvh_start_info.rsdp_paddr;
99}94}
100 95
101/*96/*
arch/x86/xen/enlighten_pv.c+1−1
@@ -392,7 +392,7 @@ static void __init xen_init_capabilities(void) · 391 unmodified lines
392 392
393 /*393 /*
394 * Xen PV would need some work to support PCID: CR3 handling as well394 * Xen PV would need some work to support PCID: CR3 handling as well
395 * as xen_flush_tlb_others() would need updating.395 * as xen_flush_tlb_multi() would need updating.
396 */396 */
397 setup_clear_cpu_cap(X86_FEATURE_PCID);397 setup_clear_cpu_cap(X86_FEATURE_PCID);
398 398
arch/x86/xen/mmu_pv.c+9−0
@@ -105,6 +105,9 @@ pte_t xen_make_pte_init(pteval_t pte); · 104 unmodified lines
105static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;105static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;
106#endif106#endif
107 107
108static pud_t level3_ident_pgt[PTRS_PER_PUD] __page_aligned_bss;
109static pmd_t level2_ident_pgt[PTRS_PER_PMD] __page_aligned_bss;
110
108/*111/*
109 * Protects atomic reservation decrease/increase against concurrent increases.112 * Protects atomic reservation decrease/increase against concurrent increases.
110 * Also protects non-atomic updates of current_pages and balloon lists.113 * Also protects non-atomic updates of current_pages and balloon lists.
@@ -1777,6 +1780,12 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) · 1666 unmodified lines
1777 /* Zap identity mapping */1780 /* Zap identity mapping */
1778 init_top_pgt[0] = __pgd(0);1781 init_top_pgt[0] = __pgd(0);
1779 1782
1783 init_top_pgt[pgd_index(__PAGE_OFFSET_BASE_L4)].pgd =
1784 __pa_symbol(level3_ident_pgt) + _KERNPG_TABLE_NOENC;
1785 init_top_pgt[pgd_index(__START_KERNEL_map)].pgd =
1786 __pa_symbol(level3_kernel_pgt) + _PAGE_TABLE_NOENC;
1787 level3_ident_pgt[0].pud = __pa_symbol(level2_ident_pgt) + _KERNPG_TABLE_NOENC;
1788
1780 /* Pre-constructed entries are in pfn, so convert to mfn */1789 /* Pre-constructed entries are in pfn, so convert to mfn */
1781 /* L4[273] -> level3_ident_pgt */1790 /* L4[273] -> level3_ident_pgt */
1782 /* L4[511] -> level3_kernel_pgt */1791 /* L4[511] -> level3_kernel_pgt */
block/blk-map.c+1−2
@@ -398,8 +398,7 @@ static struct bio *bio_copy_kern(struct request *rq, void *data, unsigned int le · 397 unmodified lines
398 if (op_is_write(op))398 if (op_is_write(op))
399 memcpy(page_address(page), p, bytes);399 memcpy(page_address(page), p, bytes);
400 400
401 if (bio_add_page(bio, page, bytes, 0) < bytes)401 __bio_add_page(bio, page, bytes, 0);
402 break;
403 402
404 len -= bytes;403 len -= bytes;
405 p += bytes;404 p += bytes;
block/blk-mq.c+30−15
@@ -4793,38 +4793,45 @@ static void blk_mq_update_queue_map(struct blk_mq_tag_set *set) · 4792 unmodified lines
4793 }4793 }
4794}4794}
4795 4795
4796static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set,4796static struct blk_mq_tags **blk_mq_prealloc_tag_set_tags(
4797 int new_nr_hw_queues)4797 struct blk_mq_tag_set *set,
4798 int new_nr_hw_queues)
4798{4799{
4799 struct blk_mq_tags **new_tags;4800 struct blk_mq_tags **new_tags;
4800 int i;4801 int i;
4801 4802
4802 if (set->nr_hw_queues >= new_nr_hw_queues)4803 if (set->nr_hw_queues >= new_nr_hw_queues)
4803 goto done;4804 return NULL;
4804 4805
4805 new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *),4806 new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *),
4806 GFP_KERNEL, set->numa_node);4807 GFP_KERNEL, set->numa_node);
4807 if (!new_tags)4808 if (!new_tags)
4808 return -ENOMEM;4809 return ERR_PTR(-ENOMEM);
4809 4810
4810 if (set->tags)4811 if (set->tags)
4811 memcpy(new_tags, set->tags, set->nr_hw_queues *4812 memcpy(new_tags, set->tags, set->nr_hw_queues *
4812 sizeof(*set->tags));4813 sizeof(*set->tags));
4813 kfree(set->tags);
4814 set->tags = new_tags;
4815 4814
4816 for (i = set->nr_hw_queues; i < new_nr_hw_queues; i++) {4815 for (i = set->nr_hw_queues; i < new_nr_hw_queues; i++) {
4817 if (!__blk_mq_alloc_map_and_rqs(set, i)) {4816 if (blk_mq_is_shared_tags(set->flags)) {
4818 while (--i >= set->nr_hw_queues)4817 new_tags[i] = set->shared_tags;
4819 __blk_mq_free_map_and_rqs(set, i);4818 } else {
4820 return -ENOMEM;4819 new_tags[i] = blk_mq_alloc_map_and_rqs(set, i,
4820 set->queue_depth);
4821 if (!new_tags[i])
4822 goto out_unwind;
4821 }4823 }
4822 cond_resched();4824 cond_resched();
4823 }4825 }
4824 4826
4825done:4827 return new_tags;
4826 set->nr_hw_queues = new_nr_hw_queues;4828out_unwind:
4827 return 0;4829 while (--i >= set->nr_hw_queues) {
4830 if (!blk_mq_is_shared_tags(set->flags))
4831 blk_mq_free_map_and_rqs(set, new_tags[i], i);
4832 }
4833 kfree(new_tags);
4834 return ERR_PTR(-ENOMEM);
4828}4835}
4829 4836
4830/*4837/*
@@ -5113,6 +5120,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 282 unmodified lines
5113 unsigned int memflags;5120 unsigned int memflags;
5114 int i;5121 int i;
5115 struct xarray elv_tbl;5122 struct xarray elv_tbl;
5123 struct blk_mq_tags **new_tags;
5116 bool queues_frozen = false;5124 bool queues_frozen = false;
5117 5125
5118 lockdep_assert_held(&set->tag_list_lock);5126 lockdep_assert_held(&set->tag_list_lock);
@@ -5147,11 +5155,18 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 28 unmodified lines
5147 if (blk_mq_elv_switch_none(q, &elv_tbl))5155 if (blk_mq_elv_switch_none(q, &elv_tbl))
5148 goto switch_back;5156 goto switch_back;
5149 5157
5158 new_tags = blk_mq_prealloc_tag_set_tags(set, nr_hw_queues);
5159 if (IS_ERR(new_tags))
5160 goto switch_back;
5161
5150 list_for_each_entry(q, &set->tag_list, tag_set_list)5162 list_for_each_entry(q, &set->tag_list, tag_set_list)
5151 blk_mq_freeze_queue_nomemsave(q);5163 blk_mq_freeze_queue_nomemsave(q);
5152 queues_frozen = true;5164 queues_frozen = true;
5153 if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0)5165 if (new_tags) {
5154 goto switch_back;5166 kfree(set->tags);
5167 set->tags = new_tags;
5168 }
5169 set->nr_hw_queues = nr_hw_queues;
5155 5170
5156fallback:5171fallback:
5157 blk_mq_update_queue_map(set);5172 blk_mq_update_queue_map(set);
block/blk-sysfs.c+7−1
@@ -78,8 +78,14 @@ queue_requests_store(struct gendisk *disk, const char *page, size_t count) · 77 unmodified lines
78 /*78 /*
79 * Serialize updating nr_requests with concurrent queue_requests_store()79 * Serialize updating nr_requests with concurrent queue_requests_store()
80 * and switching elevator.80 * and switching elevator.
81 *
82 * Use trylock to avoid circular lock dependency with kernfs active
83 * reference during concurrent disk deletion:
84 * update_nr_hwq_lock -> kn->active (via del_gendisk -> kobject_del)
85 * kn->active -> update_nr_hwq_lock (via this sysfs write path)
81 */86 */
82 down_write(&set->update_nr_hwq_lock);87 if (!down_write_trylock(&set->update_nr_hwq_lock))
88 return -EBUSY;
83 89
84 if (nr == q->nr_requests)90 if (nr == q->nr_requests)
85 goto unlock;91 goto unlock;
block/elevator.c+11−1
@@ -807,7 +807,16 @@ ssize_t elv_iosched_store(struct gendisk *disk, const char *buf, · 806 unmodified lines
807 elv_iosched_load_module(ctx.name);807 elv_iosched_load_module(ctx.name);
808 ctx.type = elevator_find_get(ctx.name);808 ctx.type = elevator_find_get(ctx.name);
809 809
810 down_read(&set->update_nr_hwq_lock);810 /*
811 * Use trylock to avoid circular lock dependency with kernfs active
812 * reference during concurrent disk deletion:
813 * update_nr_hwq_lock -> kn->active (via del_gendisk -> kobject_del)
814 * kn->active -> update_nr_hwq_lock (via this sysfs write path)
815 */
816 if (!down_read_trylock(&set->update_nr_hwq_lock)) {
817 ret = -EBUSY;
818 goto out;
819 }
811 if (!blk_queue_no_elv_switch(q)) {820 if (!blk_queue_no_elv_switch(q)) {
812 ret = elevator_change(q, &ctx);821 ret = elevator_change(q, &ctx);
813 if (!ret)822 if (!ret)
@@ -817,6 +826,7 @@ ssize_t elv_iosched_store(struct gendisk *disk, const char *buf, · 3 unmodified lines
817 }826 }
818 up_read(&set->update_nr_hwq_lock);827 up_read(&set->update_nr_hwq_lock);
819 828
829out:
820 if (ctx.type)830 if (ctx.type)
821 elevator_put(ctx.type);831 elevator_put(ctx.type);
822 return ret;832 return ret;
crypto/Kconfig+0−9
@@ -876,8 +876,6 @@ config CRYPTO_BLAKE2B · 875 unmodified lines
876 - blake2b-384876 - blake2b-384
877 - blake2b-512877 - blake2b-512
878 878
879 Used by the btrfs filesystem.
880
881 See https://blake2.net for further information.879 See https://blake2.net for further information.
882 880
883config CRYPTO_CMAC881config CRYPTO_CMAC
@@ -965,7 +963,6 @@ config CRYPTO_SHA256 · 81 unmodified lines
965 10118-3), including HMAC support.963 10118-3), including HMAC support.
966 964
967 This is required for IPsec AH (XFRM_AH) and IPsec ESP (XFRM_ESP).965 This is required for IPsec AH (XFRM_AH) and IPsec ESP (XFRM_ESP).
968 Used by the btrfs filesystem, Ceph, NFS, and SMB.
969 966
970config CRYPTO_SHA512967config CRYPTO_SHA512
971 tristate "SHA-384 and SHA-512"968 tristate "SHA-384 and SHA-512"
@@ -1039,8 +1036,6 @@ config CRYPTO_XXHASH · 67 unmodified lines
1039 1036
1040 Extremely fast, working at speeds close to RAM limits.1037 Extremely fast, working at speeds close to RAM limits.
1041 1038
1042 Used by the btrfs filesystem.
1043
1044endmenu1039endmenu
1045 1040
1046menu "CRCs (cyclic redundancy checks)"1041menu "CRCs (cyclic redundancy checks)"
@@ -1058,8 +1053,6 @@ config CRYPTO_CRC32C · 11 unmodified lines
1058 on Communications, Vol. 41, No. 6, June 1993, selected for use with1053 on Communications, Vol. 41, No. 6, June 1993, selected for use with
1059 iSCSI.1054 iSCSI.
1060 1055
1061 Used by btrfs, ext4, jbd2, NVMeoF/TCP, and iSCSI.
1062
1063config CRYPTO_CRC321056config CRYPTO_CRC32
1064 tristate "CRC32"1057 tristate "CRC32"
1065 select CRYPTO_HASH1058 select CRYPTO_HASH
@@ -1067,8 +1060,6 @@ config CRYPTO_CRC32 · 1 unmodified line
1067 help1060 help
1068 CRC32 CRC algorithm (IEEE 802.3)1061 CRC32 CRC algorithm (IEEE 802.3)
1069 1062
1070 Used by RoCEv2 and f2fs.
1071
1072endmenu1063endmenu
1073 1064
1074menu "Compression"1065menu "Compression"
crypto/testmgr.c+2−2
@@ -4132,7 +4132,7 @@ static const struct alg_test_desc alg_test_descs[] = { · 4131 unmodified lines
4132 .fips_allowed = 1,4132 .fips_allowed = 1,
4133 }, {4133 }, {
4134 .alg = "authenc(hmac(sha224),cbc(aes))",4134 .alg = "authenc(hmac(sha224),cbc(aes))",
4135 .generic_driver = "authenc(hmac-sha224-lib,cbc(aes-generic))",4135 .generic_driver = "authenc(hmac-sha224-lib,cbc(aes-lib))",
4136 .test = alg_test_aead,4136 .test = alg_test_aead,
4137 .suite = {4137 .suite = {
4138 .aead = __VECS(hmac_sha224_aes_cbc_tv_temp)4138 .aead = __VECS(hmac_sha224_aes_cbc_tv_temp)
@@ -4194,7 +4194,7 @@ static const struct alg_test_desc alg_test_descs[] = { · 55 unmodified lines
4194 .fips_allowed = 1,4194 .fips_allowed = 1,
4195 }, {4195 }, {
4196 .alg = "authenc(hmac(sha384),cbc(aes))",4196 .alg = "authenc(hmac(sha384),cbc(aes))",
4197 .generic_driver = "authenc(hmac-sha384-lib,cbc(aes-generic))",4197 .generic_driver = "authenc(hmac-sha384-lib,cbc(aes-lib))",
4198 .test = alg_test_aead,4198 .test = alg_test_aead,
4199 .suite = {4199 .suite = {
4200 .aead = __VECS(hmac_sha384_aes_cbc_tv_temp)4200 .aead = __VECS(hmac_sha384_aes_cbc_tv_temp)
drivers/accel/amdxdna/aie2_ctx.c+8−15
@@ -186,13 +186,13 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) · 185 unmodified lines
186 cmd_abo = job->cmd_bo;186 cmd_abo = job->cmd_bo;
187 187
188 if (unlikely(job->job_timeout)) {188 if (unlikely(job->job_timeout)) {
189 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT);189 amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_TIMEOUT);
190 ret = -EINVAL;190 ret = -EINVAL;
191 goto out;191 goto out;
192 }192 }
193 193
194 if (unlikely(!data) || unlikely(size != sizeof(u32))) {194 if (unlikely(!data) || unlikely(size != sizeof(u32))) {
195 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT);195 amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ABORT);
196 ret = -EINVAL;196 ret = -EINVAL;
197 goto out;197 goto out;
198 }198 }
@@ -202,7 +202,7 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) · 3 unmodified lines
202 if (status == AIE2_STATUS_SUCCESS)202 if (status == AIE2_STATUS_SUCCESS)
203 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_COMPLETED);203 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_COMPLETED);
204 else204 else
205 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ERROR);205 amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ERROR);
206 206
207out:207out:
208 aie2_sched_notify(job);208 aie2_sched_notify(job);
@@ -244,13 +244,13 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) · 35 unmodified lines
244 cmd_abo = job->cmd_bo;244 cmd_abo = job->cmd_bo;
245 245
246 if (unlikely(job->job_timeout)) {246 if (unlikely(job->job_timeout)) {
247 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT);247 amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_TIMEOUT);
248 ret = -EINVAL;248 ret = -EINVAL;
249 goto out;249 goto out;
250 }250 }
251 251
252 if (unlikely(!data) || unlikely(size != sizeof(u32) * 3)) {252 if (unlikely(!data) || unlikely(size != sizeof(u32) * 3)) {
253 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT);253 amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ABORT);
254 ret = -EINVAL;254 ret = -EINVAL;
255 goto out;255 goto out;
256 }256 }
@@ -270,19 +270,12 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) · 13 unmodified lines
270 fail_cmd_idx, fail_cmd_status);270 fail_cmd_idx, fail_cmd_status);
271 271
272 if (fail_cmd_status == AIE2_STATUS_SUCCESS) {272 if (fail_cmd_status == AIE2_STATUS_SUCCESS) {
273 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT);273 amdxdna_cmd_set_error(cmd_abo, job, fail_cmd_idx, ERT_CMD_STATE_ABORT);
274 ret = -EINVAL;274 ret = -EINVAL;
275 goto out;275 } else {
276 amdxdna_cmd_set_error(cmd_abo, job, fail_cmd_idx, ERT_CMD_STATE_ERROR);
276 }277 }
277 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ERROR);
278 278
279 if (amdxdna_cmd_get_op(cmd_abo) == ERT_CMD_CHAIN) {
280 struct amdxdna_cmd_chain *cc = amdxdna_cmd_get_payload(cmd_abo, NULL);
281
282 cc->error_index = fail_cmd_idx;
283 if (cc->error_index >= cc->command_count)
284 cc->error_index = 0;
285 }
286out:279out:
287 aie2_sched_notify(job);280 aie2_sched_notify(job);
288 return ret;281 return ret;
drivers/accel/amdxdna/aie2_message.c+28−8
@@ -40,11 +40,8 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev, · 39 unmodified lines
40 return -ENODEV;40 return -ENODEV;
41 41
42 ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg);42 ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg);
43 if (ret == -ETIME) {43 if (ret == -ETIME)
44 xdna_mailbox_stop_channel(ndev->mgmt_chann);44 aie2_destroy_mgmt_chann(ndev);
45 xdna_mailbox_destroy_channel(ndev->mgmt_chann);
46 ndev->mgmt_chann = NULL;
47 }
48 45
49 if (!ret && *hdl->status != AIE2_STATUS_SUCCESS) {46 if (!ret && *hdl->status != AIE2_STATUS_SUCCESS) {
50 XDNA_ERR(xdna, "command opcode 0x%x failed, status 0x%x",47 XDNA_ERR(xdna, "command opcode 0x%x failed, status 0x%x",
@@ -296,13 +293,20 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct · 245 unmodified lines
296 }293 }
297 294
298 intr_reg = i2x.mb_head_ptr_reg + 4;295 intr_reg = i2x.mb_head_ptr_reg + 4;
299 hwctx->priv->mbox_chann = xdna_mailbox_create_channel(ndev->mbox, &x2i, &i2x,296 hwctx->priv->mbox_chann = xdna_mailbox_alloc_channel(ndev->mbox);
300 intr_reg, ret);
301 if (!hwctx->priv->mbox_chann) {297 if (!hwctx->priv->mbox_chann) {
302 XDNA_ERR(xdna, "Not able to create channel");298 XDNA_ERR(xdna, "Not able to create channel");
303 ret = -EINVAL;299 ret = -EINVAL;
304 goto del_ctx_req;300 goto del_ctx_req;
305 }301 }
302
303 ret = xdna_mailbox_start_channel(hwctx->priv->mbox_chann, &x2i, &i2x,
304 intr_reg, ret);
305 if (ret) {
306 XDNA_ERR(xdna, "Not able to create channel");
307 ret = -EINVAL;
308 goto free_channel;
309 }
306 ndev->hwctx_num++;310 ndev->hwctx_num++;
307 311
308 XDNA_DBG(xdna, "Mailbox channel irq: %d, msix_id: %d", ret, resp.msix_id);312 XDNA_DBG(xdna, "Mailbox channel irq: %d, msix_id: %d", ret, resp.msix_id);
@@ -310,6 +314,8 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct · 1 unmodified line
310 314
311 return 0;315 return 0;
312 316
317free_channel:
318 xdna_mailbox_free_channel(hwctx->priv->mbox_chann);
313del_ctx_req:319del_ctx_req:
314 aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);320 aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
315 return ret;321 return ret;
@@ -325,7 +331,7 @@ int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwc · 9 unmodified lines
325 331
326 xdna_mailbox_stop_channel(hwctx->priv->mbox_chann);332 xdna_mailbox_stop_channel(hwctx->priv->mbox_chann);
327 ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);333 ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
328 xdna_mailbox_destroy_channel(hwctx->priv->mbox_chann);334 xdna_mailbox_free_channel(hwctx->priv->mbox_chann);
329 XDNA_DBG(xdna, "Destroyed fw ctx %d", hwctx->fw_ctx_id);335 XDNA_DBG(xdna, "Destroyed fw ctx %d", hwctx->fw_ctx_id);
330 hwctx->priv->mbox_chann = NULL;336 hwctx->priv->mbox_chann = NULL;
331 hwctx->fw_ctx_id = -1;337 hwctx->fw_ctx_id = -1;
@@ -914,6 +920,20 @@ void aie2_msg_init(struct amdxdna_dev_hdl *ndev) · 582 unmodified lines
914 ndev->exec_msg_ops = &legacy_exec_message_ops;920 ndev->exec_msg_ops = &legacy_exec_message_ops;
915}921}
916 922
923void aie2_destroy_mgmt_chann(struct amdxdna_dev_hdl *ndev)
924{
925 struct amdxdna_dev *xdna = ndev->xdna;
926
927 drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
928
929 if (!ndev->mgmt_chann)
930 return;
931
932 xdna_mailbox_stop_channel(ndev->mgmt_chann);
933 xdna_mailbox_free_channel(ndev->mgmt_chann);
934 ndev->mgmt_chann = NULL;
935}
936
917static inline struct amdxdna_gem_obj *937static inline struct amdxdna_gem_obj *
918aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job)938aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job)
919{939{
drivers/accel/amdxdna/aie2_pci.c+37−29
@@ -331,9 +331,7 @@ static void aie2_hw_stop(struct amdxdna_dev *xdna) · 330 unmodified lines
331 331
332 aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, NULL);332 aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, NULL);
333 aie2_mgmt_fw_fini(ndev);333 aie2_mgmt_fw_fini(ndev);
334 xdna_mailbox_stop_channel(ndev->mgmt_chann);334 aie2_destroy_mgmt_chann(ndev);
335 xdna_mailbox_destroy_channel(ndev->mgmt_chann);
336 ndev->mgmt_chann = NULL;
337 drmm_kfree(&xdna->ddev, ndev->mbox);335 drmm_kfree(&xdna->ddev, ndev->mbox);
338 ndev->mbox = NULL;336 ndev->mbox = NULL;
339 aie2_psp_stop(ndev->psp_hdl);337 aie2_psp_stop(ndev->psp_hdl);
@@ -364,10 +362,29 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) · 24 unmodified lines
364 }362 }
365 pci_set_master(pdev);363 pci_set_master(pdev);
366 364
365 mbox_res.ringbuf_base = ndev->sram_base;
366 mbox_res.ringbuf_size = pci_resource_len(pdev, xdna->dev_info->sram_bar);
367 mbox_res.mbox_base = ndev->mbox_base;
368 mbox_res.mbox_size = MBOX_SIZE(ndev);
369 mbox_res.name = "xdna_mailbox";
370 ndev->mbox = xdnam_mailbox_create(&xdna->ddev, &mbox_res);
371 if (!ndev->mbox) {
372 XDNA_ERR(xdna, "failed to create mailbox device");
373 ret = -ENODEV;
374 goto disable_dev;
375 }
376
377 ndev->mgmt_chann = xdna_mailbox_alloc_channel(ndev->mbox);
378 if (!ndev->mgmt_chann) {
379 XDNA_ERR(xdna, "failed to alloc channel");
380 ret = -ENODEV;
381 goto disable_dev;
382 }
383
367 ret = aie2_smu_init(ndev);384 ret = aie2_smu_init(ndev);
368 if (ret) {385 if (ret) {
369 XDNA_ERR(xdna, "failed to init smu, ret %d", ret);386 XDNA_ERR(xdna, "failed to init smu, ret %d", ret);
370 goto disable_dev;387 goto free_channel;
371 }388 }
372 389
373 ret = aie2_psp_start(ndev->psp_hdl);390 ret = aie2_psp_start(ndev->psp_hdl);
@@ -382,18 +399,6 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) · 8 unmodified lines
382 goto stop_psp;399 goto stop_psp;
383 }400 }
384 401
385 mbox_res.ringbuf_base = ndev->sram_base;
386 mbox_res.ringbuf_size = pci_resource_len(pdev, xdna->dev_info->sram_bar);
387 mbox_res.mbox_base = ndev->mbox_base;
388 mbox_res.mbox_size = MBOX_SIZE(ndev);
389 mbox_res.name = "xdna_mailbox";
390 ndev->mbox = xdnam_mailbox_create(&xdna->ddev, &mbox_res);
391 if (!ndev->mbox) {
392 XDNA_ERR(xdna, "failed to create mailbox device");
393 ret = -ENODEV;
394 goto stop_psp;
395 }
396
397 mgmt_mb_irq = pci_irq_vector(pdev, ndev->mgmt_chan_idx);402 mgmt_mb_irq = pci_irq_vector(pdev, ndev->mgmt_chan_idx);
398 if (mgmt_mb_irq < 0) {403 if (mgmt_mb_irq < 0) {
399 ret = mgmt_mb_irq;404 ret = mgmt_mb_irq;
@@ -402,13 +407,13 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) · 2 unmodified lines
402 }407 }
403 408
404 xdna_mailbox_intr_reg = ndev->mgmt_i2x.mb_head_ptr_reg + 4;409 xdna_mailbox_intr_reg = ndev->mgmt_i2x.mb_head_ptr_reg + 4;
405 ndev->mgmt_chann = xdna_mailbox_create_channel(ndev->mbox,410 ret = xdna_mailbox_start_channel(ndev->mgmt_chann,
406 &ndev->mgmt_x2i,411 &ndev->mgmt_x2i,
407 &ndev->mgmt_i2x,412 &ndev->mgmt_i2x,
408 xdna_mailbox_intr_reg,413 xdna_mailbox_intr_reg,
409 mgmt_mb_irq);414 mgmt_mb_irq);
410 if (!ndev->mgmt_chann) {415 if (ret) {
411 XDNA_ERR(xdna, "failed to create management mailbox channel");416 XDNA_ERR(xdna, "failed to start management mailbox channel");
412 ret = -EINVAL;417 ret = -EINVAL;
413 goto stop_psp;418 goto stop_psp;
414 }419 }
@@ -416,38 +421,41 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) · 1 unmodified line
416 ret = aie2_mgmt_fw_init(ndev);421 ret = aie2_mgmt_fw_init(ndev);
417 if (ret) {422 if (ret) {
418 XDNA_ERR(xdna, "initial mgmt firmware failed, ret %d", ret);423 XDNA_ERR(xdna, "initial mgmt firmware failed, ret %d", ret);
419 goto destroy_mgmt_chann;424 goto stop_fw;
420 }425 }
421 426
422 ret = aie2_pm_init(ndev);427 ret = aie2_pm_init(ndev);
423 if (ret) {428 if (ret) {
424 XDNA_ERR(xdna, "failed to init pm, ret %d", ret);429 XDNA_ERR(xdna, "failed to init pm, ret %d", ret);
425 goto destroy_mgmt_chann;430 goto stop_fw;
426 }431 }
427 432
428 ret = aie2_mgmt_fw_query(ndev);433 ret = aie2_mgmt_fw_query(ndev);
429 if (ret) {434 if (ret) {
430 XDNA_ERR(xdna, "failed to query fw, ret %d", ret);435 XDNA_ERR(xdna, "failed to query fw, ret %d", ret);
431 goto destroy_mgmt_chann;436 goto stop_fw;
432 }437 }
433 438
434 ret = aie2_error_async_events_alloc(ndev);439 ret = aie2_error_async_events_alloc(ndev);
435 if (ret) {440 if (ret) {
436 XDNA_ERR(xdna, "Allocate async events failed, ret %d", ret);441 XDNA_ERR(xdna, "Allocate async events failed, ret %d", ret);
437 goto destroy_mgmt_chann;442 goto stop_fw;
438 }443 }
439 444
440 ndev->dev_status = AIE2_DEV_START;445 ndev->dev_status = AIE2_DEV_START;
441 446
442 return 0;447 return 0;
443 448
444destroy_mgmt_chann:449stop_fw:
450 aie2_suspend_fw(ndev);
445 xdna_mailbox_stop_channel(ndev->mgmt_chann);451 xdna_mailbox_stop_channel(ndev->mgmt_chann);
446 xdna_mailbox_destroy_channel(ndev->mgmt_chann);
447stop_psp:452stop_psp:
448 aie2_psp_stop(ndev->psp_hdl);453 aie2_psp_stop(ndev->psp_hdl);
449fini_smu:454fini_smu:
450 aie2_smu_fini(ndev);455 aie2_smu_fini(ndev);
456free_channel:
457 xdna_mailbox_free_channel(ndev->mgmt_chann);
458 ndev->mgmt_chann = NULL;
451disable_dev:459disable_dev:
452 pci_disable_device(pdev);460 pci_disable_device(pdev);
453 461
drivers/accel/amdxdna/aie2_pci.h+1−0
@@ -331,6 +331,7 @@ int aie2_get_array_async_error(struct amdxdna_dev_hdl *ndev, · 330 unmodified lines
331 331
332/* aie2_message.c */332/* aie2_message.c */
333void aie2_msg_init(struct amdxdna_dev_hdl *ndev);333void aie2_msg_init(struct amdxdna_dev_hdl *ndev);
334void aie2_destroy_mgmt_chann(struct amdxdna_dev_hdl *ndev);
334int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev);335int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev);
335int aie2_resume_fw(struct amdxdna_dev_hdl *ndev);336int aie2_resume_fw(struct amdxdna_dev_hdl *ndev);
336int aie2_set_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 value);337int aie2_set_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 value);
drivers/accel/amdxdna/amdxdna_ctx.c+27−0
@@ -135,6 +135,33 @@ u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo) · 134 unmodified lines
135 return INVALID_CU_IDX;135 return INVALID_CU_IDX;
136}136}
137 137
138int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo,
139 struct amdxdna_sched_job *job, u32 cmd_idx,
140 enum ert_cmd_state error_state)
141{
142 struct amdxdna_client *client = job->hwctx->client;
143 struct amdxdna_cmd *cmd = abo->mem.kva;
144 struct amdxdna_cmd_chain *cc = NULL;
145
146 cmd->header &= ~AMDXDNA_CMD_STATE;
147 cmd->header |= FIELD_PREP(AMDXDNA_CMD_STATE, error_state);
148
149 if (amdxdna_cmd_get_op(abo) == ERT_CMD_CHAIN) {
150 cc = amdxdna_cmd_get_payload(abo, NULL);
151 cc->error_index = (cmd_idx < cc->command_count) ? cmd_idx : 0;
152 abo = amdxdna_gem_get_obj(client, cc->data[0], AMDXDNA_BO_CMD);
153 if (!abo)
154 return -EINVAL;
155 cmd = abo->mem.kva;
156 }
157
158 memset(cmd->data, 0xff, abo->mem.size - sizeof(*cmd));
159 if (cc)
160 amdxdna_gem_put_obj(abo);
161
162 return 0;
163}
164
138/*165/*
139 * This should be called in close() and remove(). DO NOT call in other syscalls.166 * This should be called in close() and remove(). DO NOT call in other syscalls.
140 * This guarantee that when hwctx and resources will be released, if user167 * This guarantee that when hwctx and resources will be released, if user
drivers/accel/amdxdna/amdxdna_ctx.h+3−0
@@ -167,6 +167,9 @@ amdxdna_cmd_get_state(struct amdxdna_gem_obj *abo) · 166 unmodified lines
167 167
168void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size);168void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size);
169u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo);169u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo);
170int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo,
171 struct amdxdna_sched_job *job, u32 cmd_idx,
172 enum ert_cmd_state error_state);
170 173
171void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job);174void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job);
172void amdxdna_hwctx_remove_all(struct amdxdna_client *client);175void amdxdna_hwctx_remove_all(struct amdxdna_client *client);
drivers/accel/amdxdna/amdxdna_mailbox.c+45−46
@@ -460,26 +460,49 @@ msg_id_failed: · 459 unmodified lines
460 return ret;460 return ret;
461}461}
462 462
463struct mailbox_channel *463struct mailbox_channel *xdna_mailbox_alloc_channel(struct mailbox *mb)
464xdna_mailbox_create_channel(struct mailbox *mb,
465 const struct xdna_mailbox_chann_res *x2i,
466 const struct xdna_mailbox_chann_res *i2x,
467 u32 iohub_int_addr,
468 int mb_irq)
469{464{
470 struct mailbox_channel *mb_chann;465 struct mailbox_channel *mb_chann;
471 int ret;
472
473 if (!is_power_of_2(x2i->rb_size) || !is_power_of_2(i2x->rb_size)) {
474 pr_err("Ring buf size must be power of 2");
475 return NULL;
476 }
477 466
478 mb_chann = kzalloc_obj(*mb_chann);467 mb_chann = kzalloc_obj(*mb_chann);
479 if (!mb_chann)468 if (!mb_chann)
480 return NULL;469 return NULL;
481 470
471 INIT_WORK(&mb_chann->rx_work, mailbox_rx_worker);
472 mb_chann->work_q = create_singlethread_workqueue(MAILBOX_NAME);
473 if (!mb_chann->work_q) {
474 MB_ERR(mb_chann, "Create workqueue failed");
475 goto free_chann;
476 }
482 mb_chann->mb = mb;477 mb_chann->mb = mb;
478
479 return mb_chann;
480
481free_chann:
482 kfree(mb_chann);
483 return NULL;
484}
485
486void xdna_mailbox_free_channel(struct mailbox_channel *mb_chann)
487{
488 destroy_workqueue(mb_chann->work_q);
489 kfree(mb_chann);
490}
491
492int
493xdna_mailbox_start_channel(struct mailbox_channel *mb_chann,
494 const struct xdna_mailbox_chann_res *x2i,
495 const struct xdna_mailbox_chann_res *i2x,
496 u32 iohub_int_addr,
497 int mb_irq)
498{
499 int ret;
500
501 if (!is_power_of_2(x2i->rb_size) || !is_power_of_2(i2x->rb_size)) {
502 pr_err("Ring buf size must be power of 2");
503 return -EINVAL;
504 }
505
483 mb_chann->msix_irq = mb_irq;506 mb_chann->msix_irq = mb_irq;
484 mb_chann->iohub_int_addr = iohub_int_addr;507 mb_chann->iohub_int_addr = iohub_int_addr;
485 memcpy(&mb_chann->res[CHAN_RES_X2I], x2i, sizeof(*x2i));508 memcpy(&mb_chann->res[CHAN_RES_X2I], x2i, sizeof(*x2i));
@@ -489,61 +512,37 @@ xdna_mailbox_create_channel(struct mailbox *mb, · 3 unmodified lines
489 mb_chann->x2i_tail = mailbox_get_tailptr(mb_chann, CHAN_RES_X2I);512 mb_chann->x2i_tail = mailbox_get_tailptr(mb_chann, CHAN_RES_X2I);
490 mb_chann->i2x_head = mailbox_get_headptr(mb_chann, CHAN_RES_I2X);513 mb_chann->i2x_head = mailbox_get_headptr(mb_chann, CHAN_RES_I2X);
491 514
492 INIT_WORK(&mb_chann->rx_work, mailbox_rx_worker);
493 mb_chann->work_q = create_singlethread_workqueue(MAILBOX_NAME);
494 if (!mb_chann->work_q) {
495 MB_ERR(mb_chann, "Create workqueue failed");
496 goto free_and_out;
497 }
498
499 /* Everything look good. Time to enable irq handler */515 /* Everything look good. Time to enable irq handler */
500 ret = request_irq(mb_irq, mailbox_irq_handler, 0, MAILBOX_NAME, mb_chann);516 ret = request_irq(mb_irq, mailbox_irq_handler, 0, MAILBOX_NAME, mb_chann);
501 if (ret) {517 if (ret) {
502 MB_ERR(mb_chann, "Failed to request irq %d ret %d", mb_irq, ret);518 MB_ERR(mb_chann, "Failed to request irq %d ret %d", mb_irq, ret);
503 goto destroy_wq;519 return ret;
504 }520 }
505 521
506 mb_chann->bad_state = false;522 mb_chann->bad_state = false;
507 mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0);523 mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0);
508 524
509 MB_DBG(mb_chann, "Mailbox channel created (irq: %d)", mb_chann->msix_irq);525 MB_DBG(mb_chann, "Mailbox channel started (irq: %d)", mb_chann->msix_irq);
510 return mb_chann;526 return 0;
511
512destroy_wq:
513 destroy_workqueue(mb_chann->work_q);
514free_and_out:
515 kfree(mb_chann);
516 return NULL;
517}527}
518 528
519int xdna_mailbox_destroy_channel(struct mailbox_channel *mb_chann)529void xdna_mailbox_stop_channel(struct mailbox_channel *mb_chann)
520{530{
521 struct mailbox_msg *mb_msg;531 struct mailbox_msg *mb_msg;
522 unsigned long msg_id;532 unsigned long msg_id;
523 533
524 MB_DBG(mb_chann, "IRQ disabled and RX work cancelled");534 /* Disable an irq and wait. This might sleep. */
525 free_irq(mb_chann->msix_irq, mb_chann);535 free_irq(mb_chann->msix_irq, mb_chann);
526 destroy_workqueue(mb_chann->work_q);
527 /* We can clean up and release resources */
528 536
537 /* Cancel RX work and wait for it to finish */
538 drain_workqueue(mb_chann->work_q);
539
540 /* We can clean up and release resources */
529 xa_for_each(&mb_chann->chan_xa, msg_id, mb_msg)541 xa_for_each(&mb_chann->chan_xa, msg_id, mb_msg)
530 mailbox_release_msg(mb_chann, mb_msg);542 mailbox_release_msg(mb_chann, mb_msg);
531
532 xa_destroy(&mb_chann->chan_xa);543 xa_destroy(&mb_chann->chan_xa);
533 544
534 MB_DBG(mb_chann, "Mailbox channel destroyed, irq: %d", mb_chann->msix_irq);545 MB_DBG(mb_chann, "Mailbox channel stopped, irq: %d", mb_chann->msix_irq);
535 kfree(mb_chann);
536 return 0;
537}
538
539void xdna_mailbox_stop_channel(struct mailbox_channel *mb_chann)
540{
541 /* Disable an irq and wait. This might sleep. */
542 disable_irq(mb_chann->msix_irq);
543
544 /* Cancel RX work and wait for it to finish */
545 cancel_work_sync(&mb_chann->rx_work);
546 MB_DBG(mb_chann, "IRQ disabled and RX work cancelled");
547}546}
548 547
549struct mailbox *xdnam_mailbox_create(struct drm_device *ddev,548struct mailbox *xdnam_mailbox_create(struct drm_device *ddev,
drivers/accel/amdxdna/amdxdna_mailbox.h+17−14
@@ -74,9 +74,16 @@ struct mailbox *xdnam_mailbox_create(struct drm_device *ddev, · 73 unmodified lines
74 const struct xdna_mailbox_res *res);74 const struct xdna_mailbox_res *res);
75 75
76/*76/*
77 * xdna_mailbox_create_channel() -- Create a mailbox channel instance77 * xdna_mailbox_alloc_channel() -- alloc a mailbox channel
78 *78 *
79 * @mailbox: the handle return from xdna_mailbox_create()79 * @mb: mailbox handle
80 */
81struct mailbox_channel *xdna_mailbox_alloc_channel(struct mailbox *mb);
82
83/*
84 * xdna_mailbox_start_channel() -- start a mailbox channel instance
85 *
86 * @mb_chann: the handle return from xdna_mailbox_alloc_channel()
80 * @x2i: host to firmware mailbox resources87 * @x2i: host to firmware mailbox resources
81 * @i2x: firmware to host mailbox resources88 * @i2x: firmware to host mailbox resources
82 * @xdna_mailbox_intr_reg: register addr of MSI-X interrupt89 * @xdna_mailbox_intr_reg: register addr of MSI-X interrupt
@@ -84,28 +91,24 @@ struct mailbox *xdnam_mailbox_create(struct drm_device *ddev, · 1 unmodified line
84 *91 *
85 * Return: If success, return a handle of mailbox channel. Otherwise, return NULL.92 * Return: If success, return a handle of mailbox channel. Otherwise, return NULL.
86 */93 */
87struct mailbox_channel *94int
88xdna_mailbox_create_channel(struct mailbox *mailbox,95xdna_mailbox_start_channel(struct mailbox_channel *mb_chann,
89 const struct xdna_mailbox_chann_res *x2i,96 const struct xdna_mailbox_chann_res *x2i,
90 const struct xdna_mailbox_chann_res *i2x,97 const struct xdna_mailbox_chann_res *i2x,
91 u32 xdna_mailbox_intr_reg,98 u32 xdna_mailbox_intr_reg,
92 int mb_irq);99 int mb_irq);
93 100
94/*101/*
95 * xdna_mailbox_destroy_channel() -- destroy mailbox channel102 * xdna_mailbox_free_channel() -- free mailbox channel
96 *103 *
97 * @mailbox_chann: the handle return from xdna_mailbox_create_channel()104 * @mailbox_chann: the handle return from xdna_mailbox_create_channel()
98 *
99 * Return: if success, return 0. otherwise return error code
100 */105 */
101int xdna_mailbox_destroy_channel(struct mailbox_channel *mailbox_chann);106void xdna_mailbox_free_channel(struct mailbox_channel *mailbox_chann);
102 107
103/*108/*
104 * xdna_mailbox_stop_channel() -- stop mailbox channel109 * xdna_mailbox_stop_channel() -- stop mailbox channel
105 *110 *
106 * @mailbox_chann: the handle return from xdna_mailbox_create_channel()111 * @mailbox_chann: the handle return from xdna_mailbox_create_channel()
107 *
108 * Return: if success, return 0. otherwise return error code
109 */112 */
110void xdna_mailbox_stop_channel(struct mailbox_channel *mailbox_chann);113void xdna_mailbox_stop_channel(struct mailbox_channel *mailbox_chann);
111 114
drivers/accel/amdxdna/npu1_regs.c+1−1
@@ -67,7 +67,7 @@ const struct dpm_clk_freq npu1_dpm_clk_table[] = { · 66 unmodified lines
67 67
68static const struct aie2_fw_feature_tbl npu1_fw_feature_table[] = {68static const struct aie2_fw_feature_tbl npu1_fw_feature_table[] = {
69 { .major = 5, .min_minor = 7 },69 { .major = 5, .min_minor = 7 },
70 { .features = BIT_U64(AIE2_NPU_COMMAND), .min_minor = 8 },70 { .features = BIT_U64(AIE2_NPU_COMMAND), .major = 5, .min_minor = 8 },
71 { 0 }71 { 0 }
72};72};
73 73
drivers/accel/ethosu/ethosu_gem.c+9−3
@@ -245,11 +245,14 @@ static int calc_sizes(struct drm_device *ddev, · 244 unmodified lines
245 ((st->ifm.stride_kernel >> 1) & 0x1) + 1;245 ((st->ifm.stride_kernel >> 1) & 0x1) + 1;
246 u32 stride_x = ((st->ifm.stride_kernel >> 5) & 0x2) +246 u32 stride_x = ((st->ifm.stride_kernel >> 5) & 0x2) +
247 (st->ifm.stride_kernel & 0x1) + 1;247 (st->ifm.stride_kernel & 0x1) + 1;
248 u32 ifm_height = st->ofm.height[2] * stride_y +248 s32 ifm_height = st->ofm.height[2] * stride_y +
249 st->ifm.height[2] - (st->ifm.pad_top + st->ifm.pad_bottom);249 st->ifm.height[2] - (st->ifm.pad_top + st->ifm.pad_bottom);
250 u32 ifm_width = st->ofm.width * stride_x +250 s32 ifm_width = st->ofm.width * stride_x +
251 st->ifm.width - (st->ifm.pad_left + st->ifm.pad_right);251 st->ifm.width - (st->ifm.pad_left + st->ifm.pad_right);
252 252
253 if (ifm_height < 0 || ifm_width < 0)
254 return -EINVAL;
255
253 len = feat_matrix_length(info, &st->ifm, ifm_width,256 len = feat_matrix_length(info, &st->ifm, ifm_width,
254 ifm_height, st->ifm.depth);257 ifm_height, st->ifm.depth);
255 dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n",258 dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n",
@@ -417,7 +420,10 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, · 161 unmodified lines
417 return ret;420 return ret;
418 break;421 break;
419 case NPU_OP_ELEMENTWISE:422 case NPU_OP_ELEMENTWISE:
420 use_ifm2 = !((st.ifm2.broadcast == 8) || (param == 5) ||423 use_scale = ethosu_is_u65(edev) ?
424 (st.ifm2.broadcast & 0x80) :
425 (st.ifm2.broadcast == 8);
426 use_ifm2 = !(use_scale || (param == 5) ||
421 (param == 6) || (param == 7) || (param == 0x24));427 (param == 6) || (param == 7) || (param == 0x24));
422 use_ifm = st.ifm.broadcast != 8;428 use_ifm = st.ifm.broadcast != 8;
423 ret = calc_sizes_elemwise(ddev, info, cmd, &st, use_ifm, use_ifm2);429 ret = calc_sizes_elemwise(ddev, info, cmd, &st, use_ifm, use_ifm2);
drivers/accel/ethosu/ethosu_job.c+18−8
@@ -143,23 +143,29 @@ out: · 142 unmodified lines
143 return ret;143 return ret;
144}144}
145 145
146static void ethosu_job_err_cleanup(struct ethosu_job *job)
147{
148 unsigned int i;
149
150 for (i = 0; i < job->region_cnt; i++)
151 drm_gem_object_put(job->region_bo[i]);
152
153 drm_gem_object_put(job->cmd_bo);
154
155 kfree(job);
156}
157
146static void ethosu_job_cleanup(struct kref *ref)158static void ethosu_job_cleanup(struct kref *ref)
147{159{
148 struct ethosu_job *job = container_of(ref, struct ethosu_job,160 struct ethosu_job *job = container_of(ref, struct ethosu_job,
149 refcount);161 refcount);
150 unsigned int i;
151 162
152 pm_runtime_put_autosuspend(job->dev->base.dev);163 pm_runtime_put_autosuspend(job->dev->base.dev);
153 164
154 dma_fence_put(job->done_fence);165 dma_fence_put(job->done_fence);
155 dma_fence_put(job->inference_done_fence);166 dma_fence_put(job->inference_done_fence);
156 167
157 for (i = 0; i < job->region_cnt; i++)168 ethosu_job_err_cleanup(job);
158 drm_gem_object_put(job->region_bo[i]);
159
160 drm_gem_object_put(job->cmd_bo);
161
162 kfree(job);
163}169}
164 170
165static void ethosu_job_put(struct ethosu_job *job)171static void ethosu_job_put(struct ethosu_job *job)
@@ -454,12 +460,16 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file · 288 unmodified lines
454 }460 }
455 }461 }
456 ret = ethosu_job_push(ejob);462 ret = ethosu_job_push(ejob);
463 if (!ret) {
464 ethosu_job_put(ejob);
465 return 0;
466 }
457 467
458out_cleanup_job:468out_cleanup_job:
459 if (ret)469 if (ret)
460 drm_sched_job_cleanup(&ejob->base);470 drm_sched_job_cleanup(&ejob->base);
461out_put_job:471out_put_job:
462 ethosu_job_put(ejob);472 ethosu_job_err_cleanup(ejob);
463 473
464 return ret;474 return ret;
465}475}
drivers/acpi/acpica/acpredef.h+3−2
@@ -379,8 +379,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { · 378 unmodified lines
379 379
380 {{"_CPC", METHOD_0ARGS,380 {{"_CPC", METHOD_0ARGS,
381 METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints/Bufs) */381 METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints/Bufs) */
382 PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER, 0,382 PACKAGE_INFO(ACPI_PTYPE1_VAR,
383 0, 0, 0),383 ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER |
384 ACPI_RTYPE_PACKAGE, 0, 0, 0, 0),
384 385
385 {{"_CR3", METHOD_0ARGS, /* ACPI 6.0 */386 {{"_CR3", METHOD_0ARGS, /* ACPI 6.0 */
386 METHOD_RETURNS(ACPI_RTYPE_INTEGER)}},387 METHOD_RETURNS(ACPI_RTYPE_INTEGER)}},
drivers/acpi/device_pm.c+0−9
@@ -1456,15 +1456,6 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) · 1455 unmodified lines
1456 if (!adev || !acpi_match_device_ids(adev, special_pm_ids))1456 if (!adev || !acpi_match_device_ids(adev, special_pm_ids))
1457 return 0;1457 return 0;
1458 1458
1459 /*
1460 * Skip devices whose ACPI companions don't support power management and
1461 * don't have a wakeup GPE.
1462 */
1463 if (!acpi_device_power_manageable(adev) && !acpi_device_can_wakeup(adev)) {
1464 dev_dbg(dev, "No ACPI power management or wakeup GPE\n");
1465 return 0;
1466 }
1467
1468 /*1459 /*
1469 * Only attach the power domain to the first device if the1460 * Only attach the power domain to the first device if the
1470 * companion is shared by multiple. This is to prevent doing power1461 * companion is shared by multiple. This is to prevent doing power
drivers/ata/libata-core.c+2−0
@@ -4189,6 +4189,7 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { · 4188 unmodified lines
4189 ATA_QUIRK_FIRMWARE_WARN },4189 ATA_QUIRK_FIRMWARE_WARN },
4190 4190
4191 /* Seagate disks with LPM issues */4191 /* Seagate disks with LPM issues */
4192 { "ST1000DM010-2EP102", NULL, ATA_QUIRK_NOLPM },
4192 { "ST2000DM008-2FR102", NULL, ATA_QUIRK_NOLPM },4193 { "ST2000DM008-2FR102", NULL, ATA_QUIRK_NOLPM },
4193 4194
4194 /* drives which fail FPDMA_AA activation (some may freeze afterwards)4195 /* drives which fail FPDMA_AA activation (some may freeze afterwards)
@@ -4231,6 +4232,7 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { · 36 unmodified lines
4231 /* Devices that do not need bridging limits applied */4232 /* Devices that do not need bridging limits applied */
4232 { "MTRON MSP-SATA*", NULL, ATA_QUIRK_BRIDGE_OK },4233 { "MTRON MSP-SATA*", NULL, ATA_QUIRK_BRIDGE_OK },
4233 { "BUFFALO HD-QSU2/R5", NULL, ATA_QUIRK_BRIDGE_OK },4234 { "BUFFALO HD-QSU2/R5", NULL, ATA_QUIRK_BRIDGE_OK },
4235 { "QEMU HARDDISK", "2.5+", ATA_QUIRK_BRIDGE_OK },
4234 4236
4235 /* Devices which aren't very happy with higher link speeds */4237 /* Devices which aren't very happy with higher link speeds */
4236 { "WD My Book", NULL, ATA_QUIRK_1_5_GBPS },4238 { "WD My Book", NULL, ATA_QUIRK_1_5_GBPS },
drivers/ata/libata-eh.c+2−1
@@ -647,7 +647,7 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, · 646 unmodified lines
647 break;647 break;
648 }648 }
649 649
650 if (qc == ap->deferred_qc) {650 if (i < ATA_MAX_QUEUE && qc == ap->deferred_qc) {
651 /*651 /*
652 * This is a deferred command that timed out while652 * This is a deferred command that timed out while
653 * waiting for the command queue to drain. Since the qc653 * waiting for the command queue to drain. Since the qc
@@ -659,6 +659,7 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, · 5 unmodified lines
659 */659 */
660 WARN_ON_ONCE(qc->flags & ATA_QCFLAG_ACTIVE);660 WARN_ON_ONCE(qc->flags & ATA_QCFLAG_ACTIVE);
661 ap->deferred_qc = NULL;661 ap->deferred_qc = NULL;
662 cancel_work(&ap->deferred_qc_work);
662 set_host_byte(scmd, DID_TIME_OUT);663 set_host_byte(scmd, DID_TIME_OUT);
663 scsi_eh_finish_cmd(scmd, &ap->eh_done_q);664 scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
664 } else if (i < ATA_MAX_QUEUE) {665 } else if (i < ATA_MAX_QUEUE) {
drivers/ata/libata-scsi.c+1−0
@@ -1699,6 +1699,7 @@ void ata_scsi_requeue_deferred_qc(struct ata_port *ap) · 1698 unmodified lines
1699 1699
1700 scmd = qc->scsicmd;1700 scmd = qc->scsicmd;
1701 ap->deferred_qc = NULL;1701 ap->deferred_qc = NULL;
1702 cancel_work(&ap->deferred_qc_work);
1702 ata_qc_free(qc);1703 ata_qc_free(qc);
1703 scmd->result = (DID_SOFT_ERROR << 16);1704 scmd->result = (DID_SOFT_ERROR << 16);
1704 scsi_done(scmd);1705 scsi_done(scmd);
drivers/base/base.h+1−10
@@ -179,19 +179,10 @@ void device_release_driver_internal(struct device *dev, const struct device_driv · 178 unmodified lines
179void driver_detach(const struct device_driver *drv);179void driver_detach(const struct device_driver *drv);
180void driver_deferred_probe_del(struct device *dev);180void driver_deferred_probe_del(struct device *dev);
181void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf);181void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf);
182static inline int driver_match_device_locked(const struct device_driver *drv,
183 struct device *dev)
184{
185 device_lock_assert(dev);
186
187 return drv->bus->match ? drv->bus->match(dev, drv) : 1;
188}
189
190static inline int driver_match_device(const struct device_driver *drv,182static inline int driver_match_device(const struct device_driver *drv,
191 struct device *dev)183 struct device *dev)
192{184{
193 guard(device)(dev);185 return drv->bus->match ? drv->bus->match(dev, drv) : 1;
194 return driver_match_device_locked(drv, dev);
195}186}
196 187
197static inline void dev_sync_state(struct device *dev)188static inline void dev_sync_state(struct device *dev)
drivers/base/dd.c+1−1
@@ -928,7 +928,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data) · 927 unmodified lines
928 bool async_allowed;928 bool async_allowed;
929 int ret;929 int ret;
930 930
931 ret = driver_match_device_locked(drv, dev);931 ret = driver_match_device(drv, dev);
932 if (ret == 0) {932 if (ret == 0) {
933 /* no match */933 /* no match */
934 return 0;934 return 0;
drivers/crypto/atmel-sha204a.c+3−2
@@ -52,9 +52,10 @@ static int atmel_sha204a_rng_read_nonblocking(struct hwrng *rng, void *data, · 51 unmodified lines
52 rng->priv = 0;52 rng->priv = 0;
53 } else {53 } else {
54 work_data = kmalloc_obj(*work_data, GFP_ATOMIC);54 work_data = kmalloc_obj(*work_data, GFP_ATOMIC);
55 if (!work_data)55 if (!work_data) {
56 atomic_dec(&i2c_priv->tfm_count);
56 return -ENOMEM;57 return -ENOMEM;
57 58 }
58 work_data->ctx = i2c_priv;59 work_data->ctx = i2c_priv;
59 work_data->client = i2c_priv->client;60 work_data->client = i2c_priv->client;
60 61
drivers/crypto/ccp/sev-dev-tsm.c+1−1
@@ -378,9 +378,9 @@ void sev_tsm_init_locked(struct sev_device *sev, void *tio_status_page) · 377 unmodified lines
378 return;378 return;
379 379
380error_exit:380error_exit:
381 kfree(t);
382 pr_err("Failed to enable SEV-TIO: ret=%d en=%d initdone=%d SEV=%d\n",381 pr_err("Failed to enable SEV-TIO: ret=%d en=%d initdone=%d SEV=%d\n",
383 ret, t->tio_en, t->tio_init_done, boot_cpu_has(X86_FEATURE_SEV));382 ret, t->tio_en, t->tio_init_done, boot_cpu_has(X86_FEATURE_SEV));
383 kfree(t);
384}384}
385 385
386void sev_tsm_uninit(struct sev_device *sev)386void sev_tsm_uninit(struct sev_device *sev)
drivers/crypto/ccp/sev-dev.c+4−6
@@ -1105,15 +1105,12 @@ struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages) · 1104 unmodified lines
1105{1105{
1106 struct psp_device *psp_master = psp_get_master_device();1106 struct psp_device *psp_master = psp_get_master_device();
1107 struct snp_hv_fixed_pages_entry *entry;1107 struct snp_hv_fixed_pages_entry *entry;
1108 struct sev_device *sev;
1109 unsigned int order;1108 unsigned int order;
1110 struct page *page;1109 struct page *page;
1111 1110
1112 if (!psp_master || !psp_master->sev_data)1111 if (!psp_master)
1113 return NULL;1112 return NULL;
1114 1113
1115 sev = psp_master->sev_data;
1116
1117 order = get_order(PMD_SIZE * num_2mb_pages);1114 order = get_order(PMD_SIZE * num_2mb_pages);
1118 1115
1119 /*1116 /*
@@ -1126,7 +1123,8 @@ struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages) · 6 unmodified lines
1126 * This API uses SNP_INIT_EX to transition allocated pages to HV_Fixed1123 * This API uses SNP_INIT_EX to transition allocated pages to HV_Fixed
1127 * page state, fail if SNP is already initialized.1124 * page state, fail if SNP is already initialized.
1128 */1125 */
1129 if (sev->snp_initialized)1126 if (psp_master->sev_data &&
1127 ((struct sev_device *)psp_master->sev_data)->snp_initialized)
1130 return NULL;1128 return NULL;
1131 1129
1132 /* Re-use freed pages that match the request */1130 /* Re-use freed pages that match the request */
@@ -1162,7 +1160,7 @@ void snp_free_hv_fixed_pages(struct page *page) · 29 unmodified lines
1162 struct psp_device *psp_master = psp_get_master_device();1160 struct psp_device *psp_master = psp_get_master_device();
1163 struct snp_hv_fixed_pages_entry *entry, *nentry;1161 struct snp_hv_fixed_pages_entry *entry, *nentry;
1164 1162
1165 if (!psp_master || !psp_master->sev_data)1163 if (!psp_master)
1166 return;1164 return;
1167 1165
1168 /*1166 /*
drivers/firmware/efi/mokvar-table.c+1−1
@@ -85,7 +85,7 @@ static struct kobject *mokvar_kobj; · 84 unmodified lines
85 * as an alternative to ordinary EFI variables, due to platform-dependent85 * as an alternative to ordinary EFI variables, due to platform-dependent
86 * limitations. The memory occupied by this table is marked as reserved.86 * limitations. The memory occupied by this table is marked as reserved.
87 *87 *
88 * This routine must be called before efi_free_boot_services() in order88 * This routine must be called before efi_unmap_boot_services() in order
89 * to guarantee that it can mark the table as reserved.89 * to guarantee that it can mark the table as reserved.
90 *90 *
91 * Implicit inputs:91 * Implicit inputs:
drivers/gpu/drm/amd/amdgpu/Makefile+1−1
@@ -47,7 +47,7 @@ subdir-ccflags-$(CONFIG_DRM_AMDGPU_WERROR) += -Werror · 46 unmodified lines
47amdgpu-y := amdgpu_drv.o47amdgpu-y := amdgpu_drv.o
48 48
49# add KMS driver49# add KMS driver
50amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \50amdgpu-y += amdgpu_device.o amdgpu_reg_access.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
51 amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \51 amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
52 atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \52 atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
53 amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \53 amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
drivers/gpu/drm/amd/amdgpu/amdgpu.h+39−115
@@ -81,6 +81,7 @@ · 80 unmodified lines
81#include "amdgpu_sdma.h"81#include "amdgpu_sdma.h"
82#include "amdgpu_lsdma.h"82#include "amdgpu_lsdma.h"
83#include "amdgpu_nbio.h"83#include "amdgpu_nbio.h"
84#include "amdgpu_reg_access.h"
84#include "amdgpu_hdp.h"85#include "amdgpu_hdp.h"
85#include "amdgpu_dm.h"86#include "amdgpu_dm.h"
86#include "amdgpu_virt.h"87#include "amdgpu_virt.h"
@@ -217,9 +218,7 @@ extern struct amdgpu_watchdog_timer amdgpu_watchdog_timer; · 130 unmodified lines
217extern int amdgpu_async_gfx_ring;218extern int amdgpu_async_gfx_ring;
218extern int amdgpu_mcbp;219extern int amdgpu_mcbp;
219extern int amdgpu_discovery;220extern int amdgpu_discovery;
220extern int amdgpu_mes;
221extern int amdgpu_mes_log_enable;221extern int amdgpu_mes_log_enable;
222extern int amdgpu_mes_kiq;
223extern int amdgpu_uni_mes;222extern int amdgpu_uni_mes;
224extern int amdgpu_noretry;223extern int amdgpu_noretry;
225extern int amdgpu_force_asic_type;224extern int amdgpu_force_asic_type;
@@ -680,21 +679,6 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device); · 454 unmodified lines
680/*679/*
681 * Core structure, functions and helpers.680 * Core structure, functions and helpers.
682 */681 */
683typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device*, uint32_t);
684typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
685
686typedef uint32_t (*amdgpu_rreg_ext_t)(struct amdgpu_device*, uint64_t);
687typedef void (*amdgpu_wreg_ext_t)(struct amdgpu_device*, uint64_t, uint32_t);
688
689typedef uint64_t (*amdgpu_rreg64_t)(struct amdgpu_device*, uint32_t);
690typedef void (*amdgpu_wreg64_t)(struct amdgpu_device*, uint32_t, uint64_t);
691
692typedef uint64_t (*amdgpu_rreg64_ext_t)(struct amdgpu_device*, uint64_t);
693typedef void (*amdgpu_wreg64_ext_t)(struct amdgpu_device*, uint64_t, uint64_t);
694
695typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
696typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);
697
698struct amdgpu_mmio_remap {682struct amdgpu_mmio_remap {
699 u32 reg_offset;683 u32 reg_offset;
700 resource_size_t bus_addr;684 resource_size_t bus_addr;
@@ -791,6 +775,12 @@ struct amd_powerplay { · 90 unmodified lines
791 (rid == 0x01) || \775 (rid == 0x01) || \
792 (rid == 0x10))))776 (rid == 0x10))))
793 777
778enum amdgpu_mqd_update_flag {
779 AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE = 1,
780 AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE = 2,
781 AMDGPU_UPDATE_FLAG_IS_GWS = 4, /* quirk for gfx9 IP */
782};
783
794struct amdgpu_mqd_prop {784struct amdgpu_mqd_prop {
795 uint64_t mqd_gpu_addr;785 uint64_t mqd_gpu_addr;
796 uint64_t hqd_base_gpu_addr;786 uint64_t hqd_base_gpu_addr;
@@ -811,6 +801,10 @@ struct amdgpu_mqd_prop { · 14 unmodified lines
811 uint64_t fence_address;801 uint64_t fence_address;
812 bool tmz_queue;802 bool tmz_queue;
813 bool kernel_queue;803 bool kernel_queue;
804 uint32_t *cu_mask;
805 uint32_t cu_mask_count;
806 uint32_t cu_flags;
807 bool is_user_cu_masked;
814};808};
815 809
816struct amdgpu_mqd {810struct amdgpu_mqd {
@@ -906,42 +900,8 @@ struct amdgpu_device { · 89 unmodified lines
906 /* protects concurrent MM_INDEX/DATA based register access */900 /* protects concurrent MM_INDEX/DATA based register access */
907 spinlock_t mmio_idx_lock;901 spinlock_t mmio_idx_lock;
908 struct amdgpu_mmio_remap rmmio_remap;902 struct amdgpu_mmio_remap rmmio_remap;
909 /* protects concurrent SMC based register access */903 /* Indirect register access blocks */
910 spinlock_t smc_idx_lock;904 struct amdgpu_reg_access reg;
911 amdgpu_rreg_t smc_rreg;
912 amdgpu_wreg_t smc_wreg;
913 /* protects concurrent PCIE register access */
914 spinlock_t pcie_idx_lock;
915 amdgpu_rreg_t pcie_rreg;
916 amdgpu_wreg_t pcie_wreg;
917 amdgpu_rreg_t pciep_rreg;
918 amdgpu_wreg_t pciep_wreg;
919 amdgpu_rreg_ext_t pcie_rreg_ext;
920 amdgpu_wreg_ext_t pcie_wreg_ext;
921 amdgpu_rreg64_t pcie_rreg64;
922 amdgpu_wreg64_t pcie_wreg64;
923 amdgpu_rreg64_ext_t pcie_rreg64_ext;
924 amdgpu_wreg64_ext_t pcie_wreg64_ext;
925 /* protects concurrent UVD register access */
926 spinlock_t uvd_ctx_idx_lock;
927 amdgpu_rreg_t uvd_ctx_rreg;
928 amdgpu_wreg_t uvd_ctx_wreg;
929 /* protects concurrent DIDT register access */
930 spinlock_t didt_idx_lock;
931 amdgpu_rreg_t didt_rreg;
932 amdgpu_wreg_t didt_wreg;
933 /* protects concurrent gc_cac register access */
934 spinlock_t gc_cac_idx_lock;
935 amdgpu_rreg_t gc_cac_rreg;
936 amdgpu_wreg_t gc_cac_wreg;
937 /* protects concurrent se_cac register access */
938 spinlock_t se_cac_idx_lock;
939 amdgpu_rreg_t se_cac_rreg;
940 amdgpu_wreg_t se_cac_wreg;
941 /* protects concurrent ENDPOINT (audio) register access */
942 spinlock_t audio_endpt_idx_lock;
943 amdgpu_block_rreg_t audio_endpt_rreg;
944 amdgpu_block_wreg_t audio_endpt_wreg;
945 struct amdgpu_doorbell doorbell;905 struct amdgpu_doorbell doorbell;
946 906
947 /* clock/pll info */907 /* clock/pll info */
@@ -1297,42 +1257,6 @@ size_t amdgpu_device_aper_access(struct amdgpu_device *adev, loff_t pos, · 349 unmodified lines
1297 1257
1298void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,1258void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
1299 void *buf, size_t size, bool write);1259 void *buf, size_t size, bool write);
1300uint32_t amdgpu_device_wait_on_rreg(struct amdgpu_device *adev,
1301 uint32_t inst, uint32_t reg_addr, char reg_name[],
1302 uint32_t expected_value, uint32_t mask);
1303uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
1304 uint32_t reg, uint32_t acc_flags);
1305u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,
1306 u64 reg_addr);
1307uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev,
1308 uint32_t reg, uint32_t acc_flags,
1309 uint32_t xcc_id);
1310void amdgpu_device_wreg(struct amdgpu_device *adev,
1311 uint32_t reg, uint32_t v,
1312 uint32_t acc_flags);
1313void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
1314 u64 reg_addr, u32 reg_data);
1315void amdgpu_device_xcc_wreg(struct amdgpu_device *adev,
1316 uint32_t reg, uint32_t v,
1317 uint32_t acc_flags,
1318 uint32_t xcc_id);
1319void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
1320 uint32_t reg, uint32_t v, uint32_t xcc_id);
1321void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
1322uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
1323
1324u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
1325 u32 reg_addr);
1326u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
1327 u32 reg_addr);
1328u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev,
1329 u64 reg_addr);
1330void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
1331 u32 reg_addr, u32 reg_data);
1332void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
1333 u32 reg_addr, u64 reg_data);
1334void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev,
1335 u64 reg_addr, u64 reg_data);
1336u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev);1260u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev);
1337bool amdgpu_device_asic_has_dc_support(struct pci_dev *pdev,1261bool amdgpu_device_asic_has_dc_support(struct pci_dev *pdev,
1338 enum amd_asic_type asic_type);1262 enum amd_asic_type asic_type);
@@ -1372,28 +1296,30 @@ int emu_soc_asic_init(struct amdgpu_device *adev); · 33 unmodified lines
1372#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)1296#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
1373#define RREG32_XCC(reg, inst) amdgpu_device_xcc_rreg(adev, (reg), 0, inst)1297#define RREG32_XCC(reg, inst) amdgpu_device_xcc_rreg(adev, (reg), 0, inst)
1374#define WREG32_XCC(reg, v, inst) amdgpu_device_xcc_wreg(adev, (reg), (v), 0, inst)1298#define WREG32_XCC(reg, v, inst) amdgpu_device_xcc_wreg(adev, (reg), (v), 0, inst)
1375#define RREG32_PCIE(reg) adev->pcie_rreg(adev, (reg))1299#define RREG32_PCIE(reg) amdgpu_reg_pcie_rd32(adev, (reg))
1376#define WREG32_PCIE(reg, v) adev->pcie_wreg(adev, (reg), (v))1300#define WREG32_PCIE(reg, v) amdgpu_reg_pcie_wr32(adev, (reg), (v))
1377#define RREG32_PCIE_PORT(reg) adev->pciep_rreg(adev, (reg))1301#define RREG32_PCIE_PORT(reg) amdgpu_reg_pciep_rd32(adev, (reg))
1378#define WREG32_PCIE_PORT(reg, v) adev->pciep_wreg(adev, (reg), (v))1302#define WREG32_PCIE_PORT(reg, v) amdgpu_reg_pciep_wr32(adev, (reg), (v))
1379#define RREG32_PCIE_EXT(reg) adev->pcie_rreg_ext(adev, (reg))1303#define RREG32_PCIE_EXT(reg) amdgpu_reg_pcie_ext_rd32(adev, (reg))
1380#define WREG32_PCIE_EXT(reg, v) adev->pcie_wreg_ext(adev, (reg), (v))1304#define WREG32_PCIE_EXT(reg, v) amdgpu_reg_pcie_ext_wr32(adev, (reg), (v))
1381#define RREG64_PCIE(reg) adev->pcie_rreg64(adev, (reg))1305#define RREG64_PCIE(reg) amdgpu_reg_pcie_rd64(adev, (reg))
1382#define WREG64_PCIE(reg, v) adev->pcie_wreg64(adev, (reg), (v))1306#define WREG64_PCIE(reg, v) amdgpu_reg_pcie_wr64(adev, (reg), (v))
1383#define RREG64_PCIE_EXT(reg) adev->pcie_rreg64_ext(adev, (reg))1307#define RREG64_PCIE_EXT(reg) amdgpu_reg_pcie_ext_rd64(adev, (reg))
1384#define WREG64_PCIE_EXT(reg, v) adev->pcie_wreg64_ext(adev, (reg), (v))1308#define WREG64_PCIE_EXT(reg, v) amdgpu_reg_pcie_ext_wr64(adev, (reg), (v))
1385#define RREG32_SMC(reg) adev->smc_rreg(adev, (reg))1309#define RREG32_SMC(reg) amdgpu_reg_smc_rd32(adev, (reg))
1386#define WREG32_SMC(reg, v) adev->smc_wreg(adev, (reg), (v))1310#define WREG32_SMC(reg, v) amdgpu_reg_smc_wr32(adev, (reg), (v))
1387#define RREG32_UVD_CTX(reg) adev->uvd_ctx_rreg(adev, (reg))1311#define RREG32_UVD_CTX(reg) amdgpu_reg_uvd_ctx_rd32(adev, (reg))
1388#define WREG32_UVD_CTX(reg, v) adev->uvd_ctx_wreg(adev, (reg), (v))1312#define WREG32_UVD_CTX(reg, v) amdgpu_reg_uvd_ctx_wr32(adev, (reg), (v))
1389#define RREG32_DIDT(reg) adev->didt_rreg(adev, (reg))1313#define RREG32_DIDT(reg) amdgpu_reg_didt_rd32(adev, (reg))
1390#define WREG32_DIDT(reg, v) adev->didt_wreg(adev, (reg), (v))1314#define WREG32_DIDT(reg, v) amdgpu_reg_didt_wr32(adev, (reg), (v))
1391#define RREG32_GC_CAC(reg) adev->gc_cac_rreg(adev, (reg))1315#define RREG32_GC_CAC(reg) amdgpu_reg_gc_cac_rd32(adev, (reg))
1392#define WREG32_GC_CAC(reg, v) adev->gc_cac_wreg(adev, (reg), (v))1316#define WREG32_GC_CAC(reg, v) amdgpu_reg_gc_cac_wr32(adev, (reg), (v))
1393#define RREG32_SE_CAC(reg) adev->se_cac_rreg(adev, (reg))1317#define RREG32_SE_CAC(reg) amdgpu_reg_se_cac_rd32(adev, (reg))
1394#define WREG32_SE_CAC(reg, v) adev->se_cac_wreg(adev, (reg), (v))1318#define WREG32_SE_CAC(reg, v) amdgpu_reg_se_cac_wr32(adev, (reg), (v))
1395#define RREG32_AUDIO_ENDPT(block, reg) adev->audio_endpt_rreg(adev, (block), (reg))1319#define RREG32_AUDIO_ENDPT(block, reg) \
1396#define WREG32_AUDIO_ENDPT(block, reg, v) adev->audio_endpt_wreg(adev, (block), (reg), (v))1320 amdgpu_reg_audio_endpt_rd32(adev, (block), (reg))
1321#define WREG32_AUDIO_ENDPT(block, reg, v) \
1322 amdgpu_reg_audio_endpt_wr32(adev, (block), (reg), (v))
1397#define WREG32_P(reg, val, mask) \1323#define WREG32_P(reg, val, mask) \
1398 do { \1324 do { \
1399 uint32_t tmp_ = RREG32(reg); \1325 uint32_t tmp_ = RREG32(reg); \
@@ -1523,10 +1449,6 @@ void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev, · 123 unmodified lines
1523 struct amdgpu_ring *ring);1449 struct amdgpu_ring *ring);
1524 1450
1525void amdgpu_device_halt(struct amdgpu_device *adev);1451void amdgpu_device_halt(struct amdgpu_device *adev);
1526u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
1527 u32 reg);
1528void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
1529 u32 reg, u32 v);
1530struct dma_fence *amdgpu_device_get_gang(struct amdgpu_device *adev);1452struct dma_fence *amdgpu_device_get_gang(struct amdgpu_device *adev);
1531struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,1453struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
1532 struct dma_fence *gang);1454 struct dma_fence *gang);
@@ -1536,6 +1458,8 @@ struct dma_fence *amdgpu_device_enforce_isolation(struct amdgpu_device *adev, · 3 unmodified lines
1536bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev);1458bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev);
1537ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring);1459ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring);
1538ssize_t amdgpu_show_reset_mask(char *buf, uint32_t supported_reset);1460ssize_t amdgpu_show_reset_mask(char *buf, uint32_t supported_reset);
1461void amdgpu_sdma_set_vm_pte_scheds(struct amdgpu_device *adev,
1462 const struct amdgpu_vm_pte_funcs *vm_pte_funcs);
1539 1463
1540/* atpx handler */1464/* atpx handler */
1541#if defined(CONFIG_VGA_SWITCHEROO)1465#if defined(CONFIG_VGA_SWITCHEROO)
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c+5−1
@@ -1439,7 +1439,10 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, · 1438 unmodified lines
1439 *process_info = info;1439 *process_info = info;
1440 }1440 }
1441 1441
1442 vm->process_info = *process_info;1442 if (cmpxchg(&vm->process_info, NULL, *process_info) != NULL) {
1443 ret = -EINVAL;
1444 goto already_acquired;
1445 }
1443 1446
1444 /* Validate page directory and attach eviction fence */1447 /* Validate page directory and attach eviction fence */
1445 ret = amdgpu_bo_reserve(vm->root.bo, true);1448 ret = amdgpu_bo_reserve(vm->root.bo, true);
@@ -1479,6 +1482,7 @@ validate_pd_fail: · 33 unmodified lines
1479 amdgpu_bo_unreserve(vm->root.bo);1482 amdgpu_bo_unreserve(vm->root.bo);
1480reserve_pd_fail:1483reserve_pd_fail:
1481 vm->process_info = NULL;1484 vm->process_info = NULL;
1485already_acquired:
1482 if (info) {1486 if (info) {
1483 dma_fence_put(&info->eviction_fence->base);1487 dma_fence_put(&info->eviction_fence->base);
1484 *process_info = NULL;1488 *process_info = NULL;
drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c+2−0
@@ -35,6 +35,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size, · 34 unmodified lines
35 struct dma_fence *fence;35 struct dma_fence *fence;
36 int i, r;36 int i, r;
37 37
38 mutex_lock(&adev->mman.default_entity.lock);
38 stime = ktime_get();39 stime = ktime_get();
39 for (i = 0; i < n; i++) {40 for (i = 0; i < n; i++) {
40 r = amdgpu_copy_buffer(adev, &adev->mman.default_entity,41 r = amdgpu_copy_buffer(adev, &adev->mman.default_entity,
@@ -49,6 +50,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size, · 8 unmodified lines
49 }50 }
50 51
51exit_do_move:52exit_do_move:
53 mutex_unlock(&adev->mman.default_entity.lock);
52 etime = ktime_get();54 etime = ktime_get();
53 *time_ms = ktime_ms_delta(etime, stime);55 *time_ms = ktime_ms_delta(etime, stime);
54 56
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+0−7
@@ -84,13 +84,6 @@ static int amdgpu_cs_job_idx(struct amdgpu_cs_parser *p, · 83 unmodified lines
84 if (r)84 if (r)
85 return r;85 return r;
86 86
87 /*
88 * Abort if there is no run queue associated with this entity.
89 * Possibly because of disabled HW IP.
90 */
91 if (entity->rq == NULL)
92 return -EINVAL;
93
94 /* Check if we can add this IB to some existing job */87 /* Check if we can add this IB to some existing job */
95 for (i = 0; i < p->gang_size; ++i)88 for (i = 0; i < p->gang_size; ++i)
96 if (p->entities[i] == entity)89 if (p->entities[i] == entity)
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c+7−2
@@ -231,13 +231,19 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, · 230 unmodified lines
231 } else {231 } else {
232 struct amdgpu_fpriv *fpriv;232 struct amdgpu_fpriv *fpriv;
233 233
234 fpriv = container_of(ctx->ctx_mgr, struct amdgpu_fpriv, ctx_mgr);234 /* TODO: Stop using fpriv here, we only need the xcp_id. */
235 fpriv = container_of(ctx->mgr, struct amdgpu_fpriv, ctx_mgr);
235 r = amdgpu_xcp_select_scheds(adev, hw_ip, hw_prio, fpriv,236 r = amdgpu_xcp_select_scheds(adev, hw_ip, hw_prio, fpriv,
236 &num_scheds, &scheds);237 &num_scheds, &scheds);
237 if (r)238 if (r)
238 goto error_free_entity;239 goto error_free_entity;
239 }240 }
240 241
242 if (num_scheds == 0) {
243 r = -EINVAL;
244 goto error_free_entity;
245 }
246
241 /* disable load balance if the hw engine retains context among dependent jobs */247 /* disable load balance if the hw engine retains context among dependent jobs */
242 if (hw_ip == AMDGPU_HW_IP_VCN_ENC ||248 if (hw_ip == AMDGPU_HW_IP_VCN_ENC ||
243 hw_ip == AMDGPU_HW_IP_VCN_DEC ||249 hw_ip == AMDGPU_HW_IP_VCN_DEC ||
@@ -348,7 +354,6 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority, · 104 unmodified lines
348 else354 else
349 ctx->stable_pstate = current_stable_pstate;355 ctx->stable_pstate = current_stable_pstate;
350 356
351 ctx->ctx_mgr = &(fpriv->ctx_mgr);
352 return 0;357 return 0;
353}358}
354 359
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h+6−7
@@ -44,20 +44,19 @@ struct amdgpu_ctx_entity { · 43 unmodified lines
44 44
45struct amdgpu_ctx {45struct amdgpu_ctx {
46 struct kref refcount;46 struct kref refcount;
47 struct amdgpu_ctx_mgr *mgr;47 spinlock_t ring_lock;
48 unsigned reset_counter;48 unsigned reset_counter;
49 unsigned reset_counter_query;49 unsigned reset_counter_query;
50 uint64_t generation;
51 spinlock_t ring_lock;
52 struct amdgpu_ctx_entity *entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM];
53 bool preamble_presented;
54 int32_t init_priority;50 int32_t init_priority;
55 int32_t override_priority;51 int32_t override_priority;
52 uint32_t stable_pstate;
56 atomic_t guilty;53 atomic_t guilty;
54 bool preamble_presented;
55 uint64_t generation;
57 unsigned long ras_counter_ce;56 unsigned long ras_counter_ce;
58 unsigned long ras_counter_ue;57 unsigned long ras_counter_ue;
59 uint32_t stable_pstate;58 struct amdgpu_ctx_mgr *mgr;
60 struct amdgpu_ctx_mgr *ctx_mgr;59 struct amdgpu_ctx_entity *entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM];
61};60};
62 61
63struct amdgpu_ctx_mgr {62struct amdgpu_ctx_mgr {
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c+4−4
@@ -638,7 +638,7 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, · 637 unmodified lines
638 if (size & 0x3 || *pos & 0x3)638 if (size & 0x3 || *pos & 0x3)
639 return -EINVAL;639 return -EINVAL;
640 640
641 if (!adev->didt_rreg)641 if (!adev->reg.didt.rreg)
642 return -EOPNOTSUPP;642 return -EOPNOTSUPP;
643 643
644 r = pm_runtime_get_sync(adev_to_drm(adev)->dev);644 r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
@@ -696,7 +696,7 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user · 51 unmodified lines
696 if (size & 0x3 || *pos & 0x3)696 if (size & 0x3 || *pos & 0x3)
697 return -EINVAL;697 return -EINVAL;
698 698
699 if (!adev->didt_wreg)699 if (!adev->reg.didt.wreg)
700 return -EOPNOTSUPP;700 return -EOPNOTSUPP;
701 701
702 r = pm_runtime_get_sync(adev_to_drm(adev)->dev);702 r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
@@ -752,7 +752,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, · 49 unmodified lines
752 ssize_t result = 0;752 ssize_t result = 0;
753 int r;753 int r;
754 754
755 if (!adev->smc_rreg)755 if (!adev->reg.smc.rreg)
756 return -EOPNOTSUPP;756 return -EOPNOTSUPP;
757 757
758 if (size & 0x3 || *pos & 0x3)758 if (size & 0x3 || *pos & 0x3)
@@ -810,7 +810,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * · 51 unmodified lines
810 ssize_t result = 0;810 ssize_t result = 0;
811 int r;811 int r;
812 812
813 if (!adev->smc_wreg)813 if (!adev->reg.smc.wreg)
814 return -EOPNOTSUPP;814 return -EOPNOTSUPP;
815 815
816 if (size & 0x3 || *pos & 0x3)816 if (size & 0x3 || *pos & 0x3)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c+7−807
@@ -846,558 +846,6 @@ bool amdgpu_device_skip_hw_access(struct amdgpu_device *adev) · 845 unmodified lines
846 return false;846 return false;
847}847}
848 848
849/**
850 * amdgpu_device_rreg - read a memory mapped IO or indirect register
851 *
852 * @adev: amdgpu_device pointer
853 * @reg: dword aligned register offset
854 * @acc_flags: access flags which require special behavior
855 *
856 * Returns the 32 bit value from the offset specified.
857 */
858uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
859 uint32_t reg, uint32_t acc_flags)
860{
861 uint32_t ret;
862
863 if (amdgpu_device_skip_hw_access(adev))
864 return 0;
865
866 if ((reg * 4) < adev->rmmio_size) {
867 if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
868 amdgpu_sriov_runtime(adev) &&
869 down_read_trylock(&adev->reset_domain->sem)) {
870 ret = amdgpu_kiq_rreg(adev, reg, 0);
871 up_read(&adev->reset_domain->sem);
872 } else {
873 ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
874 }
875 } else {
876 ret = adev->pcie_rreg(adev, reg * 4);
877 }
878
879 trace_amdgpu_device_rreg(adev->pdev->device, reg, ret);
880
881 return ret;
882}
883
884/*
885 * MMIO register read with bytes helper functions
886 * @offset:bytes offset from MMIO start
887 */
888
889/**
890 * amdgpu_mm_rreg8 - read a memory mapped IO register
891 *
892 * @adev: amdgpu_device pointer
893 * @offset: byte aligned register offset
894 *
895 * Returns the 8 bit value from the offset specified.
896 */
897uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset)
898{
899 if (amdgpu_device_skip_hw_access(adev))
900 return 0;
901
902 if (offset < adev->rmmio_size)
903 return (readb(adev->rmmio + offset));
904 BUG();
905}
906
907
908/**
909 * amdgpu_device_xcc_rreg - read a memory mapped IO or indirect register with specific XCC
910 *
911 * @adev: amdgpu_device pointer
912 * @reg: dword aligned register offset
913 * @acc_flags: access flags which require special behavior
914 * @xcc_id: xcc accelerated compute core id
915 *
916 * Returns the 32 bit value from the offset specified.
917 */
918uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev,
919 uint32_t reg, uint32_t acc_flags,
920 uint32_t xcc_id)
921{
922 uint32_t ret, rlcg_flag;
923
924 if (amdgpu_device_skip_hw_access(adev))
925 return 0;
926
927 if ((reg * 4) < adev->rmmio_size) {
928 if (amdgpu_sriov_vf(adev) &&
929 !amdgpu_sriov_runtime(adev) &&
930 adev->gfx.rlc.rlcg_reg_access_supported &&
931 amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags,
932 GC_HWIP, false,
933 &rlcg_flag)) {
934 ret = amdgpu_virt_rlcg_reg_rw(adev, reg, 0, rlcg_flag, GET_INST(GC, xcc_id));
935 } else if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
936 amdgpu_sriov_runtime(adev) &&
937 down_read_trylock(&adev->reset_domain->sem)) {
938 ret = amdgpu_kiq_rreg(adev, reg, xcc_id);
939 up_read(&adev->reset_domain->sem);
940 } else {
941 ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
942 }
943 } else {
944 ret = adev->pcie_rreg(adev, reg * 4);
945 }
946
947 return ret;
948}
949
950/*
951 * MMIO register write with bytes helper functions
952 * @offset:bytes offset from MMIO start
953 * @value: the value want to be written to the register
954 */
955
956/**
957 * amdgpu_mm_wreg8 - read a memory mapped IO register
958 *
959 * @adev: amdgpu_device pointer
960 * @offset: byte aligned register offset
961 * @value: 8 bit value to write
962 *
963 * Writes the value specified to the offset specified.
964 */
965void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
966{
967 if (amdgpu_device_skip_hw_access(adev))
968 return;
969
970 if (offset < adev->rmmio_size)
971 writeb(value, adev->rmmio + offset);
972 else
973 BUG();
974}
975
976/**
977 * amdgpu_device_wreg - write to a memory mapped IO or indirect register
978 *
979 * @adev: amdgpu_device pointer
980 * @reg: dword aligned register offset
981 * @v: 32 bit value to write to the register
982 * @acc_flags: access flags which require special behavior
983 *
984 * Writes the value specified to the offset specified.
985 */
986void amdgpu_device_wreg(struct amdgpu_device *adev,
987 uint32_t reg, uint32_t v,
988 uint32_t acc_flags)
989{
990 if (amdgpu_device_skip_hw_access(adev))
991 return;
992
993 if ((reg * 4) < adev->rmmio_size) {
994 if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
995 amdgpu_sriov_runtime(adev) &&
996 down_read_trylock(&adev->reset_domain->sem)) {
997 amdgpu_kiq_wreg(adev, reg, v, 0);
998 up_read(&adev->reset_domain->sem);
999 } else {
1000 writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
1001 }
1002 } else {
1003 adev->pcie_wreg(adev, reg * 4, v);
1004 }
1005
1006 trace_amdgpu_device_wreg(adev->pdev->device, reg, v);
1007}
1008
1009/**
1010 * amdgpu_mm_wreg_mmio_rlc - write register either with direct/indirect mmio or with RLC path if in range
1011 *
1012 * @adev: amdgpu_device pointer
1013 * @reg: mmio/rlc register
1014 * @v: value to write
1015 * @xcc_id: xcc accelerated compute core id
1016 *
1017 * this function is invoked only for the debugfs register access
1018 */
1019void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
1020 uint32_t reg, uint32_t v,
1021 uint32_t xcc_id)
1022{
1023 if (amdgpu_device_skip_hw_access(adev))
1024 return;
1025
1026 if (amdgpu_sriov_fullaccess(adev) &&
1027 adev->gfx.rlc.funcs &&
1028 adev->gfx.rlc.funcs->is_rlcg_access_range) {
1029 if (adev->gfx.rlc.funcs->is_rlcg_access_range(adev, reg))
1030 return amdgpu_sriov_wreg(adev, reg, v, 0, 0, xcc_id);
1031 } else if ((reg * 4) >= adev->rmmio_size) {
1032 adev->pcie_wreg(adev, reg * 4, v);
1033 } else {
1034 writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
1035 }
1036}
1037
1038/**
1039 * amdgpu_device_xcc_wreg - write to a memory mapped IO or indirect register with specific XCC
1040 *
1041 * @adev: amdgpu_device pointer
1042 * @reg: dword aligned register offset
1043 * @v: 32 bit value to write to the register
1044 * @acc_flags: access flags which require special behavior
1045 * @xcc_id: xcc accelerated compute core id
1046 *
1047 * Writes the value specified to the offset specified.
1048 */
1049void amdgpu_device_xcc_wreg(struct amdgpu_device *adev,
1050 uint32_t reg, uint32_t v,
1051 uint32_t acc_flags, uint32_t xcc_id)
1052{
1053 uint32_t rlcg_flag;
1054
1055 if (amdgpu_device_skip_hw_access(adev))
1056 return;
1057
1058 if ((reg * 4) < adev->rmmio_size) {
1059 if (amdgpu_sriov_vf(adev) &&
1060 !amdgpu_sriov_runtime(adev) &&
1061 adev->gfx.rlc.rlcg_reg_access_supported &&
1062 amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags,
1063 GC_HWIP, true,
1064 &rlcg_flag)) {
1065 amdgpu_virt_rlcg_reg_rw(adev, reg, v, rlcg_flag, GET_INST(GC, xcc_id));
1066 } else if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
1067 amdgpu_sriov_runtime(adev) &&
1068 down_read_trylock(&adev->reset_domain->sem)) {
1069 amdgpu_kiq_wreg(adev, reg, v, xcc_id);
1070 up_read(&adev->reset_domain->sem);
1071 } else {
1072 writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
1073 }
1074 } else {
1075 adev->pcie_wreg(adev, reg * 4, v);
1076 }
1077}
1078
1079/**
1080 * amdgpu_device_indirect_rreg - read an indirect register
1081 *
1082 * @adev: amdgpu_device pointer
1083 * @reg_addr: indirect register address to read from
1084 *
1085 * Returns the value of indirect register @reg_addr
1086 */
1087u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
1088 u32 reg_addr)
1089{
1090 unsigned long flags, pcie_index, pcie_data;
1091 void __iomem *pcie_index_offset;
1092 void __iomem *pcie_data_offset;
1093 u32 r;
1094
1095 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
1096 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
1097
1098 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1099 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
1100 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
1101
1102 writel(reg_addr, pcie_index_offset);
1103 readl(pcie_index_offset);
1104 r = readl(pcie_data_offset);
1105 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1106
1107 return r;
1108}
1109
1110u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,
1111 u64 reg_addr)
1112{
1113 unsigned long flags, pcie_index, pcie_index_hi, pcie_data;
1114 u32 r;
1115 void __iomem *pcie_index_offset;
1116 void __iomem *pcie_index_hi_offset;
1117 void __iomem *pcie_data_offset;
1118
1119 if (unlikely(!adev->nbio.funcs)) {
1120 pcie_index = AMDGPU_PCIE_INDEX_FALLBACK;
1121 pcie_data = AMDGPU_PCIE_DATA_FALLBACK;
1122 } else {
1123 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
1124 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
1125 }
1126
1127 if (reg_addr >> 32) {
1128 if (unlikely(!adev->nbio.funcs))
1129 pcie_index_hi = AMDGPU_PCIE_INDEX_HI_FALLBACK;
1130 else
1131 pcie_index_hi = adev->nbio.funcs->get_pcie_index_hi_offset(adev);
1132 } else {
1133 pcie_index_hi = 0;
1134 }
1135
1136 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1137 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
1138 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
1139 if (pcie_index_hi != 0)
1140 pcie_index_hi_offset = (void __iomem *)adev->rmmio +
1141 pcie_index_hi * 4;
1142
1143 writel(reg_addr, pcie_index_offset);
1144 readl(pcie_index_offset);
1145 if (pcie_index_hi != 0) {
1146 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
1147 readl(pcie_index_hi_offset);
1148 }
1149 r = readl(pcie_data_offset);
1150
1151 /* clear the high bits */
1152 if (pcie_index_hi != 0) {
1153 writel(0, pcie_index_hi_offset);
1154 readl(pcie_index_hi_offset);
1155 }
1156
1157 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1158
1159 return r;
1160}
1161
1162/**
1163 * amdgpu_device_indirect_rreg64 - read a 64bits indirect register
1164 *
1165 * @adev: amdgpu_device pointer
1166 * @reg_addr: indirect register address to read from
1167 *
1168 * Returns the value of indirect register @reg_addr
1169 */
1170u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
1171 u32 reg_addr)
1172{
1173 unsigned long flags, pcie_index, pcie_data;
1174 void __iomem *pcie_index_offset;
1175 void __iomem *pcie_data_offset;
1176 u64 r;
1177
1178 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
1179 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
1180
1181 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1182 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
1183 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
1184
1185 /* read low 32 bits */
1186 writel(reg_addr, pcie_index_offset);
1187 readl(pcie_index_offset);
1188 r = readl(pcie_data_offset);
1189 /* read high 32 bits */
1190 writel(reg_addr + 4, pcie_index_offset);
1191 readl(pcie_index_offset);
1192 r |= ((u64)readl(pcie_data_offset) << 32);
1193 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1194
1195 return r;
1196}
1197
1198u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev,
1199 u64 reg_addr)
1200{
1201 unsigned long flags, pcie_index, pcie_data;
1202 unsigned long pcie_index_hi = 0;
1203 void __iomem *pcie_index_offset;
1204 void __iomem *pcie_index_hi_offset;
1205 void __iomem *pcie_data_offset;
1206 u64 r;
1207
1208 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
1209 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
1210 if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
1211 pcie_index_hi = adev->nbio.funcs->get_pcie_index_hi_offset(adev);
1212
1213 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1214 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
1215 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
1216 if (pcie_index_hi != 0)
1217 pcie_index_hi_offset = (void __iomem *)adev->rmmio +
1218 pcie_index_hi * 4;
1219
1220 /* read low 32 bits */
1221 writel(reg_addr, pcie_index_offset);
1222 readl(pcie_index_offset);
1223 if (pcie_index_hi != 0) {
1224 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
1225 readl(pcie_index_hi_offset);
1226 }
1227 r = readl(pcie_data_offset);
1228 /* read high 32 bits */
1229 writel(reg_addr + 4, pcie_index_offset);
1230 readl(pcie_index_offset);
1231 if (pcie_index_hi != 0) {
1232 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
1233 readl(pcie_index_hi_offset);
1234 }
1235 r |= ((u64)readl(pcie_data_offset) << 32);
1236
1237 /* clear the high bits */
1238 if (pcie_index_hi != 0) {
1239 writel(0, pcie_index_hi_offset);
1240 readl(pcie_index_hi_offset);
1241 }
1242
1243 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1244
1245 return r;
1246}
1247
1248/**
1249 * amdgpu_device_indirect_wreg - write an indirect register address
1250 *
1251 * @adev: amdgpu_device pointer
1252 * @reg_addr: indirect register offset
1253 * @reg_data: indirect register data
1254 *
1255 */
1256void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
1257 u32 reg_addr, u32 reg_data)
1258{
1259 unsigned long flags, pcie_index, pcie_data;
1260 void __iomem *pcie_index_offset;
1261 void __iomem *pcie_data_offset;
1262
1263 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
1264 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
1265
1266 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1267 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
1268 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
1269
1270 writel(reg_addr, pcie_index_offset);
1271 readl(pcie_index_offset);
1272 writel(reg_data, pcie_data_offset);
1273 readl(pcie_data_offset);
1274 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1275}
1276
1277void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
1278 u64 reg_addr, u32 reg_data)
1279{
1280 unsigned long flags, pcie_index, pcie_index_hi, pcie_data;
1281 void __iomem *pcie_index_offset;
1282 void __iomem *pcie_index_hi_offset;
1283 void __iomem *pcie_data_offset;
1284
1285 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
1286 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
1287 if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
1288 pcie_index_hi = adev->nbio.funcs->get_pcie_index_hi_offset(adev);
1289 else
1290 pcie_index_hi = 0;
1291
1292 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1293 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
1294 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
1295 if (pcie_index_hi != 0)
1296 pcie_index_hi_offset = (void __iomem *)adev->rmmio +
1297 pcie_index_hi * 4;
1298
1299 writel(reg_addr, pcie_index_offset);
1300 readl(pcie_index_offset);
1301 if (pcie_index_hi != 0) {
1302 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
1303 readl(pcie_index_hi_offset);
1304 }
1305 writel(reg_data, pcie_data_offset);
1306 readl(pcie_data_offset);
1307
1308 /* clear the high bits */
1309 if (pcie_index_hi != 0) {
1310 writel(0, pcie_index_hi_offset);
1311 readl(pcie_index_hi_offset);
1312 }
1313
1314 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1315}
1316
1317/**
1318 * amdgpu_device_indirect_wreg64 - write a 64bits indirect register address
1319 *
1320 * @adev: amdgpu_device pointer
1321 * @reg_addr: indirect register offset
1322 * @reg_data: indirect register data
1323 *
1324 */
1325void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
1326 u32 reg_addr, u64 reg_data)
1327{
1328 unsigned long flags, pcie_index, pcie_data;
1329 void __iomem *pcie_index_offset;
1330 void __iomem *pcie_data_offset;
1331
1332 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
1333 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
1334
1335 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1336 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
1337 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
1338
1339 /* write low 32 bits */
1340 writel(reg_addr, pcie_index_offset);
1341 readl(pcie_index_offset);
1342 writel((u32)(reg_data & 0xffffffffULL), pcie_data_offset);
1343 readl(pcie_data_offset);
1344 /* write high 32 bits */
1345 writel(reg_addr + 4, pcie_index_offset);
1346 readl(pcie_index_offset);
1347 writel((u32)(reg_data >> 32), pcie_data_offset);
1348 readl(pcie_data_offset);
1349 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1350}
1351
1352void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev,
1353 u64 reg_addr, u64 reg_data)
1354{
1355 unsigned long flags, pcie_index, pcie_data;
1356 unsigned long pcie_index_hi = 0;
1357 void __iomem *pcie_index_offset;
1358 void __iomem *pcie_index_hi_offset;
1359 void __iomem *pcie_data_offset;
1360
1361 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
1362 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
1363 if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
1364 pcie_index_hi = adev->nbio.funcs->get_pcie_index_hi_offset(adev);
1365
1366 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1367 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
1368 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
1369 if (pcie_index_hi != 0)
1370 pcie_index_hi_offset = (void __iomem *)adev->rmmio +
1371 pcie_index_hi * 4;
1372
1373 /* write low 32 bits */
1374 writel(reg_addr, pcie_index_offset);
1375 readl(pcie_index_offset);
1376 if (pcie_index_hi != 0) {
1377 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
1378 readl(pcie_index_hi_offset);
1379 }
1380 writel((u32)(reg_data & 0xffffffffULL), pcie_data_offset);
1381 readl(pcie_data_offset);
1382 /* write high 32 bits */
1383 writel(reg_addr + 4, pcie_index_offset);
1384 readl(pcie_index_offset);
1385 if (pcie_index_hi != 0) {
1386 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
1387 readl(pcie_index_hi_offset);
1388 }
1389 writel((u32)(reg_data >> 32), pcie_data_offset);
1390 readl(pcie_data_offset);
1391
1392 /* clear the high bits */
1393 if (pcie_index_hi != 0) {
1394 writel(0, pcie_index_hi_offset);
1395 readl(pcie_index_hi_offset);
1396 }
1397
1398 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1399}
1400
1401/**849/**
1402 * amdgpu_device_get_rev_id - query device rev_id850 * amdgpu_device_get_rev_id - query device rev_id
1403 *851 *
@@ -1410,149 +858,6 @@ u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev) · 6 unmodified lines
1410 return adev->nbio.funcs->get_rev_id(adev);858 return adev->nbio.funcs->get_rev_id(adev);
1411}859}
1412 860
1413/**
1414 * amdgpu_invalid_rreg - dummy reg read function
1415 *
1416 * @adev: amdgpu_device pointer
1417 * @reg: offset of register
1418 *
1419 * Dummy register read function. Used for register blocks
1420 * that certain asics don't have (all asics).
1421 * Returns the value in the register.
1422 */
1423static uint32_t amdgpu_invalid_rreg(struct amdgpu_device *adev, uint32_t reg)
1424{
1425 dev_err(adev->dev, "Invalid callback to read register 0x%04X\n", reg);
1426 BUG();
1427 return 0;
1428}
1429
1430static uint32_t amdgpu_invalid_rreg_ext(struct amdgpu_device *adev, uint64_t reg)
1431{
1432 dev_err(adev->dev, "Invalid callback to read register 0x%llX\n", reg);
1433 BUG();
1434 return 0;
1435}
1436
1437/**
1438 * amdgpu_invalid_wreg - dummy reg write function
1439 *
1440 * @adev: amdgpu_device pointer
1441 * @reg: offset of register
1442 * @v: value to write to the register
1443 *
1444 * Dummy register read function. Used for register blocks
1445 * that certain asics don't have (all asics).
1446 */
1447static void amdgpu_invalid_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
1448{
1449 dev_err(adev->dev,
1450 "Invalid callback to write register 0x%04X with 0x%08X\n", reg,
1451 v);
1452 BUG();
1453}
1454
1455static void amdgpu_invalid_wreg_ext(struct amdgpu_device *adev, uint64_t reg, uint32_t v)
1456{
1457 dev_err(adev->dev,
1458 "Invalid callback to write register 0x%llX with 0x%08X\n", reg,
1459 v);
1460 BUG();
1461}
1462
1463/**
1464 * amdgpu_invalid_rreg64 - dummy 64 bit reg read function
1465 *
1466 * @adev: amdgpu_device pointer
1467 * @reg: offset of register
1468 *
1469 * Dummy register read function. Used for register blocks
1470 * that certain asics don't have (all asics).
1471 * Returns the value in the register.
1472 */
1473static uint64_t amdgpu_invalid_rreg64(struct amdgpu_device *adev, uint32_t reg)
1474{
1475 dev_err(adev->dev, "Invalid callback to read 64 bit register 0x%04X\n",
1476 reg);
1477 BUG();
1478 return 0;
1479}
1480
1481static uint64_t amdgpu_invalid_rreg64_ext(struct amdgpu_device *adev, uint64_t reg)
1482{
1483 dev_err(adev->dev, "Invalid callback to read register 0x%llX\n", reg);
1484 BUG();
1485 return 0;
1486}
1487
1488/**
1489 * amdgpu_invalid_wreg64 - dummy reg write function
1490 *
1491 * @adev: amdgpu_device pointer
1492 * @reg: offset of register
1493 * @v: value to write to the register
1494 *
1495 * Dummy register read function. Used for register blocks
1496 * that certain asics don't have (all asics).
1497 */
1498static void amdgpu_invalid_wreg64(struct amdgpu_device *adev, uint32_t reg, uint64_t v)
1499{
1500 dev_err(adev->dev,
1501 "Invalid callback to write 64 bit register 0x%04X with 0x%08llX\n",
1502 reg, v);
1503 BUG();
1504}
1505
1506static void amdgpu_invalid_wreg64_ext(struct amdgpu_device *adev, uint64_t reg, uint64_t v)
1507{
1508 dev_err(adev->dev,
1509 "Invalid callback to write 64 bit register 0x%llX with 0x%08llX\n",
1510 reg, v);
1511 BUG();
1512}
1513
1514/**
1515 * amdgpu_block_invalid_rreg - dummy reg read function
1516 *
1517 * @adev: amdgpu_device pointer
1518 * @block: offset of instance
1519 * @reg: offset of register
1520 *
1521 * Dummy register read function. Used for register blocks
1522 * that certain asics don't have (all asics).
1523 * Returns the value in the register.
1524 */
1525static uint32_t amdgpu_block_invalid_rreg(struct amdgpu_device *adev,
1526 uint32_t block, uint32_t reg)
1527{
1528 dev_err(adev->dev,
1529 "Invalid callback to read register 0x%04X in block 0x%04X\n",
1530 reg, block);
1531 BUG();
1532 return 0;
1533}
1534
1535/**
1536 * amdgpu_block_invalid_wreg - dummy reg write function
1537 *
1538 * @adev: amdgpu_device pointer
1539 * @block: offset of instance
1540 * @reg: offset of register
1541 * @v: value to write to the register
1542 *
1543 * Dummy register read function. Used for register blocks
1544 * that certain asics don't have (all asics).
1545 */
1546static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev,
1547 uint32_t block,
1548 uint32_t reg, uint32_t v)
1549{
1550 dev_err(adev->dev,
1551 "Invalid block callback to write register 0x%04X in block 0x%04X with 0x%08X\n",
1552 reg, block, v);
1553 BUG();
1554}
1555
1556static uint32_t amdgpu_device_get_vbios_flags(struct amdgpu_device *adev)861static uint32_t amdgpu_device_get_vbios_flags(struct amdgpu_device *adev)
1557{862{
1558 if (hweight32(adev->aid_mask) && (adev->flags & AMD_IS_APU))863 if (hweight32(adev->aid_mask) && (adev->flags & AMD_IS_APU))
@@ -3156,9 +2461,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) · 1597 unmodified lines
3156 if (r)2461 if (r)
3157 goto init_failed;2462 goto init_failed;
3158 2463
3159 if (adev->mman.buffer_funcs_ring &&2464 amdgpu_ttm_set_buffer_funcs_status(adev, true);
3160 adev->mman.buffer_funcs_ring->sched.ready)
3161 amdgpu_ttm_set_buffer_funcs_status(adev, true);
3162 2465
3163 /* Don't init kfd if whole hive need to be reset during init */2466 /* Don't init kfd if whole hive need to be reset during init */
3164 if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {2467 if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
@@ -4047,8 +3350,7 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev) · 882 unmodified lines
4047 3350
4048 r = amdgpu_device_ip_resume_phase2(adev);3351 r = amdgpu_device_ip_resume_phase2(adev);
4049 3352
4050 if (adev->mman.buffer_funcs_ring->sched.ready)3353 amdgpu_ttm_set_buffer_funcs_status(adev, true);
4051 amdgpu_ttm_set_buffer_funcs_status(adev, true);
4052 3354
4053 if (r)3355 if (r)
4054 return r;3356 return r;
@@ -4108,17 +3410,6 @@ bool amdgpu_device_asic_has_dc_support(struct pci_dev *pdev, · 53 unmodified lines
4108 case CHIP_VERDE:3410 case CHIP_VERDE:
4109 case CHIP_OLAND:3411 case CHIP_OLAND:
4110 return amdgpu_dc != 0 && IS_ENABLED(CONFIG_DRM_AMD_DC_SI);3412 return amdgpu_dc != 0 && IS_ENABLED(CONFIG_DRM_AMD_DC_SI);
4111 case CHIP_KAVERI:
4112 case CHIP_KABINI:
4113 case CHIP_MULLINS:
4114 /*
4115 * We have systems in the wild with these ASICs that require
4116 * TRAVIS and NUTMEG support which is not supported with DC.
4117 *
4118 * Fallback to the non-DC driver here by default so as not to
4119 * cause regressions.
4120 */
4121 return amdgpu_dc > 0;
4122 default:3413 default:
4123 return amdgpu_dc != 0;3414 return amdgpu_dc != 0;
4124#else3415#else
@@ -4396,26 +3687,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 271 unmodified lines
4396 adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS);3687 adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS);
4397 bitmap_zero(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);3688 bitmap_zero(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
4398 3689
4399 adev->smc_rreg = &amdgpu_invalid_rreg;3690 amdgpu_reg_access_init(adev);
4400 adev->smc_wreg = &amdgpu_invalid_wreg;
4401 adev->pcie_rreg = &amdgpu_invalid_rreg;
4402 adev->pcie_wreg = &amdgpu_invalid_wreg;
4403 adev->pcie_rreg_ext = &amdgpu_invalid_rreg_ext;
4404 adev->pcie_wreg_ext = &amdgpu_invalid_wreg_ext;
4405 adev->pciep_rreg = &amdgpu_invalid_rreg;
4406 adev->pciep_wreg = &amdgpu_invalid_wreg;
4407 adev->pcie_rreg64 = &amdgpu_invalid_rreg64;
4408 adev->pcie_wreg64 = &amdgpu_invalid_wreg64;
4409 adev->pcie_rreg64_ext = &amdgpu_invalid_rreg64_ext;
4410 adev->pcie_wreg64_ext = &amdgpu_invalid_wreg64_ext;
4411 adev->uvd_ctx_rreg = &amdgpu_invalid_rreg;
4412 adev->uvd_ctx_wreg = &amdgpu_invalid_wreg;
4413 adev->didt_rreg = &amdgpu_invalid_rreg;
4414 adev->didt_wreg = &amdgpu_invalid_wreg;
4415 adev->gc_cac_rreg = &amdgpu_invalid_rreg;
4416 adev->gc_cac_wreg = &amdgpu_invalid_wreg;
4417 adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg;
4418 adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg;
4419 3691
4420 dev_info(3692 dev_info(
4421 adev->dev,3693 adev->dev,
@@ -4460,13 +3732,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 38 unmodified lines
4460 return r;3732 return r;
4461 3733
4462 spin_lock_init(&adev->mmio_idx_lock);3734 spin_lock_init(&adev->mmio_idx_lock);
4463 spin_lock_init(&adev->smc_idx_lock);
4464 spin_lock_init(&adev->pcie_idx_lock);
4465 spin_lock_init(&adev->uvd_ctx_idx_lock);
4466 spin_lock_init(&adev->didt_idx_lock);
4467 spin_lock_init(&adev->gc_cac_idx_lock);
4468 spin_lock_init(&adev->se_cac_idx_lock);
4469 spin_lock_init(&adev->audio_endpt_idx_lock);
4470 spin_lock_init(&adev->mm_stats.lock);3735 spin_lock_init(&adev->mm_stats.lock);
4471 spin_lock_init(&adev->virt.rlcg_reg_lock);3736 spin_lock_init(&adev->virt.rlcg_reg_lock);
4472 spin_lock_init(&adev->wb.lock);3737 spin_lock_init(&adev->wb.lock);
@@ -5195,8 +4460,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients) · 722 unmodified lines
5195 return 0;4460 return 0;
5196 4461
5197unwind_evict:4462unwind_evict:
5198 if (adev->mman.buffer_funcs_ring->sched.ready)4463 amdgpu_ttm_set_buffer_funcs_status(adev, true);
5199 amdgpu_ttm_set_buffer_funcs_status(adev, true);
5200 amdgpu_fence_driver_hw_init(adev);4464 amdgpu_fence_driver_hw_init(adev);
5201 4465
5202unwind_userq:4466unwind_userq:
@@ -5930,8 +5194,7 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context) · 727 unmodified lines
5930 if (r)5194 if (r)
5931 goto out;5195 goto out;
5932 5196
5933 if (tmp_adev->mman.buffer_funcs_ring->sched.ready)5197 amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
5934 amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
5935 5198
5936 r = amdgpu_device_ip_resume_phase3(tmp_adev);5199 r = amdgpu_device_ip_resume_phase3(tmp_adev);
5937 if (r)5200 if (r)
@@ -6309,7 +5572,7 @@ static void amdgpu_device_halt_activities(struct amdgpu_device *adev, · 371 unmodified lines
6309 if (!amdgpu_ring_sched_ready(ring))5572 if (!amdgpu_ring_sched_ready(ring))
6310 continue;5573 continue;
6311 5574
6312 drm_sched_stop(&ring->sched, job ? &job->base : NULL);5575 drm_sched_wqueue_stop(&ring->sched);
6313 5576
6314 if (need_emergency_restart)5577 if (need_emergency_restart)
6315 amdgpu_job_stop_all_jobs_on_sched(&ring->sched);5578 amdgpu_job_stop_all_jobs_on_sched(&ring->sched);
@@ -6393,7 +5656,7 @@ static int amdgpu_device_sched_resume(struct list_head *device_list, · 77 unmodified lines
6393 if (!amdgpu_ring_sched_ready(ring))5656 if (!amdgpu_ring_sched_ready(ring))
6394 continue;5657 continue;
6395 5658
6396 drm_sched_start(&ring->sched, 0);5659 drm_sched_wqueue_start(&ring->sched);
6397 }5660 }
6398 5661
6399 if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled)5662 if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled)
@@ -7376,39 +6639,6 @@ void amdgpu_device_halt(struct amdgpu_device *adev) · 976 unmodified lines
7376 pci_wait_for_pending_transaction(pdev);6639 pci_wait_for_pending_transaction(pdev);
7377}6640}
7378 6641
7379u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
7380 u32 reg)
7381{
7382 unsigned long flags, address, data;
7383 u32 r;
7384
7385 address = adev->nbio.funcs->get_pcie_port_index_offset(adev);
7386 data = adev->nbio.funcs->get_pcie_port_data_offset(adev);
7387
7388 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
7389 WREG32(address, reg * 4);
7390 (void)RREG32(address);
7391 r = RREG32(data);
7392 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
7393 return r;
7394}
7395
7396void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
7397 u32 reg, u32 v)
7398{
7399 unsigned long flags, address, data;
7400
7401 address = adev->nbio.funcs->get_pcie_port_index_offset(adev);
7402 data = adev->nbio.funcs->get_pcie_port_data_offset(adev);
7403
7404 spin_lock_irqsave(&adev->pcie_idx_lock, flags);
7405 WREG32(address, reg * 4);
7406 (void)RREG32(address);
7407 WREG32(data, v);
7408 (void)RREG32(data);
7409 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
7410}
7411
7412/**6642/**
7413 * amdgpu_device_get_gang - return a reference to the current gang6643 * amdgpu_device_get_gang - return a reference to the current gang
7414 * @adev: amdgpu_device pointer6644 * @adev: amdgpu_device pointer
@@ -7591,36 +6821,6 @@ bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev) · 176 unmodified lines
7591 }6821 }
7592}6822}
7593 6823
7594uint32_t amdgpu_device_wait_on_rreg(struct amdgpu_device *adev,
7595 uint32_t inst, uint32_t reg_addr, char reg_name[],
7596 uint32_t expected_value, uint32_t mask)
7597{
7598 uint32_t ret = 0;
7599 uint32_t old_ = 0;
7600 uint32_t tmp_ = RREG32(reg_addr);
7601 uint32_t loop = adev->usec_timeout;
7602
7603 while ((tmp_ & (mask)) != (expected_value)) {
7604 if (old_ != tmp_) {
7605 loop = adev->usec_timeout;
7606 old_ = tmp_;
7607 } else
7608 udelay(1);
7609 tmp_ = RREG32(reg_addr);
7610 loop--;
7611 if (!loop) {
7612 dev_warn(
7613 adev->dev,
7614 "Register(%d) [%s] failed to reach value 0x%08x != 0x%08xn",
7615 inst, reg_name, (uint32_t)expected_value,
7616 (uint32_t)(tmp_ & (mask)));
7617 ret = -ETIMEDOUT;
7618 break;
7619 }
7620 }
7621 return ret;
7622}
7623
7624ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring)6824ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring)
7625{6825{
7626 ssize_t size = 0;6826 ssize_t size = 0;
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c+1−0
@@ -2298,6 +2298,7 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev) · 2297 unmodified lines
2298 case IP_VERSION(3, 5, 1):2298 case IP_VERSION(3, 5, 1):
2299 case IP_VERSION(3, 6, 0):2299 case IP_VERSION(3, 6, 0):
2300 case IP_VERSION(4, 1, 0):2300 case IP_VERSION(4, 1, 0):
2301 case IP_VERSION(4, 2, 0):
2301 /* TODO: Fix IP version. DC code expects version 4.0.1 */2302 /* TODO: Fix IP version. DC code expects version 4.0.1 */
2302 if (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(4, 1, 0))2303 if (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(4, 1, 0))
2303 adev->ip_versions[DCE_HWIP][0] = IP_VERSION(4, 0, 1);2304 adev->ip_versions[DCE_HWIP][0] = IP_VERSION(4, 0, 1);
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+0−20
@@ -223,9 +223,7 @@ uint amdgpu_dc_visual_confirm; · 222 unmodified lines
223int amdgpu_async_gfx_ring = 1;223int amdgpu_async_gfx_ring = 1;
224int amdgpu_mcbp = -1;224int amdgpu_mcbp = -1;
225int amdgpu_discovery = -1;225int amdgpu_discovery = -1;
226int amdgpu_mes;
227int amdgpu_mes_log_enable = 0;226int amdgpu_mes_log_enable = 0;
228int amdgpu_mes_kiq;
229int amdgpu_uni_mes = 1;227int amdgpu_uni_mes = 1;
230int amdgpu_noretry = -1;228int amdgpu_noretry = -1;
231int amdgpu_force_asic_type = -1;229int amdgpu_force_asic_type = -1;
@@ -690,15 +688,6 @@ MODULE_PARM_DESC(discovery, · 458 unmodified lines
690 "Allow driver to discover hardware IPs from IP Discovery table at the top of VRAM");688 "Allow driver to discover hardware IPs from IP Discovery table at the top of VRAM");
691module_param_named(discovery, amdgpu_discovery, int, 0444);689module_param_named(discovery, amdgpu_discovery, int, 0444);
692 690
693/**
694 * DOC: mes (int)
695 * Enable Micro Engine Scheduler. This is a new hw scheduling engine for gfx, sdma, and compute.
696 * (0 = disabled (default), 1 = enabled)
697 */
698MODULE_PARM_DESC(mes,
699 "Enable Micro Engine Scheduler (0 = disabled (default), 1 = enabled)");
700module_param_named(mes, amdgpu_mes, int, 0444);
701
702/**691/**
703 * DOC: mes_log_enable (int)692 * DOC: mes_log_enable (int)
704 * Enable Micro Engine Scheduler log. This is used to enable/disable MES internal log.693 * Enable Micro Engine Scheduler log. This is used to enable/disable MES internal log.
@@ -708,15 +697,6 @@ MODULE_PARM_DESC(mes_log_enable, · 3 unmodified lines
708 "Enable Micro Engine Scheduler log (0 = disabled (default), 1 = enabled)");697 "Enable Micro Engine Scheduler log (0 = disabled (default), 1 = enabled)");
709module_param_named(mes_log_enable, amdgpu_mes_log_enable, int, 0444);698module_param_named(mes_log_enable, amdgpu_mes_log_enable, int, 0444);
710 699
711/**
712 * DOC: mes_kiq (int)
713 * Enable Micro Engine Scheduler KIQ. This is a new engine pipe for kiq.
714 * (0 = disabled (default), 1 = enabled)
715 */
716MODULE_PARM_DESC(mes_kiq,
717 "Enable Micro Engine Scheduler KIQ (0 = disabled (default), 1 = enabled)");
718module_param_named(mes_kiq, amdgpu_mes_kiq, int, 0444);
719
720/**700/**
721 * DOC: uni_mes (int)701 * DOC: uni_mes (int)
722 * Enable Unified Micro Engine Scheduler. This is a new engine pipe for unified scheduler.702 * Enable Unified Micro Engine Scheduler. This is a new engine pipe for unified scheduler.
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c+45−71
@@ -89,16 +89,6 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring) · 88 unmodified lines
89 return seq;89 return seq;
90}90}
91 91
92static void amdgpu_fence_save_fence_wptr_start(struct amdgpu_fence *af)
93{
94 af->fence_wptr_start = af->ring->wptr;
95}
96
97static void amdgpu_fence_save_fence_wptr_end(struct amdgpu_fence *af)
98{
99 af->fence_wptr_end = af->ring->wptr;
100}
101
102/**92/**
103 * amdgpu_fence_emit - emit a fence on the requested ring93 * amdgpu_fence_emit - emit a fence on the requested ring
104 *94 *
@@ -107,16 +97,14 @@ static void amdgpu_fence_save_fence_wptr_end(struct amdgpu_fence *af) · 2 unmodified lines
107 * @flags: flags to pass into the subordinate .emit_fence() call97 * @flags: flags to pass into the subordinate .emit_fence() call
108 *98 *
109 * Emits a fence command on the requested ring (all asics).99 * Emits a fence command on the requested ring (all asics).
110 * Returns 0 on success, -ENOMEM on failure.
111 */100 */
112int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,101void amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
113 unsigned int flags)102 unsigned int flags)
114{103{
115 struct amdgpu_device *adev = ring->adev;104 struct amdgpu_device *adev = ring->adev;
116 struct dma_fence *fence;105 struct dma_fence *fence;
117 struct dma_fence __rcu **ptr;106 struct dma_fence __rcu **ptr;
118 uint32_t seq;107 uint32_t seq;
119 int r;
120 108
121 fence = &af->base;109 fence = &af->base;
122 af->ring = ring;110 af->ring = ring;
@@ -126,11 +114,9 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af, · 3 unmodified lines
126 &ring->fence_drv.lock,114 &ring->fence_drv.lock,
127 adev->fence_context + ring->idx, seq);115 adev->fence_context + ring->idx, seq);
128 116
129 amdgpu_fence_save_fence_wptr_start(af);
130 amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,117 amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
131 seq, flags | AMDGPU_FENCE_FLAG_INT);118 seq, flags | AMDGPU_FENCE_FLAG_INT);
132 amdgpu_fence_save_fence_wptr_end(af);119
133 amdgpu_fence_save_wptr(af);
134 pm_runtime_get_noresume(adev_to_drm(adev)->dev);120 pm_runtime_get_noresume(adev_to_drm(adev)->dev);
135 ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];121 ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
136 if (unlikely(rcu_dereference_protected(*ptr, 1))) {122 if (unlikely(rcu_dereference_protected(*ptr, 1))) {
@@ -141,10 +127,13 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af, · 4 unmodified lines
141 rcu_read_unlock();127 rcu_read_unlock();
142 128
143 if (old) {129 if (old) {
144 r = dma_fence_wait(old, false);130 /*
131 * dma_fence_wait(old, false) is not interruptible.
132 * It will not return an error in this case.
133 * So we can safely ignore the return value.
134 */
135 dma_fence_wait(old, false);
145 dma_fence_put(old);136 dma_fence_put(old);
146 if (r)
147 return r;
148 }137 }
149 }138 }
150 139
@@ -154,8 +143,6 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af, · 3 unmodified lines
154 * emitting the fence would mess up the hardware ring buffer.143 * emitting the fence would mess up the hardware ring buffer.
155 */144 */
156 rcu_assign_pointer(*ptr, dma_fence_get(fence));145 rcu_assign_pointer(*ptr, dma_fence_get(fence));
157
158 return 0;
159}146}
160 147
161/**148/**
@@ -241,7 +228,6 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring) · 79 unmodified lines
241 228
242 do {229 do {
243 struct dma_fence *fence, **ptr;230 struct dma_fence *fence, **ptr;
244 struct amdgpu_fence *am_fence;
245 231
246 ++last_seq;232 ++last_seq;
247 last_seq &= drv->num_fences_mask;233 last_seq &= drv->num_fences_mask;
@@ -254,12 +240,6 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring) · 6 unmodified lines
254 if (!fence)240 if (!fence)
255 continue;241 continue;
256 242
257 /* Save the wptr in the fence driver so we know what the last processed
258 * wptr was. This is required for re-emitting the ring state for
259 * queues that are reset but are not guilty and thus have no guilty fence.
260 */
261 am_fence = container_of(fence, struct amdgpu_fence, base);
262 drv->signalled_wptr = am_fence->wptr;
263 dma_fence_signal(fence);243 dma_fence_signal(fence);
264 dma_fence_put(fence);244 dma_fence_put(fence);
265 pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);245 pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -708,25 +688,29 @@ void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring) · 442 unmodified lines
708 */688 */
709 689
710/**690/**
711 * amdgpu_fence_driver_update_timedout_fence_state - Update fence state and set errors691 * amdgpu_ring_set_fence_errors_and_reemit - Set dma_fence errors and reemit
712 *692 *
713 * @af: fence of the ring to update693 * @ring: the ring to operate on
694 * @guilty_fence: fence of the ring to update
714 *695 *
715 */696 */
716void amdgpu_fence_driver_update_timedout_fence_state(struct amdgpu_fence *af)697void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
698 struct amdgpu_fence *guilty_fence)
717{699{
718 struct dma_fence *unprocessed;700 struct dma_fence *unprocessed;
719 struct dma_fence __rcu **ptr;701 struct dma_fence __rcu **ptr;
720 struct amdgpu_fence *fence;702 struct amdgpu_fence *fence;
721 struct amdgpu_ring *ring = af->ring;
722 unsigned long flags;703 unsigned long flags;
723 u32 seq, last_seq;704 u32 seq, last_seq;
724 bool reemitted = false;705 unsigned int i;
706 bool is_guilty_fence;
707 bool is_guilty_context;
725 708
726 last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;709 last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
727 seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;710 seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
728 711
729 /* mark all fences from the guilty context with an error */712 ring->reemit = true;
713 amdgpu_ring_alloc(ring, ring->ring_backup_entries_to_copy);
730 spin_lock_irqsave(&ring->fence_drv.lock, flags);714 spin_lock_irqsave(&ring->fence_drv.lock, flags);
731 do {715 do {
732 last_seq++;716 last_seq++;
@@ -738,39 +722,45 @@ void amdgpu_fence_driver_update_timedout_fence_state(struct amdgpu_fence *af) · 5 unmodified lines
738 722
739 if (unprocessed && !dma_fence_is_signaled_locked(unprocessed)) {723 if (unprocessed && !dma_fence_is_signaled_locked(unprocessed)) {
740 fence = container_of(unprocessed, struct amdgpu_fence, base);724 fence = container_of(unprocessed, struct amdgpu_fence, base);
725 is_guilty_fence = fence == guilty_fence;
726 is_guilty_context = fence->context == guilty_fence->context;
741 727
742 if (fence->reemitted > 1)728 /* mark all fences from the guilty context with an error */
743 reemitted = true;729 if (is_guilty_fence)
744 else if (fence == af)
745 dma_fence_set_error(&fence->base, -ETIME);730 dma_fence_set_error(&fence->base, -ETIME);
746 else if (fence->context == af->context)731 else if (is_guilty_context)
747 dma_fence_set_error(&fence->base, -ECANCELED);732 dma_fence_set_error(&fence->base, -ECANCELED);
733
734 /* reemit the packet stream and update wptrs */
735 fence->ib_wptr = ring->wptr;
736 for (i = 0; i < fence->ib_dw_size; i++) {
737 /* Skip the IB(s) for the guilty context. */
738 if (is_guilty_context &&
739 i >= fence->skip_ib_dw_start_offset &&
740 i < fence->skip_ib_dw_end_offset)
741 amdgpu_ring_write(ring, ring->funcs->nop);
742 else
743 amdgpu_ring_write(ring,
744 ring->ring_backup[fence->backup_idx + i]);
745 }
748 }746 }
749 rcu_read_unlock();747 rcu_read_unlock();
750 } while (last_seq != seq);748 } while (last_seq != seq);
751 spin_unlock_irqrestore(&ring->fence_drv.lock, flags);749 spin_unlock_irqrestore(&ring->fence_drv.lock, flags);
752 750 amdgpu_ring_commit(ring);
753 if (reemitted) {751 ring->reemit = false;
754 /* if we've already reemitted once then just cancel everything */
755 amdgpu_fence_driver_force_completion(af->ring);
756 af->ring->ring_backup_entries_to_copy = 0;
757 }
758}
759
760void amdgpu_fence_save_wptr(struct amdgpu_fence *af)
761{
762 af->wptr = af->ring->wptr;
763}752}
764 753
765static void amdgpu_ring_backup_unprocessed_command(struct amdgpu_ring *ring,754static void amdgpu_ring_backup_unprocessed_command(struct amdgpu_ring *ring,
766 u64 start_wptr, u64 end_wptr)755 struct amdgpu_fence *af)
767{756{
768 unsigned int first_idx = start_wptr & ring->buf_mask;757 unsigned int first_idx = af->ib_wptr & ring->buf_mask;
769 unsigned int last_idx = end_wptr & ring->buf_mask;758 unsigned int dw_size = af->ib_dw_size;
770 unsigned int i;759 unsigned int i;
771 760
761 af->backup_idx = ring->ring_backup_entries_to_copy;
772 /* Backup the contents of the ring buffer. */762 /* Backup the contents of the ring buffer. */
773 for (i = first_idx; i != last_idx; ++i, i &= ring->buf_mask)763 for (i = first_idx; dw_size > 0; ++i, i &= ring->buf_mask, --dw_size)
774 ring->ring_backup[ring->ring_backup_entries_to_copy++] = ring->ring[i];764 ring->ring_backup[ring->ring_backup_entries_to_copy++] = ring->ring[i];
775}765}
776 766
@@ -780,12 +770,10 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring, · 3 unmodified lines
780 struct dma_fence *unprocessed;770 struct dma_fence *unprocessed;
781 struct dma_fence __rcu **ptr;771 struct dma_fence __rcu **ptr;
782 struct amdgpu_fence *fence;772 struct amdgpu_fence *fence;
783 u64 wptr;
784 u32 seq, last_seq;773 u32 seq, last_seq;
785 774
786 last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;775 last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
787 seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;776 seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
788 wptr = ring->fence_drv.signalled_wptr;
789 ring->ring_backup_entries_to_copy = 0;777 ring->ring_backup_entries_to_copy = 0;
790 778
791 do {779 do {
@@ -799,21 +787,7 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring, · 7 unmodified lines
799 if (unprocessed && !dma_fence_is_signaled(unprocessed)) {787 if (unprocessed && !dma_fence_is_signaled(unprocessed)) {
800 fence = container_of(unprocessed, struct amdgpu_fence, base);788 fence = container_of(unprocessed, struct amdgpu_fence, base);
801 789
802 /* save everything if the ring is not guilty, otherwise790 amdgpu_ring_backup_unprocessed_command(ring, fence);
803 * just save the content from other contexts.
804 */
805 if (!fence->reemitted &&
806 (!guilty_fence || (fence->context != guilty_fence->context))) {
807 amdgpu_ring_backup_unprocessed_command(ring, wptr,
808 fence->wptr);
809 } else if (!fence->reemitted) {
810 /* always save the fence */
811 amdgpu_ring_backup_unprocessed_command(ring,
812 fence->fence_wptr_start,
813 fence->fence_wptr_end);
814 }
815 wptr = fence->wptr;
816 fence->reemitted++;
817 }791 }
818 rcu_read_unlock();792 rcu_read_unlock();
819 } while (last_seq != seq);793 } while (last_seq != seq);
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c+49−0
@@ -503,6 +503,55 @@ void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, int xcc_id) · 502 unmodified lines
503 &ring->mqd_ptr);503 &ring->mqd_ptr);
504}504}
505 505
506void amdgpu_gfx_mqd_symmetrically_map_cu_mask(struct amdgpu_device *adev, const uint32_t *cu_mask,
507 uint32_t cu_mask_count, uint32_t *se_mask)
508{
509 struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info;
510 struct amdgpu_gfx_config *gfx_info = &adev->gfx.config;
511 uint32_t cu_per_sh[8][4] = {0};
512 int i, se, sh, cu, cu_bitmap_sh_mul;
513 int xcc_inst = ffs(adev->gfx.xcc_mask) - 1;
514 bool wgp_mode_req = amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 0, 0);
515 int cu_inc = wgp_mode_req ? 2 : 1;
516 uint32_t en_mask = wgp_mode_req ? 0x3 : 0x1;
517 int num_xcc, inc, inst = 0;
518
519 if (xcc_inst < 0)
520 xcc_inst = 0;
521
522 num_xcc = hweight16(adev->gfx.xcc_mask);
523 if (!num_xcc)
524 num_xcc = 1;
525
526 inc = cu_inc * num_xcc;
527
528 cu_bitmap_sh_mul = 2;
529
530 for (se = 0; se < gfx_info->max_shader_engines; se++)
531 for (sh = 0; sh < gfx_info->max_sh_per_se; sh++)
532 cu_per_sh[se][sh] = hweight32(
533 cu_info->bitmap[xcc_inst][se % 4][sh + (se / 4) *
534 cu_bitmap_sh_mul]);
535
536 for (i = 0; i < gfx_info->max_shader_engines; i++)
537 se_mask[i] = 0;
538
539 i = inst;
540 for (cu = 0; cu < 16; cu += cu_inc) {
541 for (sh = 0; sh < gfx_info->max_sh_per_se; sh++) {
542 for (se = 0; se < gfx_info->max_shader_engines; se++) {
543 if (cu_per_sh[se][sh] > cu) {
544 if ((i / 32) < cu_mask_count && (cu_mask[i / 32] & (1 << (i % 32))))
545 se_mask[se] |= en_mask << (cu + sh * 16);
546 i += inc;
547 if (i >= cu_mask_count * 32)
548 return;
549 }
550 }
551 }
552 }
553}
554
506int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id)555int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id)
507{556{
508 struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];557 struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h+2−0
@@ -583,6 +583,8 @@ int amdgpu_gfx_kiq_init(struct amdgpu_device *adev, · 582 unmodified lines
583int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,583int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
584 unsigned mqd_size, int xcc_id);584 unsigned mqd_size, int xcc_id);
585void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, int xcc_id);585void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, int xcc_id);
586void amdgpu_gfx_mqd_symmetrically_map_cu_mask(struct amdgpu_device *adev, const uint32_t *cu_mask,
587 uint32_t cu_mask_count, uint32_t *se_mask);
586int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id);588int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id);
587int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev, int xcc_id);589int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev, int xcc_id);
588int amdgpu_gfx_disable_kgq(struct amdgpu_device *adev, int xcc_id);590int amdgpu_gfx_disable_kgq(struct amdgpu_device *adev, int xcc_id);
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+3−3
@@ -742,7 +742,7 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, · 741 unmodified lines
742 * translation. Avoid this by doing the invalidation from the SDMA742 * translation. Avoid this by doing the invalidation from the SDMA
743 * itself at least for GART.743 * itself at least for GART.
744 */744 */
745 mutex_lock(&adev->mman.gtt_window_lock);745 mutex_lock(&adev->mman.default_entity.lock);
746 r = amdgpu_job_alloc_with_ib(ring->adev, &adev->mman.default_entity.base,746 r = amdgpu_job_alloc_with_ib(ring->adev, &adev->mman.default_entity.base,
747 AMDGPU_FENCE_OWNER_UNDEFINED,747 AMDGPU_FENCE_OWNER_UNDEFINED,
748 16 * 4, AMDGPU_IB_POOL_IMMEDIATE,748 16 * 4, AMDGPU_IB_POOL_IMMEDIATE,
@@ -755,7 +755,7 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, · 6 unmodified lines
755 job->ibs->ptr[job->ibs->length_dw++] = ring->funcs->nop;755 job->ibs->ptr[job->ibs->length_dw++] = ring->funcs->nop;
756 amdgpu_ring_pad_ib(ring, &job->ibs[0]);756 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
757 fence = amdgpu_job_submit(job);757 fence = amdgpu_job_submit(job);
758 mutex_unlock(&adev->mman.gtt_window_lock);758 mutex_unlock(&adev->mman.default_entity.lock);
759 759
760 dma_fence_wait(fence, false);760 dma_fence_wait(fence, false);
761 dma_fence_put(fence);761 dma_fence_put(fence);
@@ -763,7 +763,7 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, · 1 unmodified line
763 return;763 return;
764 764
765error_alloc:765error_alloc:
766 mutex_unlock(&adev->mman.gtt_window_lock);766 mutex_unlock(&adev->mman.default_entity.lock);
767 dev_err(adev->dev, "Error flushing GPU TLB using the SDMA (%d)!\n", r);767 dev_err(adev->dev, "Error flushing GPU TLB using the SDMA (%d)!\n", r);
768}768}
769 769
drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c+1−5
@@ -324,17 +324,13 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size) · 323 unmodified lines
324{324{
325 struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;325 struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
326 struct ttm_resource_manager *man = &mgr->manager;326 struct ttm_resource_manager *man = &mgr->manager;
327 uint64_t start, size;
328 327
329 man->use_tt = true;328 man->use_tt = true;
330 man->func = &amdgpu_gtt_mgr_func;329 man->func = &amdgpu_gtt_mgr_func;
331 330
332 ttm_resource_manager_init(man, &adev->mman.bdev, gtt_size);331 ttm_resource_manager_init(man, &adev->mman.bdev, gtt_size);
333 332
334 start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;333 drm_mm_init(&mgr->mm, 0, adev->gmc.gart_size >> PAGE_SHIFT);
335 start += amdgpu_vce_required_gart_pages(adev);
336 size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
337 drm_mm_init(&mgr->mm, start, size);
338 spin_lock_init(&mgr->lock);334 spin_lock_init(&mgr->lock);
339 335
340 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager);336 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager);
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c+27−29
@@ -129,6 +129,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 128 unmodified lines
129 struct amdgpu_ib *ib = &ibs[0];129 struct amdgpu_ib *ib = &ibs[0];
130 struct dma_fence *tmp = NULL;130 struct dma_fence *tmp = NULL;
131 struct amdgpu_fence *af;131 struct amdgpu_fence *af;
132 struct amdgpu_fence *vm_af;
132 bool need_ctx_switch;133 bool need_ctx_switch;
133 struct amdgpu_vm *vm;134 struct amdgpu_vm *vm;
134 uint64_t fence_ctx;135 uint64_t fence_ctx;
@@ -215,25 +216,28 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 80 unmodified lines
215 dma_fence_put(tmp);216 dma_fence_put(tmp);
216 }217 }
217 218
218 if ((ib->flags & AMDGPU_IB_FLAG_EMIT_MEM_SYNC) && ring->funcs->emit_mem_sync)219 if (job) {
219 ring->funcs->emit_mem_sync(ring);220 vm_af = job->hw_vm_fence;
221 /* VM sequence */
222 vm_af->ib_wptr = ring->wptr;
223 amdgpu_vm_flush(ring, job, need_pipe_sync);
224 vm_af->ib_dw_size =
225 amdgpu_ring_get_dw_distance(ring, vm_af->ib_wptr, ring->wptr);
226 }
220 227
221 if (ring->funcs->emit_wave_limit &&228 /* IB sequence */
222 ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)229 af->ib_wptr = ring->wptr;
223 ring->funcs->emit_wave_limit(ring, true);230 amdgpu_ring_ib_begin(ring);
224 231
225 if (ring->funcs->insert_start)232 if (ring->funcs->insert_start)
226 ring->funcs->insert_start(ring);233 ring->funcs->insert_start(ring);
227 234
228 if (job) {235 if ((ib->flags & AMDGPU_IB_FLAG_EMIT_MEM_SYNC) && ring->funcs->emit_mem_sync)
229 r = amdgpu_vm_flush(ring, job, need_pipe_sync);236 ring->funcs->emit_mem_sync(ring);
230 if (r) {
231 amdgpu_ring_undo(ring);
232 goto free_fence;
233 }
234 }
235 237
236 amdgpu_ring_ib_begin(ring);238 if (ring->funcs->emit_wave_limit &&
239 ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
240 ring->funcs->emit_wave_limit(ring, true);
237 241
238 if (ring->funcs->emit_gfx_shadow && adev->gfx.cp_gfx_shadow)242 if (ring->funcs->emit_gfx_shadow && adev->gfx.cp_gfx_shadow)
239 amdgpu_ring_emit_gfx_shadow(ring, shadow_va, csa_va, gds_va,243 amdgpu_ring_emit_gfx_shadow(ring, shadow_va, csa_va, gds_va,
@@ -243,6 +247,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 3 unmodified lines
243 cond_exec = amdgpu_ring_init_cond_exec(ring,247 cond_exec = amdgpu_ring_init_cond_exec(ring,
244 ring->cond_exe_gpu_addr);248 ring->cond_exe_gpu_addr);
245 249
250 /* Skip the IB for guilty contexts */
251 af->skip_ib_dw_start_offset =
252 amdgpu_ring_get_dw_distance(ring, af->ib_wptr, ring->wptr);
246 amdgpu_device_flush_hdp(adev, ring);253 amdgpu_device_flush_hdp(adev, ring);
247 254
248 if (need_ctx_switch)255 if (need_ctx_switch)
@@ -281,6 +288,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 32 unmodified lines
281 amdgpu_ring_emit_frame_cntl(ring, false, secure);288 amdgpu_ring_emit_frame_cntl(ring, false, secure);
282 289
283 amdgpu_device_invalidate_hdp(adev, ring);290 amdgpu_device_invalidate_hdp(adev, ring);
291 /* Skip the IB for guilty contexts */
292 af->skip_ib_dw_end_offset =
293 amdgpu_ring_get_dw_distance(ring, af->ib_wptr, ring->wptr);
284 294
285 if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE)295 if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE)
286 fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY;296 fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY;
@@ -297,14 +307,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 10 unmodified lines
297 amdgpu_ring_init_cond_exec(ring, ring->cond_exe_gpu_addr);307 amdgpu_ring_init_cond_exec(ring, ring->cond_exe_gpu_addr);
298 }308 }
299 309
300 r = amdgpu_fence_emit(ring, af, fence_flags);310 amdgpu_fence_emit(ring, af, fence_flags);
301 if (r) {
302 dev_err(adev->dev, "failed to emit fence (%d)\n", r);
303 if (job && job->vmid)
304 amdgpu_vmid_reset(adev, ring->vm_hub, job->vmid);
305 amdgpu_ring_undo(ring);
306 goto free_fence;
307 }
308 *f = &af->base;311 *f = &af->base;
309 /* get a ref for the job */312 /* get a ref for the job */
310 if (job)313 if (job)
@@ -323,15 +326,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 12 unmodified lines
323 ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)326 ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
324 ring->funcs->emit_wave_limit(ring, false);327 ring->funcs->emit_wave_limit(ring, false);
325 328
326 /* Save the wptr associated with this fence.
327 * This must be last for resets to work properly
328 * as we need to save the wptr associated with this
329 * fence so we know what rings contents to backup
330 * after we reset the queue.
331 */
332 amdgpu_fence_save_wptr(af);
333
334 amdgpu_ring_ib_end(ring);329 amdgpu_ring_ib_end(ring);
330
331 af->ib_dw_size = amdgpu_ring_get_dw_distance(ring, af->ib_wptr, ring->wptr);
332
335 amdgpu_ring_commit(ring);333 amdgpu_ring_commit(ring);
336 334
337 return 0;335 return 0;
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c+2−4
@@ -92,7 +92,6 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) · 91 unmodified lines
92 struct drm_wedge_task_info *info = NULL;92 struct drm_wedge_task_info *info = NULL;
93 struct amdgpu_task_info *ti = NULL;93 struct amdgpu_task_info *ti = NULL;
94 struct amdgpu_device *adev = ring->adev;94 struct amdgpu_device *adev = ring->adev;
95 enum drm_gpu_sched_stat status = DRM_GPU_SCHED_STAT_RESET;
96 int idx, r;95 int idx, r;
97 96
98 if (!drm_dev_enter(adev_to_drm(adev), &idx)) {97 if (!drm_dev_enter(adev_to_drm(adev), &idx)) {
@@ -147,8 +146,6 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) · 48 unmodified lines
147 ring->sched.name);146 ring->sched.name);
148 drm_dev_wedged_event(adev_to_drm(adev),147 drm_dev_wedged_event(adev_to_drm(adev),
149 DRM_WEDGE_RECOVERY_NONE, info);148 DRM_WEDGE_RECOVERY_NONE, info);
150 /* This is needed to add the job back to the pending list */
151 status = DRM_GPU_SCHED_STAT_NO_HANG;
152 goto exit;149 goto exit;
153 }150 }
154 dev_err(adev->dev, "Ring %s reset failed\n", ring->sched.name);151 dev_err(adev->dev, "Ring %s reset failed\n", ring->sched.name);
@@ -184,7 +181,8 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) · 29 unmodified lines
184exit:181exit:
185 amdgpu_vm_put_task_info(ti);182 amdgpu_vm_put_task_info(ti);
186 drm_dev_exit(idx);183 drm_dev_exit(idx);
187 return status;184 /* This is needed to add the job back to the pending list */
185 return DRM_GPU_SCHED_STAT_NO_HANG;
188}186}
189 187
190int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,188int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c+35−15
@@ -21,6 +21,7 @@ · 20 unmodified lines
21 *21 *
22 *22 *
23 */23 */
24#include "amdgpu_reg_access.h"
24#include <linux/debugfs.h>25#include <linux/debugfs.h>
25#include <linux/list.h>26#include <linux/list.h>
26#include <linux/module.h>27#include <linux/module.h>
@@ -42,6 +43,7 @@ · 15 unmodified lines
42#include "amdgpu_reset.h"43#include "amdgpu_reset.h"
43#include "amdgpu_psp.h"44#include "amdgpu_psp.h"
44#include "amdgpu_ras_mgr.h"45#include "amdgpu_ras_mgr.h"
46#include "amdgpu_virt_ras_cmd.h"
45 47
46#ifdef CONFIG_X86_MCE_AMD48#ifdef CONFIG_X86_MCE_AMD
47#include <asm/mce.h>49#include <asm/mce.h>
@@ -228,19 +230,30 @@ static int amdgpu_check_address_validity(struct amdgpu_device *adev, · 180 unmodified lines
228 return 0;230 return 0;
229 231
230 if (amdgpu_sriov_vf(adev)) {232 if (amdgpu_sriov_vf(adev)) {
231 if (amdgpu_virt_check_vf_critical_region(adev, address, &hit))233 if (amdgpu_uniras_enabled(adev)) {
232 return -EPERM;234 if (amdgpu_virt_ras_check_address_validity(adev, address, &hit))
233 return hit ? -EACCES : 0;235 return -EPERM;
236 if (hit)
237 return -EACCES;
238 } else {
239 if (amdgpu_virt_check_vf_critical_region(adev, address, &hit))
240 return -EPERM;
241 return hit ? -EACCES : 0;
242 }
234 }243 }
235 244
236 if ((address >= adev->gmc.mc_vram_size) ||245 if ((address >= adev->gmc.mc_vram_size) ||
237 (address >= RAS_UMC_INJECT_ADDR_LIMIT))246 (address >= RAS_UMC_INJECT_ADDR_LIMIT))
238 return -EFAULT;247 return -EFAULT;
239 248
240 if (amdgpu_uniras_enabled(adev))249 if (amdgpu_uniras_enabled(adev)) {
241 count = amdgpu_ras_mgr_lookup_bad_pages_in_a_row(adev, address,250 if (amdgpu_sriov_vf(adev))
242 page_pfns, ARRAY_SIZE(page_pfns));251 count = amdgpu_virt_ras_convert_retired_address(adev, address,
243 else252 page_pfns, ARRAY_SIZE(page_pfns));
253 else
254 count = amdgpu_ras_mgr_lookup_bad_pages_in_a_row(adev, address,
255 page_pfns, ARRAY_SIZE(page_pfns));
256 } else
244 count = amdgpu_umc_lookup_bad_pages_in_a_row(adev,257 count = amdgpu_umc_lookup_bad_pages_in_a_row(adev,
245 address, page_pfns, ARRAY_SIZE(page_pfns));258 address, page_pfns, ARRAY_SIZE(page_pfns));
246 259
@@ -3118,9 +3131,11 @@ static int __amdgpu_ras_convert_rec_array_from_rom(struct amdgpu_device *adev, · 2871 unmodified lines
3118 enum amdgpu_memory_partition nps)3131 enum amdgpu_memory_partition nps)
3119{3132{
3120 int i = 0;3133 int i = 0;
3134 uint64_t chan_idx_v2;
3121 enum amdgpu_memory_partition save_nps;3135 enum amdgpu_memory_partition save_nps;
3122 3136
3123 save_nps = (bps[0].retired_page >> UMC_NPS_SHIFT) & UMC_NPS_MASK;3137 save_nps = (bps[0].retired_page >> UMC_NPS_SHIFT) & UMC_NPS_MASK;
3138 chan_idx_v2 = bps[0].retired_page & UMC_CHANNEL_IDX_V2;
3124 3139
3125 /*old asics just have pa in eeprom*/3140 /*old asics just have pa in eeprom*/
3126 if (IP_VERSION_MAJ(amdgpu_ip_version(adev, UMC_HWIP, 0)) < 12) {3141 if (IP_VERSION_MAJ(amdgpu_ip_version(adev, UMC_HWIP, 0)) < 12) {
@@ -3132,7 +3147,7 @@ static int __amdgpu_ras_convert_rec_array_from_rom(struct amdgpu_device *adev, · 5 unmodified lines
3132 for (i = 0; i < adev->umc.retire_unit; i++)3147 for (i = 0; i < adev->umc.retire_unit; i++)
3133 bps[i].retired_page &= ~(UMC_NPS_MASK << UMC_NPS_SHIFT);3148 bps[i].retired_page &= ~(UMC_NPS_MASK << UMC_NPS_SHIFT);
3134 3149
3135 if (save_nps) {3150 if (save_nps || chan_idx_v2) {
3136 if (save_nps == nps) {3151 if (save_nps == nps) {
3137 if (amdgpu_umc_pages_in_a_row(adev, err_data,3152 if (amdgpu_umc_pages_in_a_row(adev, err_data,
3138 bps[0].retired_page << AMDGPU_GPU_PAGE_SHIFT))3153 bps[0].retired_page << AMDGPU_GPU_PAGE_SHIFT))
@@ -3176,10 +3191,12 @@ static int __amdgpu_ras_convert_rec_from_rom(struct amdgpu_device *adev, · 37 unmodified lines
3176 enum amdgpu_memory_partition nps)3191 enum amdgpu_memory_partition nps)
3177{3192{
3178 int i = 0;3193 int i = 0;
3194 uint64_t chan_idx_v2;
3179 enum amdgpu_memory_partition save_nps;3195 enum amdgpu_memory_partition save_nps;
3180 3196
3181 if (!amdgpu_ras_smu_eeprom_supported(adev)) {3197 if (!amdgpu_ras_smu_eeprom_supported(adev)) {
3182 save_nps = (bps->retired_page >> UMC_NPS_SHIFT) & UMC_NPS_MASK;3198 save_nps = (bps->retired_page >> UMC_NPS_SHIFT) & UMC_NPS_MASK;
3199 chan_idx_v2 = bps->retired_page & UMC_CHANNEL_IDX_V2;
3183 bps->retired_page &= ~(UMC_NPS_MASK << UMC_NPS_SHIFT);3200 bps->retired_page &= ~(UMC_NPS_MASK << UMC_NPS_SHIFT);
3184 } else {3201 } else {
3185 /* if pmfw manages eeprom, save_nps is not stored on eeprom,3202 /* if pmfw manages eeprom, save_nps is not stored on eeprom,
@@ -3201,16 +3218,19 @@ static int __amdgpu_ras_convert_rec_from_rom(struct amdgpu_device *adev, · 15 unmodified lines
3201 err_data->err_addr[i].mcumc_id = bps->mcumc_id;3218 err_data->err_addr[i].mcumc_id = bps->mcumc_id;
3202 }3219 }
3203 } else {3220 } else {
3204 if (bps->address) {3221 if (save_nps || chan_idx_v2) {
3205 if (amdgpu_ras_mca2pa_by_idx(adev, bps, err_data))3222 if (amdgpu_ras_mca2pa_by_idx(adev, bps, err_data))
3206 return -EINVAL;3223 return -EINVAL;
3207 } else {3224 } else {
3208 /* for specific old eeprom data, mca address is not stored,3225 /* for specific old eeprom data, mca address is not stored,
3209 * calc it from pa3226 * calc it from pa
3210 */3227 */
3211 if (amdgpu_umc_pa2mca(adev, bps->retired_page << AMDGPU_GPU_PAGE_SHIFT,3228 if (bps->address == 0)
3212 &(bps->address), AMDGPU_NPS1_PARTITION_MODE))3229 if (amdgpu_umc_pa2mca(adev,
3213 return -EINVAL;3230 bps->retired_page << AMDGPU_GPU_PAGE_SHIFT,
3231 &(bps->address),
3232 AMDGPU_NPS1_PARTITION_MODE))
3233 return -EINVAL;
3214 3234
3215 if (amdgpu_ras_mca2pa(adev, bps, err_data))3235 if (amdgpu_ras_mca2pa(adev, bps, err_data))
3216 return -EOPNOTSUPP;3236 return -EOPNOTSUPP;
@@ -5516,11 +5536,11 @@ static void amdgpu_ras_boot_time_error_reporting(struct amdgpu_device *adev, · 2299 unmodified lines
5516 * is changed. In such case, replace the aqua_vanjaram implementation5536 * is changed. In such case, replace the aqua_vanjaram implementation
5517 * with more common helper */5537 * with more common helper */
5518 reg_addr = (mmMP0_SMN_C2PMSG_92 << 2) +5538 reg_addr = (mmMP0_SMN_C2PMSG_92 << 2) +
5519 aqua_vanjaram_encode_ext_smn_addressing(instance);5539 amdgpu_reg_get_smn_base64(adev, MP0_HWIP, instance);
5520 fw_status = amdgpu_device_indirect_rreg_ext(adev, reg_addr);5540 fw_status = amdgpu_device_indirect_rreg_ext(adev, reg_addr);
5521 5541
5522 reg_addr = (mmMP0_SMN_C2PMSG_126 << 2) +5542 reg_addr = (mmMP0_SMN_C2PMSG_126 << 2) +
5523 aqua_vanjaram_encode_ext_smn_addressing(instance);5543 amdgpu_reg_get_smn_base64(adev, MP0_HWIP, instance);
5524 boot_error = amdgpu_device_indirect_rreg_ext(adev, reg_addr);5544 boot_error = amdgpu_device_indirect_rreg_ext(adev, reg_addr);
5525 5545
5526 socket_id = AMDGPU_RAS_GPU_ERR_SOCKET_ID(boot_error);5546 socket_id = AMDGPU_RAS_GPU_ERR_SOCKET_ID(boot_error);
@@ -5586,7 +5606,7 @@ static bool amdgpu_ras_boot_error_detected(struct amdgpu_device *adev, · 59 unmodified lines
5586 int retry_loop;5606 int retry_loop;
5587 5607
5588 reg_addr = (mmMP0_SMN_C2PMSG_92 << 2) +5608 reg_addr = (mmMP0_SMN_C2PMSG_92 << 2) +
5589 aqua_vanjaram_encode_ext_smn_addressing(instance);5609 amdgpu_reg_get_smn_base64(adev, MP0_HWIP, instance);
5590 5610
5591 for (retry_loop = 0; retry_loop < AMDGPU_RAS_BOOT_STATUS_POLLING_LIMIT; retry_loop++) {5611 for (retry_loop = 0; retry_loop < AMDGPU_RAS_BOOT_STATUS_POLLING_LIMIT; retry_loop++) {
5592 reg_data = amdgpu_device_indirect_rreg_ext(adev, reg_addr);5612 reg_data = amdgpu_device_indirect_rreg_ext(adev, reg_addr);
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c+3−0
@@ -508,6 +508,9 @@ int amdgpu_ras_eeprom_reset_table(struct amdgpu_ras_eeprom_control *control) · 507 unmodified lines
508 control->bad_channel_bitmap = 0;508 control->bad_channel_bitmap = 0;
509 amdgpu_dpm_send_hbm_bad_channel_flag(adev, control->bad_channel_bitmap);509 amdgpu_dpm_send_hbm_bad_channel_flag(adev, control->bad_channel_bitmap);
510 con->update_channel_flag = false;510 con->update_channel_flag = false;
511 /* there is no record on eeprom now, clear the counter */
512 if (con->eh_data)
513 con->eh_data->count_saved = 0;
511 514
512 amdgpu_ras_debugfs_set_ret_size(control);515 amdgpu_ras_debugfs_set_ret_size(control);
513 516
drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c+959−0
@@ -0,0 +1,959 @@
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright 2025 Advanced Micro Devices, 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
24#include <linux/delay.h>
25
26#include "amdgpu.h"
27#include "amdgpu_reset.h"
28#include "amdgpu_trace.h"
29#include "amdgpu_virt.h"
30#include "amdgpu_reg_access.h"
31
32#define AMDGPU_PCIE_INDEX_FALLBACK (0x38 >> 2)
33#define AMDGPU_PCIE_INDEX_HI_FALLBACK (0x44 >> 2)
34#define AMDGPU_PCIE_DATA_FALLBACK (0x3C >> 2)
35
36void amdgpu_reg_access_init(struct amdgpu_device *adev)
37{
38 spin_lock_init(&adev->reg.smc.lock);
39 adev->reg.smc.rreg = NULL;
40 adev->reg.smc.wreg = NULL;
41
42 spin_lock_init(&adev->reg.uvd_ctx.lock);
43 adev->reg.uvd_ctx.rreg = NULL;
44 adev->reg.uvd_ctx.wreg = NULL;
45
46 spin_lock_init(&adev->reg.didt.lock);
47 adev->reg.didt.rreg = NULL;
48 adev->reg.didt.wreg = NULL;
49
50 spin_lock_init(&adev->reg.gc_cac.lock);
51 adev->reg.gc_cac.rreg = NULL;
52 adev->reg.gc_cac.wreg = NULL;
53
54 spin_lock_init(&adev->reg.se_cac.lock);
55 adev->reg.se_cac.rreg = NULL;
56 adev->reg.se_cac.wreg = NULL;
57
58 spin_lock_init(&adev->reg.audio_endpt.lock);
59 adev->reg.audio_endpt.rreg = NULL;
60 adev->reg.audio_endpt.wreg = NULL;
61
62 spin_lock_init(&adev->reg.pcie.lock);
63 adev->reg.pcie.rreg = NULL;
64 adev->reg.pcie.wreg = NULL;
65 adev->reg.pcie.rreg_ext = NULL;
66 adev->reg.pcie.wreg_ext = NULL;
67 adev->reg.pcie.rreg64 = NULL;
68 adev->reg.pcie.wreg64 = NULL;
69 adev->reg.pcie.rreg64_ext = NULL;
70 adev->reg.pcie.wreg64_ext = NULL;
71 adev->reg.pcie.port_rreg = NULL;
72 adev->reg.pcie.port_wreg = NULL;
73}
74
75uint32_t amdgpu_reg_smc_rd32(struct amdgpu_device *adev, uint32_t reg)
76{
77 if (!adev->reg.smc.rreg) {
78 dev_err_once(adev->dev, "SMC register read not supported\n");
79 return 0;
80 }
81 return adev->reg.smc.rreg(adev, reg);
82}
83
84void amdgpu_reg_smc_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
85{
86 if (!adev->reg.smc.wreg) {
87 dev_err_once(adev->dev, "SMC register write not supported\n");
88 return;
89 }
90 adev->reg.smc.wreg(adev, reg, v);
91}
92
93uint32_t amdgpu_reg_uvd_ctx_rd32(struct amdgpu_device *adev, uint32_t reg)
94{
95 if (!adev->reg.uvd_ctx.rreg) {
96 dev_err_once(adev->dev,
97 "UVD_CTX register read not supported\n");
98 return 0;
99 }
100 return adev->reg.uvd_ctx.rreg(adev, reg);
101}
102
103void amdgpu_reg_uvd_ctx_wr32(struct amdgpu_device *adev, uint32_t reg,
104 uint32_t v)
105{
106 if (!adev->reg.uvd_ctx.wreg) {
107 dev_err_once(adev->dev,
108 "UVD_CTX register write not supported\n");
109 return;
110 }
111 adev->reg.uvd_ctx.wreg(adev, reg, v);
112}
113
114uint32_t amdgpu_reg_didt_rd32(struct amdgpu_device *adev, uint32_t reg)
115{
116 if (!adev->reg.didt.rreg) {
117 dev_err_once(adev->dev, "DIDT register read not supported\n");
118 return 0;
119 }
120 return adev->reg.didt.rreg(adev, reg);
121}
122
123void amdgpu_reg_didt_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
124{
125 if (!adev->reg.didt.wreg) {
126 dev_err_once(adev->dev, "DIDT register write not supported\n");
127 return;
128 }
129 adev->reg.didt.wreg(adev, reg, v);
130}
131
132uint32_t amdgpu_reg_gc_cac_rd32(struct amdgpu_device *adev, uint32_t reg)
133{
134 if (!adev->reg.gc_cac.rreg) {
135 dev_err_once(adev->dev, "GC_CAC register read not supported\n");
136 return 0;
137 }
138 return adev->reg.gc_cac.rreg(adev, reg);
139}
140
141void amdgpu_reg_gc_cac_wr32(struct amdgpu_device *adev, uint32_t reg,
142 uint32_t v)
143{
144 if (!adev->reg.gc_cac.wreg) {
145 dev_err_once(adev->dev,
146 "GC_CAC register write not supported\n");
147 return;
148 }
149 adev->reg.gc_cac.wreg(adev, reg, v);
150}
151
152uint32_t amdgpu_reg_se_cac_rd32(struct amdgpu_device *adev, uint32_t reg)
153{
154 if (!adev->reg.se_cac.rreg) {
155 dev_err_once(adev->dev, "SE_CAC register read not supported\n");
156 return 0;
157 }
158 return adev->reg.se_cac.rreg(adev, reg);
159}
160
161void amdgpu_reg_se_cac_wr32(struct amdgpu_device *adev, uint32_t reg,
162 uint32_t v)
163{
164 if (!adev->reg.se_cac.wreg) {
165 dev_err_once(adev->dev,
166 "SE_CAC register write not supported\n");
167 return;
168 }
169 adev->reg.se_cac.wreg(adev, reg, v);
170}
171
172uint32_t amdgpu_reg_audio_endpt_rd32(struct amdgpu_device *adev, uint32_t block,
173 uint32_t reg)
174{
175 if (!adev->reg.audio_endpt.rreg) {
176 dev_err_once(adev->dev,
177 "AUDIO_ENDPT register read not supported\n");
178 return 0;
179 }
180 return adev->reg.audio_endpt.rreg(adev, block, reg);
181}
182
183void amdgpu_reg_audio_endpt_wr32(struct amdgpu_device *adev, uint32_t block,
184 uint32_t reg, uint32_t v)
185{
186 if (!adev->reg.audio_endpt.wreg) {
187 dev_err_once(adev->dev,
188 "AUDIO_ENDPT register write not supported\n");
189 return;
190 }
191 adev->reg.audio_endpt.wreg(adev, block, reg, v);
192}
193
194uint32_t amdgpu_reg_pcie_rd32(struct amdgpu_device *adev, uint32_t reg)
195{
196 if (!adev->reg.pcie.rreg) {
197 dev_err_once(adev->dev, "PCIE register read not supported\n");
198 return 0;
199 }
200 return adev->reg.pcie.rreg(adev, reg);
201}
202
203void amdgpu_reg_pcie_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
204{
205 if (!adev->reg.pcie.wreg) {
206 dev_err_once(adev->dev, "PCIE register write not supported\n");
207 return;
208 }
209 adev->reg.pcie.wreg(adev, reg, v);
210}
211
212uint32_t amdgpu_reg_pcie_ext_rd32(struct amdgpu_device *adev, uint64_t reg)
213{
214 if (!adev->reg.pcie.rreg_ext) {
215 dev_err_once(adev->dev, "PCIE EXT register read not supported\n");
216 return 0;
217 }
218 return adev->reg.pcie.rreg_ext(adev, reg);
219}
220
221void amdgpu_reg_pcie_ext_wr32(struct amdgpu_device *adev, uint64_t reg,
222 uint32_t v)
223{
224 if (!adev->reg.pcie.wreg_ext) {
225 dev_err_once(adev->dev, "PCIE EXT register write not supported\n");
226 return;
227 }
228 adev->reg.pcie.wreg_ext(adev, reg, v);
229}
230
231uint64_t amdgpu_reg_pcie_rd64(struct amdgpu_device *adev, uint32_t reg)
232{
233 if (!adev->reg.pcie.rreg64) {
234 dev_err_once(adev->dev, "PCIE 64-bit register read not supported\n");
235 return 0;
236 }
237 return adev->reg.pcie.rreg64(adev, reg);
238}
239
240void amdgpu_reg_pcie_wr64(struct amdgpu_device *adev, uint32_t reg, uint64_t v)
241{
242 if (!adev->reg.pcie.wreg64) {
243 dev_err_once(adev->dev, "PCIE 64-bit register write not supported\n");
244 return;
245 }
246 adev->reg.pcie.wreg64(adev, reg, v);
247}
248
249uint64_t amdgpu_reg_pcie_ext_rd64(struct amdgpu_device *adev, uint64_t reg)
250{
251 if (!adev->reg.pcie.rreg64_ext) {
252 dev_err_once(adev->dev, "PCIE EXT 64-bit register read not supported\n");
253 return 0;
254 }
255 return adev->reg.pcie.rreg64_ext(adev, reg);
256}
257
258void amdgpu_reg_pcie_ext_wr64(struct amdgpu_device *adev, uint64_t reg,
259 uint64_t v)
260{
261 if (!adev->reg.pcie.wreg64_ext) {
262 dev_err_once(adev->dev, "PCIE EXT 64-bit register write not supported\n");
263 return;
264 }
265 adev->reg.pcie.wreg64_ext(adev, reg, v);
266}
267
268uint32_t amdgpu_reg_pciep_rd32(struct amdgpu_device *adev, uint32_t reg)
269{
270 if (!adev->reg.pcie.port_rreg) {
271 dev_err_once(adev->dev, "PCIEP register read not supported\n");
272 return 0;
273 }
274 return adev->reg.pcie.port_rreg(adev, reg);
275}
276
277void amdgpu_reg_pciep_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
278{
279 if (!adev->reg.pcie.port_wreg) {
280 dev_err_once(adev->dev, "PCIEP register write not supported\n");
281 return;
282 }
283 adev->reg.pcie.port_wreg(adev, reg, v);
284}
285
286static int amdgpu_reg_get_smn_base_version(struct amdgpu_device *adev)
287{
288 struct pci_dev *pdev = adev->pdev;
289 int id;
290
291 if (amdgpu_sriov_vf(adev))
292 return -EOPNOTSUPP;
293
294 id = (pdev->device >> 4) & 0xFFFF;
295 if (id == 0x74A || id == 0x74B || id == 0x75A || id == 0x75B)
296 return 1;
297
298 return -EOPNOTSUPP;
299}
300
301uint64_t amdgpu_reg_get_smn_base64(struct amdgpu_device *adev,
302 enum amd_hw_ip_block_type block,
303 int die_inst)
304{
305 if (!adev->reg.smn.get_smn_base) {
306 int version = amdgpu_reg_get_smn_base_version(adev);
307 switch (version) {
308 case 1:
309 return amdgpu_reg_smn_v1_0_get_base(adev, block,
310 die_inst);
311 default:
312 dev_err_once(
313 adev->dev,
314 "SMN base address query not supported for this device\n");
315 return 0;
316 }
317 return 0;
318 }
319 return adev->reg.smn.get_smn_base(adev, block, die_inst);
320}
321
322uint64_t amdgpu_reg_smn_v1_0_get_base(struct amdgpu_device *adev,
323 enum amd_hw_ip_block_type block,
324 int die_inst)
325{
326 uint64_t smn_base;
327
328 if (die_inst == 0)
329 return 0;
330
331 switch (block) {
332 case XGMI_HWIP:
333 case NBIO_HWIP:
334 case MP0_HWIP:
335 case UMC_HWIP:
336 case DF_HWIP:
337 smn_base = ((uint64_t)(die_inst & 0x3) << 32) | (1ULL << 34);
338 break;
339 default:
340 dev_warn_once(
341 adev->dev,
342 "SMN base address query not supported for this block %d\n",
343 block);
344 smn_base = 0;
345 break;
346 }
347
348 return smn_base;
349}
350
351/*
352 * register access helper functions.
353 */
354
355/**
356 * amdgpu_device_rreg - read a memory mapped IO or indirect register
357 *
358 * @adev: amdgpu_device pointer
359 * @reg: dword aligned register offset
360 * @acc_flags: access flags which require special behavior
361 *
362 * Returns the 32 bit value from the offset specified.
363 */
364uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
365 uint32_t acc_flags)
366{
367 uint32_t ret;
368
369 if (amdgpu_device_skip_hw_access(adev))
370 return 0;
371
372 if ((reg * 4) < adev->rmmio_size) {
373 if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
374 amdgpu_sriov_runtime(adev) &&
375 down_read_trylock(&adev->reset_domain->sem)) {
376 ret = amdgpu_kiq_rreg(adev, reg, 0);
377 up_read(&adev->reset_domain->sem);
378 } else {
379 ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
380 }
381 } else {
382 ret = amdgpu_reg_pcie_rd32(adev, reg * 4);
383 }
384
385 trace_amdgpu_device_rreg(adev->pdev->device, reg, ret);
386
387 return ret;
388}
389
390/*
391 * MMIO register read with bytes helper functions
392 * @offset:bytes offset from MMIO start
393 */
394
395/**
396 * amdgpu_mm_rreg8 - read a memory mapped IO register
397 *
398 * @adev: amdgpu_device pointer
399 * @offset: byte aligned register offset
400 *
401 * Returns the 8 bit value from the offset specified.
402 */
403uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset)
404{
405 if (amdgpu_device_skip_hw_access(adev))
406 return 0;
407
408 if (offset < adev->rmmio_size)
409 return (readb(adev->rmmio + offset));
410 BUG();
411}
412
413/**
414 * amdgpu_device_xcc_rreg - read a memory mapped IO or indirect register with specific XCC
415 *
416 * @adev: amdgpu_device pointer
417 * @reg: dword aligned register offset
418 * @acc_flags: access flags which require special behavior
419 * @xcc_id: xcc accelerated compute core id
420 *
421 * Returns the 32 bit value from the offset specified.
422 */
423uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev, uint32_t reg,
424 uint32_t acc_flags, uint32_t xcc_id)
425{
426 uint32_t ret, rlcg_flag;
427
428 if (amdgpu_device_skip_hw_access(adev))
429 return 0;
430
431 if ((reg * 4) < adev->rmmio_size) {
432 if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_runtime(adev) &&
433 adev->gfx.rlc.rlcg_reg_access_supported &&
434 amdgpu_virt_get_rlcg_reg_access_flag(
435 adev, acc_flags, GC_HWIP, false, &rlcg_flag)) {
436 ret = amdgpu_virt_rlcg_reg_rw(adev, reg, 0, rlcg_flag,
437 GET_INST(GC, xcc_id));
438 } else if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
439 amdgpu_sriov_runtime(adev) &&
440 down_read_trylock(&adev->reset_domain->sem)) {
441 ret = amdgpu_kiq_rreg(adev, reg, xcc_id);
442 up_read(&adev->reset_domain->sem);
443 } else {
444 ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
445 }
446 } else {
447 ret = amdgpu_reg_pcie_rd32(adev, reg * 4);
448 }
449
450 return ret;
451}
452
453/*
454 * MMIO register write with bytes helper functions
455 * @offset:bytes offset from MMIO start
456 * @value: the value want to be written to the register
457 */
458
459/**
460 * amdgpu_mm_wreg8 - read a memory mapped IO register
461 *
462 * @adev: amdgpu_device pointer
463 * @offset: byte aligned register offset
464 * @value: 8 bit value to write
465 *
466 * Writes the value specified to the offset specified.
467 */
468void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
469{
470 if (amdgpu_device_skip_hw_access(adev))
471 return;
472
473 if (offset < adev->rmmio_size)
474 writeb(value, adev->rmmio + offset);
475 else
476 BUG();
477}
478
479/**
480 * amdgpu_device_wreg - write to a memory mapped IO or indirect register
481 *
482 * @adev: amdgpu_device pointer
483 * @reg: dword aligned register offset
484 * @v: 32 bit value to write to the register
485 * @acc_flags: access flags which require special behavior
486 *
487 * Writes the value specified to the offset specified.
488 */
489void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
490 uint32_t acc_flags)
491{
492 if (amdgpu_device_skip_hw_access(adev))
493 return;
494
495 if ((reg * 4) < adev->rmmio_size) {
496 if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
497 amdgpu_sriov_runtime(adev) &&
498 down_read_trylock(&adev->reset_domain->sem)) {
499 amdgpu_kiq_wreg(adev, reg, v, 0);
500 up_read(&adev->reset_domain->sem);
501 } else {
502 writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
503 }
504 } else {
505 amdgpu_reg_pcie_wr32(adev, reg * 4, v);
506 }
507
508 trace_amdgpu_device_wreg(adev->pdev->device, reg, v);
509}
510
511/**
512 * amdgpu_mm_wreg_mmio_rlc - write register either with direct/indirect mmio or with RLC path if in range
513 *
514 * @adev: amdgpu_device pointer
515 * @reg: mmio/rlc register
516 * @v: value to write
517 * @xcc_id: xcc accelerated compute core id
518 *
519 * this function is invoked only for the debugfs register access
520 */
521void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg,
522 uint32_t v, uint32_t xcc_id)
523{
524 if (amdgpu_device_skip_hw_access(adev))
525 return;
526
527 if (amdgpu_sriov_fullaccess(adev) && adev->gfx.rlc.funcs &&
528 adev->gfx.rlc.funcs->is_rlcg_access_range) {
529 if (adev->gfx.rlc.funcs->is_rlcg_access_range(adev, reg))
530 return amdgpu_sriov_wreg(adev, reg, v, 0, 0, xcc_id);
531 } else if ((reg * 4) >= adev->rmmio_size) {
532 amdgpu_reg_pcie_wr32(adev, reg * 4, v);
533 } else {
534 writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
535 }
536}
537
538/**
539 * amdgpu_device_xcc_wreg - write to a memory mapped IO or indirect register with specific XCC
540 *
541 * @adev: amdgpu_device pointer
542 * @reg: dword aligned register offset
543 * @v: 32 bit value to write to the register
544 * @acc_flags: access flags which require special behavior
545 * @xcc_id: xcc accelerated compute core id
546 *
547 * Writes the value specified to the offset specified.
548 */
549void amdgpu_device_xcc_wreg(struct amdgpu_device *adev, uint32_t reg,
550 uint32_t v, uint32_t acc_flags, uint32_t xcc_id)
551{
552 uint32_t rlcg_flag;
553
554 if (amdgpu_device_skip_hw_access(adev))
555 return;
556
557 if ((reg * 4) < adev->rmmio_size) {
558 if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_runtime(adev) &&
559 adev->gfx.rlc.rlcg_reg_access_supported &&
560 amdgpu_virt_get_rlcg_reg_access_flag(
561 adev, acc_flags, GC_HWIP, true, &rlcg_flag)) {
562 amdgpu_virt_rlcg_reg_rw(adev, reg, v, rlcg_flag,
563 GET_INST(GC, xcc_id));
564 } else if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
565 amdgpu_sriov_runtime(adev) &&
566 down_read_trylock(&adev->reset_domain->sem)) {
567 amdgpu_kiq_wreg(adev, reg, v, xcc_id);
568 up_read(&adev->reset_domain->sem);
569 } else {
570 writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
571 }
572 } else {
573 amdgpu_reg_pcie_wr32(adev, reg * 4, v);
574 }
575}
576
577/**
578 * amdgpu_device_indirect_rreg - read an indirect register
579 *
580 * @adev: amdgpu_device pointer
581 * @reg_addr: indirect register address to read from
582 *
583 * Returns the value of indirect register @reg_addr
584 */
585u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev, u32 reg_addr)
586{
587 unsigned long flags, pcie_index, pcie_data;
588 void __iomem *pcie_index_offset;
589 void __iomem *pcie_data_offset;
590 u32 r;
591
592 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
593 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
594
595 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
596 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
597 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
598
599 writel(reg_addr, pcie_index_offset);
600 readl(pcie_index_offset);
601 r = readl(pcie_data_offset);
602 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
603
604 return r;
605}
606
607u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev, u64 reg_addr)
608{
609 unsigned long flags, pcie_index, pcie_index_hi, pcie_data;
610 u32 r;
611 void __iomem *pcie_index_offset;
612 void __iomem *pcie_index_hi_offset;
613 void __iomem *pcie_data_offset;
614
615 if (unlikely(!adev->nbio.funcs)) {
616 pcie_index = AMDGPU_PCIE_INDEX_FALLBACK;
617 pcie_data = AMDGPU_PCIE_DATA_FALLBACK;
618 } else {
619 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
620 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
621 }
622
623 if (reg_addr >> 32) {
624 if (unlikely(!adev->nbio.funcs))
625 pcie_index_hi = AMDGPU_PCIE_INDEX_HI_FALLBACK;
626 else
627 pcie_index_hi =
628 adev->nbio.funcs->get_pcie_index_hi_offset(
629 adev);
630 } else {
631 pcie_index_hi = 0;
632 }
633
634 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
635 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
636 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
637 if (pcie_index_hi != 0)
638 pcie_index_hi_offset =
639 (void __iomem *)adev->rmmio + pcie_index_hi * 4;
640
641 writel(reg_addr, pcie_index_offset);
642 readl(pcie_index_offset);
643 if (pcie_index_hi != 0) {
644 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
645 readl(pcie_index_hi_offset);
646 }
647 r = readl(pcie_data_offset);
648
649 /* clear the high bits */
650 if (pcie_index_hi != 0) {
651 writel(0, pcie_index_hi_offset);
652 readl(pcie_index_hi_offset);
653 }
654
655 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
656
657 return r;
658}
659
660/**
661 * amdgpu_device_indirect_rreg64 - read a 64bits indirect register
662 *
663 * @adev: amdgpu_device pointer
664 * @reg_addr: indirect register address to read from
665 *
666 * Returns the value of indirect register @reg_addr
667 */
668u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev, u32 reg_addr)
669{
670 unsigned long flags, pcie_index, pcie_data;
671 void __iomem *pcie_index_offset;
672 void __iomem *pcie_data_offset;
673 u64 r;
674
675 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
676 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
677
678 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
679 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
680 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
681
682 /* read low 32 bits */
683 writel(reg_addr, pcie_index_offset);
684 readl(pcie_index_offset);
685 r = readl(pcie_data_offset);
686 /* read high 32 bits */
687 writel(reg_addr + 4, pcie_index_offset);
688 readl(pcie_index_offset);
689 r |= ((u64)readl(pcie_data_offset) << 32);
690 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
691
692 return r;
693}
694
695u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev, u64 reg_addr)
696{
697 unsigned long flags, pcie_index, pcie_data;
698 unsigned long pcie_index_hi = 0;
699 void __iomem *pcie_index_offset;
700 void __iomem *pcie_index_hi_offset;
701 void __iomem *pcie_data_offset;
702 u64 r;
703
704 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
705 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
706 if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
707 pcie_index_hi =
708 adev->nbio.funcs->get_pcie_index_hi_offset(adev);
709
710 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
711 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
712 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
713 if (pcie_index_hi != 0)
714 pcie_index_hi_offset =
715 (void __iomem *)adev->rmmio + pcie_index_hi * 4;
716
717 /* read low 32 bits */
718 writel(reg_addr, pcie_index_offset);
719 readl(pcie_index_offset);
720 if (pcie_index_hi != 0) {
721 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
722 readl(pcie_index_hi_offset);
723 }
724 r = readl(pcie_data_offset);
725 /* read high 32 bits */
726 writel(reg_addr + 4, pcie_index_offset);
727 readl(pcie_index_offset);
728 if (pcie_index_hi != 0) {
729 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
730 readl(pcie_index_hi_offset);
731 }
732 r |= ((u64)readl(pcie_data_offset) << 32);
733
734 /* clear the high bits */
735 if (pcie_index_hi != 0) {
736 writel(0, pcie_index_hi_offset);
737 readl(pcie_index_hi_offset);
738 }
739
740 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
741
742 return r;
743}
744
745/**
746 * amdgpu_device_indirect_wreg - write an indirect register address
747 *
748 * @adev: amdgpu_device pointer
749 * @reg_addr: indirect register offset
750 * @reg_data: indirect register data
751 *
752 */
753void amdgpu_device_indirect_wreg(struct amdgpu_device *adev, u32 reg_addr,
754 u32 reg_data)
755{
756 unsigned long flags, pcie_index, pcie_data;
757 void __iomem *pcie_index_offset;
758 void __iomem *pcie_data_offset;
759
760 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
761 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
762
763 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
764 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
765 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
766
767 writel(reg_addr, pcie_index_offset);
768 readl(pcie_index_offset);
769 writel(reg_data, pcie_data_offset);
770 readl(pcie_data_offset);
771 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
772}
773
774void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev, u64 reg_addr,
775 u32 reg_data)
776{
777 unsigned long flags, pcie_index, pcie_index_hi, pcie_data;
778 void __iomem *pcie_index_offset;
779 void __iomem *pcie_index_hi_offset;
780 void __iomem *pcie_data_offset;
781
782 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
783 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
784 if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
785 pcie_index_hi =
786 adev->nbio.funcs->get_pcie_index_hi_offset(adev);
787 else
788 pcie_index_hi = 0;
789
790 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
791 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
792 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
793 if (pcie_index_hi != 0)
794 pcie_index_hi_offset =
795 (void __iomem *)adev->rmmio + pcie_index_hi * 4;
796
797 writel(reg_addr, pcie_index_offset);
798 readl(pcie_index_offset);
799 if (pcie_index_hi != 0) {
800 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
801 readl(pcie_index_hi_offset);
802 }
803 writel(reg_data, pcie_data_offset);
804 readl(pcie_data_offset);
805
806 /* clear the high bits */
807 if (pcie_index_hi != 0) {
808 writel(0, pcie_index_hi_offset);
809 readl(pcie_index_hi_offset);
810 }
811
812 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
813}
814
815/**
816 * amdgpu_device_indirect_wreg64 - write a 64bits indirect register address
817 *
818 * @adev: amdgpu_device pointer
819 * @reg_addr: indirect register offset
820 * @reg_data: indirect register data
821 *
822 */
823void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev, u32 reg_addr,
824 u64 reg_data)
825{
826 unsigned long flags, pcie_index, pcie_data;
827 void __iomem *pcie_index_offset;
828 void __iomem *pcie_data_offset;
829
830 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
831 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
832
833 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
834 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
835 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
836
837 /* write low 32 bits */
838 writel(reg_addr, pcie_index_offset);
839 readl(pcie_index_offset);
840 writel((u32)(reg_data & 0xffffffffULL), pcie_data_offset);
841 readl(pcie_data_offset);
842 /* write high 32 bits */
843 writel(reg_addr + 4, pcie_index_offset);
844 readl(pcie_index_offset);
845 writel((u32)(reg_data >> 32), pcie_data_offset);
846 readl(pcie_data_offset);
847 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
848}
849
850void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev, u64 reg_addr,
851 u64 reg_data)
852{
853 unsigned long flags, pcie_index, pcie_data;
854 unsigned long pcie_index_hi = 0;
855 void __iomem *pcie_index_offset;
856 void __iomem *pcie_index_hi_offset;
857 void __iomem *pcie_data_offset;
858
859 pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
860 pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
861 if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
862 pcie_index_hi =
863 adev->nbio.funcs->get_pcie_index_hi_offset(adev);
864
865 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
866 pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
867 pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
868 if (pcie_index_hi != 0)
869 pcie_index_hi_offset =
870 (void __iomem *)adev->rmmio + pcie_index_hi * 4;
871
872 /* write low 32 bits */
873 writel(reg_addr, pcie_index_offset);
874 readl(pcie_index_offset);
875 if (pcie_index_hi != 0) {
876 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
877 readl(pcie_index_hi_offset);
878 }
879 writel((u32)(reg_data & 0xffffffffULL), pcie_data_offset);
880 readl(pcie_data_offset);
881 /* write high 32 bits */
882 writel(reg_addr + 4, pcie_index_offset);
883 readl(pcie_index_offset);
884 if (pcie_index_hi != 0) {
885 writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
886 readl(pcie_index_hi_offset);
887 }
888 writel((u32)(reg_data >> 32), pcie_data_offset);
889 readl(pcie_data_offset);
890
891 /* clear the high bits */
892 if (pcie_index_hi != 0) {
893 writel(0, pcie_index_hi_offset);
894 readl(pcie_index_hi_offset);
895 }
896
897 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
898}
899
900u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev, u32 reg)
901{
902 unsigned long flags, address, data;
903 u32 r;
904
905 address = adev->nbio.funcs->get_pcie_port_index_offset(adev);
906 data = adev->nbio.funcs->get_pcie_port_data_offset(adev);
907
908 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
909 WREG32(address, reg * 4);
910 (void)RREG32(address);
911 r = RREG32(data);
912 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
913 return r;
914}
915
916void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
917{
918 unsigned long flags, address, data;
919
920 address = adev->nbio.funcs->get_pcie_port_index_offset(adev);
921 data = adev->nbio.funcs->get_pcie_port_data_offset(adev);
922
923 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
924 WREG32(address, reg * 4);
925 (void)RREG32(address);
926 WREG32(data, v);
927 (void)RREG32(data);
928 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
929}
930
931uint32_t amdgpu_device_wait_on_rreg(struct amdgpu_device *adev, uint32_t inst,
932 uint32_t reg_addr, char reg_name[],
933 uint32_t expected_value, uint32_t mask)
934{
935 uint32_t ret = 0;
936 uint32_t old_ = 0;
937 uint32_t tmp_ = RREG32(reg_addr);
938 uint32_t loop = adev->usec_timeout;
939
940 while ((tmp_ & (mask)) != (expected_value)) {
941 if (old_ != tmp_) {
942 loop = adev->usec_timeout;
943 old_ = tmp_;
944 } else
945 udelay(1);
946 tmp_ = RREG32(reg_addr);
947 loop--;
948 if (!loop) {
949 dev_warn(
950 adev->dev,
951 "Register(%d) [%s] failed to reach value 0x%08x != 0x%08xn",
952 inst, reg_name, (uint32_t)expected_value,
953 (uint32_t)(tmp_ & (mask)));
954 ret = -ETIMEDOUT;
955 break;
956 }
957 }
958 return ret;
959}
drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h+163−0
@@ -0,0 +1,163 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2025 Advanced Micro Devices, 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
24#ifndef __AMDGPU_REG_ACCESS_H__
25#define __AMDGPU_REG_ACCESS_H__
26
27#include <linux/types.h>
28#include <linux/spinlock.h>
29
30#include "amdgpu_ip.h"
31
32struct amdgpu_device;
33
34typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device *, uint32_t);
35typedef void (*amdgpu_wreg_t)(struct amdgpu_device *, uint32_t, uint32_t);
36typedef uint32_t (*amdgpu_rreg_ext_t)(struct amdgpu_device *, uint64_t);
37typedef void (*amdgpu_wreg_ext_t)(struct amdgpu_device *, uint64_t, uint32_t);
38typedef uint64_t (*amdgpu_rreg64_t)(struct amdgpu_device *, uint32_t);
39typedef void (*amdgpu_wreg64_t)(struct amdgpu_device *, uint32_t, uint64_t);
40typedef uint64_t (*amdgpu_rreg64_ext_t)(struct amdgpu_device *, uint64_t);
41typedef void (*amdgpu_wreg64_ext_t)(struct amdgpu_device *, uint64_t, uint64_t);
42
43typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device *, uint32_t,
44 uint32_t);
45typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device *, uint32_t, uint32_t,
46 uint32_t);
47typedef uint64_t (*amdgpu_reg_get_smn_base64_t)(struct amdgpu_device *adev,
48 enum amd_hw_ip_block_type block,
49 int die_inst);
50
51struct amdgpu_reg_ind {
52 spinlock_t lock;
53 amdgpu_rreg_t rreg;
54 amdgpu_wreg_t wreg;
55};
56
57struct amdgpu_reg_ind_blk {
58 spinlock_t lock;
59 amdgpu_block_rreg_t rreg;
60 amdgpu_block_wreg_t wreg;
61};
62
63struct amdgpu_reg_pcie_ind {
64 spinlock_t lock;
65 amdgpu_rreg_t rreg;
66 amdgpu_wreg_t wreg;
67 amdgpu_rreg_ext_t rreg_ext;
68 amdgpu_wreg_ext_t wreg_ext;
69 amdgpu_rreg64_t rreg64;
70 amdgpu_wreg64_t wreg64;
71 amdgpu_rreg64_ext_t rreg64_ext;
72 amdgpu_wreg64_ext_t wreg64_ext;
73 amdgpu_rreg_t port_rreg;
74 amdgpu_wreg_t port_wreg;
75};
76
77struct amdgpu_reg_smn_ext {
78 amdgpu_reg_get_smn_base64_t get_smn_base;
79};
80
81struct amdgpu_reg_access {
82 struct amdgpu_reg_ind smc;
83 struct amdgpu_reg_ind uvd_ctx;
84 struct amdgpu_reg_ind didt;
85 struct amdgpu_reg_ind gc_cac;
86 struct amdgpu_reg_ind se_cac;
87 struct amdgpu_reg_ind_blk audio_endpt;
88 struct amdgpu_reg_pcie_ind pcie;
89 struct amdgpu_reg_smn_ext smn;
90};
91
92void amdgpu_reg_access_init(struct amdgpu_device *adev);
93uint32_t amdgpu_reg_smc_rd32(struct amdgpu_device *adev, uint32_t reg);
94void amdgpu_reg_smc_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
95uint32_t amdgpu_reg_uvd_ctx_rd32(struct amdgpu_device *adev, uint32_t reg);
96void amdgpu_reg_uvd_ctx_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
97uint32_t amdgpu_reg_didt_rd32(struct amdgpu_device *adev, uint32_t reg);
98void amdgpu_reg_didt_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
99uint32_t amdgpu_reg_gc_cac_rd32(struct amdgpu_device *adev, uint32_t reg);
100void amdgpu_reg_gc_cac_wr32(struct amdgpu_device *adev, uint32_t reg,
101 uint32_t v);
102uint32_t amdgpu_reg_se_cac_rd32(struct amdgpu_device *adev, uint32_t reg);
103void amdgpu_reg_se_cac_wr32(struct amdgpu_device *adev, uint32_t reg,
104 uint32_t v);
105uint32_t amdgpu_reg_audio_endpt_rd32(struct amdgpu_device *adev, uint32_t block,
106 uint32_t reg);
107void amdgpu_reg_audio_endpt_wr32(struct amdgpu_device *adev, uint32_t block,
108 uint32_t reg, uint32_t v);
109uint32_t amdgpu_reg_pcie_rd32(struct amdgpu_device *adev, uint32_t reg);
110void amdgpu_reg_pcie_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
111uint32_t amdgpu_reg_pcie_ext_rd32(struct amdgpu_device *adev, uint64_t reg);
112void amdgpu_reg_pcie_ext_wr32(struct amdgpu_device *adev, uint64_t reg,
113 uint32_t v);
114uint64_t amdgpu_reg_pcie_rd64(struct amdgpu_device *adev, uint32_t reg);
115void amdgpu_reg_pcie_wr64(struct amdgpu_device *adev, uint32_t reg, uint64_t v);
116uint64_t amdgpu_reg_pcie_ext_rd64(struct amdgpu_device *adev, uint64_t reg);
117void amdgpu_reg_pcie_ext_wr64(struct amdgpu_device *adev, uint64_t reg,
118 uint64_t v);
119uint32_t amdgpu_reg_pciep_rd32(struct amdgpu_device *adev, uint32_t reg);
120void amdgpu_reg_pciep_wr32(struct amdgpu_device *adev, uint32_t reg,
121 uint32_t v);
122uint64_t amdgpu_reg_get_smn_base64(struct amdgpu_device *adev,
123 enum amd_hw_ip_block_type block,
124 int die_inst);
125uint64_t amdgpu_reg_smn_v1_0_get_base(struct amdgpu_device *adev,
126 enum amd_hw_ip_block_type block,
127 int die_inst);
128
129uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
130 uint32_t acc_flags);
131uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev, uint32_t reg,
132 uint32_t acc_flags, uint32_t xcc_id);
133void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
134 uint32_t acc_flags);
135void amdgpu_device_xcc_wreg(struct amdgpu_device *adev, uint32_t reg,
136 uint32_t v, uint32_t acc_flags, uint32_t xcc_id);
137void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg,
138 uint32_t v, uint32_t xcc_id);
139void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset,
140 uint8_t value);
141uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
142
143u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev, u32 reg_addr);
144u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev, u64 reg_addr);
145u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev, u32 reg_addr);
146u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev, u64 reg_addr);
147void amdgpu_device_indirect_wreg(struct amdgpu_device *adev, u32 reg_addr,
148 u32 reg_data);
149void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev, u64 reg_addr,
150 u32 reg_data);
151void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev, u32 reg_addr,
152 u64 reg_data);
153void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev, u64 reg_addr,
154 u64 reg_data);
155
156u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev, u32 reg);
157void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev, u32 reg, u32 v);
158
159uint32_t amdgpu_device_wait_on_rreg(struct amdgpu_device *adev, uint32_t inst,
160 uint32_t reg_addr, char reg_name[],
161 uint32_t expected_value, uint32_t mask);
162
163#endif /* __AMDGPU_REG_ACCESS_H__ */
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c+9−37
@@ -90,10 +90,13 @@ int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned int ndw) · 89 unmodified lines
90 ndw = (ndw + ring->funcs->align_mask) & ~ring->funcs->align_mask;90 ndw = (ndw + ring->funcs->align_mask) & ~ring->funcs->align_mask;
91 91
92 /* Make sure we aren't trying to allocate more space92 /* Make sure we aren't trying to allocate more space
93 * than the maximum for one submission93 * than the maximum for one submission. Skip for reemit
94 * since we may be reemitting several submissions.
94 */95 */
95 if (WARN_ON_ONCE(ndw > ring->max_dw))96 if (!ring->reemit) {
96 return -ENOMEM;97 if (WARN_ON_ONCE(ndw > ring->max_dw))
98 return -ENOMEM;
99 }
97 100
98 ring->count_dw = ndw;101 ring->count_dw = ndw;
99 ring->wptr_old = ring->wptr;102 ring->wptr_old = ring->wptr;
@@ -104,29 +107,6 @@ int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned int ndw) · 4 unmodified lines
104 return 0;107 return 0;
105}108}
106 109
107/**
108 * amdgpu_ring_alloc_reemit - allocate space on the ring buffer for reemit
109 *
110 * @ring: amdgpu_ring structure holding ring information
111 * @ndw: number of dwords to allocate in the ring buffer
112 *
113 * Allocate @ndw dwords in the ring buffer (all asics).
114 * doesn't check the max_dw limit as we may be reemitting
115 * several submissions.
116 */
117static void amdgpu_ring_alloc_reemit(struct amdgpu_ring *ring, unsigned int ndw)
118{
119 /* Align requested size with padding so unlock_commit can
120 * pad safely */
121 ndw = (ndw + ring->funcs->align_mask) & ~ring->funcs->align_mask;
122
123 ring->count_dw = ndw;
124 ring->wptr_old = ring->wptr;
125
126 if (ring->funcs->begin_use)
127 ring->funcs->begin_use(ring);
128}
129
130/**110/**
131 * amdgpu_ring_insert_nop - insert NOP packets111 * amdgpu_ring_insert_nop - insert NOP packets
132 *112 *
@@ -875,7 +855,6 @@ void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring, · 742 unmodified lines
875int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,855int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,
876 struct amdgpu_fence *guilty_fence)856 struct amdgpu_fence *guilty_fence)
877{857{
878 unsigned int i;
879 int r;858 int r;
880 859
881 /* verify that the ring is functional */860 /* verify that the ring is functional */
@@ -883,16 +862,9 @@ int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring, · 1 unmodified line
883 if (r)862 if (r)
884 return r;863 return r;
885 864
886 /* set an error on all fences from the context */865 /* set an error on all fences from the context and reemit */
887 if (guilty_fence)866 amdgpu_ring_set_fence_errors_and_reemit(ring, guilty_fence);
888 amdgpu_fence_driver_update_timedout_fence_state(guilty_fence);867
889 /* Re-emit the non-guilty commands */
890 if (ring->ring_backup_entries_to_copy) {
891 amdgpu_ring_alloc_reemit(ring, ring->ring_backup_entries_to_copy);
892 for (i = 0; i < ring->ring_backup_entries_to_copy; i++)
893 amdgpu_ring_write(ring, ring->ring_backup[i]);
894 amdgpu_ring_commit(ring);
895 }
896 return 0;868 return 0;
897}869}
898 870
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+24−18
@@ -121,7 +121,6 @@ struct amdgpu_fence_driver { · 120 unmodified lines
121 /* sync_seq is protected by ring emission lock */121 /* sync_seq is protected by ring emission lock */
122 uint32_t sync_seq;122 uint32_t sync_seq;
123 atomic_t last_seq;123 atomic_t last_seq;
124 u64 signalled_wptr;
125 bool initialized;124 bool initialized;
126 struct amdgpu_irq_src *irq_src;125 struct amdgpu_irq_src *irq_src;
127 unsigned irq_type;126 unsigned irq_type;
@@ -146,23 +145,23 @@ struct amdgpu_fence { · 18 unmodified lines
146 struct amdgpu_ring *ring;145 struct amdgpu_ring *ring;
147 ktime_t start_timestamp;146 ktime_t start_timestamp;
148 147
149 /* wptr for the total submission for resets */148 /* location and size of the IB */
150 u64 wptr;149 u64 ib_wptr;
150 unsigned int ib_dw_size;
151 unsigned int skip_ib_dw_start_offset;
152 unsigned int skip_ib_dw_end_offset;
151 /* fence context for resets */153 /* fence context for resets */
152 u64 context;154 u64 context;
153 /* has this fence been reemitted */155 /* idx for ring backups */
154 unsigned int reemitted;156 unsigned int backup_idx;
155 /* wptr for the fence for the submission */
156 u64 fence_wptr_start;
157 u64 fence_wptr_end;
158};157};
159 158
160extern const struct drm_sched_backend_ops amdgpu_sched_ops;159extern const struct drm_sched_backend_ops amdgpu_sched_ops;
161 160
162void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);161void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);
163void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);162void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
164void amdgpu_fence_driver_update_timedout_fence_state(struct amdgpu_fence *af);163void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
165void amdgpu_fence_save_wptr(struct amdgpu_fence *af);164 struct amdgpu_fence *guilty_fence);
166 165
167int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);166int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
168int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,167int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
@@ -172,8 +171,8 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev); · 3 unmodified lines
172void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev);171void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev);
173int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev);172int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev);
174void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev);173void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev);
175int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,174void amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
176 unsigned int flags);175 unsigned int flags);
177int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s,176int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s,
178 uint32_t timeout);177 uint32_t timeout);
179bool amdgpu_fence_process(struct amdgpu_ring *ring);178bool amdgpu_fence_process(struct amdgpu_ring *ring);
@@ -313,6 +312,7 @@ struct amdgpu_ring { · 133 unmodified lines
313 /* backups for resets */312 /* backups for resets */
314 uint32_t *ring_backup;313 uint32_t *ring_backup;
315 unsigned int ring_backup_entries_to_copy;314 unsigned int ring_backup_entries_to_copy;
315 bool reemit;
316 unsigned rptr_offs;316 unsigned rptr_offs;
317 u64 rptr_gpu_addr;317 u64 rptr_gpu_addr;
318 u32 *rptr_cpu_addr;318 u32 *rptr_cpu_addr;
@@ -522,6 +522,17 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, · 203 unmodified lines
522 ring->count_dw -= count_dw;522 ring->count_dw -= count_dw;
523}523}
524 524
525static inline unsigned int amdgpu_ring_get_dw_distance(struct amdgpu_ring *ring,
526 u64 start_wptr, u64 end_wptr)
527{
528 unsigned int start = start_wptr & ring->buf_mask;
529 unsigned int end = end_wptr & ring->buf_mask;
530
531 if (end < start)
532 end += ring->ring_size >> 2;
533 return end - start;
534}
535
525/**536/**
526 * amdgpu_ring_patch_cond_exec - patch dw count of conditional execute537 * amdgpu_ring_patch_cond_exec - patch dw count of conditional execute
527 * @ring: amdgpu_ring structure538 * @ring: amdgpu_ring structure
@@ -532,18 +543,13 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, · 4 unmodified lines
532static inline void amdgpu_ring_patch_cond_exec(struct amdgpu_ring *ring,543static inline void amdgpu_ring_patch_cond_exec(struct amdgpu_ring *ring,
533 unsigned int offset)544 unsigned int offset)
534{545{
535 unsigned cur;
536
537 if (!ring->funcs->init_cond_exec)546 if (!ring->funcs->init_cond_exec)
538 return;547 return;
539 548
540 WARN_ON(offset > ring->buf_mask);549 WARN_ON(offset > ring->buf_mask);
541 WARN_ON(ring->ring[offset] != 0);550 WARN_ON(ring->ring[offset] != 0);
542 551
543 cur = (ring->wptr - 1) & ring->buf_mask;552 ring->ring[offset] = amdgpu_ring_get_dw_distance(ring, offset, ring->wptr - 1);
544 if (cur < offset)
545 cur += ring->ring_size >> 2;
546 ring->ring[offset] = cur - offset;
547}553}
548 554
549int amdgpu_ring_test_helper(struct amdgpu_ring *ring);555int amdgpu_ring_test_helper(struct amdgpu_ring *ring);
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c+106−51
@@ -163,7 +163,8 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, · 162 unmodified lines
163}163}
164 164
165static struct dma_fence *165static struct dma_fence *
166amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_job *job, u32 num_dw)166amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entity *entity,
167 struct amdgpu_job *job, u32 num_dw)
167{168{
168 struct amdgpu_ring *ring;169 struct amdgpu_ring *ring;
169 170
@@ -171,6 +172,8 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_job *job, u32 nu · 1 unmodified line
171 amdgpu_ring_pad_ib(ring, &job->ibs[0]);172 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
172 WARN_ON(job->ibs[0].length_dw > num_dw);173 WARN_ON(job->ibs[0].length_dw > num_dw);
173 174
175 lockdep_assert_held(&entity->lock);
176
174 return amdgpu_job_submit(job);177 return amdgpu_job_submit(job);
175}178}
176 179
@@ -228,9 +231,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity, · 51 unmodified lines
228 231
229 *size = min(*size, (uint64_t)num_pages * PAGE_SIZE - offset);232 *size = min(*size, (uint64_t)num_pages * PAGE_SIZE - offset);
230 233
231 *addr = adev->gmc.gart_start;234 *addr = amdgpu_compute_gart_address(&adev->gmc, entity, window);
232 *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
233 AMDGPU_GPU_PAGE_SIZE;
234 *addr += offset;235 *addr += offset;
235 236
236 num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);237 num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
@@ -248,7 +249,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity, · 11 unmodified lines
248 src_addr += job->ibs[0].gpu_addr;249 src_addr += job->ibs[0].gpu_addr;
249 250
250 dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);251 dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
251 dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8;252 dst_addr += (entity->gart_window_offs[window] >> AMDGPU_GPU_PAGE_SHIFT) * 8;
252 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,253 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
253 dst_addr, num_bytes, 0);254 dst_addr, num_bytes, 0);
254 255
@@ -269,7 +270,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity, · 14 unmodified lines
269 amdgpu_gart_map_vram_range(adev, pa, 0, num_pages, flags, cpu_addr);270 amdgpu_gart_map_vram_range(adev, pa, 0, num_pages, flags, cpu_addr);
270 }271 }
271 272
272 dma_fence_put(amdgpu_ttm_job_submit(adev, job, num_dw));273 dma_fence_put(amdgpu_ttm_job_submit(adev, entity, job, num_dw));
273 return 0;274 return 0;
274}275}
275 276
@@ -313,7 +314,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, · 37 unmodified lines
313 amdgpu_res_first(src->mem, src->offset, size, &src_mm);314 amdgpu_res_first(src->mem, src->offset, size, &src_mm);
314 amdgpu_res_first(dst->mem, dst->offset, size, &dst_mm);315 amdgpu_res_first(dst->mem, dst->offset, size, &dst_mm);
315 316
316 mutex_lock(&adev->mman.gtt_window_lock);317 mutex_lock(&entity->lock);
317 while (src_mm.remaining) {318 while (src_mm.remaining) {
318 uint64_t from, to, cur_size, tiling_flags;319 uint64_t from, to, cur_size, tiling_flags;
319 uint32_t num_type, data_format, max_com, write_compress_disable;320 uint32_t num_type, data_format, max_com, write_compress_disable;
@@ -368,7 +369,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, · 48 unmodified lines
368 amdgpu_res_next(&dst_mm, cur_size);369 amdgpu_res_next(&dst_mm, cur_size);
369 }370 }
370error:371error:
371 mutex_unlock(&adev->mman.gtt_window_lock);372 mutex_unlock(&entity->lock);
372 *f = fence;373 *f = fence;
373 return r;374 return r;
374}375}
@@ -1580,7 +1581,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo, · 1205 unmodified lines
1580 if (r)1581 if (r)
1581 goto out;1582 goto out;
1582 1583
1583 mutex_lock(&adev->mman.gtt_window_lock);1584 mutex_lock(&adev->mman.default_entity.lock);
1584 amdgpu_res_first(abo->tbo.resource, offset, len, &src_mm);1585 amdgpu_res_first(abo->tbo.resource, offset, len, &src_mm);
1585 src_addr = amdgpu_ttm_domain_start(adev, bo->resource->mem_type) +1586 src_addr = amdgpu_ttm_domain_start(adev, bo->resource->mem_type) +
1586 src_mm.start;1587 src_mm.start;
@@ -1591,8 +1592,8 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo, · 4 unmodified lines
1591 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr,1592 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr,
1592 PAGE_SIZE, 0);1593 PAGE_SIZE, 0);
1593 1594
1594 fence = amdgpu_ttm_job_submit(adev, job, num_dw);1595 fence = amdgpu_ttm_job_submit(adev, &adev->mman.default_entity, job, num_dw);
1595 mutex_unlock(&adev->mman.gtt_window_lock);1596 mutex_unlock(&adev->mman.default_entity.lock);
1596 1597
1597 if (!dma_fence_wait_timeout(fence, false, adev->sdma_timeout))1598 if (!dma_fence_wait_timeout(fence, false, adev->sdma_timeout))
1598 r = -ETIMEDOUT;1599 r = -ETIMEDOUT;
@@ -1908,7 +1909,7 @@ static void amdgpu_ttm_pools_fini(struct amdgpu_device *adev) · 309 unmodified lines
1908}1909}
1909 1910
1910/**1911/**
1911 * amdgpu_ttm_mmio_remap_bo_init - Allocate the singleton MMIO_REMAP BO1912 * amdgpu_ttm_alloc_mmio_remap_bo - Allocate the singleton MMIO_REMAP BO
1912 * @adev: amdgpu device1913 * @adev: amdgpu device
1913 *1914 *
1914 * Allocates a global BO with backing AMDGPU_PL_MMIO_REMAP when the1915 * Allocates a global BO with backing AMDGPU_PL_MMIO_REMAP when the
@@ -2013,6 +2014,50 @@ static void amdgpu_ttm_free_mmio_remap_bo(struct amdgpu_device *adev) · 98 unmodified lines
2013 adev->rmmio_remap.bo = NULL;2014 adev->rmmio_remap.bo = NULL;
2014}2015}
2015 2016
2017static int amdgpu_ttm_buffer_entity_init(struct amdgpu_gtt_mgr *mgr,
2018 struct amdgpu_ttm_buffer_entity *entity,
2019 enum drm_sched_priority prio,
2020 struct drm_gpu_scheduler **scheds,
2021 int num_schedulers,
2022 u32 num_gart_windows)
2023{
2024 int i, r, num_pages;
2025
2026 r = drm_sched_entity_init(&entity->base, prio, scheds, num_schedulers, NULL);
2027 if (r)
2028 return r;
2029
2030 mutex_init(&entity->lock);
2031
2032 if (ARRAY_SIZE(entity->gart_window_offs) < num_gart_windows)
2033 return -EINVAL;
2034 if (num_gart_windows == 0)
2035 return 0;
2036
2037 num_pages = num_gart_windows * AMDGPU_GTT_MAX_TRANSFER_SIZE;
2038 r = amdgpu_gtt_mgr_alloc_entries(mgr, &entity->gart_node, num_pages,
2039 DRM_MM_INSERT_BEST);
2040 if (r) {
2041 drm_sched_entity_destroy(&entity->base);
2042 return r;
2043 }
2044
2045 for (i = 0; i < num_gart_windows; i++) {
2046 entity->gart_window_offs[i] =
2047 amdgpu_gtt_node_to_byte_offset(&entity->gart_node) +
2048 i * AMDGPU_GTT_MAX_TRANSFER_SIZE * PAGE_SIZE;
2049 }
2050
2051 return 0;
2052}
2053
2054static void amdgpu_ttm_buffer_entity_fini(struct amdgpu_gtt_mgr *mgr,
2055 struct amdgpu_ttm_buffer_entity *entity)
2056{
2057 amdgpu_gtt_mgr_free_entries(mgr, &entity->gart_node);
2058 drm_sched_entity_destroy(&entity->base);
2059}
2060
2016/*2061/*
2017 * amdgpu_ttm_init - Init the memory management (ttm) as well as various2062 * amdgpu_ttm_init - Init the memory management (ttm) as well as various
2018 * gtt/vram related fields.2063 * gtt/vram related fields.
@@ -2027,8 +2072,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 8 unmodified lines
2027 uint64_t gtt_size;2072 uint64_t gtt_size;
2028 int r;2073 int r;
2029 2074
2030 mutex_init(&adev->mman.gtt_window_lock);
2031
2032 dma_set_max_seg_size(adev->dev, UINT_MAX);2075 dma_set_max_seg_size(adev->dev, UINT_MAX);
2033 /* No others user of address space so set it to 0 */2076 /* No others user of address space so set it to 0 */
2034 r = ttm_device_init(&adev->mman.bdev, &amdgpu_bo_driver, adev->dev,2077 r = ttm_device_init(&adev->mman.bdev, &amdgpu_bo_driver, adev->dev,
@@ -2313,42 +2356,49 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) · 278 unmodified lines
2313 struct amdgpu_ring *ring;2356 struct amdgpu_ring *ring;
2314 struct drm_gpu_scheduler *sched;2357 struct drm_gpu_scheduler *sched;
2315 2358
2359 if (!adev->mman.buffer_funcs_ring || !adev->mman.buffer_funcs_ring->sched.ready) {
2360 dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
2361 return;
2362 }
2363
2316 ring = adev->mman.buffer_funcs_ring;2364 ring = adev->mman.buffer_funcs_ring;
2317 sched = &ring->sched;2365 sched = &ring->sched;
2318 r = drm_sched_entity_init(&adev->mman.default_entity.base,2366 r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
2319 DRM_SCHED_PRIORITY_KERNEL, &sched,2367 &adev->mman.default_entity,
2320 1, NULL);2368 DRM_SCHED_PRIORITY_KERNEL,
2321 if (r) {2369 &sched, 1, 0);
2370 if (r < 0) {
2322 dev_err(adev->dev,2371 dev_err(adev->dev,
2323 "Failed setting up TTM BO move entity (%d)\n",2372 "Failed setting up TTM entity (%d)\n", r);
2324 r);
2325 return;2373 return;
2326 }2374 }
2327 2375
2328 r = drm_sched_entity_init(&adev->mman.clear_entity.base,2376 r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
2329 DRM_SCHED_PRIORITY_NORMAL, &sched,2377 &adev->mman.clear_entity,
2330 1, NULL);2378 DRM_SCHED_PRIORITY_NORMAL,
2331 if (r) {2379 &sched, 1, 1);
2380 if (r < 0) {
2332 dev_err(adev->dev,2381 dev_err(adev->dev,
2333 "Failed setting up TTM BO clear entity (%d)\n",2382 "Failed setting up TTM BO clear entity (%d)\n", r);
2334 r);2383 goto error_free_default_entity;
2335 goto error_free_entity;
2336 }2384 }
2337 2385
2338 r = drm_sched_entity_init(&adev->mman.move_entity.base,2386 r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
2339 DRM_SCHED_PRIORITY_NORMAL, &sched,2387 &adev->mman.move_entity,
2340 1, NULL);2388 DRM_SCHED_PRIORITY_NORMAL,
2341 if (r) {2389 &sched, 1, 2);
2390 if (r < 0) {
2342 dev_err(adev->dev,2391 dev_err(adev->dev,
2343 "Failed setting up TTM BO move entity (%d)\n",2392 "Failed setting up TTM BO move entity (%d)\n", r);
2344 r);2393 goto error_free_clear_entity;
2345 drm_sched_entity_destroy(&adev->mman.clear_entity.base);
2346 goto error_free_entity;
2347 }2394 }
2348 } else {2395 } else {
2349 drm_sched_entity_destroy(&adev->mman.default_entity.base);2396 amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
2350 drm_sched_entity_destroy(&adev->mman.clear_entity.base);2397 &adev->mman.default_entity);
2351 drm_sched_entity_destroy(&adev->mman.move_entity.base);2398 amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
2399 &adev->mman.clear_entity);
2400 amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
2401 &adev->mman.move_entity);
2352 /* Drop all the old fences since re-creating the scheduler entities2402 /* Drop all the old fences since re-creating the scheduler entities
2353 * will allocate new contexts.2403 * will allocate new contexts.
2354 */2404 */
@@ -2365,8 +2415,12 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) · 10 unmodified lines
2365 2415
2366 return;2416 return;
2367 2417
2368error_free_entity:2418error_free_clear_entity:
2369 drm_sched_entity_destroy(&adev->mman.default_entity.base);2419 amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
2420 &adev->mman.clear_entity);
2421error_free_default_entity:
2422 amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
2423 &adev->mman.default_entity);
2370}2424}
2371 2425
2372static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,2426static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
@@ -2440,7 +2494,7 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev, · 67 unmodified lines
2440 byte_count -= cur_size_in_bytes;2494 byte_count -= cur_size_in_bytes;
2441 }2495 }
2442 2496
2443 *fence = amdgpu_ttm_job_submit(adev, job, num_dw);2497 *fence = amdgpu_ttm_job_submit(adev, entity, job, num_dw);
2444 2498
2445 return 0;2499 return 0;
2446 2500
@@ -2483,7 +2537,7 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev, · 36 unmodified lines
2483 byte_count -= cur_size;2537 byte_count -= cur_size;
2484 }2538 }
2485 2539
2486 *fence = amdgpu_ttm_job_submit(adev, job, num_dw);2540 *fence = amdgpu_ttm_job_submit(adev, entity, job, num_dw);
2487 return 0;2541 return 0;
2488}2542}
2489 2543
@@ -2503,6 +2557,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, · 13 unmodified lines
2503 struct dma_fence **fence)2557 struct dma_fence **fence)
2504{2558{
2505 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);2559 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
2560 struct amdgpu_ttm_buffer_entity *entity;
2506 struct amdgpu_res_cursor cursor;2561 struct amdgpu_res_cursor cursor;
2507 u64 addr;2562 u64 addr;
2508 int r = 0;2563 int r = 0;
@@ -2513,11 +2568,12 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, · 4 unmodified lines
2513 if (!fence)2568 if (!fence)
2514 return -EINVAL;2569 return -EINVAL;
2515 2570
2571 entity = &adev->mman.clear_entity;
2516 *fence = dma_fence_get_stub();2572 *fence = dma_fence_get_stub();
2517 2573
2518 amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);2574 amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
2519 2575
2520 mutex_lock(&adev->mman.gtt_window_lock);2576 mutex_lock(&entity->lock);
2521 while (cursor.remaining) {2577 while (cursor.remaining) {
2522 struct dma_fence *next = NULL;2578 struct dma_fence *next = NULL;
2523 u64 size;2579 u64 size;
@@ -2530,13 +2586,12 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, · 6 unmodified lines
2530 /* Never clear more than 256MiB at once to avoid timeouts */2586 /* Never clear more than 256MiB at once to avoid timeouts */
2531 size = min(cursor.size, 256ULL << 20);2587 size = min(cursor.size, 256ULL << 20);
2532 2588
2533 r = amdgpu_ttm_map_buffer(&adev->mman.clear_entity,2589 r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &cursor,
2534 &bo->tbo, bo->tbo.resource, &cursor,2590 0, false, &size, &addr);
2535 1, false, &size, &addr);
2536 if (r)2591 if (r)
2537 goto err;2592 goto err;
2538 2593
2539 r = amdgpu_ttm_fill_mem(adev, &adev->mman.clear_entity, 0, addr, size, resv,2594 r = amdgpu_ttm_fill_mem(adev, entity, 0, addr, size, resv,
2540 &next, true,2595 &next, true,
2541 AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);2596 AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
2542 if (r)2597 if (r)
@@ -2548,7 +2603,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, · 5 unmodified lines
2548 amdgpu_res_next(&cursor, size);2603 amdgpu_res_next(&cursor, size);
2549 }2604 }
2550err:2605err:
2551 mutex_unlock(&adev->mman.gtt_window_lock);2606 mutex_unlock(&entity->lock);
2552 2607
2553 return r;2608 return r;
2554}2609}
@@ -2573,7 +2628,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, · 18 unmodified lines
2573 2628
2574 amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &dst);2629 amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &dst);
2575 2630
2576 mutex_lock(&adev->mman.gtt_window_lock);2631 mutex_lock(&entity->lock);
2577 while (dst.remaining) {2632 while (dst.remaining) {
2578 struct dma_fence *next;2633 struct dma_fence *next;
2579 uint64_t cur_size, to;2634 uint64_t cur_size, to;
@@ -2582,7 +2637,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, · 2 unmodified lines
2582 cur_size = min(dst.size, 256ULL << 20);2637 cur_size = min(dst.size, 256ULL << 20);
2583 2638
2584 r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &dst,2639 r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &dst,
2585 1, false, &cur_size, &to);2640 0, false, &cur_size, &to);
2586 if (r)2641 if (r)
2587 goto error;2642 goto error;
2588 2643
@@ -2598,7 +2653,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, · 9 unmodified lines
2598 amdgpu_res_next(&dst, cur_size);2653 amdgpu_res_next(&dst, cur_size);
2599 }2654 }
2600error:2655error:
2601 mutex_unlock(&adev->mman.gtt_window_lock);2656 mutex_unlock(&entity->lock);
2602 if (f)2657 if (f)
2603 *f = dma_fence_get(fence);2658 *f = dma_fence_get(fence);
2604 dma_fence_put(fence);2659 dma_fence_put(fence);
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h+27−4
@@ -29,6 +29,7 @@ · 28 unmodified lines
29#include <drm/ttm/ttm_placement.h>29#include <drm/ttm/ttm_placement.h>
30#include "amdgpu_vram_mgr.h"30#include "amdgpu_vram_mgr.h"
31#include "amdgpu_hmm.h"31#include "amdgpu_hmm.h"
32#include "amdgpu_gmc.h"
32 33
33#define AMDGPU_PL_GDS (TTM_PL_PRIV + 0)34#define AMDGPU_PL_GDS (TTM_PL_PRIV + 0)
34#define AMDGPU_PL_GWS (TTM_PL_PRIV + 1)35#define AMDGPU_PL_GWS (TTM_PL_PRIV + 1)
@@ -38,8 +39,7 @@ · 3 unmodified lines
38#define AMDGPU_PL_MMIO_REMAP (TTM_PL_PRIV + 5)39#define AMDGPU_PL_MMIO_REMAP (TTM_PL_PRIV + 5)
39#define __AMDGPU_PL_NUM (TTM_PL_PRIV + 6)40#define __AMDGPU_PL_NUM (TTM_PL_PRIV + 6)
40 41
41#define AMDGPU_GTT_MAX_TRANSFER_SIZE 51242#define AMDGPU_GTT_MAX_TRANSFER_SIZE 1024
42#define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2
43 43
44extern const struct attribute_group amdgpu_vram_mgr_attr_group;44extern const struct attribute_group amdgpu_vram_mgr_attr_group;
45extern const struct attribute_group amdgpu_gtt_mgr_attr_group;45extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
@@ -54,6 +54,9 @@ struct amdgpu_gtt_mgr { · 8 unmodified lines
54 54
55struct amdgpu_ttm_buffer_entity {55struct amdgpu_ttm_buffer_entity {
56 struct drm_sched_entity base;56 struct drm_sched_entity base;
57 struct mutex lock;
58 struct drm_mm_node gart_node;
59 u64 gart_window_offs[2];
57};60};
58 61
59struct amdgpu_mman {62struct amdgpu_mman {
@@ -67,8 +70,7 @@ struct amdgpu_mman { · 7 unmodified lines
67 struct amdgpu_ring *buffer_funcs_ring;70 struct amdgpu_ring *buffer_funcs_ring;
68 bool buffer_funcs_enabled;71 bool buffer_funcs_enabled;
69 72
70 struct mutex gtt_window_lock;73 /* @default_entity: for workarounds, has no gart windows */
71
72 struct amdgpu_ttm_buffer_entity default_entity;74 struct amdgpu_ttm_buffer_entity default_entity;
73 struct amdgpu_ttm_buffer_entity clear_entity;75 struct amdgpu_ttm_buffer_entity clear_entity;
74 struct amdgpu_ttm_buffer_entity move_entity;76 struct amdgpu_ttm_buffer_entity move_entity;
@@ -205,6 +207,27 @@ static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, · 130 unmodified lines
205}207}
206#endif208#endif
207 209
210/**
211 * amdgpu_compute_gart_address() - Returns GART address of an entity's window
212 * @gmc: The &struct amdgpu_gmc instance to use
213 * @entity: The &struct amdgpu_ttm_buffer_entity owning the GART window
214 * @index: The window to use (must be 0 or 1)
215 */
216static inline u64 amdgpu_compute_gart_address(struct amdgpu_gmc *gmc,
217 struct amdgpu_ttm_buffer_entity *entity,
218 int index)
219{
220 return gmc->gart_start + entity->gart_window_offs[index];
221}
222
223/**
224 * amdgpu_gtt_node_to_byte_offset() - Returns a byte offset of a gtt node
225 */
226static inline u64 amdgpu_gtt_node_to_byte_offset(const struct drm_mm_node *gtt_node)
227{
228 return gtt_node->start * (u64)PAGE_SIZE;
229}
230
208void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct amdgpu_hmm_range *range);231void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct amdgpu_hmm_range *range);
209int amdgpu_ttm_tt_get_userptr(const struct ttm_buffer_object *tbo,232int amdgpu_ttm_tt_get_userptr(const struct ttm_buffer_object *tbo,
210 uint64_t *user_addr);233 uint64_t *user_addr);
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c+81−35
@@ -446,8 +446,7 @@ static int amdgpu_userq_wait_for_last_fence(struct amdgpu_usermode_queue *queue) · 445 unmodified lines
446 return ret;446 return ret;
447}447}
448 448
449static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue,449static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue)
450 int queue_id)
451{450{
452 struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;451 struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
453 struct amdgpu_device *adev = uq_mgr->adev;452 struct amdgpu_device *adev = uq_mgr->adev;
@@ -461,7 +460,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue, · 7 unmodified lines
461 uq_funcs->mqd_destroy(queue);460 uq_funcs->mqd_destroy(queue);
462 amdgpu_userq_fence_driver_free(queue);461 amdgpu_userq_fence_driver_free(queue);
463 /* Use interrupt-safe locking since IRQ handlers may access these XArrays */462 /* Use interrupt-safe locking since IRQ handlers may access these XArrays */
464 xa_erase_irq(&uq_mgr->userq_xa, (unsigned long)queue_id);
465 xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);463 xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);
466 queue->userq_mgr = NULL;464 queue->userq_mgr = NULL;
467 list_del(&queue->userq_va_list);465 list_del(&queue->userq_va_list);
@@ -470,12 +468,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue, · 2 unmodified lines
470 up_read(&adev->reset_domain->sem);468 up_read(&adev->reset_domain->sem);
471}469}
472 470
473static struct amdgpu_usermode_queue *
474amdgpu_userq_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
475{
476 return xa_load(&uq_mgr->userq_xa, qid);
477}
478
479void471void
480amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr,472amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr,
481 struct amdgpu_eviction_fence_mgr *evf_mgr)473 struct amdgpu_eviction_fence_mgr *evf_mgr)
@@ -625,22 +617,13 @@ unref_bo: · 143 unmodified lines
625}617}
626 618
627static int619static int
628amdgpu_userq_destroy(struct drm_file *filp, int queue_id)620amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
629{621{
630 struct amdgpu_fpriv *fpriv = filp->driver_priv;
631 struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
632 struct amdgpu_device *adev = uq_mgr->adev;622 struct amdgpu_device *adev = uq_mgr->adev;
633 struct amdgpu_usermode_queue *queue;
634 int r = 0;623 int r = 0;
635 624
636 cancel_delayed_work_sync(&uq_mgr->resume_work);625 cancel_delayed_work_sync(&uq_mgr->resume_work);
637 mutex_lock(&uq_mgr->userq_mutex);626 mutex_lock(&uq_mgr->userq_mutex);
638 queue = amdgpu_userq_find(uq_mgr, queue_id);
639 if (!queue) {
640 drm_dbg_driver(adev_to_drm(uq_mgr->adev), "Invalid queue id to destroy\n");
641 mutex_unlock(&uq_mgr->userq_mutex);
642 return -EINVAL;
643 }
644 amdgpu_userq_wait_for_last_fence(queue);627 amdgpu_userq_wait_for_last_fence(queue);
645 /* Cancel any pending hang detection work and cleanup */628 /* Cancel any pending hang detection work and cleanup */
646 if (queue->hang_detect_fence) {629 if (queue->hang_detect_fence) {
@@ -672,7 +655,7 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id) · 25 unmodified lines
672 drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n");655 drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n");
673 queue->state = AMDGPU_USERQ_STATE_HUNG;656 queue->state = AMDGPU_USERQ_STATE_HUNG;
674 }657 }
675 amdgpu_userq_cleanup(queue, queue_id);658 amdgpu_userq_cleanup(queue);
676 mutex_unlock(&uq_mgr->userq_mutex);659 mutex_unlock(&uq_mgr->userq_mutex);
677 660
678 pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);661 pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -680,6 +663,37 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id) · 1 unmodified line
680 return r;663 return r;
681}664}
682 665
666static void amdgpu_userq_kref_destroy(struct kref *kref)
667{
668 int r;
669 struct amdgpu_usermode_queue *queue =
670 container_of(kref, struct amdgpu_usermode_queue, refcount);
671 struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
672
673 r = amdgpu_userq_destroy(uq_mgr, queue);
674 if (r)
675 drm_file_err(uq_mgr->file, "Failed to destroy usermode queue %d\n", r);
676}
677
678struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr *uq_mgr, u32 qid)
679{
680 struct amdgpu_usermode_queue *queue;
681
682 xa_lock(&uq_mgr->userq_xa);
683 queue = xa_load(&uq_mgr->userq_xa, qid);
684 if (queue)
685 kref_get(&queue->refcount);
686 xa_unlock(&uq_mgr->userq_xa);
687
688 return queue;
689}
690
691void amdgpu_userq_put(struct amdgpu_usermode_queue *queue)
692{
693 if (queue)
694 kref_put(&queue->refcount, amdgpu_userq_kref_destroy);
695}
696
683static int amdgpu_userq_priority_permit(struct drm_file *filp,697static int amdgpu_userq_priority_permit(struct drm_file *filp,
684 int priority)698 int priority)
685{699{
@@ -834,6 +848,9 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) · 148 unmodified lines
834 goto unlock;848 goto unlock;
835 }849 }
836 850
851 /* drop this refcount during queue destroy */
852 kref_init(&queue->refcount);
853
837 /* Wait for mode-1 reset to complete */854 /* Wait for mode-1 reset to complete */
838 down_read(&adev->reset_domain->sem);855 down_read(&adev->reset_domain->sem);
839 r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL));856 r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL));
@@ -985,7 +1002,9 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, · 145 unmodified lines
985 struct drm_file *filp)1002 struct drm_file *filp)
986{1003{
987 union drm_amdgpu_userq *args = data;1004 union drm_amdgpu_userq *args = data;
988 int r;1005 struct amdgpu_fpriv *fpriv = filp->driver_priv;
1006 struct amdgpu_usermode_queue *queue;
1007 int r = 0;
989 1008
990 if (!amdgpu_userq_enabled(dev))1009 if (!amdgpu_userq_enabled(dev))
991 return -ENOTSUPP;1010 return -ENOTSUPP;
@@ -1000,11 +1019,16 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, · 8 unmodified lines
1000 drm_file_err(filp, "Failed to create usermode queue\n");1019 drm_file_err(filp, "Failed to create usermode queue\n");
1001 break;1020 break;
1002 1021
1003 case AMDGPU_USERQ_OP_FREE:1022 case AMDGPU_USERQ_OP_FREE: {
1004 r = amdgpu_userq_destroy(filp, args->in.queue_id);1023 xa_lock(&fpriv->userq_mgr.userq_xa);
1005 if (r)1024 queue = __xa_erase(&fpriv->userq_mgr.userq_xa, args->in.queue_id);
1006 drm_file_err(filp, "Failed to destroy usermode queue\n");1025 xa_unlock(&fpriv->userq_mgr.userq_xa);
1026 if (!queue)
1027 return -ENOENT;
1028
1029 amdgpu_userq_put(queue);
1007 break;1030 break;
1031 }
1008 1032
1009 default:1033 default:
1010 drm_dbg_driver(dev, "Invalid user queue op specified: %d\n", args->in.op);1034 drm_dbg_driver(dev, "Invalid user queue op specified: %d\n", args->in.op);
@@ -1023,16 +1047,23 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr) · 12 unmodified lines
1023 1047
1024 /* Resume all the queues for this process */1048 /* Resume all the queues for this process */
1025 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {1049 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
1050 queue = amdgpu_userq_get(uq_mgr, queue_id);
1051 if (!queue)
1052 continue;
1053
1026 if (!amdgpu_userq_buffer_vas_mapped(queue)) {1054 if (!amdgpu_userq_buffer_vas_mapped(queue)) {
1027 drm_file_err(uq_mgr->file,1055 drm_file_err(uq_mgr->file,
1028 "trying restore queue without va mapping\n");1056 "trying restore queue without va mapping\n");
1029 queue->state = AMDGPU_USERQ_STATE_INVALID_VA;1057 queue->state = AMDGPU_USERQ_STATE_INVALID_VA;
1058 amdgpu_userq_put(queue);
1030 continue;1059 continue;
1031 }1060 }
1032 1061
1033 r = amdgpu_userq_restore_helper(queue);1062 r = amdgpu_userq_restore_helper(queue);
1034 if (r)1063 if (r)
1035 ret = r;1064 ret = r;
1065
1066 amdgpu_userq_put(queue);
1036 }1067 }
1037 1068
1038 if (ret)1069 if (ret)
@@ -1266,9 +1297,13 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr) · 227 unmodified lines
1266 amdgpu_userq_detect_and_reset_queues(uq_mgr);1297 amdgpu_userq_detect_and_reset_queues(uq_mgr);
1267 /* Try to unmap all the queues in this process ctx */1298 /* Try to unmap all the queues in this process ctx */
1268 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {1299 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
1300 queue = amdgpu_userq_get(uq_mgr, queue_id);
1301 if (!queue)
1302 continue;
1269 r = amdgpu_userq_preempt_helper(queue);1303 r = amdgpu_userq_preempt_helper(queue);
1270 if (r)1304 if (r)
1271 ret = r;1305 ret = r;
1306 amdgpu_userq_put(queue);
1272 }1307 }
1273 1308
1274 if (ret)1309 if (ret)
@@ -1301,16 +1336,24 @@ amdgpu_userq_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr) · 26 unmodified lines
1301 int ret;1336 int ret;
1302 1337
1303 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {1338 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
1339 queue = amdgpu_userq_get(uq_mgr, queue_id);
1340 if (!queue)
1341 continue;
1342
1304 struct dma_fence *f = queue->last_fence;1343 struct dma_fence *f = queue->last_fence;
1305 1344
1306 if (!f || dma_fence_is_signaled(f))1345 if (!f || dma_fence_is_signaled(f)) {
1346 amdgpu_userq_put(queue);
1307 continue;1347 continue;
1348 }
1308 ret = dma_fence_wait_timeout(f, true, msecs_to_jiffies(100));1349 ret = dma_fence_wait_timeout(f, true, msecs_to_jiffies(100));
1309 if (ret <= 0) {1350 if (ret <= 0) {
1310 drm_file_err(uq_mgr->file, "Timed out waiting for fence=%llu:%llu\n",1351 drm_file_err(uq_mgr->file, "Timed out waiting for fence=%llu:%llu\n",
1311 f->context, f->seqno);1352 f->context, f->seqno);
1353 amdgpu_userq_put(queue);
1312 return -ETIMEDOUT;1354 return -ETIMEDOUT;
1313 }1355 }
1356 amdgpu_userq_put(queue);
1314 }1357 }
1315 1358
1316 return 0;1359 return 0;
@@ -1361,20 +1404,23 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *f · 44 unmodified lines
1361void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)1404void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
1362{1405{
1363 struct amdgpu_usermode_queue *queue;1406 struct amdgpu_usermode_queue *queue;
1364 unsigned long queue_id;1407 unsigned long queue_id = 0;
1408
1409 for (;;) {
1410 xa_lock(&userq_mgr->userq_xa);
1411 queue = xa_find(&userq_mgr->userq_xa, &queue_id, ULONG_MAX,
1412 XA_PRESENT);
1413 if (queue)
1414 __xa_erase(&userq_mgr->userq_xa, queue_id);
1415 xa_unlock(&userq_mgr->userq_xa);
1365 1416
1366 cancel_delayed_work_sync(&userq_mgr->resume_work);1417 if (!queue)
1418 break;
1367 1419
1368 mutex_lock(&userq_mgr->userq_mutex);1420 amdgpu_userq_put(queue);
1369 amdgpu_userq_detect_and_reset_queues(userq_mgr);
1370 xa_for_each(&userq_mgr->userq_xa, queue_id, queue) {
1371 amdgpu_userq_wait_for_last_fence(queue);
1372 amdgpu_userq_unmap_helper(queue);
1373 amdgpu_userq_cleanup(queue, queue_id);
1374 }1421 }
1375 1422
1376 xa_destroy(&userq_mgr->userq_xa);1423 xa_destroy(&userq_mgr->userq_xa);
1377 mutex_unlock(&userq_mgr->userq_mutex);
1378 mutex_destroy(&userq_mgr->userq_mutex);1424 mutex_destroy(&userq_mgr->userq_mutex);
1379}1425}
1380 1426
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h+6−0
@@ -74,6 +74,7 @@ struct amdgpu_usermode_queue { · 73 unmodified lines
74 struct dentry *debugfs_queue;74 struct dentry *debugfs_queue;
75 struct delayed_work hang_detect_work;75 struct delayed_work hang_detect_work;
76 struct dma_fence *hang_detect_fence;76 struct dma_fence *hang_detect_fence;
77 struct kref refcount;
77 78
78 struct list_head userq_va_list;79 struct list_head userq_va_list;
79};80};
@@ -81,6 +82,8 @@ struct amdgpu_usermode_queue { · 1 unmodified line
81struct amdgpu_userq_funcs {82struct amdgpu_userq_funcs {
82 int (*mqd_create)(struct amdgpu_usermode_queue *queue,83 int (*mqd_create)(struct amdgpu_usermode_queue *queue,
83 struct drm_amdgpu_userq_in *args);84 struct drm_amdgpu_userq_in *args);
85 int (*mqd_update)(struct amdgpu_usermode_queue *queue,
86 struct drm_amdgpu_userq_in *args);
84 void (*mqd_destroy)(struct amdgpu_usermode_queue *uq);87 void (*mqd_destroy)(struct amdgpu_usermode_queue *uq);
85 int (*unmap)(struct amdgpu_usermode_queue *queue);88 int (*unmap)(struct amdgpu_usermode_queue *queue);
86 int (*map)(struct amdgpu_usermode_queue *queue);89 int (*map)(struct amdgpu_usermode_queue *queue);
@@ -112,6 +115,9 @@ struct amdgpu_db_info { · 25 unmodified lines
112 struct amdgpu_userq_obj *db_obj;115 struct amdgpu_userq_obj *db_obj;
113};116};
114 117
118struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr *uq_mgr, u32 qid);
119void amdgpu_userq_put(struct amdgpu_usermode_queue *queue);
120
115int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);121int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
116 122
117int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *file_priv,123int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *file_priv,
drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c+70−152
@@ -461,33 +461,31 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, · 460 unmodified lines
461 struct drm_file *filp)461 struct drm_file *filp)
462{462{
463 struct amdgpu_device *adev = drm_to_adev(dev);463 struct amdgpu_device *adev = drm_to_adev(dev);
464 struct drm_amdgpu_userq_signal *args = data;
465 const unsigned int num_write_bo_handles = args->num_bo_write_handles;
466 const unsigned int num_read_bo_handles = args->num_bo_read_handles;
464 struct amdgpu_fpriv *fpriv = filp->driver_priv;467 struct amdgpu_fpriv *fpriv = filp->driver_priv;
465 struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr;468 struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr;
466 struct drm_amdgpu_userq_signal *args = data;469 struct drm_gem_object **gobj_write, **gobj_read;
467 struct drm_gem_object **gobj_write = NULL;470 u32 *syncobj_handles, num_syncobj_handles;
468 struct drm_gem_object **gobj_read = NULL;
469 struct amdgpu_usermode_queue *queue;
470 struct amdgpu_userq_fence *userq_fence;471 struct amdgpu_userq_fence *userq_fence;
472 struct amdgpu_usermode_queue *queue = NULL;
471 struct drm_syncobj **syncobj = NULL;473 struct drm_syncobj **syncobj = NULL;
472 u32 *bo_handles_write, num_write_bo_handles;
473 u32 *syncobj_handles, num_syncobj_handles;
474 u32 *bo_handles_read, num_read_bo_handles;
475 int r, i, entry, rentry, wentry;
476 struct dma_fence *fence;474 struct dma_fence *fence;
477 struct drm_exec exec;475 struct drm_exec exec;
476 int r, i, entry;
478 u64 wptr;477 u64 wptr;
479 478
480 if (!amdgpu_userq_enabled(dev))479 if (!amdgpu_userq_enabled(dev))
481 return -ENOTSUPP;480 return -ENOTSUPP;
482 481
483 if (args->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES ||482 if (args->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
484 args->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
485 args->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)483 args->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)
486 return -EINVAL;484 return -EINVAL;
487 485
488 num_syncobj_handles = args->num_syncobj_handles;486 num_syncobj_handles = args->num_syncobj_handles;
489 syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles),487 syncobj_handles = memdup_array_user(u64_to_user_ptr(args->syncobj_handles),
490 size_mul(sizeof(u32), num_syncobj_handles));488 num_syncobj_handles, sizeof(u32));
491 if (IS_ERR(syncobj_handles))489 if (IS_ERR(syncobj_handles))
492 return PTR_ERR(syncobj_handles);490 return PTR_ERR(syncobj_handles);
493 491
@@ -506,54 +504,22 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, · 12 unmodified lines
506 }504 }
507 }505 }
508 506
509 num_read_bo_handles = args->num_bo_read_handles;507 r = drm_gem_objects_lookup(filp,
510 bo_handles_read = memdup_user(u64_to_user_ptr(args->bo_read_handles),508 u64_to_user_ptr(args->bo_read_handles),
511 sizeof(u32) * num_read_bo_handles);509 num_read_bo_handles,
512 if (IS_ERR(bo_handles_read)) {510 &gobj_read);
513 r = PTR_ERR(bo_handles_read);511 if (r)
514 goto free_syncobj;512 goto free_syncobj;
515 }
516 513
517 /* Array of pointers to the GEM read objects */514 r = drm_gem_objects_lookup(filp,
518 gobj_read = kmalloc_array(num_read_bo_handles, sizeof(*gobj_read), GFP_KERNEL);515 u64_to_user_ptr(args->bo_write_handles),
519 if (!gobj_read) {516 num_write_bo_handles,
520 r = -ENOMEM;517 &gobj_write);
521 goto free_bo_handles_read;518 if (r)
522 }
523
524 for (rentry = 0; rentry < num_read_bo_handles; rentry++) {
525 gobj_read[rentry] = drm_gem_object_lookup(filp, bo_handles_read[rentry]);
526 if (!gobj_read[rentry]) {
527 r = -ENOENT;
528 goto put_gobj_read;
529 }
530 }
531
532 num_write_bo_handles = args->num_bo_write_handles;
533 bo_handles_write = memdup_user(u64_to_user_ptr(args->bo_write_handles),
534 sizeof(u32) * num_write_bo_handles);
535 if (IS_ERR(bo_handles_write)) {
536 r = PTR_ERR(bo_handles_write);
537 goto put_gobj_read;519 goto put_gobj_read;
538 }
539
540 /* Array of pointers to the GEM write objects */
541 gobj_write = kmalloc_array(num_write_bo_handles, sizeof(*gobj_write), GFP_KERNEL);
542 if (!gobj_write) {
543 r = -ENOMEM;
544 goto free_bo_handles_write;
545 }
546
547 for (wentry = 0; wentry < num_write_bo_handles; wentry++) {
548 gobj_write[wentry] = drm_gem_object_lookup(filp, bo_handles_write[wentry]);
549 if (!gobj_write[wentry]) {
550 r = -ENOENT;
551 goto put_gobj_write;
552 }
553 }
554 520
555 /* Retrieve the user queue */521 /* Retrieve the user queue */
556 queue = xa_load(&userq_mgr->userq_xa, args->queue_id);522 queue = amdgpu_userq_get(userq_mgr, args->queue_id);
557 if (!queue) {523 if (!queue) {
558 r = -ENOENT;524 r = -ENOENT;
559 goto put_gobj_write;525 goto put_gobj_write;
@@ -629,17 +595,13 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, · 69 unmodified lines
629exec_fini:595exec_fini:
630 drm_exec_fini(&exec);596 drm_exec_fini(&exec);
631put_gobj_write:597put_gobj_write:
632 while (wentry-- > 0)598 for (i = 0; i < num_write_bo_handles; i++)
633 drm_gem_object_put(gobj_write[wentry]);599 drm_gem_object_put(gobj_write[i]);
634 kfree(gobj_write);600 kfree(gobj_write);
635free_bo_handles_write:
636 kfree(bo_handles_write);
637put_gobj_read:601put_gobj_read:
638 while (rentry-- > 0)602 for (i = 0; i < num_read_bo_handles; i++)
639 drm_gem_object_put(gobj_read[rentry]);603 drm_gem_object_put(gobj_read[i]);
640 kfree(gobj_read);604 kfree(gobj_read);
641free_bo_handles_read:
642 kfree(bo_handles_read);
643free_syncobj:605free_syncobj:
644 while (entry-- > 0)606 while (entry-- > 0)
645 if (syncobj[entry])607 if (syncobj[entry])
@@ -648,98 +610,73 @@ free_syncobj: · 2 unmodified lines
648free_syncobj_handles:610free_syncobj_handles:
649 kfree(syncobj_handles);611 kfree(syncobj_handles);
650 612
613 if (queue)
614 amdgpu_userq_put(queue);
615
651 return r;616 return r;
652}617}
653 618
654int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,619int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
655 struct drm_file *filp)620 struct drm_file *filp)
656{621{
657 u32 *syncobj_handles, *timeline_points, *timeline_handles, *bo_handles_read, *bo_handles_write;
658 u32 num_syncobj, num_read_bo_handles, num_write_bo_handles;
659 struct drm_amdgpu_userq_fence_info *fence_info = NULL;
660 struct drm_amdgpu_userq_wait *wait_info = data;622 struct drm_amdgpu_userq_wait *wait_info = data;
623 const unsigned int num_write_bo_handles = wait_info->num_bo_write_handles;
624 const unsigned int num_read_bo_handles = wait_info->num_bo_read_handles;
625 struct drm_amdgpu_userq_fence_info *fence_info = NULL;
661 struct amdgpu_fpriv *fpriv = filp->driver_priv;626 struct amdgpu_fpriv *fpriv = filp->driver_priv;
662 struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr;627 struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr;
663 struct amdgpu_usermode_queue *waitq;628 struct drm_gem_object **gobj_write, **gobj_read;
664 struct drm_gem_object **gobj_write;629 u32 *timeline_points, *timeline_handles;
665 struct drm_gem_object **gobj_read;630 struct amdgpu_usermode_queue *waitq = NULL;
631 u32 *syncobj_handles, num_syncobj;
666 struct dma_fence **fences = NULL;632 struct dma_fence **fences = NULL;
667 u16 num_points, num_fences = 0;633 u16 num_points, num_fences = 0;
668 int r, i, rentry, wentry, cnt;
669 struct drm_exec exec;634 struct drm_exec exec;
635 int r, i, cnt;
670 636
671 if (!amdgpu_userq_enabled(dev))637 if (!amdgpu_userq_enabled(dev))
672 return -ENOTSUPP;638 return -ENOTSUPP;
673 639
674 if (wait_info->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES ||640 if (wait_info->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
675 wait_info->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
676 wait_info->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)641 wait_info->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)
677 return -EINVAL;642 return -EINVAL;
678 643
679 num_read_bo_handles = wait_info->num_bo_read_handles;
680 bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles),
681 size_mul(sizeof(u32), num_read_bo_handles));
682 if (IS_ERR(bo_handles_read))
683 return PTR_ERR(bo_handles_read);
684
685 num_write_bo_handles = wait_info->num_bo_write_handles;
686 bo_handles_write = memdup_user(u64_to_user_ptr(wait_info->bo_write_handles),
687 size_mul(sizeof(u32), num_write_bo_handles));
688 if (IS_ERR(bo_handles_write)) {
689 r = PTR_ERR(bo_handles_write);
690 goto free_bo_handles_read;
691 }
692
693 num_syncobj = wait_info->num_syncobj_handles;644 num_syncobj = wait_info->num_syncobj_handles;
694 syncobj_handles = memdup_user(u64_to_user_ptr(wait_info->syncobj_handles),645 syncobj_handles = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_handles),
695 size_mul(sizeof(u32), num_syncobj));646 num_syncobj, sizeof(u32));
696 if (IS_ERR(syncobj_handles)) {647 if (IS_ERR(syncobj_handles))
697 r = PTR_ERR(syncobj_handles);648 return PTR_ERR(syncobj_handles);
698 goto free_bo_handles_write;649
699 }
700 650
701 num_points = wait_info->num_syncobj_timeline_handles;651 num_points = wait_info->num_syncobj_timeline_handles;
702 timeline_handles = memdup_user(u64_to_user_ptr(wait_info->syncobj_timeline_handles),652 timeline_handles = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_timeline_handles),
703 sizeof(u32) * num_points);653 num_points, sizeof(u32));
704 if (IS_ERR(timeline_handles)) {654 if (IS_ERR(timeline_handles)) {
705 r = PTR_ERR(timeline_handles);655 r = PTR_ERR(timeline_handles);
706 goto free_syncobj_handles;656 goto free_syncobj_handles;
707 }657 }
708 658
709 timeline_points = memdup_user(u64_to_user_ptr(wait_info->syncobj_timeline_points),659 timeline_points = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_timeline_points),
710 sizeof(u32) * num_points);660 num_points, sizeof(u32));
661
711 if (IS_ERR(timeline_points)) {662 if (IS_ERR(timeline_points)) {
712 r = PTR_ERR(timeline_points);663 r = PTR_ERR(timeline_points);
713 goto free_timeline_handles;664 goto free_timeline_handles;
714 }665 }
715 666
716 gobj_read = kmalloc_array(num_read_bo_handles, sizeof(*gobj_read), GFP_KERNEL);667 r = drm_gem_objects_lookup(filp,
717 if (!gobj_read) {668 u64_to_user_ptr(wait_info->bo_read_handles),
718 r = -ENOMEM;669 num_read_bo_handles,
670 &gobj_read);
671 if (r)
719 goto free_timeline_points;672 goto free_timeline_points;
720 }
721
722 for (rentry = 0; rentry < num_read_bo_handles; rentry++) {
723 gobj_read[rentry] = drm_gem_object_lookup(filp, bo_handles_read[rentry]);
724 if (!gobj_read[rentry]) {
725 r = -ENOENT;
726 goto put_gobj_read;
727 }
728 }
729 673
730 gobj_write = kmalloc_array(num_write_bo_handles, sizeof(*gobj_write), GFP_KERNEL);674 r = drm_gem_objects_lookup(filp,
731 if (!gobj_write) {675 u64_to_user_ptr(wait_info->bo_write_handles),
732 r = -ENOMEM;676 num_write_bo_handles,
677 &gobj_write);
678 if (r)
733 goto put_gobj_read;679 goto put_gobj_read;
734 }
735
736 for (wentry = 0; wentry < num_write_bo_handles; wentry++) {
737 gobj_write[wentry] = drm_gem_object_lookup(filp, bo_handles_write[wentry]);
738 if (!gobj_write[wentry]) {
739 r = -ENOENT;
740 goto put_gobj_write;
741 }
742 }
743 680
744 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,681 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
745 (num_read_bo_handles + num_write_bo_handles));682 (num_read_bo_handles + num_write_bo_handles));
@@ -926,7 +863,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, · 180 unmodified lines
926 */863 */
927 num_fences = dma_fence_dedup_array(fences, num_fences);864 num_fences = dma_fence_dedup_array(fences, num_fences);
928 865
929 waitq = xa_load(&userq_mgr->userq_xa, wait_info->waitq_id);866 waitq = amdgpu_userq_get(userq_mgr, wait_info->waitq_id);
930 if (!waitq) {867 if (!waitq) {
931 r = -EINVAL;868 r = -EINVAL;
932 goto free_fences;869 goto free_fences;
@@ -983,43 +920,25 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, · 50 unmodified lines
983 r = -EFAULT;920 r = -EFAULT;
984 goto free_fences;921 goto free_fences;
985 }922 }
986
987 kfree(fences);
988 kfree(fence_info);
989 }923 }
990 924
991 drm_exec_fini(&exec);
992 for (i = 0; i < num_read_bo_handles; i++)
993 drm_gem_object_put(gobj_read[i]);
994 kfree(gobj_read);
995
996 for (i = 0; i < num_write_bo_handles; i++)
997 drm_gem_object_put(gobj_write[i]);
998 kfree(gobj_write);
999
1000 kfree(timeline_points);
1001 kfree(timeline_handles);
1002 kfree(syncobj_handles);
1003 kfree(bo_handles_write);
1004 kfree(bo_handles_read);
1005
1006 return 0;
1007
1008free_fences:925free_fences:
1009 while (num_fences-- > 0)926 if (fences) {
1010 dma_fence_put(fences[num_fences]);927 while (num_fences-- > 0)
1011 kfree(fences);928 dma_fence_put(fences[num_fences]);
929 kfree(fences);
930 }
1012free_fence_info:931free_fence_info:
1013 kfree(fence_info);932 kfree(fence_info);
1014exec_fini:933exec_fini:
1015 drm_exec_fini(&exec);934 drm_exec_fini(&exec);
1016put_gobj_write:935put_gobj_write:
1017 while (wentry-- > 0)936 for (i = 0; i < num_write_bo_handles; i++)
1018 drm_gem_object_put(gobj_write[wentry]);937 drm_gem_object_put(gobj_write[i]);
1019 kfree(gobj_write);938 kfree(gobj_write);
1020put_gobj_read:939put_gobj_read:
1021 while (rentry-- > 0)940 for (i = 0; i < num_read_bo_handles; i++)
1022 drm_gem_object_put(gobj_read[rentry]);941 drm_gem_object_put(gobj_read[i]);
1023 kfree(gobj_read);942 kfree(gobj_read);
1024free_timeline_points:943free_timeline_points:
1025 kfree(timeline_points);944 kfree(timeline_points);
@@ -1027,10 +946,9 @@ free_timeline_handles: · 1 unmodified line
1027 kfree(timeline_handles);946 kfree(timeline_handles);
1028free_syncobj_handles:947free_syncobj_handles:
1029 kfree(syncobj_handles);948 kfree(syncobj_handles);
1030free_bo_handles_write:949
1031 kfree(bo_handles_write);950 if (waitq)
1032free_bo_handles_read:951 amdgpu_userq_put(waitq);
1033 kfree(bo_handles_read);
1034 952
1035 return r;953 return r;
1036}954}
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c+0−18
@@ -450,24 +450,6 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) · 449 unmodified lines
450 }450 }
451}451}
452 452
453/**
454 * amdgpu_vce_required_gart_pages() - gets number of GART pages required by VCE
455 *
456 * @adev: amdgpu_device pointer
457 *
458 * Returns how many GART pages we need before GTT for the VCE IP block.
459 * For VCE1, see vce_v1_0_ensure_vcpu_bo_32bit_addr for details.
460 * For VCE2+, this is not needed so return zero.
461 */
462u32 amdgpu_vce_required_gart_pages(struct amdgpu_device *adev)
463{
464 /* VCE IP block not added yet, so can't use amdgpu_ip_version */
465 if (adev->family == AMDGPU_FAMILY_SI)
466 return 512;
467
468 return 0;
469}
470
471/**453/**
472 * amdgpu_vce_get_create_msg - generate a VCE create msg454 * amdgpu_vce_get_create_msg - generate a VCE create msg
473 *455 *
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h+1−1
@@ -52,6 +52,7 @@ struct amdgpu_vce { · 51 unmodified lines
52 uint32_t srbm_soft_reset;52 uint32_t srbm_soft_reset;
53 unsigned num_rings;53 unsigned num_rings;
54 uint32_t keyselect;54 uint32_t keyselect;
55 struct drm_mm_node gart_node;
55};56};
56 57
57int amdgpu_vce_early_init(struct amdgpu_device *adev);58int amdgpu_vce_early_init(struct amdgpu_device *adev);
@@ -61,7 +62,6 @@ int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring) · 3 unmodified lines
61int amdgpu_vce_suspend(struct amdgpu_device *adev);62int amdgpu_vce_suspend(struct amdgpu_device *adev);
62int amdgpu_vce_resume(struct amdgpu_device *adev);63int amdgpu_vce_resume(struct amdgpu_device *adev);
63void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);64void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
64u32 amdgpu_vce_required_gart_pages(struct amdgpu_device *adev);
65int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, struct amdgpu_job *job,65int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
66 struct amdgpu_ib *ib);66 struct amdgpu_ib *ib);
67int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p,67int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p,
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c+33−12
@@ -764,12 +764,9 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, · 763 unmodified lines
764 * @need_pipe_sync: is pipe sync needed764 * @need_pipe_sync: is pipe sync needed
765 *765 *
766 * Emit a VM flush when it is necessary.766 * Emit a VM flush when it is necessary.
767 *
768 * Returns:
769 * 0 on success, errno otherwise.
770 */767 */
771int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,768void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
772 bool need_pipe_sync)769 bool need_pipe_sync)
773{770{
774 struct amdgpu_device *adev = ring->adev;771 struct amdgpu_device *adev = ring->adev;
775 struct amdgpu_isolation *isolation = &adev->isolation[ring->xcp_id];772 struct amdgpu_isolation *isolation = &adev->isolation[ring->xcp_id];
@@ -783,8 +780,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, · 7 unmodified lines
783 bool cleaner_shader_needed = false;780 bool cleaner_shader_needed = false;
784 bool pasid_mapping_needed = false;781 bool pasid_mapping_needed = false;
785 struct dma_fence *fence = NULL;782 struct dma_fence *fence = NULL;
786 unsigned int patch;783 unsigned int patch = 0;
787 int r;
788 784
789 if (amdgpu_vmid_had_gpu_reset(adev, id)) {785 if (amdgpu_vmid_had_gpu_reset(adev, id)) {
790 gds_switch_needed = true;786 gds_switch_needed = true;
@@ -812,9 +808,20 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, · 21 unmodified lines
812 808
813 if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync &&809 if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync &&
814 !cleaner_shader_needed)810 !cleaner_shader_needed)
815 return 0;811 return;
816 812
817 amdgpu_ring_ib_begin(ring);813 amdgpu_ring_ib_begin(ring);
814
815 /* There is no matching insert_end for this on purpose for the vm flush.
816 * The IB portion of the submission has both. Having multiple
817 * insert_start sequences is ok, but you can only have one insert_end
818 * per submission based on the way VCN FW works. For JPEG
819 * you can as many insert_start and insert_end sequences as you like as
820 * long as the rest of the packets come between start and end sequences.
821 */
822 if (ring->funcs->insert_start)
823 ring->funcs->insert_start(ring);
824
818 if (ring->funcs->init_cond_exec)825 if (ring->funcs->init_cond_exec)
819 patch = amdgpu_ring_init_cond_exec(ring,826 patch = amdgpu_ring_init_cond_exec(ring,
820 ring->cond_exe_gpu_addr);827 ring->cond_exe_gpu_addr);
@@ -845,9 +852,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, · 24 unmodified lines
845 }852 }
846 853
847 if (vm_flush_needed || pasid_mapping_needed || cleaner_shader_needed) {854 if (vm_flush_needed || pasid_mapping_needed || cleaner_shader_needed) {
848 r = amdgpu_fence_emit(ring, job->hw_vm_fence, 0);855 amdgpu_fence_emit(ring, job->hw_vm_fence, 0);
849 if (r)
850 return r;
851 fence = &job->hw_vm_fence->base;856 fence = &job->hw_vm_fence->base;
852 /* get a ref for the job */857 /* get a ref for the job */
853 dma_fence_get(fence);858 dma_fence_get(fence);
@@ -892,7 +897,6 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, · 38 unmodified lines
892 }897 }
893 898
894 amdgpu_ring_ib_end(ring);899 amdgpu_ring_ib_end(ring);
895 return 0;
896}900}
897 901
898/**902/**
@@ -3210,3 +3214,20 @@ void amdgpu_vm_print_task_info(struct amdgpu_device *adev, · 2311 unmodified lines
3210 task_info->process_name, task_info->tgid,3214 task_info->process_name, task_info->tgid,
3211 task_info->task.comm, task_info->task.pid);3215 task_info->task.comm, task_info->task.pid);
3212}3216}
3217
3218void amdgpu_sdma_set_vm_pte_scheds(struct amdgpu_device *adev,
3219 const struct amdgpu_vm_pte_funcs *vm_pte_funcs)
3220{
3221 struct drm_gpu_scheduler *sched;
3222 int i;
3223
3224 for (i = 0; i < adev->sdma.num_instances; i++) {
3225 if (adev->sdma.has_page_queue)
3226 sched = &adev->sdma.instance[i].page.sched;
3227 else
3228 sched = &adev->sdma.instance[i].ring.sched;
3229 adev->vm_manager.vm_pte_scheds[i] = sched;
3230 }
3231 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
3232 adev->vm_manager.vm_pte_funcs = vm_pte_funcs;
3233}
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h+1−1
@@ -513,7 +513,7 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 512 unmodified lines
513 struct ww_acquire_ctx *ticket,513 struct ww_acquire_ctx *ticket,
514 int (*callback)(void *p, struct amdgpu_bo *bo),514 int (*callback)(void *p, struct amdgpu_bo *bo),
515 void *param);515 void *param);
516int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);516void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
517int amdgpu_vm_update_pdes(struct amdgpu_device *adev,517int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
518 struct amdgpu_vm *vm, bool immediate);518 struct amdgpu_vm *vm, bool immediate);
519int amdgpu_vm_clear_freed(struct amdgpu_device *adev,519int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c+11−4
@@ -338,7 +338,7 @@ static u32 xgmi_v6_4_get_link_status(struct amdgpu_device *adev, int global_link · 337 unmodified lines
338 if (!(adev->aid_mask & BIT(i)))338 if (!(adev->aid_mask & BIT(i)))
339 return U32_MAX;339 return U32_MAX;
340 340
341 addr += adev->asic_funcs->encode_ext_smn_addressing(i);341 addr += amdgpu_reg_get_smn_base64(adev, XGMI_HWIP, i);
342 342
343 return RREG32_PCIE_EXT(addr);343 return RREG32_PCIE_EXT(addr);
344}344}
@@ -347,6 +347,9 @@ int amdgpu_get_xgmi_link_status(struct amdgpu_device *adev, int global_link_num) · 2 unmodified lines
347{347{
348 u32 xgmi_state_reg_val;348 u32 xgmi_state_reg_val;
349 349
350 if (amdgpu_sriov_vf(adev))
351 return AMDGPU_XGMI_LINK_NA;
352
350 if (adev->gmc.xgmi.num_physical_nodes <= 1)353 if (adev->gmc.xgmi.num_physical_nodes <= 1)
351 return -EINVAL;354 return -EINVAL;
352 355
@@ -1290,7 +1293,10 @@ static void amdgpu_xgmi_legacy_reset_ras_error_count(struct amdgpu_device *adev) · 937 unmodified lines
1290 1293
1291static void __xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst, u64 mca_base)1294static void __xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst, u64 mca_base)
1292{1295{
1293 WREG64_MCA(xgmi_inst, mca_base, ACA_REG_IDX_STATUS, 0ULL);1296 uint64_t smn_base =
1297 amdgpu_reg_get_smn_base64(adev, XGMI_HWIP, xgmi_inst);
1298
1299 WREG64_MCA(smn_base, mca_base, ACA_REG_IDX_STATUS, 0ULL);
1294}1300}
1295 1301
1296static void xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst)1302static void xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst)
@@ -1500,6 +1506,7 @@ static void __xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, struct a · 203 unmodified lines
1500 u64 mca_base, struct ras_err_data *err_data)1506 u64 mca_base, struct ras_err_data *err_data)
1501{1507{
1502 int xgmi_inst = mcm_info->die_id;1508 int xgmi_inst = mcm_info->die_id;
1509 uint64_t smn_base;
1503 u64 status = 0;1510 u64 status = 0;
1504 1511
1505 status = RREG64_MCA(xgmi_inst, mca_base, ACA_REG_IDX_STATUS);1512 status = RREG64_MCA(xgmi_inst, mca_base, ACA_REG_IDX_STATUS);
@@ -1516,8 +1523,8 @@ static void __xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, struct a · 10 unmodified lines
1516 default:1523 default:
1517 break;1524 break;
1518 }1525 }
1519 1526 smn_base = amdgpu_reg_get_smn_base64(adev, XGMI_HWIP, xgmi_inst);
1520 WREG64_MCA(xgmi_inst, mca_base, ACA_REG_IDX_STATUS, 0ULL);1527 WREG64_MCA(smn_base, mca_base, ACA_REG_IDX_STATUS, 0ULL);
1521}1528}
1522 1529
1523static void xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, int xgmi_inst, struct ras_err_data *err_data)1530static void xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, int xgmi_inst, struct ras_err_data *err_data)
drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h+19−6
@@ -470,14 +470,23 @@ struct amd_sriov_ras_chk_criti { · 469 unmodified lines
470 uint32_t hit;470 uint32_t hit;
471};471};
472 472
473union amd_sriov_ras_host_push {
474 struct amd_sriov_ras_telemetry_error_count error_count;
475 struct amd_sriov_ras_cper_dump cper_dump;
476 struct amd_sriov_ras_chk_criti chk_criti;
477};
478
479#define AMD_SRIOV_UNIRAS_BLOCKS_BUF_SIZE 4096
480#define AMD_SRIOV_UNIRAS_CMD_MAX_SIZE (4096 * 13)
481struct amd_sriov_uniras_shared_mem {
482 uint8_t blocks_ecc_buf[AMD_SRIOV_UNIRAS_BLOCKS_BUF_SIZE];
483 uint8_t cmd_buf[AMD_SRIOV_UNIRAS_CMD_MAX_SIZE];
484};
485
473struct amdsriov_ras_telemetry {486struct amdsriov_ras_telemetry {
474 struct amd_sriov_ras_telemetry_header header;487 struct amd_sriov_ras_telemetry_header header;
475 488 union amd_sriov_ras_host_push body;
476 union {489 struct amd_sriov_uniras_shared_mem uniras_shared_mem;
477 struct amd_sriov_ras_telemetry_error_count error_count;
478 struct amd_sriov_ras_cper_dump cper_dump;
479 struct amd_sriov_ras_chk_criti chk_criti;
480 } body;
481};490};
482 491
483/* version data stored in MAILBOX_MSGBUF_RCV_DW1 for future expansion */492/* version data stored in MAILBOX_MSGBUF_RCV_DW1 for future expansion */
@@ -510,6 +519,10 @@ _Static_assert(AMD_SRIOV_MSG_RESERVE_UCODE % 4 == 0, · 26 unmodified lines
510_Static_assert(AMD_SRIOV_MSG_RESERVE_UCODE > AMD_SRIOV_UCODE_ID__MAX,519_Static_assert(AMD_SRIOV_MSG_RESERVE_UCODE > AMD_SRIOV_UCODE_ID__MAX,
511 "AMD_SRIOV_MSG_RESERVE_UCODE must be bigger than AMD_SRIOV_UCODE_ID__MAX");520 "AMD_SRIOV_MSG_RESERVE_UCODE must be bigger than AMD_SRIOV_UCODE_ID__MAX");
512 521
522_Static_assert(
523 sizeof(struct amdsriov_ras_telemetry) <= AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1 << 10,
524"amdsriov_ras_telemetry must be " stringification(AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1) " KB");
525
513#undef _stringification526#undef _stringification
514#undef stringification527#undef stringification
515#endif528#endif
drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c+1−20
@@ -58,25 +58,6 @@ void aqua_vanjaram_doorbell_index_init(struct amdgpu_device *adev) · 57 unmodified lines
58 adev->doorbell_index.max_assignment = AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT << 1;58 adev->doorbell_index.max_assignment = AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT << 1;
59}59}
60 60
61/* Fixed pattern for smn addressing on different AIDs:
62 * bit[34]: indicate cross AID access
63 * bit[33:32]: indicate target AID id
64 * AID id range is 0 ~ 3 as maximum AID number is 4.
65 */
66u64 aqua_vanjaram_encode_ext_smn_addressing(int ext_id)
67{
68 u64 ext_offset;
69
70 /* local routing and bit[34:32] will be zeros */
71 if (ext_id == 0)
72 return 0;
73
74 /* Initiated from host, accessing to all non-zero aids are cross traffic */
75 ext_offset = ((u64)(ext_id & 0x3) << 32) | (1ULL << 34);
76
77 return ext_offset;
78}
79
80static enum amdgpu_gfx_partition61static enum amdgpu_gfx_partition
81__aqua_vanjaram_calc_xcp_mode(struct amdgpu_xcp_mgr *xcp_mgr)62__aqua_vanjaram_calc_xcp_mode(struct amdgpu_xcp_mgr *xcp_mgr)
82{63{
@@ -590,7 +571,7 @@ static void aqua_read_smn_ext(struct amdgpu_device *adev, · 507 unmodified lines
590 uint64_t smn_addr, int i)571 uint64_t smn_addr, int i)
591{572{
592 regdata->addr =573 regdata->addr =
593 smn_addr + adev->asic_funcs->encode_ext_smn_addressing(i);574 smn_addr + amdgpu_reg_get_smn_base64(adev, XGMI_HWIP, i);
594 regdata->value = RREG32_PCIE_EXT(regdata->addr);575 regdata->value = RREG32_PCIE_EXT(regdata->addr);
595}576}
596 577
drivers/gpu/drm/amd/amdgpu/atom.c+26−2
@@ -1462,8 +1462,6 @@ static void atom_get_vbios_pn(struct atom_context *ctx) · 1461 unmodified lines
1462 1462
1463 ctx->vbios_pn[count] = 0;1463 ctx->vbios_pn[count] = 0;
1464 }1464 }
1465
1466 drm_info(ctx->card->dev, "ATOM BIOS: %s\n", ctx->vbios_pn);
1467}1465}
1468 1466
1469static void atom_get_vbios_version(struct atom_context *ctx)1467static void atom_get_vbios_version(struct atom_context *ctx)
@@ -1520,6 +1518,30 @@ static void atom_get_vbios_build(struct atom_context *ctx) · 50 unmodified lines
1520 strscpy(ctx->build_num, str, len);1518 strscpy(ctx->build_num, str, len);
1521}1519}
1522 1520
1521static inline void atom_print_vbios_info(struct atom_context *ctx)
1522{
1523 char vbios_info[256];
1524 int off = 0;
1525
1526 if (ctx->vbios_pn[0])
1527 off += scnprintf(vbios_info + off, sizeof(vbios_info) - off,
1528 "%s", ctx->vbios_pn);
1529 if (ctx->build_num[0])
1530 off += scnprintf(vbios_info + off, sizeof(vbios_info) - off,
1531 "%sbuild: %s", off ? ", " : "",
1532 ctx->build_num);
1533 if (ctx->vbios_ver_str[0])
1534 off += scnprintf(vbios_info + off, sizeof(vbios_info) - off,
1535 "%sver: %s", off ? ", " : "",
1536 ctx->vbios_ver_str);
1537 if (ctx->date[0])
1538 off += scnprintf(vbios_info + off, sizeof(vbios_info) - off,
1539 "%s%.10s", off ? ", " : "",
1540 ctx->date);
1541 if (off)
1542 drm_info(ctx->card->dev, "ATOM BIOS: %s\n", vbios_info);
1543}
1544
1523struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)1545struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
1524{1546{
1525 int base;1547 int base;
@@ -1582,6 +1604,8 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios) · 56 unmodified lines
1582 atom_get_vbios_version(ctx);1604 atom_get_vbios_version(ctx);
1583 atom_get_vbios_build(ctx);1605 atom_get_vbios_build(ctx);
1584 1606
1607 atom_print_vbios_info(ctx);
1608
1585 return ctx;1609 return ctx;
1586}1610}
1587 1611
drivers/gpu/drm/amd/amdgpu/cik.c+26−26
@@ -154,11 +154,11 @@ static u32 cik_pcie_rreg(struct amdgpu_device *adev, u32 reg) · 153 unmodified lines
154 unsigned long flags;154 unsigned long flags;
155 u32 r;155 u32 r;
156 156
157 spin_lock_irqsave(&adev->pcie_idx_lock, flags);157 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
158 WREG32(mmPCIE_INDEX, reg);158 WREG32(mmPCIE_INDEX, reg);
159 (void)RREG32(mmPCIE_INDEX);159 (void)RREG32(mmPCIE_INDEX);
160 r = RREG32(mmPCIE_DATA);160 r = RREG32(mmPCIE_DATA);
161 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);161 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
162 return r;162 return r;
163}163}
164 164
@@ -166,12 +166,12 @@ static void cik_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
166{166{
167 unsigned long flags;167 unsigned long flags;
168 168
169 spin_lock_irqsave(&adev->pcie_idx_lock, flags);169 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
170 WREG32(mmPCIE_INDEX, reg);170 WREG32(mmPCIE_INDEX, reg);
171 (void)RREG32(mmPCIE_INDEX);171 (void)RREG32(mmPCIE_INDEX);
172 WREG32(mmPCIE_DATA, v);172 WREG32(mmPCIE_DATA, v);
173 (void)RREG32(mmPCIE_DATA);173 (void)RREG32(mmPCIE_DATA);
174 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);174 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
175}175}
176 176
177static u32 cik_smc_rreg(struct amdgpu_device *adev, u32 reg)177static u32 cik_smc_rreg(struct amdgpu_device *adev, u32 reg)
@@ -179,10 +179,10 @@ static u32 cik_smc_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
179 unsigned long flags;179 unsigned long flags;
180 u32 r;180 u32 r;
181 181
182 spin_lock_irqsave(&adev->smc_idx_lock, flags);182 spin_lock_irqsave(&adev->reg.smc.lock, flags);
183 WREG32(mmSMC_IND_INDEX_0, (reg));183 WREG32(mmSMC_IND_INDEX_0, (reg));
184 r = RREG32(mmSMC_IND_DATA_0);184 r = RREG32(mmSMC_IND_DATA_0);
185 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);185 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
186 return r;186 return r;
187}187}
188 188
@@ -190,10 +190,10 @@ static void cik_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
190{190{
191 unsigned long flags;191 unsigned long flags;
192 192
193 spin_lock_irqsave(&adev->smc_idx_lock, flags);193 spin_lock_irqsave(&adev->reg.smc.lock, flags);
194 WREG32(mmSMC_IND_INDEX_0, (reg));194 WREG32(mmSMC_IND_INDEX_0, (reg));
195 WREG32(mmSMC_IND_DATA_0, (v));195 WREG32(mmSMC_IND_DATA_0, (v));
196 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);196 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
197}197}
198 198
199static u32 cik_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg)199static u32 cik_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg)
@@ -201,10 +201,10 @@ static u32 cik_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
201 unsigned long flags;201 unsigned long flags;
202 u32 r;202 u32 r;
203 203
204 spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);204 spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
205 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));205 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
206 r = RREG32(mmUVD_CTX_DATA);206 r = RREG32(mmUVD_CTX_DATA);
207 spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);207 spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
208 return r;208 return r;
209}209}
210 210
@@ -212,10 +212,10 @@ static void cik_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
212{212{
213 unsigned long flags;213 unsigned long flags;
214 214
215 spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);215 spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
216 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));216 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
217 WREG32(mmUVD_CTX_DATA, (v));217 WREG32(mmUVD_CTX_DATA, (v));
218 spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);218 spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
219}219}
220 220
221static u32 cik_didt_rreg(struct amdgpu_device *adev, u32 reg)221static u32 cik_didt_rreg(struct amdgpu_device *adev, u32 reg)
@@ -223,10 +223,10 @@ static u32 cik_didt_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
223 unsigned long flags;223 unsigned long flags;
224 u32 r;224 u32 r;
225 225
226 spin_lock_irqsave(&adev->didt_idx_lock, flags);226 spin_lock_irqsave(&adev->reg.didt.lock, flags);
227 WREG32(mmDIDT_IND_INDEX, (reg));227 WREG32(mmDIDT_IND_INDEX, (reg));
228 r = RREG32(mmDIDT_IND_DATA);228 r = RREG32(mmDIDT_IND_DATA);
229 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);229 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
230 return r;230 return r;
231}231}
232 232
@@ -234,10 +234,10 @@ static void cik_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
234{234{
235 unsigned long flags;235 unsigned long flags;
236 236
237 spin_lock_irqsave(&adev->didt_idx_lock, flags);237 spin_lock_irqsave(&adev->reg.didt.lock, flags);
238 WREG32(mmDIDT_IND_INDEX, (reg));238 WREG32(mmDIDT_IND_INDEX, (reg));
239 WREG32(mmDIDT_IND_DATA, (v));239 WREG32(mmDIDT_IND_DATA, (v));
240 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);240 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
241}241}
242 242
243static const u32 bonaire_golden_spm_registers[] =243static const u32 bonaire_golden_spm_registers[] =
@@ -1027,7 +1027,7 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, · 783 unmodified lines
1027 dw_ptr = (u32 *)bios;1027 dw_ptr = (u32 *)bios;
1028 length_dw = ALIGN(length_bytes, 4) / 4;1028 length_dw = ALIGN(length_bytes, 4) / 4;
1029 /* take the smc lock since we are using the smc index */1029 /* take the smc lock since we are using the smc index */
1030 spin_lock_irqsave(&adev->smc_idx_lock, flags);1030 spin_lock_irqsave(&adev->reg.smc.lock, flags);
1031 /* set rom index to 0 */1031 /* set rom index to 0 */
1032 WREG32(mmSMC_IND_INDEX_0, ixROM_INDEX);1032 WREG32(mmSMC_IND_INDEX_0, ixROM_INDEX);
1033 WREG32(mmSMC_IND_DATA_0, 0);1033 WREG32(mmSMC_IND_DATA_0, 0);
@@ -1035,7 +1035,7 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, · 1 unmodified line
1035 WREG32(mmSMC_IND_INDEX_0, ixROM_DATA);1035 WREG32(mmSMC_IND_INDEX_0, ixROM_DATA);
1036 for (i = 0; i < length_dw; i++)1036 for (i = 0; i < length_dw; i++)
1037 dw_ptr[i] = RREG32(mmSMC_IND_DATA_0);1037 dw_ptr[i] = RREG32(mmSMC_IND_DATA_0);
1038 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);1038 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
1039 1039
1040 return true;1040 return true;
1041}1041}
@@ -1984,14 +1984,14 @@ static int cik_common_early_init(struct amdgpu_ip_block *ip_block) · 942 unmodified lines
1984{1984{
1985 struct amdgpu_device *adev = ip_block->adev;1985 struct amdgpu_device *adev = ip_block->adev;
1986 1986
1987 adev->smc_rreg = &cik_smc_rreg;1987 adev->reg.smc.rreg = cik_smc_rreg;
1988 adev->smc_wreg = &cik_smc_wreg;1988 adev->reg.smc.wreg = cik_smc_wreg;
1989 adev->pcie_rreg = &cik_pcie_rreg;1989 adev->reg.pcie.rreg = &cik_pcie_rreg;
1990 adev->pcie_wreg = &cik_pcie_wreg;1990 adev->reg.pcie.wreg = &cik_pcie_wreg;
1991 adev->uvd_ctx_rreg = &cik_uvd_ctx_rreg;1991 adev->reg.uvd_ctx.rreg = &cik_uvd_ctx_rreg;
1992 adev->uvd_ctx_wreg = &cik_uvd_ctx_wreg;1992 adev->reg.uvd_ctx.wreg = &cik_uvd_ctx_wreg;
1993 adev->didt_rreg = &cik_didt_rreg;1993 adev->reg.didt.rreg = &cik_didt_rreg;
1994 adev->didt_wreg = &cik_didt_wreg;1994 adev->reg.didt.wreg = &cik_didt_wreg;
1995 1995
1996 adev->asic_funcs = &cik_asic_funcs;1996 adev->asic_funcs = &cik_asic_funcs;
1997 1997
drivers/gpu/drm/amd/amdgpu/cik_sdma.c+9−22
@@ -53,7 +53,6 @@ static const u32 sdma_offsets[SDMA_MAX_INSTANCE] = · 52 unmodified lines
53static void cik_sdma_set_ring_funcs(struct amdgpu_device *adev);53static void cik_sdma_set_ring_funcs(struct amdgpu_device *adev);
54static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev);54static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev);
55static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev);55static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev);
56static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev);
57static int cik_sdma_soft_reset(struct amdgpu_ip_block *ip_block);56static int cik_sdma_soft_reset(struct amdgpu_ip_block *ip_block);
58 57
59u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev);58u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev);
@@ -919,6 +918,14 @@ static void cik_enable_sdma_mgls(struct amdgpu_device *adev, · 859 unmodified lines
919 }918 }
920}919}
921 920
921static const struct amdgpu_vm_pte_funcs cik_sdma_vm_pte_funcs = {
922 .copy_pte_num_dw = 7,
923 .copy_pte = cik_sdma_vm_copy_pte,
924
925 .write_pte = cik_sdma_vm_write_pte,
926 .set_pte_pde = cik_sdma_vm_set_pte_pde,
927};
928
922static int cik_sdma_early_init(struct amdgpu_ip_block *ip_block)929static int cik_sdma_early_init(struct amdgpu_ip_block *ip_block)
923{930{
924 struct amdgpu_device *adev = ip_block->adev;931 struct amdgpu_device *adev = ip_block->adev;
@@ -933,7 +940,7 @@ static int cik_sdma_early_init(struct amdgpu_ip_block *ip_block) · 8 unmodified lines
933 cik_sdma_set_ring_funcs(adev);940 cik_sdma_set_ring_funcs(adev);
934 cik_sdma_set_irq_funcs(adev);941 cik_sdma_set_irq_funcs(adev);
935 cik_sdma_set_buffer_funcs(adev);942 cik_sdma_set_buffer_funcs(adev);
936 cik_sdma_set_vm_pte_funcs(adev);943 amdgpu_sdma_set_vm_pte_scheds(adev, &cik_sdma_vm_pte_funcs);
937 944
938 return 0;945 return 0;
939}946}
@@ -1337,26 +1344,6 @@ static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev) · 397 unmodified lines
1337 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;1344 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
1338}1345}
1339 1346
1340static const struct amdgpu_vm_pte_funcs cik_sdma_vm_pte_funcs = {
1341 .copy_pte_num_dw = 7,
1342 .copy_pte = cik_sdma_vm_copy_pte,
1343
1344 .write_pte = cik_sdma_vm_write_pte,
1345 .set_pte_pde = cik_sdma_vm_set_pte_pde,
1346};
1347
1348static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev)
1349{
1350 unsigned i;
1351
1352 adev->vm_manager.vm_pte_funcs = &cik_sdma_vm_pte_funcs;
1353 for (i = 0; i < adev->sdma.num_instances; i++) {
1354 adev->vm_manager.vm_pte_scheds[i] =
1355 &adev->sdma.instance[i].ring.sched;
1356 }
1357 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
1358}
1359
1360const struct amdgpu_ip_block_version cik_sdma_ip_block =1347const struct amdgpu_ip_block_version cik_sdma_ip_block =
1361{1348{
1362 .type = AMD_IP_BLOCK_TYPE_SDMA,1349 .type = AMD_IP_BLOCK_TYPE_SDMA,
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c+6−6
@@ -175,10 +175,10 @@ static u32 dce_v10_0_audio_endpt_rreg(struct amdgpu_device *adev, · 174 unmodified lines
175 unsigned long flags;175 unsigned long flags;
176 u32 r;176 u32 r;
177 177
178 spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);178 spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
179 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);179 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
180 r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset);180 r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset);
181 spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags);181 spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags);
182 182
183 return r;183 return r;
184}184}
@@ -188,10 +188,10 @@ static void dce_v10_0_audio_endpt_wreg(struct amdgpu_device *adev, · 3 unmodified lines
188{188{
189 unsigned long flags;189 unsigned long flags;
190 190
191 spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);191 spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
192 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);192 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
193 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v);193 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v);
194 spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags);194 spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags);
195}195}
196 196
197static u32 dce_v10_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)197static u32 dce_v10_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
@@ -2750,8 +2750,8 @@ static int dce_v10_0_early_init(struct amdgpu_ip_block *ip_block) · 2552 unmodified lines
2750{2750{
2751 struct amdgpu_device *adev = ip_block->adev;2751 struct amdgpu_device *adev = ip_block->adev;
2752 2752
2753 adev->audio_endpt_rreg = &dce_v10_0_audio_endpt_rreg;2753 adev->reg.audio_endpt.rreg = &dce_v10_0_audio_endpt_rreg;
2754 adev->audio_endpt_wreg = &dce_v10_0_audio_endpt_wreg;2754 adev->reg.audio_endpt.wreg = &dce_v10_0_audio_endpt_wreg;
2755 2755
2756 dce_v10_0_set_display_funcs(adev);2756 dce_v10_0_set_display_funcs(adev);
2757 2757
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c+6−6
@@ -138,10 +138,10 @@ static u32 dce_v6_0_audio_endpt_rreg(struct amdgpu_device *adev, · 137 unmodified lines
138 unsigned long flags;138 unsigned long flags;
139 u32 r;139 u32 r;
140 140
141 spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);141 spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
142 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);142 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
143 r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset);143 r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset);
144 spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags);144 spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags);
145 145
146 return r;146 return r;
147}147}
@@ -151,11 +151,11 @@ static void dce_v6_0_audio_endpt_wreg(struct amdgpu_device *adev, · 3 unmodified lines
151{151{
152 unsigned long flags;152 unsigned long flags;
153 153
154 spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);154 spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
155 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset,155 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset,
156 reg | AZALIA_F0_CODEC_ENDPOINT_INDEX__AZALIA_ENDPOINT_REG_WRITE_EN_MASK);156 reg | AZALIA_F0_CODEC_ENDPOINT_INDEX__AZALIA_ENDPOINT_REG_WRITE_EN_MASK);
157 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v);157 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v);
158 spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags);158 spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags);
159}159}
160 160
161static u32 dce_v6_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)161static u32 dce_v6_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
@@ -2697,8 +2697,8 @@ static int dce_v6_0_early_init(struct amdgpu_ip_block *ip_block) · 2535 unmodified lines
2697{2697{
2698 struct amdgpu_device *adev = ip_block->adev;2698 struct amdgpu_device *adev = ip_block->adev;
2699 2699
2700 adev->audio_endpt_rreg = &dce_v6_0_audio_endpt_rreg;2700 adev->reg.audio_endpt.rreg = &dce_v6_0_audio_endpt_rreg;
2701 adev->audio_endpt_wreg = &dce_v6_0_audio_endpt_wreg;2701 adev->reg.audio_endpt.wreg = &dce_v6_0_audio_endpt_wreg;
2702 2702
2703 dce_v6_0_set_display_funcs(adev);2703 dce_v6_0_set_display_funcs(adev);
2704 2704
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c+6−6
@@ -126,10 +126,10 @@ static u32 dce_v8_0_audio_endpt_rreg(struct amdgpu_device *adev, · 125 unmodified lines
126 unsigned long flags;126 unsigned long flags;
127 u32 r;127 u32 r;
128 128
129 spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);129 spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
130 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);130 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
131 r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset);131 r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset);
132 spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags);132 spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags);
133 133
134 return r;134 return r;
135}135}
@@ -139,10 +139,10 @@ static void dce_v8_0_audio_endpt_wreg(struct amdgpu_device *adev, · 3 unmodified lines
139{139{
140 unsigned long flags;140 unsigned long flags;
141 141
142 spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);142 spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
143 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);143 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
144 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v);144 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v);
145 spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags);145 spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags);
146}146}
147 147
148static u32 dce_v8_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)148static u32 dce_v8_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
@@ -2655,8 +2655,8 @@ static int dce_v8_0_early_init(struct amdgpu_ip_block *ip_block) · 2506 unmodified lines
2655{2655{
2656 struct amdgpu_device *adev = ip_block->adev;2656 struct amdgpu_device *adev = ip_block->adev;
2657 2657
2658 adev->audio_endpt_rreg = &dce_v8_0_audio_endpt_rreg;2658 adev->reg.audio_endpt.rreg = &dce_v8_0_audio_endpt_rreg;
2659 adev->audio_endpt_wreg = &dce_v8_0_audio_endpt_wreg;2659 adev->reg.audio_endpt.wreg = &dce_v8_0_audio_endpt_wreg;
2660 2660
2661 dce_v8_0_set_display_funcs(adev);2661 dce_v8_0_set_display_funcs(adev);
2662 2662
drivers/gpu/drm/amd/amdgpu/df_v3_6.c+10−10
@@ -51,7 +51,7 @@ static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev, · 50 unmodified lines
51 address = adev->nbio.funcs->get_pcie_index_offset(adev);51 address = adev->nbio.funcs->get_pcie_index_offset(adev);
52 data = adev->nbio.funcs->get_pcie_data_offset(adev);52 data = adev->nbio.funcs->get_pcie_data_offset(adev);
53 53
54 spin_lock_irqsave(&adev->pcie_idx_lock, flags);54 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
55 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);55 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);
56 WREG32(data, ficaa_val);56 WREG32(data, ficaa_val);
57 57
@@ -61,7 +61,7 @@ static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev, · 3 unmodified lines
61 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);61 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);
62 ficadh_val = RREG32(data);62 ficadh_val = RREG32(data);
63 63
64 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);64 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
65 65
66 return (((ficadh_val & 0xFFFFFFFFFFFFFFFF) << 32) | ficadl_val);66 return (((ficadh_val & 0xFFFFFFFFFFFFFFFF) << 32) | ficadl_val);
67}67}
@@ -74,7 +74,7 @@ static void df_v3_6_set_fica(struct amdgpu_device *adev, uint32_t ficaa_val, · 6 unmodified lines
74 address = adev->nbio.funcs->get_pcie_index_offset(adev);74 address = adev->nbio.funcs->get_pcie_index_offset(adev);
75 data = adev->nbio.funcs->get_pcie_data_offset(adev);75 data = adev->nbio.funcs->get_pcie_data_offset(adev);
76 76
77 spin_lock_irqsave(&adev->pcie_idx_lock, flags);77 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
78 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);78 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);
79 WREG32(data, ficaa_val);79 WREG32(data, ficaa_val);
80 80
@@ -84,7 +84,7 @@ static void df_v3_6_set_fica(struct amdgpu_device *adev, uint32_t ficaa_val, · 3 unmodified lines
84 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);84 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);
85 WREG32(data, ficadh_val);85 WREG32(data, ficadh_val);
86 86
87 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);87 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
88}88}
89 89
90/*90/*
@@ -102,12 +102,12 @@ static void df_v3_6_perfmon_rreg(struct amdgpu_device *adev, · 11 unmodified lines
102 address = adev->nbio.funcs->get_pcie_index_offset(adev);102 address = adev->nbio.funcs->get_pcie_index_offset(adev);
103 data = adev->nbio.funcs->get_pcie_data_offset(adev);103 data = adev->nbio.funcs->get_pcie_data_offset(adev);
104 104
105 spin_lock_irqsave(&adev->pcie_idx_lock, flags);105 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
106 WREG32(address, lo_addr);106 WREG32(address, lo_addr);
107 *lo_val = RREG32(data);107 *lo_val = RREG32(data);
108 WREG32(address, hi_addr);108 WREG32(address, hi_addr);
109 *hi_val = RREG32(data);109 *hi_val = RREG32(data);
110 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);110 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
111}111}
112 112
113/*113/*
@@ -124,12 +124,12 @@ static void df_v3_6_perfmon_wreg(struct amdgpu_device *adev, uint32_t lo_addr, · 10 unmodified lines
124 address = adev->nbio.funcs->get_pcie_index_offset(adev);124 address = adev->nbio.funcs->get_pcie_index_offset(adev);
125 data = adev->nbio.funcs->get_pcie_data_offset(adev);125 data = adev->nbio.funcs->get_pcie_data_offset(adev);
126 126
127 spin_lock_irqsave(&adev->pcie_idx_lock, flags);127 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
128 WREG32(address, lo_addr);128 WREG32(address, lo_addr);
129 WREG32(data, lo_val);129 WREG32(data, lo_val);
130 WREG32(address, hi_addr);130 WREG32(address, hi_addr);
131 WREG32(data, hi_val);131 WREG32(data, hi_val);
132 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);132 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
133}133}
134 134
135/* same as perfmon_wreg but return status on write value check */135/* same as perfmon_wreg but return status on write value check */
@@ -143,7 +143,7 @@ static int df_v3_6_perfmon_arm_with_status(struct amdgpu_device *adev, · 7 unmodified lines
143 address = adev->nbio.funcs->get_pcie_index_offset(adev);143 address = adev->nbio.funcs->get_pcie_index_offset(adev);
144 data = adev->nbio.funcs->get_pcie_data_offset(adev);144 data = adev->nbio.funcs->get_pcie_data_offset(adev);
145 145
146 spin_lock_irqsave(&adev->pcie_idx_lock, flags);146 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
147 WREG32(address, lo_addr);147 WREG32(address, lo_addr);
148 WREG32(data, lo_val);148 WREG32(data, lo_val);
149 WREG32(address, hi_addr);149 WREG32(address, hi_addr);
@@ -153,7 +153,7 @@ static int df_v3_6_perfmon_arm_with_status(struct amdgpu_device *adev, · 3 unmodified lines
153 lo_val_rb = RREG32(data);153 lo_val_rb = RREG32(data);
154 WREG32(address, hi_addr);154 WREG32(address, hi_addr);
155 hi_val_rb = RREG32(data);155 hi_val_rb = RREG32(data);
156 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);156 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
157 157
158 if (!(lo_val == lo_val_rb && hi_val == hi_val_rb))158 if (!(lo_val == lo_val_rb && hi_val == hi_val_rb))
159 return -EBUSY;159 return -EBUSY;
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c+33−0
@@ -4238,6 +4238,37 @@ static int gfx_v11_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev) · 4237 unmodified lines
4238 return gfx_v11_0_cp_gfx_start(adev);4238 return gfx_v11_0_cp_gfx_start(adev);
4239}4239}
4240 4240
4241static void gfx_v11_0_compute_mqd_set_cu_mask(struct amdgpu_device *adev,
4242 struct v11_compute_mqd *mqd,
4243 struct amdgpu_mqd_prop *prop)
4244{
4245 uint32_t se_mask[8] = {0};
4246 uint32_t wa_mask;
4247 bool has_wa_flag = prop->cu_flags & (AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE |
4248 AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE);
4249
4250 if (!has_wa_flag && (!prop->cu_mask || !prop->cu_mask_count))
4251 return;
4252
4253 if (has_wa_flag) {
4254 wa_mask = (prop->cu_flags & AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE) ?
4255 0xffff : 0xffffffff;
4256 mqd->compute_static_thread_mgmt_se0 = wa_mask;
4257 mqd->compute_static_thread_mgmt_se1 = wa_mask;
4258 mqd->compute_static_thread_mgmt_se2 = wa_mask;
4259 mqd->compute_static_thread_mgmt_se3 = wa_mask;
4260 return;
4261 }
4262
4263 amdgpu_gfx_mqd_symmetrically_map_cu_mask(adev, prop->cu_mask,
4264 prop->cu_mask_count, se_mask);
4265
4266 mqd->compute_static_thread_mgmt_se0 = se_mask[0];
4267 mqd->compute_static_thread_mgmt_se1 = se_mask[1];
4268 mqd->compute_static_thread_mgmt_se2 = se_mask[2];
4269 mqd->compute_static_thread_mgmt_se3 = se_mask[3];
4270}
4271
4241static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,4272static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
4242 struct amdgpu_mqd_prop *prop)4273 struct amdgpu_mqd_prop *prop)
4243{4274{
@@ -4372,6 +4403,8 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m, · 128 unmodified lines
4372 /* set UQ fenceaddress */4403 /* set UQ fenceaddress */
4373 mqd->fence_address_lo = lower_32_bits(prop->fence_address);4404 mqd->fence_address_lo = lower_32_bits(prop->fence_address);
4374 mqd->fence_address_hi = upper_32_bits(prop->fence_address);4405 mqd->fence_address_hi = upper_32_bits(prop->fence_address);
4406 /* set CU mask */
4407 gfx_v11_0_compute_mqd_set_cu_mask(adev, mqd, prop);
4375 4408
4376 return 0;4409 return 0;
4377}4410}
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c+33−0
@@ -3109,6 +3109,37 @@ static int gfx_v12_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev) · 3108 unmodified lines
3109 return gfx_v12_0_cp_gfx_start(adev);3109 return gfx_v12_0_cp_gfx_start(adev);
3110}3110}
3111 3111
3112static void gfx_v12_0_compute_mqd_set_cu_mask(struct amdgpu_device *adev,
3113 struct v12_compute_mqd *mqd,
3114 struct amdgpu_mqd_prop *prop)
3115{
3116 uint32_t se_mask[8] = {0};
3117 uint32_t wa_mask;
3118 bool has_wa_flag = prop->cu_flags & (AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE |
3119 AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE);
3120
3121 if (!has_wa_flag && (!prop->cu_mask || !prop->cu_mask_count))
3122 return;
3123
3124 if (has_wa_flag) {
3125 wa_mask = (prop->cu_flags & AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE) ?
3126 0xffff : 0xffffffff;
3127 mqd->compute_static_thread_mgmt_se0 = wa_mask;
3128 mqd->compute_static_thread_mgmt_se1 = wa_mask;
3129 mqd->compute_static_thread_mgmt_se2 = wa_mask;
3130 mqd->compute_static_thread_mgmt_se3 = wa_mask;
3131 return;
3132 }
3133
3134 amdgpu_gfx_mqd_symmetrically_map_cu_mask(adev, prop->cu_mask,
3135 prop->cu_mask_count, se_mask);
3136
3137 mqd->compute_static_thread_mgmt_se0 = se_mask[0];
3138 mqd->compute_static_thread_mgmt_se1 = se_mask[1];
3139 mqd->compute_static_thread_mgmt_se2 = se_mask[2];
3140 mqd->compute_static_thread_mgmt_se3 = se_mask[3];
3141}
3142
3112static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m,3143static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
3113 struct amdgpu_mqd_prop *prop)3144 struct amdgpu_mqd_prop *prop)
3114{3145{
@@ -3242,6 +3273,8 @@ static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m, · 127 unmodified lines
3242 /* set UQ fenceaddress */3273 /* set UQ fenceaddress */
3243 mqd->fence_address_lo = lower_32_bits(prop->fence_address);3274 mqd->fence_address_lo = lower_32_bits(prop->fence_address);
3244 mqd->fence_address_hi = upper_32_bits(prop->fence_address);3275 mqd->fence_address_hi = upper_32_bits(prop->fence_address);
3276 /* set CU mask */
3277 gfx_v12_0_compute_mqd_set_cu_mask(adev, mqd, prop);
3245 3278
3246 return 0;3279 return 0;
3247}3280}
drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c+1−1
@@ -1405,7 +1405,7 @@ static void gfx_v12_1_xcc_init_compute_vmid(struct amdgpu_device *adev, · 1404 unmodified lines
1405 /*1405 /*
1406 * Configure apertures:1406 * Configure apertures:
1407 * LDS: 0x20000000'00000000 - 0x20000001'00000000 (4GB)1407 * LDS: 0x20000000'00000000 - 0x20000001'00000000 (4GB)
1408 * Scratch: 0x10000000'00000000 - 0x10000001'00000000 (4GB)1408 * Scratch: 0x10000000'00000000 - 0x11ffffff'ffffffff (128PB 57-bit)
1409 */1409 */
1410 sh_mem_bases = REG_SET_FIELD(0, SH_MEM_BASES, PRIVATE_BASE,1410 sh_mem_bases = REG_SET_FIELD(0, SH_MEM_BASES, PRIVATE_BASE,
1411 (adev->gmc.private_aperture_start >> 58));1411 (adev->gmc.private_aperture_start >> 58));
drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c+8−2
@@ -654,9 +654,15 @@ static int gmc_v12_0_early_init(struct amdgpu_ip_block *ip_block) · 653 unmodified lines
654 adev->gmc.shared_aperture_start = 0x2000000000000000ULL;654 adev->gmc.shared_aperture_start = 0x2000000000000000ULL;
655 adev->gmc.shared_aperture_end =655 adev->gmc.shared_aperture_end =
656 adev->gmc.shared_aperture_start + (4ULL << 30) - 1;656 adev->gmc.shared_aperture_start + (4ULL << 30) - 1;
657
657 adev->gmc.private_aperture_start = 0x1000000000000000ULL;658 adev->gmc.private_aperture_start = 0x1000000000000000ULL;
658 adev->gmc.private_aperture_end =659 if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 1, 0))
659 adev->gmc.private_aperture_start + (4ULL << 30) - 1;660 adev->gmc.private_aperture_end =
661 adev->gmc.private_aperture_start + (1ULL << 57) - 1;
662 else
663 adev->gmc.private_aperture_end =
664 adev->gmc.private_aperture_start + (4ULL << 30) - 1;
665
660 adev->gmc.noretry_flags = AMDGPU_VM_NORETRY_FLAGS_TF;666 adev->gmc.noretry_flags = AMDGPU_VM_NORETRY_FLAGS_TF;
661 667
662 return 0;668 return 0;
drivers/gpu/drm/amd/amdgpu/gmc_v12_1.c+0−2
@@ -345,9 +345,7 @@ static void gmc_v12_1_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, · 344 unmodified lines
345 return;345 return;
346 }346 }
347 347
348 mutex_lock(&adev->mman.gtt_window_lock);
349 gmc_v12_1_flush_vm_hub(adev, vmid, vmhub, 0);348 gmc_v12_1_flush_vm_hub(adev, vmid, vmhub, 0);
350 mutex_unlock(&adev->mman.gtt_window_lock);
351 return;349 return;
352}350}
353 351
drivers/gpu/drm/amd/amdgpu/nv.c+13−19
@@ -283,10 +283,10 @@ static u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg) · 282 unmodified lines
283 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);283 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
284 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);284 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
285 285
286 spin_lock_irqsave(&adev->didt_idx_lock, flags);286 spin_lock_irqsave(&adev->reg.didt.lock, flags);
287 WREG32(address, (reg));287 WREG32(address, (reg));
288 r = RREG32(data);288 r = RREG32(data);
289 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);289 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
290 return r;290 return r;
291}291}
292 292
@@ -297,10 +297,10 @@ static void nv_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 4 unmodified lines
297 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);297 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
298 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);298 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
299 299
300 spin_lock_irqsave(&adev->didt_idx_lock, flags);300 spin_lock_irqsave(&adev->reg.didt.lock, flags);
301 WREG32(address, (reg));301 WREG32(address, (reg));
302 WREG32(data, (v));302 WREG32(data, (v));
303 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);303 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
304}304}
305 305
306static u32 nv_get_config_memsize(struct amdgpu_device *adev)306static u32 nv_get_config_memsize(struct amdgpu_device *adev)
@@ -635,21 +635,15 @@ static int nv_common_early_init(struct amdgpu_ip_block *ip_block) · 328 unmodified lines
635 struct amdgpu_device *adev = ip_block->adev;635 struct amdgpu_device *adev = ip_block->adev;
636 636
637 adev->nbio.funcs->set_reg_remap(adev);637 adev->nbio.funcs->set_reg_remap(adev);
638 adev->smc_rreg = NULL;638 adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
639 adev->smc_wreg = NULL;639 adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
640 adev->pcie_rreg = &amdgpu_device_indirect_rreg;640 adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
641 adev->pcie_wreg = &amdgpu_device_indirect_wreg;641 adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
642 adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;642 adev->reg.pcie.port_rreg = &amdgpu_device_pcie_port_rreg;
643 adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;643 adev->reg.pcie.port_wreg = &amdgpu_device_pcie_port_wreg;
644 adev->pciep_rreg = amdgpu_device_pcie_port_rreg;644
645 adev->pciep_wreg = amdgpu_device_pcie_port_wreg;645 adev->reg.didt.rreg = &nv_didt_rreg;
646 646 adev->reg.didt.wreg = &nv_didt_wreg;
647 /* TODO: will add them during VCN v2 implementation */
648 adev->uvd_ctx_rreg = NULL;
649 adev->uvd_ctx_wreg = NULL;
650
651 adev->didt_rreg = &nv_didt_rreg;
652 adev->didt_wreg = &nv_didt_wreg;
653 647
654 adev->asic_funcs = &nv_asic_funcs;648 adev->asic_funcs = &nv_asic_funcs;
655 649
drivers/gpu/drm/amd/amdgpu/psp_v13_0.c+1−1
@@ -166,7 +166,7 @@ static void psp_v13_0_bootloader_print_status(struct psp_context *psp, · 165 unmodified lines
166 bl_status_reg =166 bl_status_reg =
167 (SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_92)167 (SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_92)
168 << 2) +168 << 2) +
169 adev->asic_funcs->encode_ext_smn_addressing(i);169 amdgpu_reg_get_smn_base64(adev, MP0_HWIP, i);
170 at += snprintf(bl_status_msg + at,170 at += snprintf(bl_status_msg + at,
171 PSP13_BL_STATUS_SIZE - at,171 PSP13_BL_STATUS_SIZE - at,
172 " status(%02i): 0x%08x", i,172 " status(%02i): 0x%08x", i,
drivers/gpu/drm/amd/amdgpu/psp_v15_0.c+10−10
@@ -69,12 +69,12 @@ static int psp_v15_0_0_ring_stop(struct psp_context *psp, · 68 unmodified lines
69 0x80000000, 0x80000000, false);69 0x80000000, 0x80000000, false);
70 } else {70 } else {
71 /* Write the ring destroy command*/71 /* Write the ring destroy command*/
72 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64,72 WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64,
73 GFX_CTRL_CMD_ID_DESTROY_RINGS);73 GFX_CTRL_CMD_ID_DESTROY_RINGS);
74 /* there might be handshake issue with hardware which needs delay */74 /* there might be handshake issue with hardware which needs delay */
75 mdelay(20);75 mdelay(20);
76 /* Wait for response flag (bit 31) */76 /* Wait for response flag (bit 31) */
77 ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),77 ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
78 0x80000000, 0x80000000, false);78 0x80000000, 0x80000000, false);
79 }79 }
80 80
@@ -116,7 +116,7 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp, · 35 unmodified lines
116 116
117 } else {117 } else {
118 /* Wait for sOS ready for ring creation */118 /* Wait for sOS ready for ring creation */
119 ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),119 ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
120 0x80000000, 0x80000000, false);120 0x80000000, 0x80000000, false);
121 if (ret) {121 if (ret) {
122 DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");122 DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");
@@ -125,23 +125,23 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp, · 2 unmodified lines
125 125
126 /* Write low address of the ring to C2PMSG_69 */126 /* Write low address of the ring to C2PMSG_69 */
127 psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);127 psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
128 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_69, psp_ring_reg);128 WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_69, psp_ring_reg);
129 /* Write high address of the ring to C2PMSG_70 */129 /* Write high address of the ring to C2PMSG_70 */
130 psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);130 psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
131 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_70, psp_ring_reg);131 WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_70, psp_ring_reg);
132 /* Write size of ring to C2PMSG_71 */132 /* Write size of ring to C2PMSG_71 */
133 psp_ring_reg = ring->ring_size;133 psp_ring_reg = ring->ring_size;
134 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_71, psp_ring_reg);134 WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_71, psp_ring_reg);
135 /* Write the ring initialization command to C2PMSG_64 */135 /* Write the ring initialization command to C2PMSG_64 */
136 psp_ring_reg = ring_type;136 psp_ring_reg = ring_type;
137 psp_ring_reg = psp_ring_reg << 16;137 psp_ring_reg = psp_ring_reg << 16;
138 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64, psp_ring_reg);138 WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64, psp_ring_reg);
139 139
140 /* there might be handshake issue with hardware which needs delay */140 /* there might be handshake issue with hardware which needs delay */
141 mdelay(20);141 mdelay(20);
142 142
143 /* Wait for response flag (bit 31) in C2PMSG_64 */143 /* Wait for response flag (bit 31) in C2PMSG_64 */
144 ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),144 ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
145 0x80000000, 0x8000FFFF, false);145 0x80000000, 0x8000FFFF, false);
146 }146 }
147 147
@@ -174,7 +174,7 @@ static uint32_t psp_v15_0_0_ring_get_wptr(struct psp_context *psp) · 26 unmodified lines
174 if (amdgpu_sriov_vf(adev))174 if (amdgpu_sriov_vf(adev))
175 data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102);175 data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102);
176 else176 else
177 data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67);177 data = RREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67);
178 178
179 return data;179 return data;
180}180}
@@ -188,7 +188,7 @@ static void psp_v15_0_0_ring_set_wptr(struct psp_context *psp, uint32_t value) · 7 unmodified lines
188 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,188 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,
189 GFX_CTRL_CMD_ID_CONSUME_CMD);189 GFX_CTRL_CMD_ID_CONSUME_CMD);
190 } else190 } else
191 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67, value);191 WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67, value);
192}192}
193 193
194static const struct psp_funcs psp_v15_0_0_funcs = {194static const struct psp_funcs psp_v15_0_0_funcs = {
drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c+9−22
@@ -51,7 +51,6 @@ · 50 unmodified lines
51 51
52static void sdma_v2_4_set_ring_funcs(struct amdgpu_device *adev);52static void sdma_v2_4_set_ring_funcs(struct amdgpu_device *adev);
53static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev);53static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev);
54static void sdma_v2_4_set_vm_pte_funcs(struct amdgpu_device *adev);
55static void sdma_v2_4_set_irq_funcs(struct amdgpu_device *adev);54static void sdma_v2_4_set_irq_funcs(struct amdgpu_device *adev);
56 55
57MODULE_FIRMWARE("amdgpu/topaz_sdma.bin");56MODULE_FIRMWARE("amdgpu/topaz_sdma.bin");
@@ -809,6 +808,14 @@ static void sdma_v2_4_ring_emit_wreg(struct amdgpu_ring *ring, · 751 unmodified lines
809 amdgpu_ring_write(ring, val);808 amdgpu_ring_write(ring, val);
810}809}
811 810
811static const struct amdgpu_vm_pte_funcs sdma_v2_4_vm_pte_funcs = {
812 .copy_pte_num_dw = 7,
813 .copy_pte = sdma_v2_4_vm_copy_pte,
814
815 .write_pte = sdma_v2_4_vm_write_pte,
816 .set_pte_pde = sdma_v2_4_vm_set_pte_pde,
817};
818
812static int sdma_v2_4_early_init(struct amdgpu_ip_block *ip_block)819static int sdma_v2_4_early_init(struct amdgpu_ip_block *ip_block)
813{820{
814 struct amdgpu_device *adev = ip_block->adev;821 struct amdgpu_device *adev = ip_block->adev;
@@ -822,7 +829,7 @@ static int sdma_v2_4_early_init(struct amdgpu_ip_block *ip_block) · 7 unmodified lines
822 829
823 sdma_v2_4_set_ring_funcs(adev);830 sdma_v2_4_set_ring_funcs(adev);
824 sdma_v2_4_set_buffer_funcs(adev);831 sdma_v2_4_set_buffer_funcs(adev);
825 sdma_v2_4_set_vm_pte_funcs(adev);832 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v2_4_vm_pte_funcs);
826 sdma_v2_4_set_irq_funcs(adev);833 sdma_v2_4_set_irq_funcs(adev);
827 834
828 return 0;835 return 0;
@@ -1232,26 +1239,6 @@ static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev) · 403 unmodified lines
1232 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;1239 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
1233}1240}
1234 1241
1235static const struct amdgpu_vm_pte_funcs sdma_v2_4_vm_pte_funcs = {
1236 .copy_pte_num_dw = 7,
1237 .copy_pte = sdma_v2_4_vm_copy_pte,
1238
1239 .write_pte = sdma_v2_4_vm_write_pte,
1240 .set_pte_pde = sdma_v2_4_vm_set_pte_pde,
1241};
1242
1243static void sdma_v2_4_set_vm_pte_funcs(struct amdgpu_device *adev)
1244{
1245 unsigned i;
1246
1247 adev->vm_manager.vm_pte_funcs = &sdma_v2_4_vm_pte_funcs;
1248 for (i = 0; i < adev->sdma.num_instances; i++) {
1249 adev->vm_manager.vm_pte_scheds[i] =
1250 &adev->sdma.instance[i].ring.sched;
1251 }
1252 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
1253}
1254
1255const struct amdgpu_ip_block_version sdma_v2_4_ip_block = {1242const struct amdgpu_ip_block_version sdma_v2_4_ip_block = {
1256 .type = AMD_IP_BLOCK_TYPE_SDMA,1243 .type = AMD_IP_BLOCK_TYPE_SDMA,
1257 .major = 2,1244 .major = 2,
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c+9−22
@@ -51,7 +51,6 @@ · 50 unmodified lines
51 51
52static void sdma_v3_0_set_ring_funcs(struct amdgpu_device *adev);52static void sdma_v3_0_set_ring_funcs(struct amdgpu_device *adev);
53static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev);53static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev);
54static void sdma_v3_0_set_vm_pte_funcs(struct amdgpu_device *adev);
55static void sdma_v3_0_set_irq_funcs(struct amdgpu_device *adev);54static void sdma_v3_0_set_irq_funcs(struct amdgpu_device *adev);
56 55
57MODULE_FIRMWARE("amdgpu/tonga_sdma.bin");56MODULE_FIRMWARE("amdgpu/tonga_sdma.bin");
@@ -1082,6 +1081,14 @@ static void sdma_v3_0_ring_emit_wreg(struct amdgpu_ring *ring, · 1024 unmodified lines
1082 amdgpu_ring_write(ring, val);1081 amdgpu_ring_write(ring, val);
1083}1082}
1084 1083
1084static const struct amdgpu_vm_pte_funcs sdma_v3_0_vm_pte_funcs = {
1085 .copy_pte_num_dw = 7,
1086 .copy_pte = sdma_v3_0_vm_copy_pte,
1087
1088 .write_pte = sdma_v3_0_vm_write_pte,
1089 .set_pte_pde = sdma_v3_0_vm_set_pte_pde,
1090};
1091
1085static int sdma_v3_0_early_init(struct amdgpu_ip_block *ip_block)1092static int sdma_v3_0_early_init(struct amdgpu_ip_block *ip_block)
1086{1093{
1087 struct amdgpu_device *adev = ip_block->adev;1094 struct amdgpu_device *adev = ip_block->adev;
@@ -1102,7 +1109,7 @@ static int sdma_v3_0_early_init(struct amdgpu_ip_block *ip_block) · 14 unmodified lines
1102 1109
1103 sdma_v3_0_set_ring_funcs(adev);1110 sdma_v3_0_set_ring_funcs(adev);
1104 sdma_v3_0_set_buffer_funcs(adev);1111 sdma_v3_0_set_buffer_funcs(adev);
1105 sdma_v3_0_set_vm_pte_funcs(adev);1112 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v3_0_vm_pte_funcs);
1106 sdma_v3_0_set_irq_funcs(adev);1113 sdma_v3_0_set_irq_funcs(adev);
1107 1114
1108 return 0;1115 return 0;
@@ -1674,26 +1681,6 @@ static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev) · 565 unmodified lines
1674 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;1681 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
1675}1682}
1676 1683
1677static const struct amdgpu_vm_pte_funcs sdma_v3_0_vm_pte_funcs = {
1678 .copy_pte_num_dw = 7,
1679 .copy_pte = sdma_v3_0_vm_copy_pte,
1680
1681 .write_pte = sdma_v3_0_vm_write_pte,
1682 .set_pte_pde = sdma_v3_0_vm_set_pte_pde,
1683};
1684
1685static void sdma_v3_0_set_vm_pte_funcs(struct amdgpu_device *adev)
1686{
1687 unsigned i;
1688
1689 adev->vm_manager.vm_pte_funcs = &sdma_v3_0_vm_pte_funcs;
1690 for (i = 0; i < adev->sdma.num_instances; i++) {
1691 adev->vm_manager.vm_pte_scheds[i] =
1692 &adev->sdma.instance[i].ring.sched;
1693 }
1694 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
1695}
1696
1697const struct amdgpu_ip_block_version sdma_v3_0_ip_block =1684const struct amdgpu_ip_block_version sdma_v3_0_ip_block =
1698{1685{
1699 .type = AMD_IP_BLOCK_TYPE_SDMA,1686 .type = AMD_IP_BLOCK_TYPE_SDMA,
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c+25−29
@@ -129,7 +129,6 @@ static const struct amdgpu_hwip_reg_entry sdma_reg_list_4_0[] = { · 128 unmodified lines
129 129
130static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev);130static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev);
131static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev);131static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev);
132static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev);
133static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev);132static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev);
134static void sdma_v4_0_set_ras_funcs(struct amdgpu_device *adev);133static void sdma_v4_0_set_ras_funcs(struct amdgpu_device *adev);
135 134
@@ -1751,6 +1750,14 @@ static bool sdma_v4_0_fw_support_paging_queue(struct amdgpu_device *adev) · 1615 unmodified lines
1751 }1750 }
1752}1751}
1753 1752
1753static const struct amdgpu_vm_pte_funcs sdma_v4_0_vm_pte_funcs = {
1754 .copy_pte_num_dw = 7,
1755 .copy_pte = sdma_v4_0_vm_copy_pte,
1756
1757 .write_pte = sdma_v4_0_vm_write_pte,
1758 .set_pte_pde = sdma_v4_0_vm_set_pte_pde,
1759};
1760
1754static int sdma_v4_0_early_init(struct amdgpu_ip_block *ip_block)1761static int sdma_v4_0_early_init(struct amdgpu_ip_block *ip_block)
1755{1762{
1756 struct amdgpu_device *adev = ip_block->adev;1763 struct amdgpu_device *adev = ip_block->adev;
@@ -1769,7 +1776,7 @@ static int sdma_v4_0_early_init(struct amdgpu_ip_block *ip_block) · 12 unmodified lines
1769 1776
1770 sdma_v4_0_set_ring_funcs(adev);1777 sdma_v4_0_set_ring_funcs(adev);
1771 sdma_v4_0_set_buffer_funcs(adev);1778 sdma_v4_0_set_buffer_funcs(adev);
1772 sdma_v4_0_set_vm_pte_funcs(adev);1779 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v4_0_vm_pte_funcs);
1773 sdma_v4_0_set_irq_funcs(adev);1780 sdma_v4_0_set_irq_funcs(adev);
1774 sdma_v4_0_set_ras_funcs(adev);1781 sdma_v4_0_set_ras_funcs(adev);
1775 1782
@@ -2597,48 +2604,37 @@ static void sdma_v4_0_emit_fill_buffer(struct amdgpu_ib *ib, · 821 unmodified lines
2597}2604}
2598 2605
2599static const struct amdgpu_buffer_funcs sdma_v4_0_buffer_funcs = {2606static const struct amdgpu_buffer_funcs sdma_v4_0_buffer_funcs = {
2600 .copy_max_bytes = 0x400000,2607 .copy_max_bytes = 1 << 22,
2601 .copy_num_dw = 7,2608 .copy_num_dw = 7,
2602 .emit_copy_buffer = sdma_v4_0_emit_copy_buffer,2609 .emit_copy_buffer = sdma_v4_0_emit_copy_buffer,
2603 2610
2604 .fill_max_bytes = 0x400000,2611 .fill_max_bytes = 1 << 22,
2612 .fill_num_dw = 5,
2613 .emit_fill_buffer = sdma_v4_0_emit_fill_buffer,
2614};
2615
2616static const struct amdgpu_buffer_funcs sdma_v4_4_buffer_funcs = {
2617 .copy_max_bytes = 1 << 30,
2618 .copy_num_dw = 7,
2619 .emit_copy_buffer = sdma_v4_0_emit_copy_buffer,
2620
2621 .fill_max_bytes = 1 << 30,
2605 .fill_num_dw = 5,2622 .fill_num_dw = 5,
2606 .emit_fill_buffer = sdma_v4_0_emit_fill_buffer,2623 .emit_fill_buffer = sdma_v4_0_emit_fill_buffer,
2607};2624};
2608 2625
2609static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)2626static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
2610{2627{
2611 adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;2628 if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) >= IP_VERSION(4, 4, 0))
2629 adev->mman.buffer_funcs = &sdma_v4_4_buffer_funcs;
2630 else
2631 adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;
2612 if (adev->sdma.has_page_queue)2632 if (adev->sdma.has_page_queue)
2613 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;2633 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
2614 else2634 else
2615 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;2635 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
2616}2636}
2617 2637
2618static const struct amdgpu_vm_pte_funcs sdma_v4_0_vm_pte_funcs = {
2619 .copy_pte_num_dw = 7,
2620 .copy_pte = sdma_v4_0_vm_copy_pte,
2621
2622 .write_pte = sdma_v4_0_vm_write_pte,
2623 .set_pte_pde = sdma_v4_0_vm_set_pte_pde,
2624};
2625
2626static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev)
2627{
2628 struct drm_gpu_scheduler *sched;
2629 unsigned i;
2630
2631 adev->vm_manager.vm_pte_funcs = &sdma_v4_0_vm_pte_funcs;
2632 for (i = 0; i < adev->sdma.num_instances; i++) {
2633 if (adev->sdma.has_page_queue)
2634 sched = &adev->sdma.instance[i].page.sched;
2635 else
2636 sched = &adev->sdma.instance[i].ring.sched;
2637 adev->vm_manager.vm_pte_scheds[i] = sched;
2638 }
2639 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
2640}
2641
2642static void sdma_v4_0_get_ras_error_count(uint32_t value,2638static void sdma_v4_0_get_ras_error_count(uint32_t value,
2643 uint32_t instance,2639 uint32_t instance,
2644 uint32_t *sec_count)2640 uint32_t *sec_count)
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c+11−28
@@ -104,7 +104,6 @@ static const struct amdgpu_hwip_reg_entry sdma_reg_list_4_4_2[] = { · 103 unmodified lines
104 104
105static void sdma_v4_4_2_set_ring_funcs(struct amdgpu_device *adev);105static void sdma_v4_4_2_set_ring_funcs(struct amdgpu_device *adev);
106static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev);106static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev);
107static void sdma_v4_4_2_set_vm_pte_funcs(struct amdgpu_device *adev);
108static void sdma_v4_4_2_set_irq_funcs(struct amdgpu_device *adev);107static void sdma_v4_4_2_set_irq_funcs(struct amdgpu_device *adev);
109static void sdma_v4_4_2_set_ras_funcs(struct amdgpu_device *adev);108static void sdma_v4_4_2_set_ras_funcs(struct amdgpu_device *adev);
110static void sdma_v4_4_2_update_reset_mask(struct amdgpu_device *adev);109static void sdma_v4_4_2_update_reset_mask(struct amdgpu_device *adev);
@@ -1347,6 +1346,14 @@ static const struct amdgpu_sdma_funcs sdma_v4_4_2_sdma_funcs = { · 1236 unmodified lines
1347 .soft_reset_kernel_queue = &sdma_v4_4_2_soft_reset_engine,1346 .soft_reset_kernel_queue = &sdma_v4_4_2_soft_reset_engine,
1348};1347};
1349 1348
1349static const struct amdgpu_vm_pte_funcs sdma_v4_4_2_vm_pte_funcs = {
1350 .copy_pte_num_dw = 7,
1351 .copy_pte = sdma_v4_4_2_vm_copy_pte,
1352
1353 .write_pte = sdma_v4_4_2_vm_write_pte,
1354 .set_pte_pde = sdma_v4_4_2_vm_set_pte_pde,
1355};
1356
1350static int sdma_v4_4_2_early_init(struct amdgpu_ip_block *ip_block)1357static int sdma_v4_4_2_early_init(struct amdgpu_ip_block *ip_block)
1351{1358{
1352 struct amdgpu_device *adev = ip_block->adev;1359 struct amdgpu_device *adev = ip_block->adev;
@@ -1362,7 +1369,7 @@ static int sdma_v4_4_2_early_init(struct amdgpu_ip_block *ip_block) · 9 unmodified lines
1362 1369
1363 sdma_v4_4_2_set_ring_funcs(adev);1370 sdma_v4_4_2_set_ring_funcs(adev);
1364 sdma_v4_4_2_set_buffer_funcs(adev);1371 sdma_v4_4_2_set_buffer_funcs(adev);
1365 sdma_v4_4_2_set_vm_pte_funcs(adev);1372 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v4_4_2_vm_pte_funcs);
1366 sdma_v4_4_2_set_irq_funcs(adev);1373 sdma_v4_4_2_set_irq_funcs(adev);
1367 sdma_v4_4_2_set_ras_funcs(adev);1374 sdma_v4_4_2_set_ras_funcs(adev);
1368 return 0;1375 return 0;
@@ -2298,11 +2305,11 @@ static void sdma_v4_4_2_emit_fill_buffer(struct amdgpu_ib *ib, · 929 unmodified lines
2298}2305}
2299 2306
2300static const struct amdgpu_buffer_funcs sdma_v4_4_2_buffer_funcs = {2307static const struct amdgpu_buffer_funcs sdma_v4_4_2_buffer_funcs = {
2301 .copy_max_bytes = 0x400000,2308 .copy_max_bytes = 1 << 30,
2302 .copy_num_dw = 7,2309 .copy_num_dw = 7,
2303 .emit_copy_buffer = sdma_v4_4_2_emit_copy_buffer,2310 .emit_copy_buffer = sdma_v4_4_2_emit_copy_buffer,
2304 2311
2305 .fill_max_bytes = 0x400000,2312 .fill_max_bytes = 1 << 30,
2306 .fill_num_dw = 5,2313 .fill_num_dw = 5,
2307 .emit_fill_buffer = sdma_v4_4_2_emit_fill_buffer,2314 .emit_fill_buffer = sdma_v4_4_2_emit_fill_buffer,
2308};2315};
@@ -2316,30 +2323,6 @@ static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev) · 7 unmodified lines
2316 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;2323 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
2317}2324}
2318 2325
2319static const struct amdgpu_vm_pte_funcs sdma_v4_4_2_vm_pte_funcs = {
2320 .copy_pte_num_dw = 7,
2321 .copy_pte = sdma_v4_4_2_vm_copy_pte,
2322
2323 .write_pte = sdma_v4_4_2_vm_write_pte,
2324 .set_pte_pde = sdma_v4_4_2_vm_set_pte_pde,
2325};
2326
2327static void sdma_v4_4_2_set_vm_pte_funcs(struct amdgpu_device *adev)
2328{
2329 struct drm_gpu_scheduler *sched;
2330 unsigned i;
2331
2332 adev->vm_manager.vm_pte_funcs = &sdma_v4_4_2_vm_pte_funcs;
2333 for (i = 0; i < adev->sdma.num_instances; i++) {
2334 if (adev->sdma.has_page_queue)
2335 sched = &adev->sdma.instance[i].page.sched;
2336 else
2337 sched = &adev->sdma.instance[i].ring.sched;
2338 adev->vm_manager.vm_pte_scheds[i] = sched;
2339 }
2340 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
2341}
2342
2343/**2326/**
2344 * sdma_v4_4_2_update_reset_mask - update reset mask for SDMA2327 * sdma_v4_4_2_update_reset_mask - update reset mask for SDMA
2345 * @adev: Pointer to the AMDGPU device structure2328 * @adev: Pointer to the AMDGPU device structure
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c+8−23
@@ -110,7 +110,6 @@ static const struct amdgpu_hwip_reg_entry sdma_reg_list_5_0[] = { · 109 unmodified lines
110 110
111static void sdma_v5_0_set_ring_funcs(struct amdgpu_device *adev);111static void sdma_v5_0_set_ring_funcs(struct amdgpu_device *adev);
112static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev);112static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev);
113static void sdma_v5_0_set_vm_pte_funcs(struct amdgpu_device *adev);
114static void sdma_v5_0_set_irq_funcs(struct amdgpu_device *adev);113static void sdma_v5_0_set_irq_funcs(struct amdgpu_device *adev);
115static int sdma_v5_0_stop_queue(struct amdgpu_ring *ring);114static int sdma_v5_0_stop_queue(struct amdgpu_ring *ring);
116static int sdma_v5_0_restore_queue(struct amdgpu_ring *ring);115static int sdma_v5_0_restore_queue(struct amdgpu_ring *ring);
@@ -1357,6 +1356,13 @@ static const struct amdgpu_sdma_funcs sdma_v5_0_sdma_funcs = { · 1240 unmodified lines
1357 .soft_reset_kernel_queue = &sdma_v5_0_soft_reset_engine,1356 .soft_reset_kernel_queue = &sdma_v5_0_soft_reset_engine,
1358};1357};
1359 1358
1359static const struct amdgpu_vm_pte_funcs sdma_v5_0_vm_pte_funcs = {
1360 .copy_pte_num_dw = 7,
1361 .copy_pte = sdma_v5_0_vm_copy_pte,
1362 .write_pte = sdma_v5_0_vm_write_pte,
1363 .set_pte_pde = sdma_v5_0_vm_set_pte_pde,
1364};
1365
1360static int sdma_v5_0_early_init(struct amdgpu_ip_block *ip_block)1366static int sdma_v5_0_early_init(struct amdgpu_ip_block *ip_block)
1361{1367{
1362 struct amdgpu_device *adev = ip_block->adev;1368 struct amdgpu_device *adev = ip_block->adev;
@@ -1368,7 +1374,7 @@ static int sdma_v5_0_early_init(struct amdgpu_ip_block *ip_block) · 5 unmodified lines
1368 1374
1369 sdma_v5_0_set_ring_funcs(adev);1375 sdma_v5_0_set_ring_funcs(adev);
1370 sdma_v5_0_set_buffer_funcs(adev);1376 sdma_v5_0_set_buffer_funcs(adev);
1371 sdma_v5_0_set_vm_pte_funcs(adev);1377 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v5_0_vm_pte_funcs);
1372 sdma_v5_0_set_irq_funcs(adev);1378 sdma_v5_0_set_irq_funcs(adev);
1373 sdma_v5_0_set_mqd_funcs(adev);1379 sdma_v5_0_set_mqd_funcs(adev);
1374 1380
@@ -2052,27 +2058,6 @@ static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev) · 677 unmodified lines
2052 }2058 }
2053}2059}
2054 2060
2055static const struct amdgpu_vm_pte_funcs sdma_v5_0_vm_pte_funcs = {
2056 .copy_pte_num_dw = 7,
2057 .copy_pte = sdma_v5_0_vm_copy_pte,
2058 .write_pte = sdma_v5_0_vm_write_pte,
2059 .set_pte_pde = sdma_v5_0_vm_set_pte_pde,
2060};
2061
2062static void sdma_v5_0_set_vm_pte_funcs(struct amdgpu_device *adev)
2063{
2064 unsigned i;
2065
2066 if (adev->vm_manager.vm_pte_funcs == NULL) {
2067 adev->vm_manager.vm_pte_funcs = &sdma_v5_0_vm_pte_funcs;
2068 for (i = 0; i < adev->sdma.num_instances; i++) {
2069 adev->vm_manager.vm_pte_scheds[i] =
2070 &adev->sdma.instance[i].ring.sched;
2071 }
2072 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
2073 }
2074}
2075
2076const struct amdgpu_ip_block_version sdma_v5_0_ip_block = {2061const struct amdgpu_ip_block_version sdma_v5_0_ip_block = {
2077 .type = AMD_IP_BLOCK_TYPE_SDMA,2062 .type = AMD_IP_BLOCK_TYPE_SDMA,
2078 .major = 5,2063 .major = 5,
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c+10−25
@@ -111,7 +111,6 @@ static const struct amdgpu_hwip_reg_entry sdma_reg_list_5_2[] = { · 110 unmodified lines
111 111
112static void sdma_v5_2_set_ring_funcs(struct amdgpu_device *adev);112static void sdma_v5_2_set_ring_funcs(struct amdgpu_device *adev);
113static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev);113static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev);
114static void sdma_v5_2_set_vm_pte_funcs(struct amdgpu_device *adev);
115static void sdma_v5_2_set_irq_funcs(struct amdgpu_device *adev);114static void sdma_v5_2_set_irq_funcs(struct amdgpu_device *adev);
116static int sdma_v5_2_stop_queue(struct amdgpu_ring *ring);115static int sdma_v5_2_stop_queue(struct amdgpu_ring *ring);
117static int sdma_v5_2_restore_queue(struct amdgpu_ring *ring);116static int sdma_v5_2_restore_queue(struct amdgpu_ring *ring);
@@ -1248,6 +1247,13 @@ static void sdma_v5_2_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring, · 1130 unmodified lines
1248 amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);1247 amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);
1249}1248}
1250 1249
1250static const struct amdgpu_vm_pte_funcs sdma_v5_2_vm_pte_funcs = {
1251 .copy_pte_num_dw = 7,
1252 .copy_pte = sdma_v5_2_vm_copy_pte,
1253 .write_pte = sdma_v5_2_vm_write_pte,
1254 .set_pte_pde = sdma_v5_2_vm_set_pte_pde,
1255};
1256
1251static int sdma_v5_2_early_init(struct amdgpu_ip_block *ip_block)1257static int sdma_v5_2_early_init(struct amdgpu_ip_block *ip_block)
1252{1258{
1253 struct amdgpu_device *adev = ip_block->adev;1259 struct amdgpu_device *adev = ip_block->adev;
@@ -1259,7 +1265,7 @@ static int sdma_v5_2_early_init(struct amdgpu_ip_block *ip_block) · 5 unmodified lines
1259 1265
1260 sdma_v5_2_set_ring_funcs(adev);1266 sdma_v5_2_set_ring_funcs(adev);
1261 sdma_v5_2_set_buffer_funcs(adev);1267 sdma_v5_2_set_buffer_funcs(adev);
1262 sdma_v5_2_set_vm_pte_funcs(adev);1268 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v5_2_vm_pte_funcs);
1263 sdma_v5_2_set_irq_funcs(adev);1269 sdma_v5_2_set_irq_funcs(adev);
1264 sdma_v5_2_set_mqd_funcs(adev);1270 sdma_v5_2_set_mqd_funcs(adev);
1265 1271
@@ -2039,11 +2045,11 @@ static void sdma_v5_2_emit_fill_buffer(struct amdgpu_ib *ib, · 773 unmodified lines
2039}2045}
2040 2046
2041static const struct amdgpu_buffer_funcs sdma_v5_2_buffer_funcs = {2047static const struct amdgpu_buffer_funcs sdma_v5_2_buffer_funcs = {
2042 .copy_max_bytes = 0x400000,2048 .copy_max_bytes = 1 << 30,
2043 .copy_num_dw = 7,2049 .copy_num_dw = 7,
2044 .emit_copy_buffer = sdma_v5_2_emit_copy_buffer,2050 .emit_copy_buffer = sdma_v5_2_emit_copy_buffer,
2045 2051
2046 .fill_max_bytes = 0x400000,2052 .fill_max_bytes = 1 << 30, /* HW supports 1 << 30, but PAL uses 1 << 22 */
2047 .fill_num_dw = 5,2053 .fill_num_dw = 5,
2048 .emit_fill_buffer = sdma_v5_2_emit_fill_buffer,2054 .emit_fill_buffer = sdma_v5_2_emit_fill_buffer,
2049};2055};
@@ -2056,27 +2062,6 @@ static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev) · 6 unmodified lines
2056 }2062 }
2057}2063}
2058 2064
2059static const struct amdgpu_vm_pte_funcs sdma_v5_2_vm_pte_funcs = {
2060 .copy_pte_num_dw = 7,
2061 .copy_pte = sdma_v5_2_vm_copy_pte,
2062 .write_pte = sdma_v5_2_vm_write_pte,
2063 .set_pte_pde = sdma_v5_2_vm_set_pte_pde,
2064};
2065
2066static void sdma_v5_2_set_vm_pte_funcs(struct amdgpu_device *adev)
2067{
2068 unsigned i;
2069
2070 if (adev->vm_manager.vm_pte_funcs == NULL) {
2071 adev->vm_manager.vm_pte_funcs = &sdma_v5_2_vm_pte_funcs;
2072 for (i = 0; i < adev->sdma.num_instances; i++) {
2073 adev->vm_manager.vm_pte_scheds[i] =
2074 &adev->sdma.instance[i].ring.sched;
2075 }
2076 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
2077 }
2078}
2079
2080const struct amdgpu_ip_block_version sdma_v5_2_ip_block = {2065const struct amdgpu_ip_block_version sdma_v5_2_ip_block = {
2081 .type = AMD_IP_BLOCK_TYPE_SDMA,2066 .type = AMD_IP_BLOCK_TYPE_SDMA,
2082 .major = 5,2067 .major = 5,
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c+10−23
@@ -120,7 +120,6 @@ static const struct amdgpu_hwip_reg_entry sdma_reg_list_6_0[] = { · 119 unmodified lines
120 120
121static void sdma_v6_0_set_ring_funcs(struct amdgpu_device *adev);121static void sdma_v6_0_set_ring_funcs(struct amdgpu_device *adev);
122static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev);122static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev);
123static void sdma_v6_0_set_vm_pte_funcs(struct amdgpu_device *adev);
124static void sdma_v6_0_set_irq_funcs(struct amdgpu_device *adev);123static void sdma_v6_0_set_irq_funcs(struct amdgpu_device *adev);
125static int sdma_v6_0_start(struct amdgpu_device *adev);124static int sdma_v6_0_start(struct amdgpu_device *adev);
126 125
@@ -1280,6 +1279,13 @@ static void sdma_v6_0_get_csa_info(struct amdgpu_device *adev, · 1153 unmodified lines
1280 csa_info->alignment = SDMA6_CSA_ALIGNMENT;1279 csa_info->alignment = SDMA6_CSA_ALIGNMENT;
1281}1280}
1282 1281
1282static const struct amdgpu_vm_pte_funcs sdma_v6_0_vm_pte_funcs = {
1283 .copy_pte_num_dw = 7,
1284 .copy_pte = sdma_v6_0_vm_copy_pte,
1285 .write_pte = sdma_v6_0_vm_write_pte,
1286 .set_pte_pde = sdma_v6_0_vm_set_pte_pde,
1287};
1288
1283static int sdma_v6_0_early_init(struct amdgpu_ip_block *ip_block)1289static int sdma_v6_0_early_init(struct amdgpu_ip_block *ip_block)
1284{1290{
1285 struct amdgpu_device *adev = ip_block->adev;1291 struct amdgpu_device *adev = ip_block->adev;
@@ -1308,7 +1314,7 @@ static int sdma_v6_0_early_init(struct amdgpu_ip_block *ip_block) · 22 unmodified lines
1308 1314
1309 sdma_v6_0_set_ring_funcs(adev);1315 sdma_v6_0_set_ring_funcs(adev);
1310 sdma_v6_0_set_buffer_funcs(adev);1316 sdma_v6_0_set_buffer_funcs(adev);
1311 sdma_v6_0_set_vm_pte_funcs(adev);1317 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v6_0_vm_pte_funcs);
1312 sdma_v6_0_set_irq_funcs(adev);1318 sdma_v6_0_set_irq_funcs(adev);
1313 sdma_v6_0_set_mqd_funcs(adev);1319 sdma_v6_0_set_mqd_funcs(adev);
1314 sdma_v6_0_set_ras_funcs(adev);1320 sdma_v6_0_set_ras_funcs(adev);
@@ -1878,11 +1884,11 @@ static void sdma_v6_0_emit_fill_buffer(struct amdgpu_ib *ib, · 563 unmodified lines
1878}1884}
1879 1885
1880static const struct amdgpu_buffer_funcs sdma_v6_0_buffer_funcs = {1886static const struct amdgpu_buffer_funcs sdma_v6_0_buffer_funcs = {
1881 .copy_max_bytes = 0x400000,1887 .copy_max_bytes = 1 << 30,
1882 .copy_num_dw = 7,1888 .copy_num_dw = 7,
1883 .emit_copy_buffer = sdma_v6_0_emit_copy_buffer,1889 .emit_copy_buffer = sdma_v6_0_emit_copy_buffer,
1884 1890
1885 .fill_max_bytes = 0x400000,1891 .fill_max_bytes = 1 << 30,
1886 .fill_num_dw = 5,1892 .fill_num_dw = 5,
1887 .emit_fill_buffer = sdma_v6_0_emit_fill_buffer,1893 .emit_fill_buffer = sdma_v6_0_emit_fill_buffer,
1888};1894};
@@ -1893,25 +1899,6 @@ static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev) · 4 unmodified lines
1893 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;1899 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
1894}1900}
1895 1901
1896static const struct amdgpu_vm_pte_funcs sdma_v6_0_vm_pte_funcs = {
1897 .copy_pte_num_dw = 7,
1898 .copy_pte = sdma_v6_0_vm_copy_pte,
1899 .write_pte = sdma_v6_0_vm_write_pte,
1900 .set_pte_pde = sdma_v6_0_vm_set_pte_pde,
1901};
1902
1903static void sdma_v6_0_set_vm_pte_funcs(struct amdgpu_device *adev)
1904{
1905 unsigned i;
1906
1907 adev->vm_manager.vm_pte_funcs = &sdma_v6_0_vm_pte_funcs;
1908 for (i = 0; i < adev->sdma.num_instances; i++) {
1909 adev->vm_manager.vm_pte_scheds[i] =
1910 &adev->sdma.instance[i].ring.sched;
1911 }
1912 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
1913}
1914
1915const struct amdgpu_ip_block_version sdma_v6_0_ip_block = {1902const struct amdgpu_ip_block_version sdma_v6_0_ip_block = {
1916 .type = AMD_IP_BLOCK_TYPE_SDMA,1903 .type = AMD_IP_BLOCK_TYPE_SDMA,
1917 .major = 6,1904 .major = 6,
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c+10−23
@@ -119,7 +119,6 @@ static const struct amdgpu_hwip_reg_entry sdma_reg_list_7_0[] = { · 118 unmodified lines
119 119
120static void sdma_v7_0_set_ring_funcs(struct amdgpu_device *adev);120static void sdma_v7_0_set_ring_funcs(struct amdgpu_device *adev);
121static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev);121static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev);
122static void sdma_v7_0_set_vm_pte_funcs(struct amdgpu_device *adev);
123static void sdma_v7_0_set_irq_funcs(struct amdgpu_device *adev);122static void sdma_v7_0_set_irq_funcs(struct amdgpu_device *adev);
124static int sdma_v7_0_start(struct amdgpu_device *adev);123static int sdma_v7_0_start(struct amdgpu_device *adev);
125 124
@@ -1264,6 +1263,13 @@ static void sdma_v7_0_get_csa_info(struct amdgpu_device *adev, · 1138 unmodified lines
1264 csa_info->alignment = SDMA7_CSA_ALIGNMENT;1263 csa_info->alignment = SDMA7_CSA_ALIGNMENT;
1265}1264}
1266 1265
1266static const struct amdgpu_vm_pte_funcs sdma_v7_0_vm_pte_funcs = {
1267 .copy_pte_num_dw = 8,
1268 .copy_pte = sdma_v7_0_vm_copy_pte,
1269 .write_pte = sdma_v7_0_vm_write_pte,
1270 .set_pte_pde = sdma_v7_0_vm_set_pte_pde,
1271};
1272
1267static int sdma_v7_0_early_init(struct amdgpu_ip_block *ip_block)1273static int sdma_v7_0_early_init(struct amdgpu_ip_block *ip_block)
1268{1274{
1269 struct amdgpu_device *adev = ip_block->adev;1275 struct amdgpu_device *adev = ip_block->adev;
@@ -1294,7 +1300,7 @@ static int sdma_v7_0_early_init(struct amdgpu_ip_block *ip_block) · 24 unmodified lines
1294 1300
1295 sdma_v7_0_set_ring_funcs(adev);1301 sdma_v7_0_set_ring_funcs(adev);
1296 sdma_v7_0_set_buffer_funcs(adev);1302 sdma_v7_0_set_buffer_funcs(adev);
1297 sdma_v7_0_set_vm_pte_funcs(adev);1303 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v7_0_vm_pte_funcs);
1298 sdma_v7_0_set_irq_funcs(adev);1304 sdma_v7_0_set_irq_funcs(adev);
1299 sdma_v7_0_set_mqd_funcs(adev);1305 sdma_v7_0_set_mqd_funcs(adev);
1300 adev->sdma.get_csa_info = &sdma_v7_0_get_csa_info;1306 adev->sdma.get_csa_info = &sdma_v7_0_get_csa_info;
@@ -1829,10 +1835,10 @@ static void sdma_v7_0_emit_fill_buffer(struct amdgpu_ib *ib, · 528 unmodified lines
1829}1835}
1830 1836
1831static const struct amdgpu_buffer_funcs sdma_v7_0_buffer_funcs = {1837static const struct amdgpu_buffer_funcs sdma_v7_0_buffer_funcs = {
1832 .copy_max_bytes = 0x400000,1838 .copy_max_bytes = 1 << 30,
1833 .copy_num_dw = 8,1839 .copy_num_dw = 8,
1834 .emit_copy_buffer = sdma_v7_0_emit_copy_buffer,1840 .emit_copy_buffer = sdma_v7_0_emit_copy_buffer,
1835 .fill_max_bytes = 0x400000,1841 .fill_max_bytes = 1 << 30,
1836 .fill_num_dw = 5,1842 .fill_num_dw = 5,
1837 .emit_fill_buffer = sdma_v7_0_emit_fill_buffer,1843 .emit_fill_buffer = sdma_v7_0_emit_fill_buffer,
1838};1844};
@@ -1843,25 +1849,6 @@ static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev) · 4 unmodified lines
1843 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;1849 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
1844}1850}
1845 1851
1846static const struct amdgpu_vm_pte_funcs sdma_v7_0_vm_pte_funcs = {
1847 .copy_pte_num_dw = 8,
1848 .copy_pte = sdma_v7_0_vm_copy_pte,
1849 .write_pte = sdma_v7_0_vm_write_pte,
1850 .set_pte_pde = sdma_v7_0_vm_set_pte_pde,
1851};
1852
1853static void sdma_v7_0_set_vm_pte_funcs(struct amdgpu_device *adev)
1854{
1855 unsigned i;
1856
1857 adev->vm_manager.vm_pte_funcs = &sdma_v7_0_vm_pte_funcs;
1858 for (i = 0; i < adev->sdma.num_instances; i++) {
1859 adev->vm_manager.vm_pte_scheds[i] =
1860 &adev->sdma.instance[i].ring.sched;
1861 }
1862 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
1863}
1864
1865const struct amdgpu_ip_block_version sdma_v7_0_ip_block = {1852const struct amdgpu_ip_block_version sdma_v7_0_ip_block = {
1866 .type = AMD_IP_BLOCK_TYPE_SDMA,1853 .type = AMD_IP_BLOCK_TYPE_SDMA,
1867 .major = 7,1854 .major = 7,
drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c+10−23
@@ -110,7 +110,6 @@ static const struct amdgpu_hwip_reg_entry sdma_reg_list_7_1[] = { · 109 unmodified lines
110 110
111static void sdma_v7_1_set_ring_funcs(struct amdgpu_device *adev);111static void sdma_v7_1_set_ring_funcs(struct amdgpu_device *adev);
112static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev);112static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev);
113static void sdma_v7_1_set_vm_pte_funcs(struct amdgpu_device *adev);
114static void sdma_v7_1_set_irq_funcs(struct amdgpu_device *adev);113static void sdma_v7_1_set_irq_funcs(struct amdgpu_device *adev);
115static int sdma_v7_1_inst_start(struct amdgpu_device *adev,114static int sdma_v7_1_inst_start(struct amdgpu_device *adev,
116 uint32_t inst_mask);115 uint32_t inst_mask);
@@ -1248,6 +1247,13 @@ static void sdma_v7_1_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring, · 1131 unmodified lines
1248 amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);1247 amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);
1249}1248}
1250 1249
1250static const struct amdgpu_vm_pte_funcs sdma_v7_1_vm_pte_funcs = {
1251 .copy_pte_num_dw = 8,
1252 .copy_pte = sdma_v7_1_vm_copy_pte,
1253 .write_pte = sdma_v7_1_vm_write_pte,
1254 .set_pte_pde = sdma_v7_1_vm_set_pte_pde,
1255};
1256
1251static int sdma_v7_1_early_init(struct amdgpu_ip_block *ip_block)1257static int sdma_v7_1_early_init(struct amdgpu_ip_block *ip_block)
1252{1258{
1253 struct amdgpu_device *adev = ip_block->adev;1259 struct amdgpu_device *adev = ip_block->adev;
@@ -1261,7 +1267,7 @@ static int sdma_v7_1_early_init(struct amdgpu_ip_block *ip_block) · 7 unmodified lines
1261 1267
1262 sdma_v7_1_set_ring_funcs(adev);1268 sdma_v7_1_set_ring_funcs(adev);
1263 sdma_v7_1_set_buffer_funcs(adev);1269 sdma_v7_1_set_buffer_funcs(adev);
1264 sdma_v7_1_set_vm_pte_funcs(adev);1270 amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v7_1_vm_pte_funcs);
1265 sdma_v7_1_set_irq_funcs(adev);1271 sdma_v7_1_set_irq_funcs(adev);
1266 sdma_v7_1_set_mqd_funcs(adev);1272 sdma_v7_1_set_mqd_funcs(adev);
1267 1273
@@ -1739,10 +1745,10 @@ static void sdma_v7_1_emit_fill_buffer(struct amdgpu_ib *ib, · 471 unmodified lines
1739}1745}
1740 1746
1741static const struct amdgpu_buffer_funcs sdma_v7_1_buffer_funcs = {1747static const struct amdgpu_buffer_funcs sdma_v7_1_buffer_funcs = {
1742 .copy_max_bytes = 0x400000,1748 .copy_max_bytes = 1 << 30,
1743 .copy_num_dw = 8,1749 .copy_num_dw = 8,
1744 .emit_copy_buffer = sdma_v7_1_emit_copy_buffer,1750 .emit_copy_buffer = sdma_v7_1_emit_copy_buffer,
1745 .fill_max_bytes = 0x400000,1751 .fill_max_bytes = 1 << 30,
1746 .fill_num_dw = 5,1752 .fill_num_dw = 5,
1747 .emit_fill_buffer = sdma_v7_1_emit_fill_buffer,1753 .emit_fill_buffer = sdma_v7_1_emit_fill_buffer,
1748};1754};
@@ -1753,25 +1759,6 @@ static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev) · 4 unmodified lines
1753 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;1759 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
1754}1760}
1755 1761
1756static const struct amdgpu_vm_pte_funcs sdma_v7_1_vm_pte_funcs = {
1757 .copy_pte_num_dw = 8,
1758 .copy_pte = sdma_v7_1_vm_copy_pte,
1759 .write_pte = sdma_v7_1_vm_write_pte,
1760 .set_pte_pde = sdma_v7_1_vm_set_pte_pde,
1761};
1762
1763static void sdma_v7_1_set_vm_pte_funcs(struct amdgpu_device *adev)
1764{
1765 unsigned i;
1766
1767 adev->vm_manager.vm_pte_funcs = &sdma_v7_1_vm_pte_funcs;
1768 for (i = 0; i < adev->sdma.num_instances; i++) {
1769 adev->vm_manager.vm_pte_scheds[i] =
1770 &adev->sdma.instance[i].ring.sched;
1771 }
1772 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
1773}
1774
1775const struct amdgpu_ip_block_version sdma_v7_1_ip_block = {1762const struct amdgpu_ip_block_version sdma_v7_1_ip_block = {
1776 .type = AMD_IP_BLOCK_TYPE_SDMA,1763 .type = AMD_IP_BLOCK_TYPE_SDMA,
1777 .major = 7,1764 .major = 7,
drivers/gpu/drm/amd/amdgpu/si.c+32−34
@@ -1027,11 +1027,11 @@ static u32 si_pcie_rreg(struct amdgpu_device *adev, u32 reg) · 1026 unmodified lines
1027 unsigned long flags;1027 unsigned long flags;
1028 u32 r;1028 u32 r;
1029 1029
1030 spin_lock_irqsave(&adev->pcie_idx_lock, flags);1030 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
1031 WREG32(AMDGPU_PCIE_INDEX, reg);1031 WREG32(AMDGPU_PCIE_INDEX, reg);
1032 (void)RREG32(AMDGPU_PCIE_INDEX);1032 (void)RREG32(AMDGPU_PCIE_INDEX);
1033 r = RREG32(AMDGPU_PCIE_DATA);1033 r = RREG32(AMDGPU_PCIE_DATA);
1034 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);1034 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
1035 return r;1035 return r;
1036}1036}
1037 1037
@@ -1039,12 +1039,12 @@ static void si_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
1039{1039{
1040 unsigned long flags;1040 unsigned long flags;
1041 1041
1042 spin_lock_irqsave(&adev->pcie_idx_lock, flags);1042 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
1043 WREG32(AMDGPU_PCIE_INDEX, reg);1043 WREG32(AMDGPU_PCIE_INDEX, reg);
1044 (void)RREG32(AMDGPU_PCIE_INDEX);1044 (void)RREG32(AMDGPU_PCIE_INDEX);
1045 WREG32(AMDGPU_PCIE_DATA, v);1045 WREG32(AMDGPU_PCIE_DATA, v);
1046 (void)RREG32(AMDGPU_PCIE_DATA);1046 (void)RREG32(AMDGPU_PCIE_DATA);
1047 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);1047 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
1048}1048}
1049 1049
1050static u32 si_pciep_rreg(struct amdgpu_device *adev, u32 reg)1050static u32 si_pciep_rreg(struct amdgpu_device *adev, u32 reg)
@@ -1052,11 +1052,11 @@ static u32 si_pciep_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
1052 unsigned long flags;1052 unsigned long flags;
1053 u32 r;1053 u32 r;
1054 1054
1055 spin_lock_irqsave(&adev->pcie_idx_lock, flags);1055 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
1056 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));1056 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
1057 (void)RREG32(PCIE_PORT_INDEX);1057 (void)RREG32(PCIE_PORT_INDEX);
1058 r = RREG32(PCIE_PORT_DATA);1058 r = RREG32(PCIE_PORT_DATA);
1059 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);1059 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
1060 return r;1060 return r;
1061}1061}
1062 1062
@@ -1064,12 +1064,12 @@ static void si_pciep_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
1064{1064{
1065 unsigned long flags;1065 unsigned long flags;
1066 1066
1067 spin_lock_irqsave(&adev->pcie_idx_lock, flags);1067 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
1068 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));1068 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
1069 (void)RREG32(PCIE_PORT_INDEX);1069 (void)RREG32(PCIE_PORT_INDEX);
1070 WREG32(PCIE_PORT_DATA, (v));1070 WREG32(PCIE_PORT_DATA, (v));
1071 (void)RREG32(PCIE_PORT_DATA);1071 (void)RREG32(PCIE_PORT_DATA);
1072 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);1072 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
1073}1073}
1074 1074
1075static u32 si_smc_rreg(struct amdgpu_device *adev, u32 reg)1075static u32 si_smc_rreg(struct amdgpu_device *adev, u32 reg)
@@ -1077,10 +1077,10 @@ static u32 si_smc_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
1077 unsigned long flags;1077 unsigned long flags;
1078 u32 r;1078 u32 r;
1079 1079
1080 spin_lock_irqsave(&adev->smc_idx_lock, flags);1080 spin_lock_irqsave(&adev->reg.smc.lock, flags);
1081 WREG32(mmSMC_IND_INDEX_0, (reg));1081 WREG32(mmSMC_IND_INDEX_0, (reg));
1082 r = RREG32(mmSMC_IND_DATA_0);1082 r = RREG32(mmSMC_IND_DATA_0);
1083 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);1083 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
1084 return r;1084 return r;
1085}1085}
1086 1086
@@ -1088,10 +1088,10 @@ static void si_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
1088{1088{
1089 unsigned long flags;1089 unsigned long flags;
1090 1090
1091 spin_lock_irqsave(&adev->smc_idx_lock, flags);1091 spin_lock_irqsave(&adev->reg.smc.lock, flags);
1092 WREG32(mmSMC_IND_INDEX_0, (reg));1092 WREG32(mmSMC_IND_INDEX_0, (reg));
1093 WREG32(mmSMC_IND_DATA_0, (v));1093 WREG32(mmSMC_IND_DATA_0, (v));
1094 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);1094 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
1095}1095}
1096 1096
1097static u32 si_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg)1097static u32 si_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg)
@@ -1099,10 +1099,10 @@ static u32 si_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
1099 unsigned long flags;1099 unsigned long flags;
1100 u32 r;1100 u32 r;
1101 1101
1102 spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);1102 spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
1103 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));1103 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
1104 r = RREG32(mmUVD_CTX_DATA);1104 r = RREG32(mmUVD_CTX_DATA);
1105 spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);1105 spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
1106 return r;1106 return r;
1107}1107}
1108 1108
@@ -1110,10 +1110,10 @@ static void si_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
1110{1110{
1111 unsigned long flags;1111 unsigned long flags;
1112 1112
1113 spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);1113 spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
1114 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));1114 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
1115 WREG32(mmUVD_CTX_DATA, (v));1115 WREG32(mmUVD_CTX_DATA, (v));
1116 spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);1116 spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
1117}1117}
1118 1118
1119static struct amdgpu_allowed_register_entry si_allowed_read_registers[] = {1119static struct amdgpu_allowed_register_entry si_allowed_read_registers[] = {
@@ -2037,16 +2037,14 @@ static int si_common_early_init(struct amdgpu_ip_block *ip_block) · 917 unmodified lines
2037{2037{
2038 struct amdgpu_device *adev = ip_block->adev;2038 struct amdgpu_device *adev = ip_block->adev;
2039 2039
2040 adev->smc_rreg = &si_smc_rreg;2040 adev->reg.smc.rreg = si_smc_rreg;
2041 adev->smc_wreg = &si_smc_wreg;2041 adev->reg.smc.wreg = si_smc_wreg;
2042 adev->pcie_rreg = &si_pcie_rreg;2042 adev->reg.pcie.rreg = &si_pcie_rreg;
2043 adev->pcie_wreg = &si_pcie_wreg;2043 adev->reg.pcie.wreg = &si_pcie_wreg;
2044 adev->pciep_rreg = &si_pciep_rreg;2044 adev->reg.pcie.port_rreg = &si_pciep_rreg;
2045 adev->pciep_wreg = &si_pciep_wreg;2045 adev->reg.pcie.port_wreg = &si_pciep_wreg;
2046 adev->uvd_ctx_rreg = si_uvd_ctx_rreg;2046 adev->reg.uvd_ctx.rreg = &si_uvd_ctx_rreg;
2047 adev->uvd_ctx_wreg = si_uvd_ctx_wreg;2047 adev->reg.uvd_ctx.wreg = &si_uvd_ctx_wreg;
2048 adev->didt_rreg = NULL;
2049 adev->didt_wreg = NULL;
2050 2048
2051 adev->asic_funcs = &si_asic_funcs;2049 adev->asic_funcs = &si_asic_funcs;
2052 2050
@@ -2382,10 +2380,10 @@ static inline u32 si_pif_phy0_rreg(struct amdgpu_device *adev, u32 reg) · 329 unmodified lines
2382 unsigned long flags;2380 unsigned long flags;
2383 u32 r;2381 u32 r;
2384 2382
2385 spin_lock_irqsave(&adev->pcie_idx_lock, flags);2383 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
2386 WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));2384 WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
2387 r = RREG32(EVERGREEN_PIF_PHY0_DATA);2385 r = RREG32(EVERGREEN_PIF_PHY0_DATA);
2388 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);2386 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
2389 return r;2387 return r;
2390}2388}
2391 2389
@@ -2393,10 +2391,10 @@ static inline void si_pif_phy0_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
2393{2391{
2394 unsigned long flags;2392 unsigned long flags;
2395 2393
2396 spin_lock_irqsave(&adev->pcie_idx_lock, flags);2394 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
2397 WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));2395 WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
2398 WREG32(EVERGREEN_PIF_PHY0_DATA, (v));2396 WREG32(EVERGREEN_PIF_PHY0_DATA, (v));
2399 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);2397 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
2400}2398}
2401 2399
2402static inline u32 si_pif_phy1_rreg(struct amdgpu_device *adev, u32 reg)2400static inline u32 si_pif_phy1_rreg(struct amdgpu_device *adev, u32 reg)
@@ -2404,10 +2402,10 @@ static inline u32 si_pif_phy1_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
2404 unsigned long flags;2402 unsigned long flags;
2405 u32 r;2403 u32 r;
2406 2404
2407 spin_lock_irqsave(&adev->pcie_idx_lock, flags);2405 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
2408 WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));2406 WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
2409 r = RREG32(EVERGREEN_PIF_PHY1_DATA);2407 r = RREG32(EVERGREEN_PIF_PHY1_DATA);
2410 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);2408 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
2411 return r;2409 return r;
2412}2410}
2413 2411
@@ -2415,10 +2413,10 @@ static inline void si_pif_phy1_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
2415{2413{
2416 unsigned long flags;2414 unsigned long flags;
2417 2415
2418 spin_lock_irqsave(&adev->pcie_idx_lock, flags);2416 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
2419 WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));2417 WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
2420 WREG32(EVERGREEN_PIF_PHY1_DATA, (v));2418 WREG32(EVERGREEN_PIF_PHY1_DATA, (v));
2421 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);2419 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
2422}2420}
2423static void si_program_aspm(struct amdgpu_device *adev)2421static void si_program_aspm(struct amdgpu_device *adev)
2424{2422{
drivers/gpu/drm/amd/amdgpu/si_dma.c+9−22
@@ -37,7 +37,6 @@ const u32 sdma_offsets[SDMA_MAX_INSTANCE] = · 36 unmodified lines
37 37
38static void si_dma_set_ring_funcs(struct amdgpu_device *adev);38static void si_dma_set_ring_funcs(struct amdgpu_device *adev);
39static void si_dma_set_buffer_funcs(struct amdgpu_device *adev);39static void si_dma_set_buffer_funcs(struct amdgpu_device *adev);
40static void si_dma_set_vm_pte_funcs(struct amdgpu_device *adev);
41static void si_dma_set_irq_funcs(struct amdgpu_device *adev);40static void si_dma_set_irq_funcs(struct amdgpu_device *adev);
42 41
43/**42/**
@@ -473,6 +472,14 @@ static void si_dma_ring_emit_wreg(struct amdgpu_ring *ring, · 429 unmodified lines
473 amdgpu_ring_write(ring, val);472 amdgpu_ring_write(ring, val);
474}473}
475 474
475static const struct amdgpu_vm_pte_funcs si_dma_vm_pte_funcs = {
476 .copy_pte_num_dw = 5,
477 .copy_pte = si_dma_vm_copy_pte,
478
479 .write_pte = si_dma_vm_write_pte,
480 .set_pte_pde = si_dma_vm_set_pte_pde,
481};
482
476static int si_dma_early_init(struct amdgpu_ip_block *ip_block)483static int si_dma_early_init(struct amdgpu_ip_block *ip_block)
477{484{
478 struct amdgpu_device *adev = ip_block->adev;485 struct amdgpu_device *adev = ip_block->adev;
@@ -481,7 +488,7 @@ static int si_dma_early_init(struct amdgpu_ip_block *ip_block) · 2 unmodified lines
481 488
482 si_dma_set_ring_funcs(adev);489 si_dma_set_ring_funcs(adev);
483 si_dma_set_buffer_funcs(adev);490 si_dma_set_buffer_funcs(adev);
484 si_dma_set_vm_pte_funcs(adev);491 amdgpu_sdma_set_vm_pte_scheds(adev, &si_dma_vm_pte_funcs);
485 si_dma_set_irq_funcs(adev);492 si_dma_set_irq_funcs(adev);
486 493
487 return 0;494 return 0;
@@ -830,26 +837,6 @@ static void si_dma_set_buffer_funcs(struct amdgpu_device *adev) · 342 unmodified lines
830 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;837 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
831}838}
832 839
833static const struct amdgpu_vm_pte_funcs si_dma_vm_pte_funcs = {
834 .copy_pte_num_dw = 5,
835 .copy_pte = si_dma_vm_copy_pte,
836
837 .write_pte = si_dma_vm_write_pte,
838 .set_pte_pde = si_dma_vm_set_pte_pde,
839};
840
841static void si_dma_set_vm_pte_funcs(struct amdgpu_device *adev)
842{
843 unsigned i;
844
845 adev->vm_manager.vm_pte_funcs = &si_dma_vm_pte_funcs;
846 for (i = 0; i < adev->sdma.num_instances; i++) {
847 adev->vm_manager.vm_pte_scheds[i] =
848 &adev->sdma.instance[i].ring.sched;
849 }
850 adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
851}
852
853const struct amdgpu_ip_block_version si_dma_ip_block =840const struct amdgpu_ip_block_version si_dma_ip_block =
854{841{
855 .type = AMD_IP_BLOCK_TYPE_SDMA,842 .type = AMD_IP_BLOCK_TYPE_SDMA,
drivers/gpu/drm/amd/amdgpu/soc15.c+33−35
@@ -245,10 +245,10 @@ static u32 soc15_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) · 244 unmodified lines
245 address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX);245 address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX);
246 data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA);246 data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA);
247 247
248 spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);248 spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
249 WREG32(address, ((reg) & 0x1ff));249 WREG32(address, ((reg) & 0x1ff));
250 r = RREG32(data);250 r = RREG32(data);
251 spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);251 spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
252 return r;252 return r;
253}253}
254 254
@@ -259,10 +259,10 @@ static void soc15_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 4 unmodified lines
259 address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX);259 address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX);
260 data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA);260 data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA);
261 261
262 spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);262 spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
263 WREG32(address, ((reg) & 0x1ff));263 WREG32(address, ((reg) & 0x1ff));
264 WREG32(data, (v));264 WREG32(data, (v));
265 spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);265 spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
266}266}
267 267
268static u32 soc15_didt_rreg(struct amdgpu_device *adev, u32 reg)268static u32 soc15_didt_rreg(struct amdgpu_device *adev, u32 reg)
@@ -273,10 +273,10 @@ static u32 soc15_didt_rreg(struct amdgpu_device *adev, u32 reg) · 4 unmodified lines
273 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);273 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
274 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);274 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
275 275
276 spin_lock_irqsave(&adev->didt_idx_lock, flags);276 spin_lock_irqsave(&adev->reg.didt.lock, flags);
277 WREG32(address, (reg));277 WREG32(address, (reg));
278 r = RREG32(data);278 r = RREG32(data);
279 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);279 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
280 return r;280 return r;
281}281}
282 282
@@ -287,10 +287,10 @@ static void soc15_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 4 unmodified lines
287 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);287 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
288 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);288 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
289 289
290 spin_lock_irqsave(&adev->didt_idx_lock, flags);290 spin_lock_irqsave(&adev->reg.didt.lock, flags);
291 WREG32(address, (reg));291 WREG32(address, (reg));
292 WREG32(data, (v));292 WREG32(data, (v));
293 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);293 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
294}294}
295 295
296static u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg)296static u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg)
@@ -298,10 +298,10 @@ static u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
298 unsigned long flags;298 unsigned long flags;
299 u32 r;299 u32 r;
300 300
301 spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);301 spin_lock_irqsave(&adev->reg.gc_cac.lock, flags);
302 WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));302 WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
303 r = RREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA);303 r = RREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA);
304 spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);304 spin_unlock_irqrestore(&adev->reg.gc_cac.lock, flags);
305 return r;305 return r;
306}306}
307 307
@@ -309,10 +309,10 @@ static void soc15_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
309{309{
310 unsigned long flags;310 unsigned long flags;
311 311
312 spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);312 spin_lock_irqsave(&adev->reg.gc_cac.lock, flags);
313 WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));313 WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
314 WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, (v));314 WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, (v));
315 spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);315 spin_unlock_irqrestore(&adev->reg.gc_cac.lock, flags);
316}316}
317 317
318static u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg)318static u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg)
@@ -320,10 +320,10 @@ static u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
320 unsigned long flags;320 unsigned long flags;
321 u32 r;321 u32 r;
322 322
323 spin_lock_irqsave(&adev->se_cac_idx_lock, flags);323 spin_lock_irqsave(&adev->reg.se_cac.lock, flags);
324 WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));324 WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
325 r = RREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA);325 r = RREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA);
326 spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags);326 spin_unlock_irqrestore(&adev->reg.se_cac.lock, flags);
327 return r;327 return r;
328}328}
329 329
@@ -331,10 +331,10 @@ static void soc15_se_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
331{331{
332 unsigned long flags;332 unsigned long flags;
333 333
334 spin_lock_irqsave(&adev->se_cac_idx_lock, flags);334 spin_lock_irqsave(&adev->reg.se_cac.lock, flags);
335 WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));335 WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
336 WREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA, (v));336 WREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA, (v));
337 spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags);337 spin_unlock_irqrestore(&adev->reg.se_cac.lock, flags);
338}338}
339 339
340static u32 soc15_get_config_memsize(struct amdgpu_device *adev)340static u32 soc15_get_config_memsize(struct amdgpu_device *adev)
@@ -952,7 +952,6 @@ static const struct amdgpu_asic_funcs aqua_vanjaram_asic_funcs = · 611 unmodified lines
952 .get_pcie_replay_count = &amdgpu_nbio_get_pcie_replay_count,952 .get_pcie_replay_count = &amdgpu_nbio_get_pcie_replay_count,
953 .supports_baco = &soc15_supports_baco,953 .supports_baco = &soc15_supports_baco,
954 .query_video_codecs = &soc15_query_video_codecs,954 .query_video_codecs = &soc15_query_video_codecs,
955 .encode_ext_smn_addressing = &aqua_vanjaram_encode_ext_smn_addressing,
956 .get_reg_state = &aqua_vanjaram_get_reg_state,955 .get_reg_state = &aqua_vanjaram_get_reg_state,
957};956};
958 957
@@ -961,24 +960,22 @@ static int soc15_common_early_init(struct amdgpu_ip_block *ip_block) · 2 unmodified lines
961 struct amdgpu_device *adev = ip_block->adev;960 struct amdgpu_device *adev = ip_block->adev;
962 961
963 adev->nbio.funcs->set_reg_remap(adev);962 adev->nbio.funcs->set_reg_remap(adev);
964 adev->smc_rreg = NULL;963 adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
965 adev->smc_wreg = NULL;964 adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
966 adev->pcie_rreg = &amdgpu_device_indirect_rreg;965 adev->reg.pcie.rreg_ext = &amdgpu_device_indirect_rreg_ext;
967 adev->pcie_wreg = &amdgpu_device_indirect_wreg;966 adev->reg.pcie.wreg_ext = &amdgpu_device_indirect_wreg_ext;
968 adev->pcie_rreg_ext = &amdgpu_device_indirect_rreg_ext;967 adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
969 adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext;968 adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
970 adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;969 adev->reg.pcie.rreg64_ext = &amdgpu_device_indirect_rreg64_ext;
971 adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;970 adev->reg.pcie.wreg64_ext = &amdgpu_device_indirect_wreg64_ext;
972 adev->pcie_rreg64_ext = &amdgpu_device_indirect_rreg64_ext;971 adev->reg.uvd_ctx.rreg = &soc15_uvd_ctx_rreg;
973 adev->pcie_wreg64_ext = &amdgpu_device_indirect_wreg64_ext;972 adev->reg.uvd_ctx.wreg = &soc15_uvd_ctx_wreg;
974 adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg;973 adev->reg.didt.rreg = &soc15_didt_rreg;
975 adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg;974 adev->reg.didt.wreg = &soc15_didt_wreg;
976 adev->didt_rreg = &soc15_didt_rreg;975 adev->reg.gc_cac.rreg = &soc15_gc_cac_rreg;
977 adev->didt_wreg = &soc15_didt_wreg;976 adev->reg.gc_cac.wreg = &soc15_gc_cac_wreg;
978 adev->gc_cac_rreg = &soc15_gc_cac_rreg;977 adev->reg.se_cac.rreg = &soc15_se_cac_rreg;
979 adev->gc_cac_wreg = &soc15_gc_cac_wreg;978 adev->reg.se_cac.wreg = &soc15_se_cac_wreg;
980 adev->se_cac_rreg = &soc15_se_cac_rreg;
981 adev->se_cac_wreg = &soc15_se_cac_wreg;
982 979
983 adev->rev_id = amdgpu_device_get_rev_id(adev);980 adev->rev_id = amdgpu_device_get_rev_id(adev);
984 adev->external_rev_id = 0xFF;981 adev->external_rev_id = 0xFF;
@@ -1200,6 +1197,7 @@ static int soc15_common_early_init(struct amdgpu_ip_block *ip_block) · 215 unmodified lines
1200 case IP_VERSION(9, 4, 4):1197 case IP_VERSION(9, 4, 4):
1201 case IP_VERSION(9, 5, 0):1198 case IP_VERSION(9, 5, 0):
1202 adev->asic_funcs = &aqua_vanjaram_asic_funcs;1199 adev->asic_funcs = &aqua_vanjaram_asic_funcs;
1200 adev->reg.smn.get_smn_base = &amdgpu_reg_smn_v1_0_get_base;
1203 adev->cg_flags =1201 adev->cg_flags =
1204 AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG |1202 AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG |
1205 AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_SDMA_MGCG |1203 AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_SDMA_MGCG |
drivers/gpu/drm/amd/amdgpu/soc15.h+0−1
@@ -118,7 +118,6 @@ int vega10_reg_base_init(struct amdgpu_device *adev); · 117 unmodified lines
118int vega20_reg_base_init(struct amdgpu_device *adev);118int vega20_reg_base_init(struct amdgpu_device *adev);
119int arct_reg_base_init(struct amdgpu_device *adev);119int arct_reg_base_init(struct amdgpu_device *adev);
120int aldebaran_reg_base_init(struct amdgpu_device *adev);120int aldebaran_reg_base_init(struct amdgpu_device *adev);
121u64 aqua_vanjaram_encode_ext_smn_addressing(int ext_id);
122int aqua_vanjaram_init_soc_config(struct amdgpu_device *adev);121int aqua_vanjaram_init_soc_config(struct amdgpu_device *adev);
123ssize_t aqua_vanjaram_get_reg_state(struct amdgpu_device *adev,122ssize_t aqua_vanjaram_get_reg_state(struct amdgpu_device *adev,
124 enum amdgpu_reg_state reg_state, void *buf,123 enum amdgpu_reg_state reg_state, void *buf,
drivers/gpu/drm/amd/amdgpu/soc15_common.h+17−14
@@ -195,19 +195,22 @@ · 194 unmodified lines
195 __RREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, AMDGPU_REGS_RLC, ip##_HWIP, inst)195 __RREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, AMDGPU_REGS_RLC, ip##_HWIP, inst)
196 196
197/* inst equals to ext for some IPs */197/* inst equals to ext for some IPs */
198#define RREG32_SOC15_EXT(ip, inst, reg, ext) \198#define RREG32_SOC15_EXT(ip, inst, reg, ext) \
199 RREG32_PCIE_EXT((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) * 4 \199 RREG32_PCIE_EXT((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + \
200 + adev->asic_funcs->encode_ext_smn_addressing(ext)) \200 reg) * 4 + \
201 201 amdgpu_reg_get_smn_base64(adev, ip##_HWIP, inst))
202#define WREG32_SOC15_EXT(ip, inst, reg, ext, value) \202
203 WREG32_PCIE_EXT((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) * 4 \203#define WREG32_SOC15_EXT(ip, inst, reg, ext, value) \
204 + adev->asic_funcs->encode_ext_smn_addressing(ext), \204 WREG32_PCIE_EXT( \
205 value) \205 (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) * \
206 206 4 + \
207#define RREG64_MCA(ext, mca_base, idx) \207 amdgpu_reg_get_smn_base64(adev, ip##_HWIP, inst), \
208 RREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8))208 value)
209 209
210#define WREG64_MCA(ext, mca_base, idx, val) \210#define RREG64_MCA(smn_base, mca_base, idx) \
211 WREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8), val)211 RREG64_PCIE_EXT(smn_base + mca_base + (idx * 8))
212
213#define WREG64_MCA(smn_base, mca_base, idx, val) \
214 WREG64_PCIE_EXT(smn_base + mca_base + (idx * 8), val)
212 215
213#endif216#endif
drivers/gpu/drm/amd/amdgpu/soc21.c+16−20
@@ -229,10 +229,10 @@ static u32 soc21_didt_rreg(struct amdgpu_device *adev, u32 reg) · 228 unmodified lines
229 address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);229 address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
230 data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);230 data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
231 231
232 spin_lock_irqsave(&adev->didt_idx_lock, flags);232 spin_lock_irqsave(&adev->reg.didt.lock, flags);
233 WREG32(address, (reg));233 WREG32(address, (reg));
234 r = RREG32(data);234 r = RREG32(data);
235 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);235 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
236 return r;236 return r;
237}237}
238 238
@@ -243,10 +243,10 @@ static void soc21_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 4 unmodified lines
243 address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);243 address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
244 data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);244 data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
245 245
246 spin_lock_irqsave(&adev->didt_idx_lock, flags);246 spin_lock_irqsave(&adev->reg.didt.lock, flags);
247 WREG32(address, (reg));247 WREG32(address, (reg));
248 WREG32(data, (v));248 WREG32(data, (v));
249 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);249 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
250}250}
251 251
252static u32 soc21_get_config_memsize(struct amdgpu_device *adev)252static u32 soc21_get_config_memsize(struct amdgpu_device *adev)
@@ -589,21 +589,15 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block) · 336 unmodified lines
589 struct amdgpu_device *adev = ip_block->adev;589 struct amdgpu_device *adev = ip_block->adev;
590 590
591 adev->nbio.funcs->set_reg_remap(adev);591 adev->nbio.funcs->set_reg_remap(adev);
592 adev->smc_rreg = NULL;592 adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
593 adev->smc_wreg = NULL;593 adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
594 adev->pcie_rreg = &amdgpu_device_indirect_rreg;594 adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
595 adev->pcie_wreg = &amdgpu_device_indirect_wreg;595 adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
596 adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;596 adev->reg.pcie.port_rreg = &amdgpu_device_pcie_port_rreg;
597 adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;597 adev->reg.pcie.port_wreg = &amdgpu_device_pcie_port_wreg;
598 adev->pciep_rreg = amdgpu_device_pcie_port_rreg;598
599 adev->pciep_wreg = amdgpu_device_pcie_port_wreg;599 adev->reg.didt.rreg = &soc21_didt_rreg;
600 600 adev->reg.didt.wreg = &soc21_didt_wreg;
601 /* TODO: will add them during VCN v2 implementation */
602 adev->uvd_ctx_rreg = NULL;
603 adev->uvd_ctx_wreg = NULL;
604
605 adev->didt_rreg = &soc21_didt_rreg;
606 adev->didt_wreg = &soc21_didt_wreg;
607 601
608 adev->asic_funcs = &soc21_asic_funcs;602 adev->asic_funcs = &soc21_asic_funcs;
609 603
@@ -858,7 +852,9 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block) · 248 unmodified lines
858 AMD_CG_SUPPORT_IH_CG |852 AMD_CG_SUPPORT_IH_CG |
859 AMD_CG_SUPPORT_BIF_MGCG |853 AMD_CG_SUPPORT_BIF_MGCG |
860 AMD_CG_SUPPORT_BIF_LS;854 AMD_CG_SUPPORT_BIF_LS;
861 adev->pg_flags = AMD_PG_SUPPORT_VCN |855 adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG |
856 AMD_PG_SUPPORT_VCN |
857 AMD_PG_SUPPORT_JPEG_DPG |
862 AMD_PG_SUPPORT_JPEG |858 AMD_PG_SUPPORT_JPEG |
863 AMD_PG_SUPPORT_GFX_PG;859 AMD_PG_SUPPORT_GFX_PG;
864 adev->external_rev_id = adev->rev_id + 0x1;860 adev->external_rev_id = adev->rev_id + 0x1;
drivers/gpu/drm/amd/amdgpu/soc24.c+6−12
@@ -362,18 +362,12 @@ static int soc24_common_early_init(struct amdgpu_ip_block *ip_block) · 361 unmodified lines
362 struct amdgpu_device *adev = ip_block->adev;362 struct amdgpu_device *adev = ip_block->adev;
363 363
364 adev->nbio.funcs->set_reg_remap(adev);364 adev->nbio.funcs->set_reg_remap(adev);
365 adev->smc_rreg = NULL;365 adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
366 adev->smc_wreg = NULL;366 adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
367 adev->pcie_rreg = &amdgpu_device_indirect_rreg;367 adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
368 adev->pcie_wreg = &amdgpu_device_indirect_wreg;368 adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
369 adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;369 adev->reg.pcie.port_rreg = &amdgpu_device_pcie_port_rreg;
370 adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;370 adev->reg.pcie.port_wreg = &amdgpu_device_pcie_port_wreg;
371 adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
372 adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
373 adev->uvd_ctx_rreg = NULL;
374 adev->uvd_ctx_wreg = NULL;
375 adev->didt_rreg = NULL;
376 adev->didt_wreg = NULL;
377 371
378 adev->asic_funcs = &soc24_asic_funcs;372 adev->asic_funcs = &soc24_asic_funcs;
379 373
drivers/gpu/drm/amd/amdgpu/soc_v1_0.c+10−16
@@ -250,22 +250,16 @@ static int soc_v1_0_common_early_init(struct amdgpu_ip_block *ip_block) · 249 unmodified lines
250{250{
251 struct amdgpu_device *adev = ip_block->adev;251 struct amdgpu_device *adev = ip_block->adev;
252 252
253 adev->smc_rreg = NULL;253 adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
254 adev->smc_wreg = NULL;254 adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
255 adev->pcie_rreg = &amdgpu_device_indirect_rreg;255 adev->reg.pcie.rreg_ext = &amdgpu_device_indirect_rreg_ext;
256 adev->pcie_wreg = &amdgpu_device_indirect_wreg;256 adev->reg.pcie.wreg_ext = &amdgpu_device_indirect_wreg_ext;
257 adev->pcie_rreg_ext = &amdgpu_device_indirect_rreg_ext;257 adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
258 adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext;258 adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
259 adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;259 adev->reg.pcie.port_rreg = &amdgpu_device_pcie_port_rreg;
260 adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;260 adev->reg.pcie.port_wreg = &amdgpu_device_pcie_port_wreg;
261 adev->pciep_rreg = amdgpu_device_pcie_port_rreg;261 adev->reg.pcie.rreg64_ext = &amdgpu_device_indirect_rreg64_ext;
262 adev->pciep_wreg = amdgpu_device_pcie_port_wreg;262 adev->reg.pcie.wreg64_ext = &amdgpu_device_indirect_wreg64_ext;
263 adev->pcie_rreg64_ext = &amdgpu_device_indirect_rreg64_ext;
264 adev->pcie_wreg64_ext = &amdgpu_device_indirect_wreg64_ext;
265 adev->uvd_ctx_rreg = NULL;
266 adev->uvd_ctx_wreg = NULL;
267 adev->didt_rreg = NULL;
268 adev->didt_wreg = NULL;
269 263
270 adev->asic_funcs = &soc_v1_0_asic_funcs;264 adev->asic_funcs = &soc_v1_0_asic_funcs;
271 265
drivers/gpu/drm/amd/amdgpu/vce_v1_0.c+17−16
@@ -47,11 +47,6 @@ · 46 unmodified lines
47#define VCE_V1_0_DATA_SIZE (7808 * (AMDGPU_MAX_VCE_HANDLES + 1))47#define VCE_V1_0_DATA_SIZE (7808 * (AMDGPU_MAX_VCE_HANDLES + 1))
48#define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x0248#define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02
49 49
50#define VCE_V1_0_GART_PAGE_START \
51 (AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS)
52#define VCE_V1_0_GART_ADDR_START \
53 (VCE_V1_0_GART_PAGE_START * AMDGPU_GPU_PAGE_SIZE)
54
55static void vce_v1_0_set_ring_funcs(struct amdgpu_device *adev);50static void vce_v1_0_set_ring_funcs(struct amdgpu_device *adev);
56static void vce_v1_0_set_irq_funcs(struct amdgpu_device *adev);51static void vce_v1_0_set_irq_funcs(struct amdgpu_device *adev);
57 52
@@ -535,27 +530,29 @@ static int vce_v1_0_early_init(struct amdgpu_ip_block *ip_block) · 477 unmodified lines
535 */530 */
536static int vce_v1_0_ensure_vcpu_bo_32bit_addr(struct amdgpu_device *adev)531static int vce_v1_0_ensure_vcpu_bo_32bit_addr(struct amdgpu_device *adev)
537{532{
538 u64 gpu_addr = amdgpu_bo_gpu_offset(adev->vce.vcpu_bo);
539 u64 bo_size = amdgpu_bo_size(adev->vce.vcpu_bo);533 u64 bo_size = amdgpu_bo_size(adev->vce.vcpu_bo);
540 u64 max_vcpu_bo_addr = 0xffffffff - bo_size;534 u64 max_vcpu_bo_addr = 0xffffffff - bo_size;
541 u64 num_pages = ALIGN(bo_size, AMDGPU_GPU_PAGE_SIZE) / AMDGPU_GPU_PAGE_SIZE;535 u64 num_pages = ALIGN(bo_size, AMDGPU_GPU_PAGE_SIZE) / AMDGPU_GPU_PAGE_SIZE;
542 u64 pa = amdgpu_gmc_vram_pa(adev, adev->vce.vcpu_bo);536 u64 pa = amdgpu_gmc_vram_pa(adev, adev->vce.vcpu_bo);
543 u64 flags = AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | AMDGPU_PTE_VALID;537 u64 flags = AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | AMDGPU_PTE_VALID;
538 u64 vce_gart_start_offs;
539 int r;
544 540
545 /*541 r = amdgpu_gtt_mgr_alloc_entries(&adev->mman.gtt_mgr,
546 * Check if the VCPU BO already has a 32-bit address.542 &adev->vce.gart_node, num_pages,
547 * Eg. if MC is configured to put VRAM in the low address range.543 DRM_MM_INSERT_LOW);
548 */544 if (r)
549 if (gpu_addr <= max_vcpu_bo_addr)545 return r;
550 return 0;546
547 vce_gart_start_offs = amdgpu_gtt_node_to_byte_offset(&adev->vce.gart_node);
551 548
552 /* Check if we can map the VCPU BO in GART to a 32-bit address. */549 /* Check if we can map the VCPU BO in GART to a 32-bit address. */
553 if (adev->gmc.gart_start + VCE_V1_0_GART_ADDR_START > max_vcpu_bo_addr)550 if (adev->gmc.gart_start + vce_gart_start_offs > max_vcpu_bo_addr)
554 return -EINVAL;551 return -EINVAL;
555 552
556 amdgpu_gart_map_vram_range(adev, pa, VCE_V1_0_GART_PAGE_START,553 amdgpu_gart_map_vram_range(adev, pa, adev->vce.gart_node.start,
557 num_pages, flags, adev->gart.ptr);554 num_pages, flags, adev->gart.ptr);
558 adev->vce.gpu_addr = adev->gmc.gart_start + VCE_V1_0_GART_ADDR_START;555 adev->vce.gpu_addr = adev->gmc.gart_start + vce_gart_start_offs;
559 if (adev->vce.gpu_addr > max_vcpu_bo_addr)556 if (adev->vce.gpu_addr > max_vcpu_bo_addr)
560 return -EINVAL;557 return -EINVAL;
561 558
@@ -610,7 +607,11 @@ static int vce_v1_0_sw_fini(struct amdgpu_ip_block *ip_block) · 48 unmodified lines
610 if (r)607 if (r)
611 return r;608 return r;
612 609
613 return amdgpu_vce_sw_fini(adev);610 r = amdgpu_vce_sw_fini(adev);
611
612 amdgpu_gtt_mgr_free_entries(&adev->mman.gtt_mgr, &adev->vce.gart_node);
613
614 return r;
614}615}
615 616
616/**617/**
drivers/gpu/drm/amd/amdgpu/vi.c+38−38
@@ -299,11 +299,11 @@ static u32 vi_pcie_rreg(struct amdgpu_device *adev, u32 reg) · 298 unmodified lines
299 unsigned long flags;299 unsigned long flags;
300 u32 r;300 u32 r;
301 301
302 spin_lock_irqsave(&adev->pcie_idx_lock, flags);302 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
303 WREG32_NO_KIQ(mmPCIE_INDEX, reg);303 WREG32_NO_KIQ(mmPCIE_INDEX, reg);
304 (void)RREG32_NO_KIQ(mmPCIE_INDEX);304 (void)RREG32_NO_KIQ(mmPCIE_INDEX);
305 r = RREG32_NO_KIQ(mmPCIE_DATA);305 r = RREG32_NO_KIQ(mmPCIE_DATA);
306 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);306 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
307 return r;307 return r;
308}308}
309 309
@@ -311,12 +311,12 @@ static void vi_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
311{311{
312 unsigned long flags;312 unsigned long flags;
313 313
314 spin_lock_irqsave(&adev->pcie_idx_lock, flags);314 spin_lock_irqsave(&adev->reg.pcie.lock, flags);
315 WREG32_NO_KIQ(mmPCIE_INDEX, reg);315 WREG32_NO_KIQ(mmPCIE_INDEX, reg);
316 (void)RREG32_NO_KIQ(mmPCIE_INDEX);316 (void)RREG32_NO_KIQ(mmPCIE_INDEX);
317 WREG32_NO_KIQ(mmPCIE_DATA, v);317 WREG32_NO_KIQ(mmPCIE_DATA, v);
318 (void)RREG32_NO_KIQ(mmPCIE_DATA);318 (void)RREG32_NO_KIQ(mmPCIE_DATA);
319 spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);319 spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
320}320}
321 321
322static u32 vi_smc_rreg(struct amdgpu_device *adev, u32 reg)322static u32 vi_smc_rreg(struct amdgpu_device *adev, u32 reg)
@@ -324,10 +324,10 @@ static u32 vi_smc_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
324 unsigned long flags;324 unsigned long flags;
325 u32 r;325 u32 r;
326 326
327 spin_lock_irqsave(&adev->smc_idx_lock, flags);327 spin_lock_irqsave(&adev->reg.smc.lock, flags);
328 WREG32_NO_KIQ(mmSMC_IND_INDEX_11, (reg));328 WREG32_NO_KIQ(mmSMC_IND_INDEX_11, (reg));
329 r = RREG32_NO_KIQ(mmSMC_IND_DATA_11);329 r = RREG32_NO_KIQ(mmSMC_IND_DATA_11);
330 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);330 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
331 return r;331 return r;
332}332}
333 333
@@ -335,10 +335,10 @@ static void vi_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
335{335{
336 unsigned long flags;336 unsigned long flags;
337 337
338 spin_lock_irqsave(&adev->smc_idx_lock, flags);338 spin_lock_irqsave(&adev->reg.smc.lock, flags);
339 WREG32_NO_KIQ(mmSMC_IND_INDEX_11, (reg));339 WREG32_NO_KIQ(mmSMC_IND_INDEX_11, (reg));
340 WREG32_NO_KIQ(mmSMC_IND_DATA_11, (v));340 WREG32_NO_KIQ(mmSMC_IND_DATA_11, (v));
341 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);341 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
342}342}
343 343
344/* smu_8_0_d.h */344/* smu_8_0_d.h */
@@ -350,10 +350,10 @@ static u32 cz_smc_rreg(struct amdgpu_device *adev, u32 reg) · 5 unmodified lines
350 unsigned long flags;350 unsigned long flags;
351 u32 r;351 u32 r;
352 352
353 spin_lock_irqsave(&adev->smc_idx_lock, flags);353 spin_lock_irqsave(&adev->reg.smc.lock, flags);
354 WREG32(mmMP0PUB_IND_INDEX, (reg));354 WREG32(mmMP0PUB_IND_INDEX, (reg));
355 r = RREG32(mmMP0PUB_IND_DATA);355 r = RREG32(mmMP0PUB_IND_DATA);
356 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);356 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
357 return r;357 return r;
358}358}
359 359
@@ -361,10 +361,10 @@ static void cz_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
361{361{
362 unsigned long flags;362 unsigned long flags;
363 363
364 spin_lock_irqsave(&adev->smc_idx_lock, flags);364 spin_lock_irqsave(&adev->reg.smc.lock, flags);
365 WREG32(mmMP0PUB_IND_INDEX, (reg));365 WREG32(mmMP0PUB_IND_INDEX, (reg));
366 WREG32(mmMP0PUB_IND_DATA, (v));366 WREG32(mmMP0PUB_IND_DATA, (v));
367 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);367 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
368}368}
369 369
370static u32 vi_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg)370static u32 vi_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg)
@@ -372,10 +372,10 @@ static u32 vi_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
372 unsigned long flags;372 unsigned long flags;
373 u32 r;373 u32 r;
374 374
375 spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);375 spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
376 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));376 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
377 r = RREG32(mmUVD_CTX_DATA);377 r = RREG32(mmUVD_CTX_DATA);
378 spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);378 spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
379 return r;379 return r;
380}380}
381 381
@@ -383,10 +383,10 @@ static void vi_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
383{383{
384 unsigned long flags;384 unsigned long flags;
385 385
386 spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);386 spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
387 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));387 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
388 WREG32(mmUVD_CTX_DATA, (v));388 WREG32(mmUVD_CTX_DATA, (v));
389 spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);389 spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
390}390}
391 391
392static u32 vi_didt_rreg(struct amdgpu_device *adev, u32 reg)392static u32 vi_didt_rreg(struct amdgpu_device *adev, u32 reg)
@@ -394,10 +394,10 @@ static u32 vi_didt_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
394 unsigned long flags;394 unsigned long flags;
395 u32 r;395 u32 r;
396 396
397 spin_lock_irqsave(&adev->didt_idx_lock, flags);397 spin_lock_irqsave(&adev->reg.didt.lock, flags);
398 WREG32(mmDIDT_IND_INDEX, (reg));398 WREG32(mmDIDT_IND_INDEX, (reg));
399 r = RREG32(mmDIDT_IND_DATA);399 r = RREG32(mmDIDT_IND_DATA);
400 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);400 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
401 return r;401 return r;
402}402}
403 403
@@ -405,10 +405,10 @@ static void vi_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
405{405{
406 unsigned long flags;406 unsigned long flags;
407 407
408 spin_lock_irqsave(&adev->didt_idx_lock, flags);408 spin_lock_irqsave(&adev->reg.didt.lock, flags);
409 WREG32(mmDIDT_IND_INDEX, (reg));409 WREG32(mmDIDT_IND_INDEX, (reg));
410 WREG32(mmDIDT_IND_DATA, (v));410 WREG32(mmDIDT_IND_DATA, (v));
411 spin_unlock_irqrestore(&adev->didt_idx_lock, flags);411 spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
412}412}
413 413
414static u32 vi_gc_cac_rreg(struct amdgpu_device *adev, u32 reg)414static u32 vi_gc_cac_rreg(struct amdgpu_device *adev, u32 reg)
@@ -416,10 +416,10 @@ static u32 vi_gc_cac_rreg(struct amdgpu_device *adev, u32 reg) · 1 unmodified line
416 unsigned long flags;416 unsigned long flags;
417 u32 r;417 u32 r;
418 418
419 spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);419 spin_lock_irqsave(&adev->reg.gc_cac.lock, flags);
420 WREG32(mmGC_CAC_IND_INDEX, (reg));420 WREG32(mmGC_CAC_IND_INDEX, (reg));
421 r = RREG32(mmGC_CAC_IND_DATA);421 r = RREG32(mmGC_CAC_IND_DATA);
422 spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);422 spin_unlock_irqrestore(&adev->reg.gc_cac.lock, flags);
423 return r;423 return r;
424}424}
425 425
@@ -427,10 +427,10 @@ static void vi_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
427{427{
428 unsigned long flags;428 unsigned long flags;
429 429
430 spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);430 spin_lock_irqsave(&adev->reg.gc_cac.lock, flags);
431 WREG32(mmGC_CAC_IND_INDEX, (reg));431 WREG32(mmGC_CAC_IND_INDEX, (reg));
432 WREG32(mmGC_CAC_IND_DATA, (v));432 WREG32(mmGC_CAC_IND_DATA, (v));
433 spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);433 spin_unlock_irqrestore(&adev->reg.gc_cac.lock, flags);
434}434}
435 435
436 436
@@ -649,7 +649,7 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, · 212 unmodified lines
649 dw_ptr = (u32 *)bios;649 dw_ptr = (u32 *)bios;
650 length_dw = ALIGN(length_bytes, 4) / 4;650 length_dw = ALIGN(length_bytes, 4) / 4;
651 /* take the smc lock since we are using the smc index */651 /* take the smc lock since we are using the smc index */
652 spin_lock_irqsave(&adev->smc_idx_lock, flags);652 spin_lock_irqsave(&adev->reg.smc.lock, flags);
653 /* set rom index to 0 */653 /* set rom index to 0 */
654 WREG32(mmSMC_IND_INDEX_11, ixROM_INDEX);654 WREG32(mmSMC_IND_INDEX_11, ixROM_INDEX);
655 WREG32(mmSMC_IND_DATA_11, 0);655 WREG32(mmSMC_IND_DATA_11, 0);
@@ -657,7 +657,7 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, · 1 unmodified line
657 WREG32(mmSMC_IND_INDEX_11, ixROM_DATA);657 WREG32(mmSMC_IND_INDEX_11, ixROM_DATA);
658 for (i = 0; i < length_dw; i++)658 for (i = 0; i < length_dw; i++)
659 dw_ptr[i] = RREG32(mmSMC_IND_DATA_11);659 dw_ptr[i] = RREG32(mmSMC_IND_DATA_11);
660 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);660 spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
661 661
662 return true;662 return true;
663}663}
@@ -1454,20 +1454,20 @@ static int vi_common_early_init(struct amdgpu_ip_block *ip_block) · 790 unmodified lines
1454 struct amdgpu_device *adev = ip_block->adev;1454 struct amdgpu_device *adev = ip_block->adev;
1455 1455
1456 if (adev->flags & AMD_IS_APU) {1456 if (adev->flags & AMD_IS_APU) {
1457 adev->smc_rreg = &cz_smc_rreg;1457 adev->reg.smc.rreg = cz_smc_rreg;
1458 adev->smc_wreg = &cz_smc_wreg;1458 adev->reg.smc.wreg = cz_smc_wreg;
1459 } else {1459 } else {
1460 adev->smc_rreg = &vi_smc_rreg;1460 adev->reg.smc.rreg = vi_smc_rreg;
1461 adev->smc_wreg = &vi_smc_wreg;1461 adev->reg.smc.wreg = vi_smc_wreg;
1462 }1462 }
1463 adev->pcie_rreg = &vi_pcie_rreg;1463 adev->reg.pcie.rreg = &vi_pcie_rreg;
1464 adev->pcie_wreg = &vi_pcie_wreg;1464 adev->reg.pcie.wreg = &vi_pcie_wreg;
1465 adev->uvd_ctx_rreg = &vi_uvd_ctx_rreg;1465 adev->reg.uvd_ctx.rreg = &vi_uvd_ctx_rreg;
1466 adev->uvd_ctx_wreg = &vi_uvd_ctx_wreg;1466 adev->reg.uvd_ctx.wreg = &vi_uvd_ctx_wreg;
1467 adev->didt_rreg = &vi_didt_rreg;1467 adev->reg.didt.rreg = &vi_didt_rreg;
1468 adev->didt_wreg = &vi_didt_wreg;1468 adev->reg.didt.wreg = &vi_didt_wreg;
1469 adev->gc_cac_rreg = &vi_gc_cac_rreg;1469 adev->reg.gc_cac.rreg = &vi_gc_cac_rreg;
1470 adev->gc_cac_wreg = &vi_gc_cac_wreg;1470 adev->reg.gc_cac.wreg = &vi_gc_cac_wreg;
1471 1471
1472 adev->asic_funcs = &vi_asic_funcs;1472 adev->asic_funcs = &vi_asic_funcs;
1473 1473
drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx12.asm+0−3
@@ -134,9 +134,6 @@ var SQ_WAVE_MODE_DST_SRC0_SRC1_VGPR_MSB_SHIFT = 12 · 133 unmodified lines
134var SQ_WAVE_MODE_DST_SRC0_SRC1_VGPR_MSB_SIZE = 6134var SQ_WAVE_MODE_DST_SRC0_SRC1_VGPR_MSB_SIZE = 6
135#endif135#endif
136 136
137var TTMP11_SCHED_MODE_SHIFT = 26
138var TTMP11_SCHED_MODE_SIZE = 2
139var TTMP11_SCHED_MODE_MASK = 0xC000000
140var TTMP11_DEBUG_TRAP_ENABLED_SHIFT = 23137var TTMP11_DEBUG_TRAP_ENABLED_SHIFT = 23
141var TTMP11_DEBUG_TRAP_ENABLED_MASK = 0x800000138var TTMP11_DEBUG_TRAP_ENABLED_MASK = 0x800000
142var TTMP11_FIRST_REPLAY_SHIFT = 22139var TTMP11_FIRST_REPLAY_SHIFT = 22
drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c+25−10
@@ -342,20 +342,14 @@ static void kfd_init_apertures_vi(struct kfd_process_device *pdd, uint8_t id) · 341 unmodified lines
342 342
343static void kfd_init_apertures_v9(struct kfd_process_device *pdd, uint8_t id)343static void kfd_init_apertures_v9(struct kfd_process_device *pdd, uint8_t id)
344{344{
345 if (KFD_GC_VERSION(pdd->dev) >= IP_VERSION(12, 1, 0))345 pdd->lds_base = MAKE_LDS_APP_BASE_V9();
346 pdd->lds_base = pdd->dev->adev->gmc.shared_aperture_start;
347 else
348 pdd->lds_base = MAKE_LDS_APP_BASE_V9();
349 pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base);346 pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base);
350 347
351 pdd->gpuvm_base = AMDGPU_VA_RESERVED_BOTTOM;348 pdd->gpuvm_base = AMDGPU_VA_RESERVED_BOTTOM;
352 pdd->gpuvm_limit =349 pdd->gpuvm_limit =
353 pdd->dev->kfd->shared_resources.gpuvm_size - 1;350 pdd->dev->kfd->shared_resources.gpuvm_size - 1;
354 351
355 if (KFD_GC_VERSION(pdd->dev) >= IP_VERSION(12, 1, 0))352 pdd->scratch_base = MAKE_SCRATCH_APP_BASE_V9();
356 pdd->scratch_base = pdd->dev->adev->gmc.private_aperture_start;
357 else
358 pdd->scratch_base = MAKE_SCRATCH_APP_BASE_V9();
359 pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base);353 pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base);
360 354
361 /*355 /*
@@ -365,6 +359,25 @@ static void kfd_init_apertures_v9(struct kfd_process_device *pdd, uint8_t id) · 3 unmodified lines
365 pdd->qpd.cwsr_base = AMDGPU_VA_RESERVED_TRAP_START(pdd->dev->adev);359 pdd->qpd.cwsr_base = AMDGPU_VA_RESERVED_TRAP_START(pdd->dev->adev);
366}360}
367 361
362static void kfd_init_apertures_v12(struct kfd_process_device *pdd, uint8_t id)
363{
364 pdd->lds_base = pdd->dev->adev->gmc.shared_aperture_start;
365 pdd->lds_limit = pdd->dev->adev->gmc.shared_aperture_end;
366
367 pdd->gpuvm_base = AMDGPU_VA_RESERVED_BOTTOM;
368 pdd->gpuvm_limit =
369 pdd->dev->kfd->shared_resources.gpuvm_size - 1;
370
371 pdd->scratch_base = pdd->dev->adev->gmc.private_aperture_start;
372 pdd->scratch_limit = pdd->dev->adev->gmc.private_aperture_end;
373
374 /*
375 * Place TBA/TMA on opposite side of VM hole to prevent
376 * stray faults from triggering SVM on these pages.
377 */
378 pdd->qpd.cwsr_base = AMDGPU_VA_RESERVED_TRAP_START(pdd->dev->adev);
379}
380
368int kfd_init_apertures(struct kfd_process *process)381int kfd_init_apertures(struct kfd_process *process)
369{382{
370 uint8_t id = 0;383 uint8_t id = 0;
@@ -412,9 +425,11 @@ int kfd_init_apertures(struct kfd_process *process) · 41 unmodified lines
412 kfd_init_apertures_vi(pdd, id);425 kfd_init_apertures_vi(pdd, id);
413 break;426 break;
414 default:427 default:
415 if (KFD_GC_VERSION(dev) >= IP_VERSION(9, 0, 1))428 if (KFD_GC_VERSION(dev) >= IP_VERSION(12, 1, 0)) {
429 kfd_init_apertures_v12(pdd, id);
430 } else if (KFD_GC_VERSION(dev) >= IP_VERSION(9, 0, 1)) {
416 kfd_init_apertures_v9(pdd, id);431 kfd_init_apertures_v9(pdd, id);
417 else {432 } else {
418 WARN(1, "Unexpected ASIC family %u",433 WARN(1, "Unexpected ASIC family %u",
419 dev->adev->asic_type);434 dev->adev->asic_type);
420 return -EINVAL;435 return -EINVAL;
drivers/gpu/drm/amd/amdkfd/kfd_migrate.c+6−6
@@ -59,8 +59,7 @@ svm_migrate_gart_map(struct amdgpu_ring *ring, · 58 unmodified lines
59 void *cpu_addr;59 void *cpu_addr;
60 int r;60 int r;
61 61
62 /* use gart window 0 */62 *gart_addr = amdgpu_compute_gart_address(&adev->gmc, entity, 0);
63 *gart_addr = adev->gmc.gart_start;
64 63
65 num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);64 num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
66 num_bytes = npages * 8 * AMDGPU_GPU_PAGES_IN_CPU_PAGE;65 num_bytes = npages * 8 * AMDGPU_GPU_PAGES_IN_CPU_PAGE;
@@ -78,6 +77,7 @@ svm_migrate_gart_map(struct amdgpu_ring *ring, · 11 unmodified lines
78 src_addr += job->ibs[0].gpu_addr;77 src_addr += job->ibs[0].gpu_addr;
79 78
80 dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);79 dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
80 dst_addr += (entity->gart_window_offs[0] >> AMDGPU_GPU_PAGE_SHIFT) * 8;
81 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,81 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
82 dst_addr, num_bytes, 0);82 dst_addr, num_bytes, 0);
83 83
@@ -116,7 +116,7 @@ svm_migrate_gart_map(struct amdgpu_ring *ring, · 32 unmodified lines
116 * multiple GTT_MAX_PAGES transfer, all sdma operations are serialized, wait for116 * multiple GTT_MAX_PAGES transfer, all sdma operations are serialized, wait for
117 * the last sdma finish fence which is returned to check copy memory is done.117 * the last sdma finish fence which is returned to check copy memory is done.
118 *118 *
119 * Context: Process context, takes and releases gtt_window_lock119 * Context: Process context
120 *120 *
121 * Return:121 * Return:
122 * 0 - OK, otherwise error code122 * 0 - OK, otherwise error code
@@ -136,9 +136,9 @@ svm_migrate_copy_memory_gart(struct amdgpu_device *adev, dma_addr_t *sys, · 13 unmodified lines
136 u64 size;136 u64 size;
137 int r;137 int r;
138 138
139 entity = &adev->mman.default_entity;139 entity = &adev->mman.move_entity;
140 140
141 mutex_lock(&adev->mman.gtt_window_lock);141 mutex_lock(&entity->lock);
142 142
143 while (npages) {143 while (npages) {
144 size = min(GTT_MAX_PAGES, npages);144 size = min(GTT_MAX_PAGES, npages);
@@ -175,7 +175,7 @@ svm_migrate_copy_memory_gart(struct amdgpu_device *adev, dma_addr_t *sys, · 30 unmodified lines
175 }175 }
176 176
177out_unlock:177out_unlock:
178 mutex_unlock(&adev->mman.gtt_window_lock);178 mutex_unlock(&entity->lock);
179 179
180 return r;180 return r;
181}181}
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c+0−1
@@ -70,7 +70,6 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 69 unmodified lines
70static void set_priority(struct cik_mqd *m, struct queue_properties *q)70static void set_priority(struct cik_mqd *m, struct queue_properties *q)
71{71{
72 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];72 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
73 /* m->cp_hqd_queue_priority = q->priority; */
74}73}
75 74
76static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,75static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c+0−1
@@ -70,7 +70,6 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 69 unmodified lines
70static void set_priority(struct v10_compute_mqd *m, struct queue_properties *q)70static void set_priority(struct v10_compute_mqd *m, struct queue_properties *q)
71{71{
72 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];72 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
73 /* m->cp_hqd_queue_priority = q->priority; */
74}73}
75 74
76static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,75static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c+0−1
@@ -96,7 +96,6 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 95 unmodified lines
96static void set_priority(struct v11_compute_mqd *m, struct queue_properties *q)96static void set_priority(struct v11_compute_mqd *m, struct queue_properties *q)
97{97{
98 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];98 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
99 /* m->cp_hqd_queue_priority = q->priority; */
100}99}
101 100
102static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,101static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c+0−1
@@ -77,7 +77,6 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 76 unmodified lines
77static void set_priority(struct v12_compute_mqd *m, struct queue_properties *q)77static void set_priority(struct v12_compute_mqd *m, struct queue_properties *q)
78{78{
79 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];79 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
80 /* m->cp_hqd_queue_priority = q->priority; */
81}80}
82 81
83static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,82static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c+0−1
@@ -131,7 +131,6 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 130 unmodified lines
131static void set_priority(struct v12_1_compute_mqd *m, struct queue_properties *q)131static void set_priority(struct v12_1_compute_mqd *m, struct queue_properties *q)
132{132{
133 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];133 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
134 /* m->cp_hqd_queue_priority = q->priority; */
135}134}
136 135
137static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,136static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c+0−1
@@ -106,7 +106,6 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 105 unmodified lines
106static void set_priority(struct v9_mqd *m, struct queue_properties *q)106static void set_priority(struct v9_mqd *m, struct queue_properties *q)
107{107{
108 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];108 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
109 /* m->cp_hqd_queue_priority = q->priority; */
110}109}
111 110
112static bool mqd_on_vram(struct amdgpu_device *adev)111static bool mqd_on_vram(struct amdgpu_device *adev)
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c+0−1
@@ -73,7 +73,6 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 72 unmodified lines
73static void set_priority(struct vi_mqd *m, struct queue_properties *q)73static void set_priority(struct vi_mqd *m, struct queue_properties *q)
74{74{
75 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];75 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
76 /* m->cp_hqd_queue_priority = q->priority; */
77}76}
78 77
79static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,78static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c+79−140
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: MIT1// SPDX-License-Identifier: MIT
2/*2/*
3 * Copyright 2015 Advanced Micro Devices, Inc.3 * Copyright 2015-2026 Advanced Micro Devices, Inc.
4 *4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),6 * copy of this software and associated documentation files (the "Software"),
@@ -153,6 +153,9 @@ MODULE_FIRMWARE(FIRMWARE_DCN_36_DMUB); · 146 unmodified lines
153#define FIRMWARE_DCN_401_DMUB "amdgpu/dcn_4_0_1_dmcub.bin"153#define FIRMWARE_DCN_401_DMUB "amdgpu/dcn_4_0_1_dmcub.bin"
154MODULE_FIRMWARE(FIRMWARE_DCN_401_DMUB);154MODULE_FIRMWARE(FIRMWARE_DCN_401_DMUB);
155 155
156#define FIRMWARE_DCN_42_DMUB "amdgpu/dcn_4_2_dmcub.bin"
157MODULE_FIRMWARE(FIRMWARE_DCN_42_DMUB);
158
156/**159/**
157 * DOC: overview160 * DOC: overview
158 *161 *
@@ -1369,6 +1372,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) · 1210 unmodified lines
1369 case IP_VERSION(3, 5, 0):1372 case IP_VERSION(3, 5, 0):
1370 case IP_VERSION(3, 5, 1):1373 case IP_VERSION(3, 5, 1):
1371 case IP_VERSION(3, 6, 0):1374 case IP_VERSION(3, 6, 0):
1375 case IP_VERSION(4, 2, 0):
1372 hw_params.ips_sequential_ono = adev->external_rev_id > 0x10;1376 hw_params.ips_sequential_ono = adev->external_rev_id > 0x10;
1373 hw_params.lower_hbr3_phy_ssc = true;1377 hw_params.lower_hbr3_phy_ssc = true;
1374 break;1378 break;
@@ -1816,6 +1820,9 @@ static void *dm_dmub_get_vbios_bounding_box(struct amdgpu_device *adev) · 441 unmodified lines
1816 case IP_VERSION(4, 0, 1):1820 case IP_VERSION(4, 0, 1):
1817 bb_size = sizeof(struct dml2_soc_bb);1821 bb_size = sizeof(struct dml2_soc_bb);
1818 break;1822 break;
1823 case IP_VERSION(4, 2, 0):
1824 bb_size = sizeof(struct dml2_soc_bb);
1825 break;
1819 default:1826 default:
1820 return NULL;1827 return NULL;
1821 }1828 }
@@ -1860,6 +1867,9 @@ static enum dmub_ips_disable_type dm_get_default_ips_mode( · 38 unmodified lines
1860 case IP_VERSION(3, 5, 1):1867 case IP_VERSION(3, 5, 1):
1861 ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;1868 ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
1862 break;1869 break;
1870 case IP_VERSION(4, 2, 0):
1871 ret = DMUB_IPS_DISABLE_ALL;
1872 break;
1863 default:1873 default:
1864 /* ASICs older than DCN35 do not have IPSs */1874 /* ASICs older than DCN35 do not have IPSs */
1865 if (amdgpu_ip_version(adev, DCE_HWIP, 0) < IP_VERSION(3, 5, 0))1875 if (amdgpu_ip_version(adev, DCE_HWIP, 0) < IP_VERSION(3, 5, 0))
@@ -2003,6 +2013,13 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 137 unmodified lines
2003 if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0))2013 if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0))
2004 init_data.num_virtual_links = 1;2014 init_data.num_virtual_links = 1;
2005 2015
2016 /* DCN42 and above dpia switch to unified link training path */
2017 if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(4, 2, 0)) {
2018 init_data.flags.consolidated_dpia_dp_lt = true;
2019 init_data.flags.enable_dpia_pre_training = true;
2020 init_data.flags.unify_link_enc_assignment = true;
2021 init_data.flags.usb4_bw_alloc_support = true;
2022 }
2006 retrieve_dmi_info(&adev->dm);2023 retrieve_dmi_info(&adev->dm);
2007 if (adev->dm.edp0_on_dp1_quirk)2024 if (adev->dm.edp0_on_dp1_quirk)
2008 init_data.flags.support_edp0_on_dp1 = true;2025 init_data.flags.support_edp0_on_dp1 = true;
@@ -2370,6 +2387,7 @@ static int load_dmcu_fw(struct amdgpu_device *adev) · 361 unmodified lines
2370 case IP_VERSION(3, 5, 1):2387 case IP_VERSION(3, 5, 1):
2371 case IP_VERSION(3, 6, 0):2388 case IP_VERSION(3, 6, 0):
2372 case IP_VERSION(4, 0, 1):2389 case IP_VERSION(4, 0, 1):
2390 case IP_VERSION(4, 2, 0):
2373 return 0;2391 return 0;
2374 default:2392 default:
2375 break;2393 break;
@@ -2503,7 +2521,9 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 127 unmodified lines
2503 case IP_VERSION(4, 0, 1):2521 case IP_VERSION(4, 0, 1):
2504 dmub_asic = DMUB_ASIC_DCN401;2522 dmub_asic = DMUB_ASIC_DCN401;
2505 break;2523 break;
2506 2524 case IP_VERSION(4, 2, 0):
2525 dmub_asic = DMUB_ASIC_DCN42;
2526 break;
2507 default:2527 default:
2508 /* ASIC doesn't support DMUB. */2528 /* ASIC doesn't support DMUB. */
2509 return 0;2529 return 0;
@@ -4390,105 +4410,6 @@ static int register_hpd_handlers(struct amdgpu_device *adev) · 1880 unmodified lines
4390 return 0;4410 return 0;
4391}4411}
4392 4412
4393#if defined(CONFIG_DRM_AMD_DC_SI)
4394/* Register IRQ sources and initialize IRQ callbacks */
4395static int dce60_register_irq_handlers(struct amdgpu_device *adev)
4396{
4397 struct dc *dc = adev->dm.dc;
4398 struct common_irq_params *c_irq_params;
4399 struct dc_interrupt_params int_params = {0};
4400 int r;
4401 int i;
4402 unsigned int client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
4403
4404 int_params.requested_polarity = INTERRUPT_POLARITY_DEFAULT;
4405 int_params.current_polarity = INTERRUPT_POLARITY_DEFAULT;
4406
4407 /*
4408 * Actions of amdgpu_irq_add_id():
4409 * 1. Register a set() function with base driver.
4410 * Base driver will call set() function to enable/disable an
4411 * interrupt in DC hardware.
4412 * 2. Register amdgpu_dm_irq_handler().
4413 * Base driver will call amdgpu_dm_irq_handler() for ALL interrupts
4414 * coming from DC hardware.
4415 * amdgpu_dm_irq_handler() will re-direct the interrupt to DC
4416 * for acknowledging and handling.
4417 */
4418
4419 /* Use VBLANK interrupt */
4420 for (i = 0; i < adev->mode_info.num_crtc; i++) {
4421 r = amdgpu_irq_add_id(adev, client_id, i + 1, &adev->crtc_irq);
4422 if (r) {
4423 drm_err(adev_to_drm(adev), "Failed to add crtc irq id!\n");
4424 return r;
4425 }
4426
4427 int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
4428 int_params.irq_source =
4429 dc_interrupt_to_irq_source(dc, i + 1, 0);
4430
4431 if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
4432 int_params.irq_source < DC_IRQ_SOURCE_VBLANK1 ||
4433 int_params.irq_source > DC_IRQ_SOURCE_VBLANK6) {
4434 drm_err(adev_to_drm(adev), "Failed to register vblank irq!\n");
4435 return -EINVAL;
4436 }
4437
4438 c_irq_params = &adev->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1];
4439
4440 c_irq_params->adev = adev;
4441 c_irq_params->irq_src = int_params.irq_source;
4442
4443 if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
4444 dm_crtc_high_irq, c_irq_params))
4445 return -ENOMEM;
4446 }
4447
4448 /* Use GRPH_PFLIP interrupt */
4449 for (i = VISLANDS30_IV_SRCID_D1_GRPH_PFLIP;
4450 i <= VISLANDS30_IV_SRCID_D6_GRPH_PFLIP; i += 2) {
4451 r = amdgpu_irq_add_id(adev, client_id, i, &adev->pageflip_irq);
4452 if (r) {
4453 drm_err(adev_to_drm(adev), "Failed to add page flip irq id!\n");
4454 return r;
4455 }
4456
4457 int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
4458 int_params.irq_source =
4459 dc_interrupt_to_irq_source(dc, i, 0);
4460
4461 if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
4462 int_params.irq_source < DC_IRQ_SOURCE_PFLIP_FIRST ||
4463 int_params.irq_source > DC_IRQ_SOURCE_PFLIP_LAST) {
4464 drm_err(adev_to_drm(adev), "Failed to register pflip irq!\n");
4465 return -EINVAL;
4466 }
4467
4468 c_irq_params = &adev->dm.pflip_params[int_params.irq_source - DC_IRQ_SOURCE_PFLIP_FIRST];
4469
4470 c_irq_params->adev = adev;
4471 c_irq_params->irq_src = int_params.irq_source;
4472
4473 if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
4474 dm_pflip_high_irq, c_irq_params))
4475 return -ENOMEM;
4476 }
4477
4478 /* HPD */
4479 r = amdgpu_irq_add_id(adev, client_id,
4480 VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A, &adev->hpd_irq);
4481 if (r) {
4482 drm_err(adev_to_drm(adev), "Failed to add hpd irq id!\n");
4483 return r;
4484 }
4485
4486 r = register_hpd_handlers(adev);
4487
4488 return r;
4489}
4490#endif
4491
4492/* Register IRQ sources and initialize IRQ callbacks */4413/* Register IRQ sources and initialize IRQ callbacks */
4493static int dce110_register_irq_handlers(struct amdgpu_device *adev)4414static int dce110_register_irq_handlers(struct amdgpu_device *adev)
4494{4415{
@@ -4497,7 +4418,12 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) · 2 unmodified lines
4497 struct dc_interrupt_params int_params = {0};4418 struct dc_interrupt_params int_params = {0};
4498 int r;4419 int r;
4499 int i;4420 int i;
4421 unsigned int src_id;
4500 unsigned int client_id = AMDGPU_IRQ_CLIENTID_LEGACY;4422 unsigned int client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
4423 /* Use different interrupts for VBLANK on DCE 6 vs. newer. */
4424 const unsigned int vblank_d1 =
4425 adev->dm.dc->ctx->dce_version >= DCE_VERSION_8_0
4426 ? VISLANDS30_IV_SRCID_D1_VERTICAL_INTERRUPT0 : 1;
4501 4427
4502 if (adev->family >= AMDGPU_FAMILY_AI)4428 if (adev->family >= AMDGPU_FAMILY_AI)
4503 client_id = SOC15_IH_CLIENTID_DCE;4429 client_id = SOC15_IH_CLIENTID_DCE;
@@ -4518,8 +4444,9 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) · 14 unmodified lines
4518 */4444 */
4519 4445
4520 /* Use VBLANK interrupt */4446 /* Use VBLANK interrupt */
4521 for (i = VISLANDS30_IV_SRCID_D1_VERTICAL_INTERRUPT0; i <= VISLANDS30_IV_SRCID_D6_VERTICAL_INTERRUPT0; i++) {4447 for (i = 0; i < adev->mode_info.num_crtc; i++) {
4522 r = amdgpu_irq_add_id(adev, client_id, i, &adev->crtc_irq);4448 src_id = vblank_d1 + i;
4449 r = amdgpu_irq_add_id(adev, client_id, src_id, &adev->crtc_irq);
4523 if (r) {4450 if (r) {
4524 drm_err(adev_to_drm(adev), "Failed to add crtc irq id!\n");4451 drm_err(adev_to_drm(adev), "Failed to add crtc irq id!\n");
4525 return r;4452 return r;
@@ -4527,7 +4454,7 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) · 1 unmodified line
4527 4454
4528 int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;4455 int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
4529 int_params.irq_source =4456 int_params.irq_source =
4530 dc_interrupt_to_irq_source(dc, i, 0);4457 dc_interrupt_to_irq_source(dc, src_id, 0);
4531 4458
4532 if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||4459 if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
4533 int_params.irq_source < DC_IRQ_SOURCE_VBLANK1 ||4460 int_params.irq_source < DC_IRQ_SOURCE_VBLANK1 ||
@@ -4546,33 +4473,36 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) · 12 unmodified lines
4546 return -ENOMEM;4473 return -ENOMEM;
4547 }4474 }
4548 4475
4549 /* Use VUPDATE interrupt */4476 if (dc_supports_vrr(adev->dm.dc->ctx->dce_version)) {
4550 for (i = VISLANDS30_IV_SRCID_D1_V_UPDATE_INT; i <= VISLANDS30_IV_SRCID_D6_V_UPDATE_INT; i += 2) {4477 /* Use VUPDATE interrupt */
4551 r = amdgpu_irq_add_id(adev, client_id, i, &adev->vupdate_irq);4478 for (i = 0; i < adev->mode_info.num_crtc; i++) {
4552 if (r) {4479 src_id = VISLANDS30_IV_SRCID_D1_V_UPDATE_INT + i * 2;
4553 drm_err(adev_to_drm(adev), "Failed to add vupdate irq id!\n");4480 r = amdgpu_irq_add_id(adev, client_id, src_id, &adev->vupdate_irq);
4554 return r;4481 if (r) {
4555 }4482 drm_err(adev_to_drm(adev), "Failed to add vupdate irq id!\n");
4556 4483 return r;
4557 int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;4484 }
4558 int_params.irq_source =
4559 dc_interrupt_to_irq_source(dc, i, 0);
4560 4485
4561 if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||4486 int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
4562 int_params.irq_source < DC_IRQ_SOURCE_VUPDATE1 ||4487 int_params.irq_source =
4563 int_params.irq_source > DC_IRQ_SOURCE_VUPDATE6) {4488 dc_interrupt_to_irq_source(dc, src_id, 0);
4564 drm_err(adev_to_drm(adev), "Failed to register vupdate irq!\n");
4565 return -EINVAL;
4566 }
4567 4489
4568 c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1];4490 if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
4491 int_params.irq_source < DC_IRQ_SOURCE_VUPDATE1 ||
4492 int_params.irq_source > DC_IRQ_SOURCE_VUPDATE6) {
4493 drm_err(adev_to_drm(adev), "Failed to register vupdate irq!\n");
4494 return -EINVAL;
4495 }
4569 4496
4570 c_irq_params->adev = adev;4497 c_irq_params = &adev->dm.vupdate_params[
4571 c_irq_params->irq_src = int_params.irq_source;4498 int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1];
4499 c_irq_params->adev = adev;
4500 c_irq_params->irq_src = int_params.irq_source;
4572 4501
4573 if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,4502 if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
4574 dm_vupdate_high_irq, c_irq_params))4503 dm_vupdate_high_irq, c_irq_params))
4575 return -ENOMEM;4504 return -ENOMEM;
4505 }
4576 }4506 }
4577 4507
4578 /* Use GRPH_PFLIP interrupt */4508 /* Use GRPH_PFLIP interrupt */
@@ -5544,6 +5474,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 965 unmodified lines
5544 case IP_VERSION(3, 5, 1):5474 case IP_VERSION(3, 5, 1):
5545 case IP_VERSION(3, 6, 0):5475 case IP_VERSION(3, 6, 0):
5546 case IP_VERSION(4, 0, 1):5476 case IP_VERSION(4, 0, 1):
5477 case IP_VERSION(4, 2, 0):
5547 if (register_outbox_irq_handlers(dm->adev)) {5478 if (register_outbox_irq_handlers(dm->adev)) {
5548 drm_err(adev_to_drm(adev), "DM: Failed to initialize IRQ\n");5479 drm_err(adev_to_drm(adev), "DM: Failed to initialize IRQ\n");
5549 goto fail;5480 goto fail;
@@ -5568,6 +5499,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 18 unmodified lines
5568 case IP_VERSION(3, 5, 1):5499 case IP_VERSION(3, 5, 1):
5569 case IP_VERSION(3, 6, 0):5500 case IP_VERSION(3, 6, 0):
5570 case IP_VERSION(4, 0, 1):5501 case IP_VERSION(4, 0, 1):
5502 case IP_VERSION(4, 2, 0):
5571 psr_feature_enabled = true;5503 psr_feature_enabled = true;
5572 break;5504 break;
5573 default:5505 default:
@@ -5700,11 +5632,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 126 unmodified lines
5700 case CHIP_PITCAIRN:5632 case CHIP_PITCAIRN:
5701 case CHIP_VERDE:5633 case CHIP_VERDE:
5702 case CHIP_OLAND:5634 case CHIP_OLAND:
5703 if (dce60_register_irq_handlers(dm->adev)) {
5704 drm_err(adev_to_drm(adev), "DM: Failed to initialize IRQ\n");
5705 goto fail;
5706 }
5707 break;
5708#endif5635#endif
5709 case CHIP_BONAIRE:5636 case CHIP_BONAIRE:
5710 case CHIP_HAWAII:5637 case CHIP_HAWAII:
@@ -5750,6 +5677,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 39 unmodified lines
5750 case IP_VERSION(3, 5, 1):5677 case IP_VERSION(3, 5, 1):
5751 case IP_VERSION(3, 6, 0):5678 case IP_VERSION(3, 6, 0):
5752 case IP_VERSION(4, 0, 1):5679 case IP_VERSION(4, 0, 1):
5680 case IP_VERSION(4, 2, 0):
5753 if (dcn10_register_irq_handlers(dm->adev)) {5681 if (dcn10_register_irq_handlers(dm->adev)) {
5754 drm_err(adev_to_drm(adev), "DM: Failed to initialize IRQ\n");5682 drm_err(adev_to_drm(adev), "DM: Failed to initialize IRQ\n");
5755 goto fail;5683 goto fail;
@@ -5898,6 +5826,9 @@ static int dm_init_microcode(struct amdgpu_device *adev) · 142 unmodified lines
5898 case IP_VERSION(4, 0, 1):5826 case IP_VERSION(4, 0, 1):
5899 fw_name_dmub = FIRMWARE_DCN_401_DMUB;5827 fw_name_dmub = FIRMWARE_DCN_401_DMUB;
5900 break;5828 break;
5829 case IP_VERSION(4, 2, 0):
5830 fw_name_dmub = FIRMWARE_DCN_42_DMUB;
5831 break;
5901 default:5832 default:
5902 /* ASIC doesn't support DMUB. */5833 /* ASIC doesn't support DMUB. */
5903 return 0;5834 return 0;
@@ -6025,6 +5956,7 @@ static int dm_early_init(struct amdgpu_ip_block *ip_block) · 121 unmodified lines
6025 case IP_VERSION(3, 5, 1):5956 case IP_VERSION(3, 5, 1):
6026 case IP_VERSION(3, 6, 0):5957 case IP_VERSION(3, 6, 0):
6027 case IP_VERSION(4, 0, 1):5958 case IP_VERSION(4, 0, 1):
5959 case IP_VERSION(4, 2, 0):
6028 adev->mode_info.num_crtc = 4;5960 adev->mode_info.num_crtc = 4;
6029 adev->mode_info.num_hpd = 4;5961 adev->mode_info.num_hpd = 4;
6030 adev->mode_info.num_dig = 4;5962 adev->mode_info.num_dig = 4;
@@ -6041,8 +5973,8 @@ static int dm_early_init(struct amdgpu_ip_block *ip_block) · 10 unmodified lines
6041 adev->mode_info.funcs = &dm_display_funcs;5973 adev->mode_info.funcs = &dm_display_funcs;
6042 5974
6043 /*5975 /*
6044 * Note: Do NOT change adev->audio_endpt_rreg and5976 * Note: Do NOT change adev->reg.audio_endpt.rreg and
6045 * adev->audio_endpt_wreg because they are initialised in5977 * adev->reg.audio_endpt.wreg because they are initialised in
6046 * amdgpu_device_init()5978 * amdgpu_device_init()
6047 */5979 */
6048#if defined(CONFIG_DEBUG_KERNEL_DC)5980#if defined(CONFIG_DEBUG_KERNEL_DC)
@@ -8583,6 +8515,12 @@ static int to_drm_connector_type(enum signal_type st, uint32_t connector_id) · 2534 unmodified lines
8583 return DRM_MODE_CONNECTOR_VGA;8515 return DRM_MODE_CONNECTOR_VGA;
8584 case SIGNAL_TYPE_DISPLAY_PORT:8516 case SIGNAL_TYPE_DISPLAY_PORT:
8585 case SIGNAL_TYPE_DISPLAY_PORT_MST:8517 case SIGNAL_TYPE_DISPLAY_PORT_MST:
8518 /* External DP bridges have a different connector type. */
8519 if (connector_id == CONNECTOR_ID_VGA)
8520 return DRM_MODE_CONNECTOR_VGA;
8521 else if (connector_id == CONNECTOR_ID_LVDS)
8522 return DRM_MODE_CONNECTOR_LVDS;
8523
8586 return DRM_MODE_CONNECTOR_DisplayPort;8524 return DRM_MODE_CONNECTOR_DisplayPort;
8587 case SIGNAL_TYPE_DVI_DUAL_LINK:8525 case SIGNAL_TYPE_DVI_DUAL_LINK:
8588 case SIGNAL_TYPE_DVI_SINGLE_LINK:8526 case SIGNAL_TYPE_DVI_SINGLE_LINK:
@@ -9257,8 +9195,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, · 668 unmodified lines
9257 connector_type == DRM_MODE_CONNECTOR_HDMIB)9195 connector_type == DRM_MODE_CONNECTOR_HDMIB)
9258 amdgpu_dm_initialize_hdmi_connector(aconnector);9196 amdgpu_dm_initialize_hdmi_connector(aconnector);
9259 9197
9260 if (connector_type == DRM_MODE_CONNECTOR_DisplayPort9198 if (dc_is_dp_signal(link->connector_signal))
9261 || connector_type == DRM_MODE_CONNECTOR_eDP)
9262 amdgpu_dm_initialize_dp_connector(dm, aconnector, link->link_index);9199 amdgpu_dm_initialize_dp_connector(dm, aconnector, link->link_index);
9263 9200
9264out_free:9201out_free:
@@ -12320,10 +12257,11 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, · 3055 unmodified lines
12320 int i;12257 int i;
12321 12258
12322 /* Overlay cursor not supported on HW before DCN12259 /* Overlay cursor not supported on HW before DCN
12323 * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions12260 * DCN401/420 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions
12324 * as previous DCN generations, so enable native mode on DCN40112261 * as previous DCN generations, so enable native mode on DCN401/420
12325 */12262 */
12326 if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {12263 if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1) ||
12264 amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 2, 0)) {
12327 *cursor_mode = DM_CURSOR_NATIVE_MODE;12265 *cursor_mode = DM_CURSOR_NATIVE_MODE;
12328 return 0;12266 return 0;
12329 }12267 }
@@ -12743,7 +12681,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 413 unmodified lines
12743 12681
12744 /* Check if rotation or scaling is enabled on DCN401 */12682 /* Check if rotation or scaling is enabled on DCN401 */
12745 if ((drm_plane_mask(crtc->cursor) & new_crtc_state->plane_mask) &&12683 if ((drm_plane_mask(crtc->cursor) & new_crtc_state->plane_mask) &&
12746 amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {12684 (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 2, 0) ||
12685 amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1))) {
12747 new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);12686 new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
12748 12687
12749 is_rotated = new_cursor_state &&12688 is_rotated = new_cursor_state &&
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c+4−2
@@ -1706,6 +1706,7 @@ __set_dm_plane_colorop_3dlut(struct drm_plane_state *plane_state, · 1705 unmodified lines
1706 struct dc_transfer_func *tf = &dc_plane_state->in_shaper_func;1706 struct dc_transfer_func *tf = &dc_plane_state->in_shaper_func;
1707 struct drm_atomic_state *state = plane_state->state;1707 struct drm_atomic_state *state = plane_state->state;
1708 const struct amdgpu_device *adev = drm_to_adev(colorop->dev);1708 const struct amdgpu_device *adev = drm_to_adev(colorop->dev);
1709 bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend;
1709 const struct drm_device *dev = colorop->dev;1710 const struct drm_device *dev = colorop->dev;
1710 const struct drm_color_lut32 *lut3d;1711 const struct drm_color_lut32 *lut3d;
1711 uint32_t lut3d_size;1712 uint32_t lut3d_size;
@@ -1722,7 +1723,7 @@ __set_dm_plane_colorop_3dlut(struct drm_plane_state *plane_state, · 10 unmodified lines
1722 }1723 }
1723 1724
1724 if (colorop_state && !colorop_state->bypass && colorop->type == DRM_COLOROP_3D_LUT) {1725 if (colorop_state && !colorop_state->bypass && colorop->type == DRM_COLOROP_3D_LUT) {
1725 if (!adev->dm.dc->caps.color.dpp.hw_3d_lut) {1726 if (!has_3dlut) {
1726 drm_dbg(dev, "3D LUT is not supported by hardware\n");1727 drm_dbg(dev, "3D LUT is not supported by hardware\n");
1727 return -EINVAL;1728 return -EINVAL;
1728 }1729 }
@@ -1875,6 +1876,7 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state, · 146 unmodified lines
1875 struct drm_colorop *colorop = plane_state->color_pipeline;1876 struct drm_colorop *colorop = plane_state->color_pipeline;
1876 struct drm_device *dev = plane_state->plane->dev;1877 struct drm_device *dev = plane_state->plane->dev;
1877 struct amdgpu_device *adev = drm_to_adev(dev);1878 struct amdgpu_device *adev = drm_to_adev(dev);
1879 bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend;
1878 int ret;1880 int ret;
1879 1881
1880 /* 1D Curve - DEGAM TF */1882 /* 1D Curve - DEGAM TF */
@@ -1907,7 +1909,7 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state, · 26 unmodified lines
1907 if (ret)1909 if (ret)
1908 return ret;1910 return ret;
1909 1911
1910 if (adev->dm.dc->caps.color.dpp.hw_3d_lut) {1912 if (has_3dlut) {
1911 /* 1D Curve & LUT - SHAPER TF & LUT */1913 /* 1D Curve & LUT - SHAPER TF & LUT */
1912 colorop = colorop->next;1914 colorop = colorop->next;
1913 if (!colorop) {1915 if (!colorop) {
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c+2−1
@@ -64,6 +64,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr · 63 unmodified lines
64 struct drm_colorop *ops[MAX_COLOR_PIPELINE_OPS];64 struct drm_colorop *ops[MAX_COLOR_PIPELINE_OPS];
65 struct drm_device *dev = plane->dev;65 struct drm_device *dev = plane->dev;
66 struct amdgpu_device *adev = drm_to_adev(dev);66 struct amdgpu_device *adev = drm_to_adev(dev);
67 bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend;
67 int ret;68 int ret;
68 int i = 0;69 int i = 0;
69 70
@@ -119,7 +120,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr · 49 unmodified lines
119 120
120 i++;121 i++;
121 122
122 if (adev->dm.dc->caps.color.dpp.hw_3d_lut) {123 if (has_3dlut) {
123 /* 1D curve - SHAPER TF */124 /* 1D curve - SHAPER TF */
124 ops[i] = kzalloc_obj(*ops[0]);125 ops[i] = kzalloc_obj(*ops[0]);
125 if (!ops[i]) {126 if (!ops[i]) {
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c+8−8
@@ -765,15 +765,15 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, · 764 unmodified lines
765 dm->adev->mode_info.crtcs[crtc_index] = acrtc;765 dm->adev->mode_info.crtcs[crtc_index] = acrtc;
766 766
767 /* Don't enable DRM CRTC degamma property for767 /* Don't enable DRM CRTC degamma property for
768 * 1. Degamma is replaced by color pipeline.768 * 1. DCE since it doesn't support programmable degamma anywhere.
769 * 2. DCE since it doesn't support programmable degamma anywhere.769 * 2. DCN401 since pre-blending degamma LUT doesn't apply to cursor.
770 * 3. DCN401 since pre-blending degamma LUT doesn't apply to cursor.770 * Note: DEGAMMA properties are created even if the primary plane has the
771 * COLOR_PIPELINE property. User space can use either the DEGAMMA properties
772 * or the COLOR_PIPELINE property. An atomic commit which attempts to enable
773 * both is rejected.
771 */774 */
772 if (plane->color_pipeline_property)775 has_degamma = dm->adev->dm.dc->caps.color.dpp.dcn_arch &&
773 has_degamma = false;776 dm->adev->dm.dc->ctx->dce_version != DCN_VERSION_4_01;
774 else
775 has_degamma = dm->adev->dm.dc->caps.color.dpp.dcn_arch &&
776 dm->adev->dm.dc->ctx->dce_version != DCN_VERSION_4_01;
777 777
778 drm_crtc_enable_color_mgmt(&acrtc->base, has_degamma ? MAX_COLOR_LUT_ENTRIES : 0,778 drm_crtc_enable_color_mgmt(&acrtc->base, has_degamma ? MAX_COLOR_LUT_ENTRIES : 0,
779 true, MAX_COLOR_LUT_ENTRIES);779 true, MAX_COLOR_LUT_ENTRIES);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c+6−3
@@ -1016,6 +1016,9 @@ enum dc_edid_status dm_helpers_read_local_edid( · 1015 unmodified lines
1016 else1016 else
1017 ddc = &aconnector->i2c->base;1017 ddc = &aconnector->i2c->base;
1018 1018
1019 if (link->dc->hwss.prepare_ddc)
1020 link->dc->hwss.prepare_ddc(link);
1021
1019 /* some dongles read edid incorrectly the first time,1022 /* some dongles read edid incorrectly the first time,
1020 * do check sum and retry to make sure read correct edid.1023 * do check sum and retry to make sure read correct edid.
1021 */1024 */
@@ -1162,9 +1165,9 @@ void dm_helpers_override_panel_settings( · 140 unmodified lines
1162 link->panel_config.dsc.disable_dsc_edp = true;1165 link->panel_config.dsc.disable_dsc_edp = true;
1163 1166
1164 if (dc_get_edp_link_panel_inst(ctx->dc, link, &panel_inst) && panel_inst == 1) {1167 if (dc_get_edp_link_panel_inst(ctx->dc, link, &panel_inst) && panel_inst == 1) {
1165 link->panel_config.psr.disable_psr = true;1168 link->panel_config.psr.disable_psr = true;
1166 link->panel_config.psr.disallow_psrsu = true;;1169 link->panel_config.psr.disallow_psrsu = true;
1167 link->panel_config.psr.disallow_replay = true;1170 link->panel_config.psr.disallow_replay = true;
1168 }1171 }
1169}1172}
1170 1173
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c+10−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: MIT1// SPDX-License-Identifier: MIT
2/*2/*
3 * Copyright 2022 Advanced Micro Devices, Inc.3 * Copyright 2022-2026 Advanced Micro Devices, Inc.
4 *4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),6 * copy of this software and associated documentation files (the "Software"),
@@ -759,6 +759,7 @@ static int amdgpu_dm_plane_get_plane_modifiers(struct amdgpu_device *adev, unsig · 752 unmodified lines
759 case AMDGPU_FAMILY_GC_11_0_0:759 case AMDGPU_FAMILY_GC_11_0_0:
760 case AMDGPU_FAMILY_GC_11_0_1:760 case AMDGPU_FAMILY_GC_11_0_1:
761 case AMDGPU_FAMILY_GC_11_5_0:761 case AMDGPU_FAMILY_GC_11_5_0:
762 case AMDGPU_FAMILY_GC_11_5_4:
762 amdgpu_dm_plane_add_gfx11_modifiers(adev, mods, &size, &capacity);763 amdgpu_dm_plane_add_gfx11_modifiers(adev, mods, &size, &capacity);
763 break;764 break;
764 case AMDGPU_FAMILY_GC_12_0_0:765 case AMDGPU_FAMILY_GC_12_0_0:
@@ -1256,6 +1257,14 @@ static int amdgpu_dm_plane_atomic_check(struct drm_plane *plane, · 491 unmodified lines
1256 if (ret)1257 if (ret)
1257 return ret;1258 return ret;
1258 1259
1260 /* Reject commits that attempt to use both COLOR_PIPELINE and CRTC DEGAMMA_LUT */
1261 if (new_plane_state->color_pipeline && new_crtc_state->degamma_lut) {
1262 drm_dbg_atomic(plane->dev,
1263 "[PLANE:%d:%s] COLOR_PIPELINE and CRTC DEGAMMA_LUT cannot be enabled simultaneously\n",
1264 plane->base.id, plane->name);
1265 return -EINVAL;
1266 }
1267
1259 ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info);1268 ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info);
1260 if (ret)1269 if (ret)
1261 return ret;1270 return ret;
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c+33−13
@@ -780,28 +780,33 @@ static enum bp_result bios_parser_encoder_control( · 779 unmodified lines
780 return bp->cmd_tbl.dig_encoder_control(bp, cntl);780 return bp->cmd_tbl.dig_encoder_control(bp, cntl);
781}781}
782 782
783static enum bp_result bios_parser_external_encoder_control(
784 struct dc_bios *dcb,
785 struct bp_external_encoder_control *cntl)
786{
787 struct bios_parser *bp = BP_FROM_DCB(dcb);
788
789 if (!bp->cmd_tbl.external_encoder_control)
790 return BP_RESULT_UNSUPPORTED;
791
792 return bp->cmd_tbl.external_encoder_control(bp, cntl);
793}
794
783static enum bp_result bios_parser_dac_load_detection(795static enum bp_result bios_parser_dac_load_detection(
784 struct dc_bios *dcb,796 struct dc_bios *dcb,
785 enum engine_id engine_id,797 enum engine_id engine_id,
786 enum dal_device_type device_type,798 struct graphics_object_id ext_enc_id)
787 uint32_t enum_id)
788{799{
789 struct bios_parser *bp = BP_FROM_DCB(dcb);800 struct bios_parser *bp = BP_FROM_DCB(dcb);
790 struct dc_context *ctx = dcb->ctx;801 struct dc_context *ctx = dcb->ctx;
791 struct bp_load_detection_parameters bp_params = {0};802 struct bp_load_detection_parameters bp_params = {0};
792 enum bp_result bp_result;803 struct bp_external_encoder_control ext_cntl = {0};
804 enum bp_result bp_result = BP_RESULT_UNSUPPORTED;
793 uint32_t bios_0_scratch;805 uint32_t bios_0_scratch;
794 uint32_t device_id_mask = 0;806 uint32_t device_id_mask = 0;
795 807
796 bp_params.engine_id = engine_id;808 bp_params.device_id = get_support_mask_for_device_id(
797 bp_params.device_id = get_support_mask_for_device_id(device_type, enum_id);809 DEVICE_TYPE_CRT, engine_id == ENGINE_ID_DACB ? 2 : 1);
798
799 if (engine_id != ENGINE_ID_DACA &&
800 engine_id != ENGINE_ID_DACB)
801 return BP_RESULT_UNSUPPORTED;
802
803 if (!bp->cmd_tbl.dac_load_detection)
804 return BP_RESULT_UNSUPPORTED;
805 810
806 if (bp_params.device_id == ATOM_DEVICE_CRT1_SUPPORT)811 if (bp_params.device_id == ATOM_DEVICE_CRT1_SUPPORT)
807 device_id_mask = ATOM_S0_CRT1_MASK;812 device_id_mask = ATOM_S0_CRT1_MASK;
@@ -815,7 +820,20 @@ static enum bp_result bios_parser_dac_load_detection( · 7 unmodified lines
815 bios_0_scratch &= ~device_id_mask;820 bios_0_scratch &= ~device_id_mask;
816 dm_write_reg(ctx, bp->base.regs->BIOS_SCRATCH_0, bios_0_scratch);821 dm_write_reg(ctx, bp->base.regs->BIOS_SCRATCH_0, bios_0_scratch);
817 822
818 bp_result = bp->cmd_tbl.dac_load_detection(bp, &bp_params);823 if (engine_id == ENGINE_ID_DACA || engine_id == ENGINE_ID_DACB) {
824 if (!bp->cmd_tbl.dac_load_detection)
825 return BP_RESULT_UNSUPPORTED;
826
827 bp_params.engine_id = engine_id;
828 bp_result = bp->cmd_tbl.dac_load_detection(bp, &bp_params);
829 } else if (ext_enc_id.id) {
830 if (!bp->cmd_tbl.external_encoder_control)
831 return BP_RESULT_UNSUPPORTED;
832
833 ext_cntl.action = EXTERNAL_ENCODER_CONTROL_DAC_LOAD_DETECT;
834 ext_cntl.encoder_id = ext_enc_id;
835 bp_result = bp->cmd_tbl.external_encoder_control(bp, &ext_cntl);
836 }
819 837
820 if (bp_result != BP_RESULT_OK)838 if (bp_result != BP_RESULT_OK)
821 return bp_result;839 return bp_result;
@@ -2912,6 +2930,8 @@ static const struct dc_vbios_funcs vbios_funcs = { · 2090 unmodified lines
2912 2930
2913 .encoder_control = bios_parser_encoder_control,2931 .encoder_control = bios_parser_encoder_control,
2914 2932
2933 .external_encoder_control = bios_parser_external_encoder_control,
2934
2915 .dac_load_detection = bios_parser_dac_load_detection,2935 .dac_load_detection = bios_parser_dac_load_detection,
2916 2936
2917 .transmitter_control = bios_parser_transmitter_control,2937 .transmitter_control = bios_parser_transmitter_control,
drivers/gpu/drm/amd/display/dc/bios/command_table.c+37−87
@@ -226,6 +226,28 @@ static enum bp_result encoder_control_dig2_v1( · 225 unmodified lines
226 return result;226 return result;
227}227}
228 228
229static uint8_t dc_color_depth_to_atom(enum dc_color_depth color_depth)
230{
231 switch (color_depth) {
232 case COLOR_DEPTH_UNDEFINED:
233 return PANEL_BPC_UNDEFINE;
234 case COLOR_DEPTH_666:
235 return PANEL_6BIT_PER_COLOR;
236 default:
237 case COLOR_DEPTH_888:
238 return PANEL_8BIT_PER_COLOR;
239 case COLOR_DEPTH_101010:
240 return PANEL_10BIT_PER_COLOR;
241 case COLOR_DEPTH_121212:
242 return PANEL_12BIT_PER_COLOR;
243 case COLOR_DEPTH_141414:
244 dm_error("14-bit color not supported by ATOMBIOS\n");
245 return PANEL_BPC_UNDEFINE;
246 case COLOR_DEPTH_161616:
247 return PANEL_16BIT_PER_COLOR;
248 }
249}
250
229static enum bp_result encoder_control_digx_v3(251static enum bp_result encoder_control_digx_v3(
230 struct bios_parser *bp,252 struct bios_parser *bp,
231 struct bp_encoder_control *cntl)253 struct bp_encoder_control *cntl)
@@ -248,23 +270,7 @@ static enum bp_result encoder_control_digx_v3( · 16 unmodified lines
248 cntl->signal,270 cntl->signal,
249 cntl->enable_dp_audio);271 cntl->enable_dp_audio);
250 params.ucLaneNum = (uint8_t)(cntl->lanes_number);272 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
251 273 params.ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth);
252 switch (cntl->color_depth) {
253 case COLOR_DEPTH_888:
254 params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
255 break;
256 case COLOR_DEPTH_101010:
257 params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
258 break;
259 case COLOR_DEPTH_121212:
260 params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
261 break;
262 case COLOR_DEPTH_161616:
263 params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
264 break;
265 default:
266 break;
267 }
268 274
269 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))275 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
270 result = BP_RESULT_OK;276 result = BP_RESULT_OK;
@@ -294,23 +300,7 @@ static enum bp_result encoder_control_digx_v4( · 23 unmodified lines
294 cntl->signal,300 cntl->signal,
295 cntl->enable_dp_audio));301 cntl->enable_dp_audio));
296 params.ucLaneNum = (uint8_t)(cntl->lanes_number);302 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
297 303 params.ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth);
298 switch (cntl->color_depth) {
299 case COLOR_DEPTH_888:
300 params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
301 break;
302 case COLOR_DEPTH_101010:
303 params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
304 break;
305 case COLOR_DEPTH_121212:
306 params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
307 break;
308 case COLOR_DEPTH_161616:
309 params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
310 break;
311 default:
312 break;
313 }
314 304
315 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))305 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
316 result = BP_RESULT_OK;306 result = BP_RESULT_OK;
@@ -334,23 +324,7 @@ static enum bp_result encoder_control_digx_v5( · 17 unmodified lines
334 cntl->signal,324 cntl->signal,
335 cntl->enable_dp_audio));325 cntl->enable_dp_audio));
336 params.ucLaneNum = (uint8_t)(cntl->lanes_number);326 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
337 327 params.ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth);
338 switch (cntl->color_depth) {
339 case COLOR_DEPTH_888:
340 params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
341 break;
342 case COLOR_DEPTH_101010:
343 params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
344 break;
345 case COLOR_DEPTH_121212:
346 params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
347 break;
348 case COLOR_DEPTH_161616:
349 params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
350 break;
351 default:
352 break;
353 }
354 328
355 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)329 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
356 switch (cntl->color_depth) {330 switch (cntl->color_depth) {
@@ -1797,30 +1771,7 @@ static enum bp_result select_crtc_source_v3( · 1440 unmodified lines
1797 &params.ucEncodeMode))1771 &params.ucEncodeMode))
1798 return BP_RESULT_BADINPUT;1772 return BP_RESULT_BADINPUT;
1799 1773
1800 switch (bp_params->color_depth) {1774 params.ucDstBpc = dc_color_depth_to_atom(bp_params->color_depth);
1801 case COLOR_DEPTH_UNDEFINED:
1802 params.ucDstBpc = PANEL_BPC_UNDEFINE;
1803 break;
1804 case COLOR_DEPTH_666:
1805 params.ucDstBpc = PANEL_6BIT_PER_COLOR;
1806 break;
1807 default:
1808 case COLOR_DEPTH_888:
1809 params.ucDstBpc = PANEL_8BIT_PER_COLOR;
1810 break;
1811 case COLOR_DEPTH_101010:
1812 params.ucDstBpc = PANEL_10BIT_PER_COLOR;
1813 break;
1814 case COLOR_DEPTH_121212:
1815 params.ucDstBpc = PANEL_12BIT_PER_COLOR;
1816 break;
1817 case COLOR_DEPTH_141414:
1818 dm_error("14-bit color not supported by SelectCRTC_Source v3\n");
1819 break;
1820 case COLOR_DEPTH_161616:
1821 params.ucDstBpc = PANEL_16BIT_PER_COLOR;
1822 break;
1823 }
1824 1775
1825 if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))1776 if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
1826 result = BP_RESULT_OK;1777 result = BP_RESULT_OK;
@@ -2569,6 +2520,7 @@ static enum bp_result external_encoder_control_v3( · 742 unmodified lines
2569 cpu_to_le16((uint16_t)cntl->connector_obj_id.id);2520 cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
2570 break;2521 break;
2571 case EXTERNAL_ENCODER_CONTROL_SETUP:2522 case EXTERNAL_ENCODER_CONTROL_SETUP:
2523 case EXTERNAL_ENCODER_CONTROL_ENABLE:
2572 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in2524 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
2573 * 10KHz2525 * 10KHz
2574 * output display device pixel clock frequency in unit of 10KHz.2526 * output display device pixel clock frequency in unit of 10KHz.
@@ -2585,26 +2537,24 @@ static enum bp_result external_encoder_control_v3( · 10 unmodified lines
2585 if (is_input_signal_dp) {2537 if (is_input_signal_dp) {
2586 /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,2538 /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
2587 * only valid in encoder setup with DP mode. */2539 * only valid in encoder setup with DP mode. */
2588 if (LINK_RATE_HIGH == cntl->link_rate)2540 if (cntl->link_rate == LINK_RATE_LOW)
2589 cntl_params->ucConfig |= 1;2541 cntl_params->ucConfig |=
2542 EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_1_62GHZ;
2543 else if (cntl->link_rate == LINK_RATE_HIGH)
2544 cntl_params->ucConfig |=
2545 EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
2546 else
2547 dm_error("Link rate not supported by external encoder");
2548
2590 /* output color depth Indicate encoder data bpc format2549 /* output color depth Indicate encoder data bpc format
2591 * in DP mode, only valid in encoder setup in DP mode.2550 * in DP mode, only valid in encoder setup in DP mode.
2592 */2551 */
2593 cntl_params->ucBitPerColor =2552 cntl_params->ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth);
2594 (uint8_t)(cntl->color_depth);
2595 }2553 }
2596 /* Indicate how many lanes used by external encoder, only valid2554 /* Indicate how many lanes used by external encoder, only valid
2597 * in encoder setup and enableoutput. */2555 * in encoder setup and enableoutput. */
2598 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);2556 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
2599 break;2557 break;
2600 case EXTERNAL_ENCODER_CONTROL_ENABLE:
2601 cntl_params->usPixelClock =
2602 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2603 cntl_params->ucEncoderMode =
2604 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2605 cntl->signal, false);
2606 cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
2607 break;
2608 default:2558 default:
2609 break;2559 break;
2610 }2560 }
drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c+1−0
@@ -84,6 +84,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2( · 83 unmodified lines
84 case DCN_VERSION_3_51:84 case DCN_VERSION_3_51:
85 case DCN_VERSION_3_6:85 case DCN_VERSION_3_6:
86 case DCN_VERSION_4_01:86 case DCN_VERSION_4_01:
87 case DCN_VERSION_4_2:
87 *h = dal_cmd_tbl_helper_dce112_get_table2();88 *h = dal_cmd_tbl_helper_dce112_get_table2();
88 return true;89 return true;
89 90
drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile+10−13
@@ -1,5 +1,5 @@
1#1#
2# Copyright 2017 Advanced Micro Devices, Inc.2# Copyright 2017-2026 Advanced Micro Devices, Inc.
3#3#
4# Permission is hereby granted, free of charge, to any person obtaining a4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),5# copy of this software and associated documentation files (the "Software"),
@@ -29,18 +29,6 @@ AMD_DAL_CLK_MGR = $(addprefix $(AMDDALPATH)/dc/clk_mgr/,$(CLK_MGR)) · 23 unmodified lines
29 29
30AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR)30AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR)
31 31
32
33ifdef CONFIG_DRM_AMD_DC_SI
34###############################################################################
35# DCE 60
36###############################################################################
37CLK_MGR_DCE60 = dce60_clk_mgr.o
38
39AMD_DAL_CLK_MGR_DCE60 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dce60/,$(CLK_MGR_DCE60))
40
41AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCE60)
42endif
43
44###############################################################################32###############################################################################
45# DCE 100 and DCE8x33# DCE 100 and DCE8x
46###############################################################################34###############################################################################
@@ -188,4 +176,13 @@ CLK_MGR_DCN401 = dcn401_clk_mgr.o dcn401_clk_mgr_smu_msg.o · 141 unmodified lines
188AMD_DAL_CLK_MGR_DCN401 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn401/,$(CLK_MGR_DCN401))176AMD_DAL_CLK_MGR_DCN401 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn401/,$(CLK_MGR_DCN401))
189 177
190AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN401)178AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN401)
179
180###############################################################################
181# DCN42
182###############################################################################
183CLK_MGR_DCN42 = dcn42_smu.o dcn42_clk_mgr.o
184
185AMD_DAL_CLK_MGR_DCN42 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn42/,$(CLK_MGR_DCN42))
186
187AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN42)
191endif188endif
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c+1−13
@@ -34,7 +34,6 @@ · 33 unmodified lines
34#include "dce110/dce110_clk_mgr.h"34#include "dce110/dce110_clk_mgr.h"
35#include "dce112/dce112_clk_mgr.h"35#include "dce112/dce112_clk_mgr.h"
36#include "dce120/dce120_clk_mgr.h"36#include "dce120/dce120_clk_mgr.h"
37#include "dce60/dce60_clk_mgr.h"
38#include "dcn10/rv1_clk_mgr.h"37#include "dcn10/rv1_clk_mgr.h"
39#include "dcn10/rv2_clk_mgr.h"38#include "dcn10/rv2_clk_mgr.h"
40#include "dcn20/dcn20_clk_mgr.h"39#include "dcn20/dcn20_clk_mgr.h"
@@ -149,18 +148,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p · 108 unmodified lines
149 struct hw_asic_id asic_id = ctx->asic_id;148 struct hw_asic_id asic_id = ctx->asic_id;
150 149
151 switch (asic_id.chip_family) {150 switch (asic_id.chip_family) {
152#if defined(CONFIG_DRM_AMD_DC_SI)151 case FAMILY_SI:
153 case FAMILY_SI: {
154 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
155
156 if (clk_mgr == NULL) {
157 BREAK_TO_DEBUGGER();
158 return NULL;
159 }
160 dce60_clk_mgr_construct(ctx, clk_mgr);
161 return &clk_mgr->base;
162 }
163#endif
164 case FAMILY_CI:152 case FAMILY_CI:
165 case FAMILY_KV: {153 case FAMILY_KV: {
166 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);154 struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c+51−13
@@ -62,6 +62,18 @@ static const struct clk_mgr_mask disp_clk_mask = { · 61 unmodified lines
62 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)62 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
63};63};
64 64
65/* Max clock values for each state indexed by "enum clocks_state": */
66static const struct state_dependent_clocks dce60_max_clks_by_state[] = {
67/* ClocksStateInvalid - should not be used */
68{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
69/* ClocksStateUltraLow - not expected to be used for DCE 6.0 */
70{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
71/* ClocksStateLow */
72{ .display_clk_khz = 352000, .pixel_clk_khz = 330000},
73/* ClocksStateNominal */
74{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 },
75/* ClocksStatePerformance */
76{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 } };
65 77
66/* Max clock values for each state indexed by "enum clocks_state": */78/* Max clock values for each state indexed by "enum clocks_state": */
67static const struct state_dependent_clocks dce80_max_clks_by_state[] = {79static const struct state_dependent_clocks dce80_max_clks_by_state[] = {
@@ -126,6 +138,20 @@ int dce_adjust_dp_ref_freq_for_ss(struct clk_mgr_internal *clk_mgr_dce, int dp_r · 58 unmodified lines
126 return dp_ref_clk_khz;138 return dp_ref_clk_khz;
127}139}
128 140
141static int dce60_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
142{
143 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
144 struct dc_context *ctx = clk_mgr_base->ctx;
145 int dp_ref_clk_khz = 0;
146
147 if (ASIC_REV_IS_TAHITI_P(ctx->asic_id.hw_internal_rev))
148 dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency;
149 else
150 dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz;
151
152 return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz);
153}
154
129int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)155int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
130{156{
131 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);157 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
@@ -134,6 +160,9 @@ int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base) · 2 unmodified lines
134 int dp_ref_clk_khz;160 int dp_ref_clk_khz;
135 int target_div;161 int target_div;
136 162
163 if (clk_mgr_base->ctx->dce_version <= DCE_VERSION_6_4)
164 return dce60_get_dp_ref_freq_khz(clk_mgr_base);
165
137 /* ASSERT DP Reference Clock source is from DFS*/166 /* ASSERT DP Reference Clock source is from DFS*/
138 REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel);167 REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel);
139 ASSERT(dprefclk_src_sel == 0);168 ASSERT(dprefclk_src_sel == 0);
@@ -441,27 +470,37 @@ void dce_clk_mgr_construct( · 301 unmodified lines
441 struct clk_mgr *base = &clk_mgr->base;470 struct clk_mgr *base = &clk_mgr->base;
442 struct dm_pp_static_clock_info static_clk_info = {0};471 struct dm_pp_static_clock_info static_clk_info = {0};
443 472
444 memcpy(clk_mgr->max_clks_by_state,473 if (ctx->dce_version <= DCE_VERSION_6_4)
445 dce80_max_clks_by_state,474 memcpy(clk_mgr->max_clks_by_state,
446 sizeof(dce80_max_clks_by_state));475 dce60_max_clks_by_state,
476 sizeof(dce60_max_clks_by_state));
477 else
478 memcpy(clk_mgr->max_clks_by_state,
479 dce80_max_clks_by_state,
480 sizeof(dce80_max_clks_by_state));
481
447 482
448 base->ctx = ctx;483 base->ctx = ctx;
449 base->funcs = &dce_funcs;484 base->funcs = &dce_funcs;
450 485
451 clk_mgr->regs = &disp_clk_regs;486 if (ctx->dce_version >= DCE_VERSION_8_0) {
452 clk_mgr->clk_mgr_shift = &disp_clk_shift;487 clk_mgr->regs = &disp_clk_regs;
453 clk_mgr->clk_mgr_mask = &disp_clk_mask;488 clk_mgr->clk_mgr_shift = &disp_clk_shift;
454 clk_mgr->dfs_bypass_disp_clk = 0;489 clk_mgr->clk_mgr_mask = &disp_clk_mask;
490 }
455 491
492 clk_mgr->dfs_bypass_disp_clk = 0;
456 clk_mgr->dprefclk_ss_percentage = 0;493 clk_mgr->dprefclk_ss_percentage = 0;
457 clk_mgr->dprefclk_ss_divider = 1000;494 clk_mgr->dprefclk_ss_divider = 1000;
458 clk_mgr->ss_on_dprefclk = false;495 clk_mgr->ss_on_dprefclk = false;
459 496
460 if (dm_pp_get_static_clocks(ctx, &static_clk_info))497 if (ctx->dce_version >= DCE_VERSION_8_0) {
461 clk_mgr->max_clks_state = static_clk_info.max_clocks_state;498 if (dm_pp_get_static_clocks(ctx, &static_clk_info))
462 else499 clk_mgr->max_clks_state = static_clk_info.max_clocks_state;
463 clk_mgr->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL;500 else
464 clk_mgr->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID;501 clk_mgr->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL;
502 clk_mgr->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID;
503 }
465 504
466 base->clks.max_supported_dispclk_khz =505 base->clks.max_supported_dispclk_khz =
467 clk_mgr->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz;506 clk_mgr->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz;
@@ -469,4 +508,3 @@ void dce_clk_mgr_construct( · 1 unmodified line
469 dce_clock_read_integrated_info(clk_mgr);508 dce_clock_read_integrated_info(clk_mgr);
470 dce_clock_read_ss_info(clk_mgr);509 dce_clock_read_ss_info(clk_mgr);
471}510}
472
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c+0−166
@@ -1,166 +0,0 @@
1/*
2 * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com>
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: AMD
23 *
24 */
25
26
27#include "dccg.h"
28#include "clk_mgr_internal.h"
29#include "dce100/dce_clk_mgr.h"
30#include "dce110/dce110_clk_mgr.h"
31#include "dce60_clk_mgr.h"
32#include "reg_helper.h"
33#include "dmcu.h"
34#include "core_types.h"
35#include "dal_asic_id.h"
36
37/*
38 * Currently the register shifts and masks in this file are used for dce60
39 * which has no DPREFCLK_CNTL register
40 * TODO: remove this when DENTIST_DISPCLK_CNTL
41 * is moved to dccg, where it belongs
42 */
43#include "dce/dce_6_0_d.h"
44#include "dce/dce_6_0_sh_mask.h"
45
46#define REG(reg) \
47 (clk_mgr->regs->reg)
48
49#undef FN
50#define FN(reg_name, field_name) \
51 clk_mgr->clk_mgr_shift->field_name, clk_mgr->clk_mgr_mask->field_name
52
53/* set register offset */
54#define SR(reg_name)\
55 .reg_name = mm ## reg_name
56
57static const struct clk_mgr_registers disp_clk_regs = {
58 CLK_COMMON_REG_LIST_DCE60_BASE()
59};
60
61static const struct clk_mgr_shift disp_clk_shift = {
62 CLK_COMMON_MASK_SH_LIST_DCE60_COMMON_BASE(__SHIFT)
63};
64
65static const struct clk_mgr_mask disp_clk_mask = {
66 CLK_COMMON_MASK_SH_LIST_DCE60_COMMON_BASE(_MASK)
67};
68
69
70/* Max clock values for each state indexed by "enum clocks_state": */
71static const struct state_dependent_clocks dce60_max_clks_by_state[] = {
72/* ClocksStateInvalid - should not be used */
73{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
74/* ClocksStateUltraLow - not expected to be used for DCE 6.0 */
75{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
76/* ClocksStateLow */
77{ .display_clk_khz = 352000, .pixel_clk_khz = 330000},
78/* ClocksStateNominal */
79{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 },
80/* ClocksStatePerformance */
81{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 } };
82
83static int dce60_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
84{
85 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
86 struct dc_context *ctx = clk_mgr_base->ctx;
87 int dp_ref_clk_khz = 0;
88
89 if (ASIC_REV_IS_TAHITI_P(ctx->asic_id.hw_internal_rev))
90 dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency;
91 else
92 dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz;
93
94 return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz);
95}
96
97static void dce60_pplib_apply_display_requirements(
98 struct dc *dc,
99 struct dc_state *context)
100{
101 struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
102
103 dce110_fill_display_configs(context, pp_display_cfg);
104
105 if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0)
106 dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
107}
108
109static void dce60_update_clocks(struct clk_mgr *clk_mgr_base,
110 struct dc_state *context,
111 bool safe_to_lower)
112{
113 struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base);
114 struct dm_pp_power_level_change_request level_change_req;
115 const int max_disp_clk =
116 clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz;
117 int patched_disp_clk = MIN(max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz);
118
119 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context);
120 /* get max clock state from PPLIB */
121 if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower)
122 || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) {
123 if (dm_pp_apply_power_level_change_request(clk_mgr_base->ctx, &level_change_req))
124 clk_mgr_dce->cur_min_clks_state = level_change_req.power_level;
125 }
126
127 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr_base->clks.dispclk_khz)) {
128 patched_disp_clk = dce_set_clock(clk_mgr_base, patched_disp_clk);
129 clk_mgr_base->clks.dispclk_khz = patched_disp_clk;
130 }
131 dce60_pplib_apply_display_requirements(clk_mgr_base->ctx->dc, context);
132}
133
134
135
136
137
138
139
140
141static struct clk_mgr_funcs dce60_funcs = {
142 .get_dp_ref_clk_frequency = dce60_get_dp_ref_freq_khz,
143 .update_clocks = dce60_update_clocks
144};
145
146void dce60_clk_mgr_construct(
147 struct dc_context *ctx,
148 struct clk_mgr_internal *clk_mgr)
149{
150 struct clk_mgr *base = &clk_mgr->base;
151
152 dce_clk_mgr_construct(ctx, clk_mgr);
153
154 memcpy(clk_mgr->max_clks_by_state,
155 dce60_max_clks_by_state,
156 sizeof(dce60_max_clks_by_state));
157
158 clk_mgr->regs = &disp_clk_regs;
159 clk_mgr->clk_mgr_shift = &disp_clk_shift;
160 clk_mgr->clk_mgr_mask = &disp_clk_mask;
161 clk_mgr->base.funcs = &dce60_funcs;
162
163 base->clks.max_supported_dispclk_khz =
164 clk_mgr->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz;
165}
166
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c+7−7
@@ -204,7 +204,7 @@ int dcn35_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispcl · 203 unmodified lines
204 khz_to_mhz_ceil(requested_dispclk_khz));204 khz_to_mhz_ceil(requested_dispclk_khz));
205 205
206 smu_print("requested_dispclk_khz = %d, actual_dispclk_set_mhz: %d\n", requested_dispclk_khz, actual_dispclk_set_mhz);206 smu_print("requested_dispclk_khz = %d, actual_dispclk_set_mhz: %d\n", requested_dispclk_khz, actual_dispclk_set_mhz);
207 return actual_dispclk_set_mhz * 1000;207 return (int)((long long)actual_dispclk_set_mhz * 1000);
208}208}
209 209
210int dcn35_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr)210int dcn35_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr)
@@ -221,7 +221,7 @@ int dcn35_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr) · 10 unmodified lines
221 221
222 /* TODO: add code for programing DP DTO, currently this is down by command table */222 /* TODO: add code for programing DP DTO, currently this is down by command table */
223 223
224 return actual_dprefclk_set_mhz * 1000;224 return (int)((long long)actual_dprefclk_set_mhz * 1000);
225}225}
226 226
227int dcn35_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz)227int dcn35_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz)
@@ -238,7 +238,7 @@ int dcn35_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requeste · 10 unmodified lines
238 238
239 smu_print("requested_dcfclk_khz = %d, actual_dcfclk_set_mhz: %d\n", requested_dcfclk_khz, actual_dcfclk_set_mhz);239 smu_print("requested_dcfclk_khz = %d, actual_dcfclk_set_mhz: %d\n", requested_dcfclk_khz, actual_dcfclk_set_mhz);
240 240
241 return actual_dcfclk_set_mhz * 1000;241 return (int)((long long)actual_dcfclk_set_mhz * 1000);
242}242}
243 243
244int dcn35_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz)244int dcn35_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz)
@@ -255,7 +255,7 @@ int dcn35_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int re · 10 unmodified lines
255 255
256 smu_print("requested_min_ds_dcfclk_khz = %d, actual_min_ds_dcfclk_mhz: %d\n", requested_min_ds_dcfclk_khz, actual_min_ds_dcfclk_mhz);256 smu_print("requested_min_ds_dcfclk_khz = %d, actual_min_ds_dcfclk_mhz: %d\n", requested_min_ds_dcfclk_khz, actual_min_ds_dcfclk_mhz);
257 257
258 return actual_min_ds_dcfclk_mhz * 1000;258 return (int)((long long)actual_min_ds_dcfclk_mhz * 1000);
259}259}
260 260
261int dcn35_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz)261int dcn35_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz)
@@ -272,7 +272,7 @@ int dcn35_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz · 10 unmodified lines
272 272
273 smu_print("requested_dpp_khz = %d, actual_dppclk_set_mhz: %d\n", requested_dpp_khz, actual_dppclk_set_mhz);273 smu_print("requested_dpp_khz = %d, actual_dppclk_set_mhz: %d\n", requested_dpp_khz, actual_dppclk_set_mhz);
274 274
275 return actual_dppclk_set_mhz * 1000;275 return (int)((long long)actual_dppclk_set_mhz * 1000);
276}276}
277 277
278void dcn35_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info)278void dcn35_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info)
@@ -424,7 +424,7 @@ int dcn35_smu_get_dprefclk(struct clk_mgr_internal *clk_mgr) · 145 unmodified lines
424 0);424 0);
425 425
426 smu_print("%s: SMU DPREF clk = %d mhz\n", __func__, dprefclk);426 smu_print("%s: SMU DPREF clk = %d mhz\n", __func__, dprefclk);
427 return dprefclk * 1000;427 return (int)((long long)dprefclk * 1000);
428}428}
429 429
430int dcn35_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr)430int dcn35_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr)
@@ -439,7 +439,7 @@ int dcn35_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr) · 8 unmodified lines
439 0);439 0);
440 440
441 smu_print("%s: get_dtbclk = %dmhz\n", __func__, dtbclk);441 smu_print("%s: get_dtbclk = %dmhz\n", __func__, dtbclk);
442 return dtbclk * 1000;442 return (int)((long long)dtbclk * 1000);
443}443}
444/* Arg = 1: Turn DTB on; 0: Turn DTB CLK OFF. when it is on, it is 600MHZ */444/* Arg = 1: Turn DTB on; 0: Turn DTB CLK OFF. when it is on, it is 600MHZ */
445void dcn35_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable)445void dcn35_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c+1152−0
@@ -0,0 +1,1152 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "dcn42_clk_mgr.h"
6
7#include "dccg.h"
8#include "clk_mgr_internal.h"
9
10// For dce12_get_dp_ref_freq_khz
11#include "dce100/dce_clk_mgr.h"
12
13// For dcn20_update_clocks_update_dpp_dto
14#include "dcn20/dcn20_clk_mgr.h"
15
16
17
18
19#include "reg_helper.h"
20#include "core_types.h"
21#include "dcn42_smu.h"
22#include "dm_helpers.h"
23
24/* TODO: remove this include once we ported over remaining clk mgr functions*/
25#include "dcn30/dcn30_clk_mgr.h"
26#include "dcn31/dcn31_clk_mgr.h"
27
28#include "dcn35/dcn35_clk_mgr.h"
29
30#include "dc_dmub_srv.h"
31#include "link_service.h"
32#include "logger_types.h"
33
34
35#undef DC_LOGGER
36#define DC_LOGGER \
37 clk_mgr->base.base.ctx->logger
38
39
40#define DCN_BASE__INST0_SEG1 0x000000C0
41
42#define regCLK8_CLK2_BYPASS_CNTL 0x4c2a
43#define regCLK8_CLK2_BYPASS_CNTL_BASE_IDX 0
44#define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL__SHIFT 0x0
45#define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV__SHIFT 0x10
46#define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK 0x00000007L
47#define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV_MASK 0x000F0000L
48
49#define regDENTIST_DISPCLK_CNTL 0x0064
50#define regDENTIST_DISPCLK_CNTL_BASE_IDX 1
51
52// DENTIST_DISPCLK_CNTL
53#define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_WDIVIDER__SHIFT 0x0
54#define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_RDIVIDER__SHIFT 0x8
55#define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_CHG_DONE__SHIFT 0x13
56#define DENTIST_DISPCLK_CNTL__DENTIST_DPPCLK_CHG_DONE__SHIFT 0x14
57#define DENTIST_DISPCLK_CNTL__DENTIST_DPPCLK_WDIVIDER__SHIFT 0x18
58#define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_WDIVIDER_MASK 0x0000007FL
59#define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_RDIVIDER_MASK 0x00007F00L
60#define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_CHG_DONE_MASK 0x00080000L
61#define DENTIST_DISPCLK_CNTL__DENTIST_DPPCLK_CHG_DONE_MASK 0x00100000L
62#define DENTIST_DISPCLK_CNTL__DENTIST_DPPCLK_WDIVIDER_MASK 0x7F000000L
63#define mmDENTIST_DISPCLK_CNTL 0x0124
64#define mmCLK8_CLK_TICK_CNT_CONFIG_REG 0x1B851
65#define mmCLK8_CLK0_CURRENT_CNT 0x1B853
66#define mmCLK8_CLK1_CURRENT_CNT 0x1B854
67#define mmCLK8_CLK2_CURRENT_CNT 0x1B855
68#define mmCLK8_CLK3_CURRENT_CNT 0x1B856
69#define mmCLK8_CLK4_CURRENT_CNT 0x1B857
70
71
72#define mmCLK8_CLK0_BYPASS_CNTL 0x1B81A
73#define mmCLK8_CLK1_BYPASS_CNTL 0x1B822
74#define mmCLK8_CLK2_BYPASS_CNTL 0x1B82A
75#define mmCLK8_CLK3_BYPASS_CNTL 0x1B832
76#define mmCLK8_CLK4_BYPASS_CNTL 0x1B83A
77
78
79#define mmCLK8_CLK0_DS_CNTL 0x1B814
80#define mmCLK8_CLK1_DS_CNTL 0x1B81C
81#define mmCLK8_CLK2_DS_CNTL 0x1B824
82#define mmCLK8_CLK3_DS_CNTL 0x1B82C
83#define mmCLK8_CLK4_DS_CNTL 0x1B834
84
85
86
87
88#undef FN
89#define FN(reg_name, field_name) \
90 clk_mgr->clk_mgr_shift->field_name, clk_mgr->clk_mgr_mask->field_name
91
92#define REG(reg) \
93 (clk_mgr->regs->reg)
94
95#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
96
97#define BASE(seg) BASE_INNER(seg)
98
99#define SR(reg_name)\
100 .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
101 reg ## reg_name
102
103#define CLK_SR_DCN42(reg_name)\
104 .reg_name = mm ## reg_name
105
106static const struct clk_mgr_registers clk_mgr_regs_dcn42 = {
107 CLK_REG_LIST_DCN42()
108};
109
110static const struct clk_mgr_shift clk_mgr_shift_dcn42 = {
111 CLK_COMMON_MASK_SH_LIST_DCN42(__SHIFT)
112};
113
114static const struct clk_mgr_mask clk_mgr_mask_dcn42 = {
115 CLK_COMMON_MASK_SH_LIST_DCN42(_MASK)
116};
117
118
119
120#define TO_CLK_MGR_DCN42(clk_mgr_int)\
121 container_of(clk_mgr_int, struct clk_mgr_dcn42, base)
122
123int dcn42_get_active_display_cnt_wa(
124 struct dc *dc,
125 struct dc_state *context,
126 int *all_active_disps)
127{
128 int i, display_count = 0;
129 bool tmds_present = false;
130
131 for (i = 0; i < context->stream_count; i++) {
132 const struct dc_stream_state *stream = context->streams[i];
133
134 if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
135 stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
136 stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
137 tmds_present = true;
138 }
139
140 for (i = 0; i < dc->link_count; i++) {
141 const struct dc_link *link = dc->links[i];
142
143 /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */
144 if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
145 link->link_enc->funcs->is_dig_enabled(link->link_enc))
146 display_count++;
147 }
148 if (all_active_disps != NULL)
149 *all_active_disps = display_count;
150 /* WA for hang on HDMI after display off back on*/
151 if (display_count == 0 && tmds_present)
152 display_count = 1;
153
154 return display_count;
155}
156
157void dcn42_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr,
158 struct dc_state *context,
159 int ref_dtbclk_khz)
160{
161 /* DCN42 does not implement set_dtbclk_dto function, so this is a no-op */
162}
163
164void dcn42_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
165 struct dc_state *context, bool safe_to_lower)
166{
167 int i;
168 bool dppclk_active[MAX_PIPES] = {0};
169
170
171 clk_mgr->dccg->ref_dppclk = clk_mgr->base.clks.dppclk_khz;
172 for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
173 int dpp_inst = 0, dppclk_khz, prev_dppclk_khz;
174
175 dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
176
177 if (context->res_ctx.pipe_ctx[i].plane_res.dpp)
178 dpp_inst = context->res_ctx.pipe_ctx[i].plane_res.dpp->inst;
179 else if (!context->res_ctx.pipe_ctx[i].plane_res.dpp && dppclk_khz == 0) {
180 /* dpp == NULL && dppclk_khz == 0 is valid because of pipe harvesting.
181 * In this case just continue in loop
182 */
183 continue;
184 } else if (!context->res_ctx.pipe_ctx[i].plane_res.dpp && dppclk_khz > 0) {
185 /* The software state is not valid if dpp resource is NULL and
186 * dppclk_khz > 0.
187 */
188 ASSERT(false);
189 continue;
190 }
191
192 prev_dppclk_khz = clk_mgr->dccg->pipe_dppclk_khz[i];
193
194 if (safe_to_lower || prev_dppclk_khz < dppclk_khz)
195 clk_mgr->dccg->funcs->update_dpp_dto(
196 clk_mgr->dccg, dpp_inst, dppclk_khz);
197 dppclk_active[dpp_inst] = true;
198 }
199 if (safe_to_lower)
200 for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
201 struct dpp *old_dpp = clk_mgr->base.ctx->dc->current_state->res_ctx.pipe_ctx[i].plane_res.dpp;
202
203 if (old_dpp && !dppclk_active[old_dpp->inst])
204 clk_mgr->dccg->funcs->update_dpp_dto(clk_mgr->dccg, old_dpp->inst, 0);
205 }
206}
207
208void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
209 struct dc_state *context,
210 bool safe_to_lower)
211{
212 union dmub_rb_cmd cmd;
213 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
214 struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
215 struct dc *dc = clk_mgr_base->ctx->dc;
216 int display_count = 0;
217 bool update_dppclk = false;
218 bool update_dispclk = false;
219 bool dpp_clock_lowered = false;
220 int all_active_disps = 0;
221
222 if (dc->work_arounds.skip_clock_update)
223 return;
224
225 display_count = dcn42_get_active_display_cnt_wa(dc, context, &all_active_disps);
226
227 /*dml21 issue*/
228 ASSERT(new_clocks->dtbclk_en && new_clocks->ref_dtbclk_khz > 590000); //remove this section if assert is hit
229 if (new_clocks->dtbclk_en && new_clocks->ref_dtbclk_khz < 590000)
230 new_clocks->ref_dtbclk_khz = 600000;
231
232 /*
233 * if it is safe to lower, but we are already in the lower state, we don't have to do anything
234 * also if safe to lower is false, we just go in the higher state
235 */
236 if (safe_to_lower) {
237 if (new_clocks->zstate_support != DCN_ZSTATE_SUPPORT_DISALLOW &&
238 new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) {
239 dcn42_smu_set_zstate_support(clk_mgr, new_clocks->zstate_support);
240 clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
241 }
242
243 if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) {
244 if (clk_mgr->base.ctx->dc->config.allow_0_dtb_clk)
245 dcn42_smu_set_dtbclk(clk_mgr, false);
246 clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
247 }
248 /* check that we're not already in lower */
249 if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
250 /* if we can go lower, go lower */
251 if (display_count == 0)
252 clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
253 }
254 } else {
255 if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_DISALLOW &&
256 new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) {
257 dcn42_smu_set_zstate_support(clk_mgr, DCN_ZSTATE_SUPPORT_DISALLOW);
258 clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
259 }
260 if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) {
261 int actual_dtbclk = 0;
262
263 dcn42_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz);
264 dcn42_smu_set_dtbclk(clk_mgr, true);
265 if (clk_mgr_base->boot_snapshot.timer_threhold)
266 actual_dtbclk = REG_READ(CLK8_CLK4_CURRENT_CNT) / (clk_mgr_base->boot_snapshot.timer_threhold / 48000);
267
268
269 if (actual_dtbclk > 590000) {
270 clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz;
271 clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
272 }
273 }
274
275 /* check that we're not already in D0 */
276 if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) {
277 union display_idle_optimization_u idle_info = { 0 };
278
279 dcn42_smu_set_display_idle_optimization(clk_mgr, idle_info.data);
280 /* update power state */
281 clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_MISSION_MODE;
282 }
283 }
284 if (dc->debug.force_min_dcfclk_mhz > 0)
285 new_clocks->dcfclk_khz = (new_clocks->dcfclk_khz > (dc->debug.force_min_dcfclk_mhz * 1000)) ?
286 new_clocks->dcfclk_khz : (dc->debug.force_min_dcfclk_mhz * 1000);
287
288 if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz)) {
289 clk_mgr_base->clks.dcfclk_khz = new_clocks->dcfclk_khz;
290 clk_mgr_base->clks.fclk_khz = new_clocks->fclk_khz;
291 clk_mgr_base->clks.dramclk_khz = new_clocks->dramclk_khz;
292 dcn42_smu_set_hard_min_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_khz);
293 }
294
295 if (should_set_clock(safe_to_lower,
296 new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) {
297 clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz;
298 dcn42_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz);
299 }
300
301 // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow.
302
303 if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) {
304 if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz)
305 dpp_clock_lowered = true;
306 clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz;
307 update_dppclk = true;
308 }
309
310 if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) &&
311 (new_clocks->dispclk_khz > 0 || (safe_to_lower && display_count == 0))) {
312 int requested_dispclk_khz = new_clocks->dispclk_khz;
313
314 dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
315
316 /* Clamp the requested clock to PMFW based on their limit. */
317 if (dc->debug.min_disp_clk_khz > 0 && requested_dispclk_khz < dc->debug.min_disp_clk_khz)
318 requested_dispclk_khz = dc->debug.min_disp_clk_khz;
319
320 dcn42_smu_set_dispclk(clk_mgr, requested_dispclk_khz);
321 clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
322 dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false);
323
324 update_dispclk = true;
325 }
326
327 /* clock limits are received with MHz precision, divide by 1000 to prevent setting clocks at every call */
328 if (!dc->debug.disable_dtb_ref_clk_switch &&
329 should_set_clock(safe_to_lower, new_clocks->ref_dtbclk_khz / 1000,
330 clk_mgr_base->clks.ref_dtbclk_khz / 1000)) {
331 dcn42_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz);
332 clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz;
333 }
334
335 if (dpp_clock_lowered) {
336 // increase per DPP DTO before lowering global dppclk
337 dcn42_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
338 dcn42_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
339 } else {
340 // increase global DPPCLK before lowering per DPP DTO
341 if (update_dppclk || update_dispclk)
342 dcn42_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
343 dcn42_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
344 }
345 // notify DMCUB of latest clocks
346 memset(&cmd, 0, sizeof(cmd));
347 cmd.notify_clocks.header.type = DMUB_CMD__CLK_MGR;
348 cmd.notify_clocks.header.sub_type = DMUB_CMD__CLK_MGR_NOTIFY_CLOCKS;
349 cmd.notify_clocks.clocks.dcfclk_khz = clk_mgr_base->clks.dcfclk_khz;
350 cmd.notify_clocks.clocks.dcfclk_deep_sleep_khz =
351 clk_mgr_base->clks.dcfclk_deep_sleep_khz;
352 cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
353 cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
354
355 dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
356}
357
358
359void dcn42_enable_pme_wa(struct clk_mgr *clk_mgr_base)
360{
361 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
362
363 dcn42_smu_enable_pme_wa(clk_mgr);
364}
365
366
367bool dcn42_are_clock_states_equal(struct dc_clocks *a,
368 struct dc_clocks *b)
369{
370 if (a->dispclk_khz != b->dispclk_khz)
371 return false;
372 else if (a->dppclk_khz != b->dppclk_khz)
373 return false;
374 else if (a->dcfclk_khz != b->dcfclk_khz)
375 return false;
376 else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz)
377 return false;
378 else if (a->zstate_support != b->zstate_support)
379 return false;
380 else if (a->dtbclk_en != b->dtbclk_en)
381 return false;
382
383 return true;
384}
385
386static void dcn42_dump_clk_registers_internal(struct dcn42_clk_internal *internal, struct clk_mgr *clk_mgr_base)
387{
388 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
389 uint32_t ratio = 1;
390
391 internal->CLK8_CLK_TICK_CNT__TIMER_THRESHOLD = REG_READ(CLK8_CLK_TICK_CNT_CONFIG_REG) & 0xFFFFFF;
392
393 ratio = internal->CLK8_CLK_TICK_CNT__TIMER_THRESHOLD / 48000;
394 ASSERT(ratio != 0);
395
396 if (ratio) {
397 // read dcf deep sleep divider
398 internal->CLK8_CLK0_DS_CNTL = REG_READ(CLK8_CLK0_DS_CNTL);
399 internal->CLK8_CLK3_DS_CNTL = REG_READ(CLK8_CLK3_DS_CNTL);
400 // read dispclk
401 internal->CLK8_CLK0_CURRENT_CNT = REG_READ(CLK8_CLK0_CURRENT_CNT) / ratio;
402 internal->CLK8_CLK0_BYPASS_CNTL = REG_READ(CLK8_CLK0_BYPASS_CNTL);
403 // read dppclk
404 internal->CLK8_CLK1_CURRENT_CNT = REG_READ(CLK8_CLK1_CURRENT_CNT) / ratio;
405 internal->CLK8_CLK1_BYPASS_CNTL = REG_READ(CLK8_CLK1_BYPASS_CNTL);
406 // read dprefclk
407 internal->CLK8_CLK2_CURRENT_CNT = REG_READ(CLK8_CLK2_CURRENT_CNT) / ratio;
408 internal->CLK8_CLK2_BYPASS_CNTL = REG_READ(CLK8_CLK2_BYPASS_CNTL);
409 // read dcfclk
410 internal->CLK8_CLK3_CURRENT_CNT = REG_READ(CLK8_CLK3_CURRENT_CNT) / ratio;
411 internal->CLK8_CLK3_BYPASS_CNTL = REG_READ(CLK8_CLK3_BYPASS_CNTL);
412 // read dtbclk
413 internal->CLK8_CLK4_CURRENT_CNT = REG_READ(CLK8_CLK4_CURRENT_CNT) / ratio;
414 internal->CLK8_CLK4_BYPASS_CNTL = REG_READ(CLK8_CLK4_BYPASS_CNTL);
415 }
416
417}
418
419static void dcn42_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
420 struct clk_mgr_dcn42 *clk_mgr)
421{
422 struct dcn42_clk_internal internal = {0};
423 char *bypass_clks[5] = {"0x0 DFS", "0x1 REFCLK", "0x2 ERROR", "0x3 400 FCH", "0x4 600 FCH"};
424
425 dcn42_dump_clk_registers_internal(&internal, &clk_mgr->base.base);
426 regs_and_bypass->timer_threhold = internal.CLK8_CLK_TICK_CNT__TIMER_THRESHOLD;
427 regs_and_bypass->dcfclk = internal.CLK8_CLK3_CURRENT_CNT / 10;
428 regs_and_bypass->dcf_deep_sleep_divider = internal.CLK8_CLK3_DS_CNTL / 10;
429 regs_and_bypass->dcf_deep_sleep_allow = internal.CLK8_CLK3_DS_CNTL & 0x10; /*bit 4: CLK0_ALLOW_DS*/
430 regs_and_bypass->dprefclk = internal.CLK8_CLK2_CURRENT_CNT / 10;
431 regs_and_bypass->dispclk = internal.CLK8_CLK0_CURRENT_CNT / 10;
432 regs_and_bypass->dppclk = internal.CLK8_CLK1_CURRENT_CNT / 10;
433 regs_and_bypass->dtbclk = internal.CLK8_CLK4_CURRENT_CNT / 10;
434
435 regs_and_bypass->dppclk_bypass = internal.CLK8_CLK1_BYPASS_CNTL & 0x0007;
436 if (regs_and_bypass->dppclk_bypass > 4)
437 regs_and_bypass->dppclk_bypass = 0;
438 regs_and_bypass->dcfclk_bypass = internal.CLK8_CLK3_BYPASS_CNTL & 0x0007;
439 if (regs_and_bypass->dcfclk_bypass > 4)
440 regs_and_bypass->dcfclk_bypass = 0;
441 regs_and_bypass->dispclk_bypass = internal.CLK8_CLK0_BYPASS_CNTL & 0x0007;
442 if (regs_and_bypass->dispclk_bypass > 4)
443 regs_and_bypass->dispclk_bypass = 0;
444 regs_and_bypass->dprefclk_bypass = internal.CLK8_CLK2_BYPASS_CNTL & 0x0007;
445 if (regs_and_bypass->dprefclk_bypass > 4)
446 regs_and_bypass->dprefclk_bypass = 0;
447
448 if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
449 DC_LOG_SMU("clk_type,clk_value,deepsleep_cntl,deepsleep_allow,bypass\n");
450
451 DC_LOG_SMU("dcfclk,%d,%d,%d,%s\n",
452 regs_and_bypass->dcfclk,
453 regs_and_bypass->dcf_deep_sleep_divider,
454 regs_and_bypass->dcf_deep_sleep_allow,
455 bypass_clks[(int) regs_and_bypass->dcfclk_bypass]);
456
457 DC_LOG_SMU("dprefclk,%d,N/A,N/A,%s\n",
458 regs_and_bypass->dprefclk,
459 bypass_clks[(int) regs_and_bypass->dprefclk_bypass]);
460
461 DC_LOG_SMU("dispclk,%d,N/A,N/A,%s\n",
462 regs_and_bypass->dispclk,
463 bypass_clks[(int) regs_and_bypass->dispclk_bypass]);
464
465 //split
466 DC_LOG_SMU("SPLIT\n");
467
468 // REGISTER VALUES
469 DC_LOG_SMU("reg_name,value,clk_type\n");
470
471 DC_LOG_SMU("CLK1_CLK3_CURRENT_CNT,%d,dcfclk\n",
472 internal.CLK8_CLK3_CURRENT_CNT);
473
474 DC_LOG_SMU("CLK1_CLK3_DS_CNTL,%d,dcf_deep_sleep_divider\n",
475 internal.CLK8_CLK3_DS_CNTL);
476
477 DC_LOG_SMU("CLK1_CLK3_ALLOW_DS,%d,dcf_deep_sleep_allow\n",
478 (internal.CLK8_CLK3_DS_CNTL & 0x10));
479
480 DC_LOG_SMU("CLK1_CLK2_CURRENT_CNT,%d,dprefclk\n",
481 internal.CLK8_CLK2_CURRENT_CNT);
482
483 DC_LOG_SMU("CLK1_CLK0_CURRENT_CNT,%d,dispclk\n",
484 internal.CLK8_CLK0_CURRENT_CNT);
485
486 DC_LOG_SMU("CLK1_CLK1_CURRENT_CNT,%d,dppclk\n",
487 internal.CLK8_CLK1_CURRENT_CNT);
488
489 DC_LOG_SMU("CLK1_CLK3_BYPASS_CNTL,%d,dcfclk_bypass\n",
490 internal.CLK8_CLK3_BYPASS_CNTL);
491
492 DC_LOG_SMU("CLK1_CLK2_BYPASS_CNTL,%d,dprefclk_bypass\n",
493 internal.CLK8_CLK2_BYPASS_CNTL);
494
495 DC_LOG_SMU("CLK1_CLK0_BYPASS_CNTL,%d,dispclk_bypass\n",
496 internal.CLK8_CLK0_BYPASS_CNTL);
497
498 DC_LOG_SMU("CLK1_CLK1_BYPASS_CNTL,%d,dppclk_bypass\n",
499 internal.CLK8_CLK1_BYPASS_CNTL);
500 }
501}
502
503bool dcn42_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base)
504{
505 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
506 struct dc_context *ctx = clk_mgr->base.ctx;
507
508
509 if (ctx->dc->config.ignore_dpref_ss) {
510 /*revert bios's ss info for test only*/
511 return (clk_mgr->dprefclk_ss_percentage == 0);
512 }
513 /*need to update after BU*/
514 return false;
515}
516
517static void init_clk_states(struct clk_mgr *clk_mgr)
518{
519 uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
520
521 memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
522
523 clk_mgr->clks.dtbclk_en = true; // request DTBCLK disable on first commit
524 clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk
525 clk_mgr->clks.p_state_change_support = true;
526 clk_mgr->clks.prev_p_state_change_support = true;
527 clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
528 clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
529}
530
531static void dcn42_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
532 struct dcn42_smu_dpm_clks *smu_dpm_clks)
533{
534 DpmClocks_t_dcn42 *table = smu_dpm_clks->dpm_clks;
535
536 if (!clk_mgr->smu_ver)
537 return;
538
539 if (!table || smu_dpm_clks->mc_address.quad_part == 0)
540 return;
541
542 memset(table, 0, sizeof(*table));
543
544 dcn42_smu_set_dram_addr_high(clk_mgr,
545 smu_dpm_clks->mc_address.high_part);
546 dcn42_smu_set_dram_addr_low(clk_mgr,
547 smu_dpm_clks->mc_address.low_part);
548 dcn42_smu_transfer_dpm_table_smu_2_dram(clk_mgr);
549}
550
551void dcn42_init_single_clock(unsigned int *entry_0,
552 uint32_t *smu_entry_0,
553 uint8_t num_levels)
554{
555 int i;
556 char *entry_i = (char *)entry_0;
557
558 ASSERT(num_levels <= MAX_NUM_DPM_LVL);
559 if (num_levels > MAX_NUM_DPM_LVL)
560 num_levels = MAX_NUM_DPM_LVL;
561
562
563 for (i = 0; i < num_levels; i++) {
564 *((unsigned int *)entry_i) = smu_entry_0[i];
565 entry_i += sizeof(struct clk_limit_table_entry);
566 }
567}
568
569unsigned int dcn42_convert_wck_ratio(uint8_t wck_ratio)
570{
571 switch (wck_ratio) {
572 case WCK_RATIO_1_2:
573 return 2;
574
575 case WCK_RATIO_1_4:
576 return 4;
577
578 default:
579 break;
580 }
581
582 return 1;
583}
584
585void dcn42_init_clocks(struct clk_mgr *clk_mgr_base)
586{
587 struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr_base);
588 struct clk_mgr_dcn42 *clk_mgr = TO_CLK_MGR_DCN42(clk_mgr_int);
589 struct dcn42_smu_dpm_clks smu_dpm_clks = { 0 };
590
591 init_clk_states(clk_mgr_base);
592
593 // to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
594 if (dcn42_is_spll_ssc_enabled(clk_mgr_base))
595 clk_mgr_base->dp_dto_source_clock_in_khz =
596 dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr_base->dprefclk_khz);
597 else
598 clk_mgr_base->dp_dto_source_clock_in_khz = clk_mgr_base->dprefclk_khz;
599
600 dcn42_dump_clk_registers(&clk_mgr_base->boot_snapshot, clk_mgr);
601
602 clk_mgr_base->clks.ref_dtbclk_khz = clk_mgr_base->boot_snapshot.dtbclk * 10;
603 if (clk_mgr_base->boot_snapshot.dtbclk > 59000) {
604 /*dtbclk enabled based on*/
605 clk_mgr_base->clks.dtbclk_en = true;
606 }
607
608 smu_dpm_clks.dpm_clks = (DpmClocks_t_dcn42 *)dm_helpers_allocate_gpu_mem(
609 clk_mgr_base->ctx,
610 DC_MEM_ALLOC_TYPE_GART,
611 sizeof(DpmClocks_t_dcn42),
612 &smu_dpm_clks.mc_address.quad_part);
613
614 ASSERT(smu_dpm_clks.dpm_clks);
615 if (clk_mgr_base->ctx->dc->debug.pstate_enabled && clk_mgr_int->smu_present && smu_dpm_clks.mc_address.quad_part != 0) {
616 int i;
617 DpmClocks_t_dcn42 *dpm_clks = smu_dpm_clks.dpm_clks;
618
619 dcn42_get_dpm_table_from_smu(clk_mgr_int, &smu_dpm_clks);
620 DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n"
621 "NumDispClkLevelsEnabled: %d\n"
622 "NumSocClkLevelsEnabled: %d\n"
623 "VcnClkLevelsEnabled: %d\n"
624 "FClkLevelsEnabled: %d\n"
625 "NumMemPstatesEnabled: %d\n"
626 "MinGfxClk: %d\n"
627 "MaxGfxClk: %d\n",
628 dpm_clks->NumDcfClkLevelsEnabled,
629 dpm_clks->NumDispClkLevelsEnabled,
630 dpm_clks->NumSocClkLevelsEnabled,
631 dpm_clks->VcnClkLevelsEnabled,
632 dpm_clks->NumFclkLevelsEnabled,
633 dpm_clks->NumMemPstatesEnabled,
634 dpm_clks->MinGfxClk,
635 dpm_clks->MaxGfxClk);
636
637 for (i = 0; i < NUM_DCFCLK_DPM_LEVELS; i++) {
638 DC_LOG_SMU("dpm_clks->DcfClocks[%d] = %d\n",
639 i,
640 dpm_clks->DcfClocks[i]);
641 }
642 for (i = 0; i < NUM_DISPCLK_DPM_LEVELS; i++) {
643 DC_LOG_SMU("dpm_clks->DispClocks[%d] = %d\n",
644 i, dpm_clks->DispClocks[i]);
645 }
646 for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) {
647 DC_LOG_SMU("dpm_clks->SocClocks[%d] = %d\n",
648 i, dpm_clks->SocClocks[i]);
649 }
650 for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) {
651 DC_LOG_SMU("dpm_clks->FclkClocks_Freq[%d] = %d\n",
652 i, dpm_clks->FclkClocks_Freq[i]);
653 DC_LOG_SMU("dpm_clks->FclkClocks_Voltage[%d] = %d\n",
654 i, dpm_clks->FclkClocks_Voltage[i]);
655 }
656 for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++)
657 DC_LOG_SMU("dpm_clks->SocVoltage[%d] = %d\n",
658 i, dpm_clks->SocVoltage[i]);
659
660 for (i = 0; i < NUM_MEM_PSTATE_LEVELS; i++) {
661 DC_LOG_SMU("dpm_clks.MemPstateTable[%d].UClk = %d\n"
662 "dpm_clks->MemPstateTable[%d].MemClk= %d\n"
663 "dpm_clks->MemPstateTable[%d].Voltage = %d\n",
664 i, dpm_clks->MemPstateTable[i].UClk,
665 i, dpm_clks->MemPstateTable[i].MemClk,
666 i, dpm_clks->MemPstateTable[i].Voltage);
667 }
668
669 if (clk_mgr_base->ctx->dc_bios->integrated_info && clk_mgr_base->ctx->dc->config.use_default_clock_table == false) {
670 /* DCFCLK */
671 dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz,
672 dpm_clks->DcfClocks,
673 dpm_clks->NumDcfClkLevelsEnabled);
674 clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels = dpm_clks->NumDcfClkLevelsEnabled;
675
676 /* SOCCLK */
677 dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz,
678 dpm_clks->SocClocks,
679 dpm_clks->NumSocClkLevelsEnabled);
680 clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_socclk_levels = dpm_clks->NumSocClkLevelsEnabled;
681
682 /* DISPCLK */
683 dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz,
684 dpm_clks->DispClocks,
685 dpm_clks->NumDispClkLevelsEnabled);
686 clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels = dpm_clks->NumDispClkLevelsEnabled;
687
688 /* DPPCLK */
689 dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dppclk_mhz,
690 dpm_clks->DppClocks,
691 dpm_clks->NumDispClkLevelsEnabled);
692 clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dppclk_levels = dpm_clks->NumDispClkLevelsEnabled;
693
694 /* FCLK */
695 dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz,
696 dpm_clks->FclkClocks_Freq,
697 NUM_FCLK_DPM_LEVELS);
698 clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_fclk_levels = dpm_clks->NumFclkLevelsEnabled;
699 clk_mgr_base->bw_params->clk_table.num_entries = dpm_clks->NumFclkLevelsEnabled;
700
701 /* Memory Pstate table is in reverse order*/
702 ASSERT(dpm_clks->NumMemPstatesEnabled <= NUM_MEM_PSTATE_LEVELS);
703 if (dpm_clks->NumMemPstatesEnabled > NUM_MEM_PSTATE_LEVELS)
704 dpm_clks->NumMemPstatesEnabled = NUM_MEM_PSTATE_LEVELS;
705 for (i = 0; i < dpm_clks->NumMemPstatesEnabled; i++) {
706 clk_mgr_base->bw_params->clk_table.entries[dpm_clks->NumMemPstatesEnabled - 1 - i].memclk_mhz = dpm_clks->MemPstateTable[i].UClk;
707 clk_mgr_base->bw_params->clk_table.entries[dpm_clks->NumMemPstatesEnabled - 1 - i].wck_ratio = dcn42_convert_wck_ratio(dpm_clks->MemPstateTable[i].WckRatio) ;
708 }
709 clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels = dpm_clks->NumMemPstatesEnabled;
710
711 /* DTBCLK*/
712 clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz = clk_mgr_base->clks.ref_dtbclk_khz / 1000;
713 clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels = 1;
714
715 /* Refresh bounding box */
716 clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box(
717 clk_mgr_base->ctx->dc, clk_mgr_base->bw_params);
718 }
719 }
720 if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0)
721 dm_helpers_free_gpu_mem(clk_mgr_base->ctx, DC_MEM_ALLOC_TYPE_GART,
722 smu_dpm_clks.dpm_clks);
723}
724
725static struct clk_bw_params dcn42_bw_params = {
726 .vram_type = Ddr4MemType,
727 .num_channels = 1,
728 .clk_table = {
729 .num_entries = 4,
730 },
731
732};
733
734static struct wm_table ddr5_wm_table = {
735 .entries = {
736 {
737 .wm_inst = WM_A,
738 .wm_type = WM_TYPE_PSTATE_CHG,
739 .pstate_latency_us = 11.72,
740 .sr_exit_time_us = 28.0,
741 .sr_enter_plus_exit_time_us = 30.0,
742 .valid = true,
743 },
744 {
745 .wm_inst = WM_B,
746 .wm_type = WM_TYPE_PSTATE_CHG,
747 .pstate_latency_us = 11.72,
748 .sr_exit_time_us = 28.0,
749 .sr_enter_plus_exit_time_us = 30.0,
750 .valid = true,
751 },
752 {
753 .wm_inst = WM_C,
754 .wm_type = WM_TYPE_PSTATE_CHG,
755 .pstate_latency_us = 11.72,
756 .sr_exit_time_us = 28.0,
757 .sr_enter_plus_exit_time_us = 30.0,
758 .valid = true,
759 },
760 {
761 .wm_inst = WM_D,
762 .wm_type = WM_TYPE_PSTATE_CHG,
763 .pstate_latency_us = 11.72,
764 .sr_exit_time_us = 28.0,
765 .sr_enter_plus_exit_time_us = 30.0,
766 .valid = true,
767 },
768 }
769};
770
771static struct wm_table lpddr5_wm_table = {
772 .entries = {
773 {
774 .wm_inst = WM_A,
775 .wm_type = WM_TYPE_PSTATE_CHG,
776 .pstate_latency_us = 11.65333,
777 .sr_exit_time_us = 28.0,
778 .sr_enter_plus_exit_time_us = 30.0,
779 .valid = true,
780 },
781 {
782 .wm_inst = WM_B,
783 .wm_type = WM_TYPE_PSTATE_CHG,
784 .pstate_latency_us = 11.65333,
785 .sr_exit_time_us = 28.0,
786 .sr_enter_plus_exit_time_us = 30.0,
787 .valid = true,
788 },
789 {
790 .wm_inst = WM_C,
791 .wm_type = WM_TYPE_PSTATE_CHG,
792 .pstate_latency_us = 11.65333,
793 .sr_exit_time_us = 28.0,
794 .sr_enter_plus_exit_time_us = 30.0,
795 .valid = true,
796 },
797 {
798 .wm_inst = WM_D,
799 .wm_type = WM_TYPE_PSTATE_CHG,
800 .pstate_latency_us = 11.65333,
801 .sr_exit_time_us = 28.0,
802 .sr_enter_plus_exit_time_us = 30.0,
803 .valid = true,
804 },
805 }
806};
807
808struct dcn42_ss_info_table dcn42_ss_info_table = {
809 .ss_divider = 1000,
810 .ss_percentage = {0, 0, 375, 375, 375}
811};
812
813static void dcn42_read_ss_info_from_lut(struct clk_mgr_internal *clk_mgr)
814{
815 uint32_t clock_source;
816
817 clock_source = (REG_READ(CLK8_CLK2_BYPASS_CNTL) & CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK);
818 // If it's DFS mode, clock_source is 0.
819 if (dcn42_is_spll_ssc_enabled(&clk_mgr->base) && (clock_source < ARRAY_SIZE(dcn42_ss_info_table.ss_percentage))) {
820 clk_mgr->dprefclk_ss_percentage = dcn42_ss_info_table.ss_percentage[clock_source];
821
822 if (clk_mgr->dprefclk_ss_percentage != 0) {
823 clk_mgr->ss_on_dprefclk = true;
824 clk_mgr->dprefclk_ss_divider = dcn42_ss_info_table.ss_divider;
825 }
826 }
827}
828
829/* Exposed for dcn42b reuse */
830void dcn42_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn42_watermarks *table)
831{
832 int i, num_valid_sets;
833
834 num_valid_sets = 0;
835
836 for (i = 0; i < WM_SET_COUNT; i++) {
837 /* skip empty entries, the smu array has no holes*/
838 if (!bw_params->wm_table.entries[i].valid)
839 continue;
840
841 table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmSetting = bw_params->wm_table.entries[i].wm_inst;
842 table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType = bw_params->wm_table.entries[i].wm_type;
843 /* We will not select WM based on fclk, so leave it as unconstrained */
844 table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0;
845 table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF;
846
847 if (table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType == WM_TYPE_PSTATE_CHG) {
848 if (i == 0)
849 table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk = 0;
850 else {
851 /* add 1 to make it non-overlapping with next lvl */
852 table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk =
853 bw_params->clk_table.entries[i - 1].dcfclk_mhz + 1;
854 }
855 table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxMclk =
856 bw_params->clk_table.entries[i].dcfclk_mhz;
857
858 } else {
859 /* unconstrained for memory retraining */
860 table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0;
861 table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF;
862
863 /* Modify previous watermark range to cover up to max */
864 if (num_valid_sets > 0)
865 table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF;
866 }
867 num_valid_sets++;
868 }
869
870 ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */
871
872 /* modify the min and max to make sure we cover the whole range*/
873 table->WatermarkRow[WM_DCFCLK][0].MinMclk = 0;
874 table->WatermarkRow[WM_DCFCLK][0].MinClock = 0;
875 table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxMclk = 0xFFFF;
876 table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF;
877
878 /* This is for writeback only, does not matter currently as no writeback support*/
879 table->WatermarkRow[WM_SOCCLK][0].WmSetting = WM_A;
880 table->WatermarkRow[WM_SOCCLK][0].MinClock = 0;
881 table->WatermarkRow[WM_SOCCLK][0].MaxClock = 0xFFFF;
882 table->WatermarkRow[WM_SOCCLK][0].MinMclk = 0;
883 table->WatermarkRow[WM_SOCCLK][0].MaxMclk = 0xFFFF;
884}
885
886void dcn42_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
887{
888 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
889 struct clk_mgr_dcn42 *clk_mgr_dcn42 = TO_CLK_MGR_DCN42(clk_mgr);
890 struct dcn42_watermarks *table = clk_mgr_dcn42->smu_wm_set.wm_set;
891
892 if (!clk_mgr->smu_ver)
893 return;
894
895 if (!table || clk_mgr_dcn42->smu_wm_set.mc_address.quad_part == 0)
896 return;
897
898 memset(table, 0, sizeof(*table));
899
900 dcn42_build_watermark_ranges(clk_mgr_base->bw_params, table);
901
902 dcn42_smu_set_dram_addr_high(clk_mgr,
903 clk_mgr_dcn42->smu_wm_set.mc_address.high_part);
904 dcn42_smu_set_dram_addr_low(clk_mgr,
905 clk_mgr_dcn42->smu_wm_set.mc_address.low_part);
906 dcn42_smu_transfer_wm_table_dram_2_smu(clk_mgr);
907}
908
909void dcn42_set_low_power_state(struct clk_mgr *clk_mgr_base)
910{
911 int display_count;
912 struct dc *dc = clk_mgr_base->ctx->dc;
913 struct dc_state *context = dc->current_state;
914
915 if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
916 display_count = dcn42_get_active_display_cnt_wa(dc, context, NULL);
917 /* if we can go lower, go lower */
918 if (display_count == 0)
919 clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
920 }
921
922 if (clk_mgr_base->clks.pwr_state == DCN_PWR_STATE_LOW_POWER) {
923 union display_idle_optimization_u idle_info = { 0 };
924 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
925
926 idle_info.idle_info.df_request_disabled = 1;
927 idle_info.idle_info.phy_ref_clk_off = 1;
928 idle_info.idle_info.s0i2_rdy = 1;
929 dcn42_smu_set_display_idle_optimization(clk_mgr, idle_info.data);
930 }
931}
932
933void dcn42_exit_low_power_state(struct clk_mgr *clk_mgr_base)
934{
935
936}
937
938static void dcn42_init_clocks_fpga(struct clk_mgr *clk_mgr)
939{
940 init_clk_states(clk_mgr);
941
942}
943
944static void dcn42_update_clocks_fpga(struct clk_mgr *clk_mgr,
945 struct dc_state *context,
946 bool safe_to_lower)
947{
948 struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
949 struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
950 int fclk_adj = new_clocks->fclk_khz;
951
952 /* TODO: remove this after correctly set by DML */
953 new_clocks->dcfclk_khz = 400000;
954 new_clocks->socclk_khz = 400000;
955
956 /* Min fclk = 1.2GHz since all the extra scemi logic seems to run off of it */
957 //int fclk_adj = new_clocks->fclk_khz > 1200000 ? new_clocks->fclk_khz : 1200000;
958 new_clocks->fclk_khz = 4320000;
959
960 if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr->clks.phyclk_khz))
961 clk_mgr->clks.phyclk_khz = new_clocks->phyclk_khz;
962
963 if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr->clks.dcfclk_khz))
964 clk_mgr->clks.dcfclk_khz = new_clocks->dcfclk_khz;
965
966 if (should_set_clock(safe_to_lower,
967 new_clocks->dcfclk_deep_sleep_khz, clk_mgr->clks.dcfclk_deep_sleep_khz))
968 clk_mgr->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz;
969
970 if (should_set_clock(safe_to_lower, new_clocks->socclk_khz, clk_mgr->clks.socclk_khz))
971 clk_mgr->clks.socclk_khz = new_clocks->socclk_khz;
972
973 if (should_set_clock(safe_to_lower, new_clocks->dramclk_khz, clk_mgr->clks.dramclk_khz))
974 clk_mgr->clks.dramclk_khz = new_clocks->dramclk_khz;
975
976 if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->clks.dppclk_khz))
977 clk_mgr->clks.dppclk_khz = new_clocks->dppclk_khz;
978
979 if (should_set_clock(safe_to_lower, fclk_adj, clk_mgr->clks.fclk_khz))
980 clk_mgr->clks.fclk_khz = fclk_adj;
981
982 if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr->clks.dispclk_khz))
983 clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz;
984
985 /* Both fclk and ref_dppclk run on the same scemi clock.
986 * So take the higher value since the DPP DTO is typically programmed
987 * such that max dppclk is 1:1 with ref_dppclk.
988 */
989 if (clk_mgr->clks.fclk_khz > clk_mgr->clks.dppclk_khz)
990 clk_mgr->clks.dppclk_khz = clk_mgr->clks.fclk_khz;
991 if (clk_mgr->clks.dppclk_khz > clk_mgr->clks.fclk_khz)
992 clk_mgr->clks.fclk_khz = clk_mgr->clks.dppclk_khz;
993
994 // Both fclk and ref_dppclk run on the same scemi clock.
995 clk_mgr_int->dccg->ref_dppclk = clk_mgr->clks.fclk_khz;
996
997 /* TODO: set dtbclk in correct place */
998 clk_mgr->clks.dtbclk_en = true;
999
1000 dm_set_dcn_clocks(clk_mgr->ctx, &clk_mgr->clks);
1001 dcn42_update_clocks_update_dpp_dto(clk_mgr_int, context, safe_to_lower);
1002
1003 dcn42_update_clocks_update_dtb_dto(clk_mgr_int, context, clk_mgr->clks.ref_dtbclk_khz);
1004}
1005
1006unsigned int dcn42_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_type clk_type)
1007{
1008 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
1009
1010 unsigned int num_clk_levels;
1011
1012 switch (clk_type) {
1013 case CLK_TYPE_DISPCLK:
1014 num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
1015 return num_clk_levels ?
1016 clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dispclk_mhz * 1000 :
1017 clk_mgr->base.boot_snapshot.dispclk;
1018 case CLK_TYPE_DPPCLK:
1019 num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dppclk_levels;
1020 return num_clk_levels ?
1021 clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dppclk_mhz * 1000 :
1022 clk_mgr->base.boot_snapshot.dppclk;
1023 case CLK_TYPE_DSCCLK:
1024 num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
1025 return num_clk_levels ?
1026 clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dispclk_mhz * 1000 / 3 :
1027 clk_mgr->base.boot_snapshot.dispclk / 3;
1028 default:
1029 break;
1030 }
1031
1032 return 0;
1033}
1034
1035static int dcn42_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base)
1036{
1037 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
1038 uint32_t dispclk_wdivider;
1039 int disp_divider;
1040
1041 REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, &dispclk_wdivider);
1042 disp_divider = dentist_get_divider_from_did(dispclk_wdivider);
1043
1044 /* Return DISPCLK freq in Khz */
1045 if (disp_divider)
1046 return (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / disp_divider;
1047
1048 return 0;
1049}
1050bool dcn42_is_smu_present(struct clk_mgr *clk_mgr_base)
1051{
1052 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
1053 return clk_mgr->smu_present;
1054}
1055
1056static struct clk_mgr_funcs dcn42_funcs = {
1057 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
1058 .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
1059 .update_clocks = dcn42_update_clocks,
1060 .init_clocks = dcn42_init_clocks,
1061 .enable_pme_wa = dcn42_enable_pme_wa,
1062 .are_clock_states_equal = dcn42_are_clock_states_equal,
1063 .notify_wm_ranges = dcn42_notify_wm_ranges,
1064 .set_low_power_state = dcn42_set_low_power_state,
1065 .exit_low_power_state = dcn42_exit_low_power_state,
1066 .get_max_clock_khz = dcn42_get_max_clock_khz,
1067 .get_dispclk_from_dentist = dcn42_get_dispclk_from_dentist,
1068 .is_smu_present = dcn42_is_smu_present,
1069};
1070
1071struct clk_mgr_funcs dcn42_fpga_funcs = {
1072 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
1073 .update_clocks = dcn42_update_clocks_fpga,
1074 .init_clocks = dcn42_init_clocks_fpga,
1075 .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
1076};
1077
1078void dcn42_clk_mgr_construct(
1079 struct dc_context *ctx,
1080 struct clk_mgr_dcn42 *clk_mgr,
1081 struct pp_smu_funcs *pp_smu,
1082 struct dccg *dccg)
1083{
1084 clk_mgr->base.base.ctx = ctx;
1085 clk_mgr->base.base.funcs = &dcn42_funcs;
1086 clk_mgr->base.regs = &clk_mgr_regs_dcn42;
1087 clk_mgr->base.clk_mgr_shift = &clk_mgr_shift_dcn42;
1088 clk_mgr->base.clk_mgr_mask = &clk_mgr_mask_dcn42;
1089
1090 clk_mgr->base.pp_smu = pp_smu;
1091
1092 clk_mgr->base.dccg = dccg;
1093 clk_mgr->base.dfs_bypass_disp_clk = 0;
1094
1095 clk_mgr->base.dprefclk_ss_percentage = 0;
1096 clk_mgr->base.dprefclk_ss_divider = 1000;
1097 clk_mgr->base.ss_on_dprefclk = false;
1098 clk_mgr->base.dfs_ref_freq_khz = 48000; /*sync with pmfw*/
1099
1100 clk_mgr->smu_wm_set.wm_set = (struct dcn42_watermarks *)dm_helpers_allocate_gpu_mem(
1101 clk_mgr->base.base.ctx,
1102 DC_MEM_ALLOC_TYPE_GART,
1103 sizeof(struct dcn42_watermarks),
1104 &clk_mgr->smu_wm_set.mc_address.quad_part);
1105
1106 ASSERT(clk_mgr->smu_wm_set.wm_set);
1107
1108 /* Changed from DCN3.2_clock_frequency doc to match
1109 * dcn32_dump_clk_registers from 4 * dentist_vco_freq_khz /
1110 * dprefclk DID divider
1111 */
1112 clk_mgr->base.base.dprefclk_khz = 600000;
1113
1114 clk_mgr->base.smu_present = false;
1115
1116 if (ctx->dc_bios->integrated_info) {
1117 clk_mgr->base.base.dentist_vco_freq_khz = ctx->dc_bios->integrated_info->dentist_vco_freq;
1118
1119 if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType)
1120 dcn42_bw_params.wm_table = lpddr5_wm_table;
1121 else
1122 dcn42_bw_params.wm_table = ddr5_wm_table;
1123 dcn42_bw_params.vram_type = ctx->dc_bios->integrated_info->memory_type;
1124 dcn42_bw_params.dram_channel_width_bytes = ctx->dc_bios->integrated_info->memory_type == 0x22 ? 8 : 4;
1125 dcn42_bw_params.num_channels = ctx->dc_bios->integrated_info->ma_channel_number ? ctx->dc_bios->integrated_info->ma_channel_number : 4;
1126 }
1127 /* in case we don't get a value from the BIOS, use default */
1128 if (clk_mgr->base.base.dentist_vco_freq_khz == 0)
1129 clk_mgr->base.base.dentist_vco_freq_khz = 3000000; /* 3000MHz */
1130
1131 /* Saved clocks configured at boot for debug purposes */
1132 dcn42_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, clk_mgr);
1133
1134 if (clk_mgr->base.smu_present)
1135 clk_mgr->base.base.dprefclk_khz = dcn42_smu_get_dprefclk(&clk_mgr->base);
1136 clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
1137 dce_clock_read_ss_info(&clk_mgr->base);
1138 /*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/
1139
1140 dcn42_read_ss_info_from_lut(&clk_mgr->base);
1141
1142 clk_mgr->base.base.bw_params = &dcn42_bw_params;
1143}
1144
1145void dcn42_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int)
1146{
1147 struct clk_mgr_dcn42 *clk_mgr = TO_CLK_MGR_DCN42(clk_mgr_int);
1148
1149 if (clk_mgr->smu_wm_set.wm_set && clk_mgr->smu_wm_set.mc_address.quad_part != 0)
1150 dm_helpers_free_gpu_mem(clk_mgr_int->base.ctx, DC_MEM_ALLOC_TYPE_GART,
1151 clk_mgr->smu_wm_set.wm_set);
1152}
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h+79−0
@@ -0,0 +1,79 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2026 Advanced Micro Devices, 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 */
24
25#ifndef __DCN42_CLK_MGR_H__
26#define __DCN42_CLK_MGR_H__
27#include "clk_mgr_internal.h"
28
29#define NUM_CLOCK_SOURCES 5
30
31struct dcn42_watermarks;
32
33struct dcn42_smu_watermark_set {
34 struct dcn42_watermarks *wm_set;
35 union large_integer mc_address;
36};
37
38struct dcn42_ss_info_table {
39 uint32_t ss_divider;
40 uint32_t ss_percentage[NUM_CLOCK_SOURCES];
41};
42
43struct clk_mgr_dcn42 {
44 struct clk_mgr_internal base;
45 struct dcn42_smu_watermark_set smu_wm_set;
46};
47
48bool dcn42_are_clock_states_equal(struct dc_clocks *a,
49 struct dc_clocks *b);
50void dcn42_init_clocks(struct clk_mgr *clk_mgr);
51void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
52 struct dc_state *context,
53 bool safe_to_lower);
54
55void dcn42_clk_mgr_construct(struct dc_context *ctx,
56 struct clk_mgr_dcn42 *clk_mgr,
57 struct pp_smu_funcs *pp_smu,
58 struct dccg *dccg);
59
60void dcn42_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int);
61
62/* Exposed for dcn42b reuse */
63void dcn42_init_single_clock(unsigned int *entry_0,
64 uint32_t *smu_entry_0,
65 uint8_t num_levels);
66unsigned int dcn42_convert_wck_ratio(uint8_t wck_ratio);
67extern struct dcn42_ss_info_table dcn42_ss_info_table;
68void dcn42_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn42_watermarks *table);
69void dcn42_enable_pme_wa(struct clk_mgr *clk_mgr_base);
70void dcn42_notify_wm_ranges(struct clk_mgr *clk_mgr_base);
71void dcn42_set_low_power_state(struct clk_mgr *clk_mgr_base);
72void dcn42_exit_low_power_state(struct clk_mgr *clk_mgr_base);
73unsigned int dcn42_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_type clk_type);
74bool dcn42_is_smu_present(struct clk_mgr *clk_mgr_base);
75int dcn42_get_active_display_cnt_wa(struct dc *dc, struct dc_state *context, int *all_active_disps);
76void dcn42_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, bool safe_to_lower);
77void dcn42_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, int ref_dtbclk_khz);
78bool dcn42_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base);
79#endif //__DCN42_CLK_MGR_H__
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_smu.c+431−0
@@ -0,0 +1,431 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5
6
7#include "core_types.h"
8#include "clk_mgr_internal.h"
9#include "reg_helper.h"
10#include "dm_helpers.h"
11#include "dcn42_smu.h"
12
13#include "mp/mp_15_0_0_offset.h"
14#include "mp/mp_15_0_0_sh_mask.h"
15
16#ifdef BASE_INNER
17#undef BASE_INNER
18#endif
19
20#define MP1_BASE__INST0_SEG0 0x00016000
21#define MP1_BASE__INST0_SEG1 0x00016200
22#define MP1_BASE__INST0_SEG2 0x00E00000
23#define MP1_BASE__INST0_SEG3 0x00E80000
24#define MP1_BASE__INST0_SEG4 0x00EC0000
25#define MP1_BASE__INST0_SEG5 0x00F00000
26#define MP1_BASE__INST0_SEG6 0x02400400
27#define MP1_BASE__INST0_SEG7 0x0243F400
28#define MP1_BASE__INST0_SEG8 0x3C004000
29#define MP1_BASE__INST0_SEG9 0x3C3F4000
30
31#define BASE_INNER(seg) MP1_BASE__INST0_SEG ## seg
32
33#define BASE(seg) BASE_INNER(seg)
34
35#define REG(reg_name) (BASE(reg##reg_name##_BASE_IDX) + reg##reg_name)
36
37#define FN(reg_name, field) \
38 FD(reg_name##__##field)
39
40#include "logger_types.h"
41#undef DC_LOGGER
42#define DC_LOGGER \
43 CTX->logger
44#define smu_print(str, ...) {DC_LOG_SMU(str, ##__VA_ARGS__); }
45
46// VBIOS and DAL to PMFW Interface
47
48// DAL to PMFW interface registers
49#define DAL_MSG_REG MP1_SMN_C2PMSG_71
50#define DAL_RESP_REG MP1_SMN_C2PMSG_72
51#define DAL_ARG_REG MP1_SMN_C2PMSG_73
52
53/** @defgroup ResponseCodes PMFW Response Codes
54* @{
55*/
56// SMU Response Codes:
57#define DALSMC_Result_OK 0x01 ///< Message Response OK
58#define DALSMC_Result_Failed 0xFF ///< Message Response Failed
59#define DALSMC_Result_UnknownCmd 0xFE ///< Message Response Unknown Command
60#define DALSMC_Result_CmdRejectedPrereq 0xFD ///< Message Response Command Failed Prerequisite
61#define DALSMC_Result_CmdRejectedBusy 0xFC ///< Message Response Command Rejected due to PMFW is busy. Sender should retry sending this message
62/** @}*/
63
64// Message Definitions:
65/** @defgroup definitions Message definitions
66* @{
67*/
68#define DALSMC_MSG_TestMessage 0x01 ///< To check if PMFW is alive and responding. Requirement specified by PMFW team
69#define DALSMC_MSG_GetPmfwVersion 0x02 ///< Get version
70#define DALSMC_MSG_SetDispclkFreq 0x03 ///< Set display clock frequency in MHZ
71#define DALSMC_MSG_SetDppclkFreq 0x04 ///< Set DPP clock frequency in MHZ
72#define DALSMC_MSG_SetHardMinDcfclkByFreq 0x05 ///< Set DCF clock frequency hard min in MHZ
73#define DALSMC_MSG_SetMinDeepSleepDcfclk 0x06 ///< Set DCF clock minimum frequency in deep sleep in MHZ
74#define DALSMC_MSG_UpdatePmeRestore 0x07 ///< To ask PMFW to write into Azalia for PME wake up event
75#define DALSMC_MSG_SetDramAddrHigh 0x08 ///< Set DRAM address high 32 bits for WM table transfer
76#define DALSMC_MSG_SetDramAddrLow 0x09 ///< Set DRAM address low 32 bits for WM table transfer
77
78#define DALSMC_MSG_TransferTableSmu2Dram 0x0A ///< Transfer table from PMFW SRAM to system DRAM
79#define DALSMC_MSG_TransferTableDram2Smu 0x0B ///< Transfer table from system DRAM to PMFW
80#define DALSMC_MSG_SetDisplayIdleOptimizations 0x0C ///< Set Idle state optimization for display off
81#define DALSMC_MSG_GetDprefclkFreq 0x0D ///< Get DPREF clock frequency. Return in MHZ
82#define DALSMC_MSG_GetDtbclkFreq 0x0E ///< Get DTB clock frequency. Return in MHZ
83#define DALSMC_MSG_AllowZstatesEntry 0x0F ///< Inform PMFW of display allowing Zstate entry
84#define DALSMC_MSG_SetDtbClk 0x10 ///< Inform PMFW to turn of/off DTB cl0ck. arg = 1: turn DTB on with 600MHZ; arg = 0: turn DTB clk off
85#define DALSMC_MSG_DispIPS2Exit 0x11 ///< Display IPS2 exit
86
87#define DALSMC_MSG_QueryIPS2Support 0x12 ///< Return 1: support; else not supported
88#define DALSMC_Message_Count 0x13 ///< Total number of VBIS and DAL messages
89/** @}*/
90
91
92union dcn42_dpia_host_router_bw {
93 struct {
94 uint32_t hr_id : 16;
95 uint32_t bw_mbps : 16;
96 } bits;
97 uint32_t all;
98};
99
100/*
101 * Function to be used instead of REG_WAIT macro because the wait ends when
102 * the register is NOT EQUAL to zero, and because `the translation in msg_if.h
103 * won't work with REG_WAIT.
104 */
105static uint32_t dcn42_smu_wait_for_response(struct clk_mgr_internal *clk_mgr,
106 unsigned int delay_us, unsigned int max_retries)
107{
108 uint32_t res_val;
109
110 do {
111 res_val = REG_READ(DAL_RESP_REG);
112 if (res_val != DALSMC_Result_CmdRejectedBusy)
113 break;
114
115 if (delay_us >= 1000)
116 msleep(delay_us/1000);
117 else if (delay_us > 0)
118 udelay(delay_us);
119
120 if (clk_mgr->base.ctx->dc->debug.disable_timeout)
121 max_retries++;
122 } while (max_retries--);
123
124 return res_val;
125}
126
127static int dcn42_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr,
128 unsigned int msg_id,
129 unsigned int param)
130{
131 uint32_t result;
132
133 result = dcn42_smu_wait_for_response(clk_mgr, 10, 2000000);
134
135 if (result != DALSMC_Result_OK) {
136 DC_LOG_WARNING("SMU response after wait: %d, msg id = %d\n", result, msg_id);
137
138 if (result == DALSMC_Result_CmdRejectedBusy)
139 return -1;
140 }
141
142 /* First clear response register */
143 REG_WRITE(DAL_RESP_REG, DALSMC_Result_CmdRejectedBusy);
144
145 /* Set the parameter register for the SMU message, unit is Mhz */
146 REG_WRITE(DAL_ARG_REG, param);
147
148 /* Trigger the message transaction by writing the message ID */
149 REG_WRITE(DAL_MSG_REG, msg_id);
150
151 result = dcn42_smu_wait_for_response(clk_mgr, 10, 2000000);
152
153 if (result == DALSMC_Result_Failed) {
154 if (msg_id == DALSMC_MSG_TransferTableDram2Smu &&
155 param == TABLE_WATERMARKS)
156 DC_LOG_WARNING("Watermarks table not configured properly by SMU");
157 REG_WRITE(DAL_RESP_REG, DALSMC_Result_OK);
158 DC_LOG_WARNING("SMU response after wait: %d, msg id = %d\n", result, msg_id);
159 return -1;
160 }
161
162 if (IS_SMU_TIMEOUT(result)) {
163 ASSERT(0);
164 result = dcn42_smu_wait_for_response(clk_mgr, 10, 2000000);
165 //dm_helpers_smu_timeout(CTX, msg_id, param, 10 * 200000);
166 DC_LOG_WARNING("SMU response after wait: %d, msg id = %d\n", result, msg_id);
167 }
168
169 return REG_READ(DAL_ARG_REG);
170}
171
172int dcn42_smu_get_pmfw_version(struct clk_mgr_internal *clk_mgr)
173{
174 return dcn42_smu_send_msg_with_param(
175 clk_mgr,
176 DALSMC_MSG_GetPmfwVersion,
177 0);
178}
179
180
181int dcn42_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz)
182{
183 int actual_dispclk_set_mhz;
184
185 if (!clk_mgr->smu_present)
186 return requested_dispclk_khz;
187
188 /* Unit of SMU msg parameter is Mhz */
189 actual_dispclk_set_mhz = dcn42_smu_send_msg_with_param(
190 clk_mgr,
191 DALSMC_MSG_SetDispclkFreq,
192 khz_to_mhz_ceil(requested_dispclk_khz));
193
194 smu_print("requested_dispclk_khz = %d, actual_dispclk_set_mhz: %d\n",
195 requested_dispclk_khz, actual_dispclk_set_mhz);
196 return (int)((long long)actual_dispclk_set_mhz * 1000);
197}
198
199
200int dcn42_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz)
201{
202 int actual_dcfclk_set_mhz;
203
204 if (!clk_mgr->smu_present)
205 return requested_dcfclk_khz;
206
207 actual_dcfclk_set_mhz = dcn42_smu_send_msg_with_param(
208 clk_mgr,
209 DALSMC_MSG_SetHardMinDcfclkByFreq,
210 khz_to_mhz_ceil(requested_dcfclk_khz));
211
212 smu_print("requested_dcfclk_khz = %d, actual_dcfclk_set_mhz: %d\n",
213 requested_dcfclk_khz, actual_dcfclk_set_mhz);
214
215 return (int)((long long)actual_dcfclk_set_mhz * 1000);
216}
217
218int dcn42_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz)
219{
220 int actual_min_ds_dcfclk_mhz;
221
222 if (!clk_mgr->smu_present)
223 return requested_min_ds_dcfclk_khz;
224
225 actual_min_ds_dcfclk_mhz = dcn42_smu_send_msg_with_param(
226 clk_mgr,
227 DALSMC_MSG_SetMinDeepSleepDcfclk,
228 khz_to_mhz_ceil(requested_min_ds_dcfclk_khz));
229
230 smu_print("requested_min_ds_dcfclk_khz = %d, actual_min_ds_dcfclk_mhz: %d\n",
231 requested_min_ds_dcfclk_khz, actual_min_ds_dcfclk_mhz);
232
233 return (int)((long long)actual_min_ds_dcfclk_mhz * 1000);
234}
235
236int dcn42_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz)
237{
238 int actual_dppclk_set_mhz;
239
240 if (!clk_mgr->smu_present)
241 return requested_dpp_khz;
242
243 actual_dppclk_set_mhz = dcn42_smu_send_msg_with_param(
244 clk_mgr,
245 DALSMC_MSG_SetDppclkFreq,
246 khz_to_mhz_ceil(requested_dpp_khz));
247
248 smu_print("requested_dpp_khz = %d, actual_dppclk_set_mhz: %d\n",
249 requested_dpp_khz, actual_dppclk_set_mhz);
250
251 return (int)((long long)actual_dppclk_set_mhz * 1000);
252}
253
254void dcn42_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info)
255{
256 if (!clk_mgr->base.ctx->dc->debug.pstate_enabled)
257 return;
258
259 if (!clk_mgr->smu_present)
260 return;
261
262 dcn42_smu_send_msg_with_param(
263 clk_mgr,
264 DALSMC_MSG_SetDisplayIdleOptimizations,
265 idle_info);
266 smu_print("%s: SMC_MSG_SetDisplayIdleOptimizations idle_info = %x\n", __func__, idle_info);
267}
268
269void dcn42_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable)
270{
271 union display_idle_optimization_u idle_info = { 0 };
272
273 if (!clk_mgr->smu_present)
274 return;
275
276 if (enable) {
277 idle_info.idle_info.df_request_disabled = 1;
278 idle_info.idle_info.phy_ref_clk_off = 1;
279 }
280
281 dcn42_smu_send_msg_with_param(
282 clk_mgr,
283 DALSMC_MSG_SetDisplayIdleOptimizations,
284 idle_info.data);
285 smu_print("%s smu_enable_phy_refclk_pwrdwn = %d\n", __func__, enable ? 1 : 0);
286}
287
288void dcn42_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr)
289{
290 if (!clk_mgr->smu_present)
291 return;
292
293 dcn42_smu_send_msg_with_param(
294 clk_mgr,
295 DALSMC_MSG_UpdatePmeRestore,
296 0);
297 smu_print("%s: SMC_MSG_UpdatePmeRestore\n", __func__);
298}
299
300void dcn42_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high)
301{
302 if (!clk_mgr->smu_present)
303 return;
304
305 dcn42_smu_send_msg_with_param(clk_mgr,
306 DALSMC_MSG_SetDramAddrHigh, addr_high);
307}
308
309void dcn42_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low)
310{
311 if (!clk_mgr->smu_present)
312 return;
313
314 dcn42_smu_send_msg_with_param(clk_mgr,
315 DALSMC_MSG_SetDramAddrLow, addr_low);
316}
317
318void dcn42_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr)
319{
320 if (!clk_mgr->smu_present)
321 return;
322
323 dcn42_smu_send_msg_with_param(clk_mgr,
324 DALSMC_MSG_TransferTableSmu2Dram, TABLE_DPMCLOCKS);
325}
326
327void dcn42_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr)
328{
329 if (!clk_mgr->smu_present)
330 return;
331
332 dcn42_smu_send_msg_with_param(clk_mgr,
333 DALSMC_MSG_TransferTableDram2Smu, TABLE_WATERMARKS);
334}
335
336void dcn42_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zstate_support_state support)
337{
338 unsigned int msg_id, param, retv;
339
340 if (!clk_mgr->smu_present)
341 return;
342
343 switch (support) {
344
345 case DCN_ZSTATE_SUPPORT_ALLOW:
346 msg_id = DALSMC_MSG_AllowZstatesEntry;
347 param = (1 << 10) | (1 << 9) | (1 << 8);
348 smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW, param = 0x%x\n", __func__, param);
349 break;
350
351 case DCN_ZSTATE_SUPPORT_DISALLOW:
352 msg_id = DALSMC_MSG_AllowZstatesEntry;
353 param = 0;
354 smu_print("%s: SMC_MSG_AllowZstatesEntry msg_id = DISALLOW, param = 0x%x\n", __func__, param);
355 break;
356
357
358 case DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY:
359 msg_id = DALSMC_MSG_AllowZstatesEntry;
360 param = (1 << 10);
361 smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z10_ONLY, param = 0x%x\n", __func__, param);
362 break;
363
364 case DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY:
365 msg_id = DALSMC_MSG_AllowZstatesEntry;
366 param = (1 << 10) | (1 << 8);
367 smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z8_Z10_ONLY, param = 0x%x\n", __func__, param);
368 break;
369
370 case DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY:
371 msg_id = DALSMC_MSG_AllowZstatesEntry;
372 param = (1 << 8);
373 smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z8_ONLY, param = 0x%x\n", __func__, param);
374 break;
375
376 default: //DCN_ZSTATE_SUPPORT_UNKNOWN
377 msg_id = DALSMC_MSG_AllowZstatesEntry;
378 param = 0;
379 break;
380 }
381
382
383 retv = dcn42_smu_send_msg_with_param(
384 clk_mgr,
385 msg_id,
386 param);
387 smu_print("%s: msg_id = %d, param = 0x%x, return = 0x%x\n", __func__, msg_id, param, retv);
388}
389
390int dcn42_smu_get_dprefclk(struct clk_mgr_internal *clk_mgr)
391{
392 int dprefclk;
393
394 if (!clk_mgr->smu_present)
395 return 0;
396
397 dprefclk = dcn42_smu_send_msg_with_param(clk_mgr,
398 DALSMC_MSG_GetDprefclkFreq,
399 0);
400
401 smu_print("%s: SMU DPREF clk = %d mhz\n", __func__, dprefclk);
402 return (int)((long long)dprefclk * 1000);
403}
404
405int dcn42_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr)
406{
407 int dtbclk;
408
409 if (!clk_mgr->smu_present)
410 return 0;
411
412 dtbclk = dcn42_smu_send_msg_with_param(clk_mgr,
413 DALSMC_MSG_GetDtbclkFreq,
414 0);
415
416 smu_print("%s: get_dtbclk = %dmhz\n", __func__, dtbclk);
417 return (int)((long long)dtbclk * 1000);
418}
419/* Arg = 1: Turn DTB on; 0: Turn DTB CLK OFF. when it is on, it is 600MHZ */
420void dcn42_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable)
421{
422 if (!clk_mgr->smu_present)
423 return;
424
425 dcn42_smu_send_msg_with_param(
426 clk_mgr,
427 DALSMC_MSG_SetDtbClk,
428 enable);
429 smu_print("%s: smu_set_dtbclk = %d\n", __func__, enable ? 1 : 0);
430}
431
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_smu.h+190−0
@@ -0,0 +1,190 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2026 Advanced Micro Devices, 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 */
24
25#ifndef DAL_DC_42_SMU_H_
26#define DAL_DC_42_SMU_H_
27
28#include "os_types.h"
29
30#ifndef PMFW_DRIVER_IF_H
31#define PMFW_DRIVER_IF_H
32#define PMFW_DRIVER_IF_VERSION 7
33
34typedef enum {
35 DSPCLK_DCFCLK = 0,
36 DSPCLK_DISPCLK,
37 DSPCLK_PIXCLK,
38 DSPCLK_PHYCLK,
39 DSPCLK_COUNT,
40} DSPCLK_e;
41
42typedef struct {
43 uint16_t Freq; // in MHz
44 uint16_t Vid; // min voltage in SVI3 VID
45} DisplayClockTable_t;
46
47typedef struct {
48 uint16_t MinClock; // This is either DCFCLK or SOCCLK (in MHz)
49 uint16_t MaxClock; // This is either DCFCLK or SOCCLK (in MHz)
50 uint16_t MinMclk;
51 uint16_t MaxMclk;
52
53 uint8_t WmSetting;
54 uint8_t WmType; // Used for normal pstate change or memory retraining
55 uint8_t Padding[2];
56} WatermarkRowGeneric_t;
57
58#define NUM_WM_RANGES 4
59#define WM_PSTATE_CHG 0
60#define WM_RETRAINING 1
61
62typedef enum {
63 WM_SOCCLK = 0,
64 WM_DCFCLK,
65 WM_COUNT,
66} WM_CLOCK_e;
67
68typedef struct {
69 WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES];
70
71 uint32_t MmHubPadding[7]; // SMU internal use
72} Watermarks_t;
73
74#define NUM_DCFCLK_DPM_LEVELS 8
75#define NUM_DISPCLK_DPM_LEVELS 8
76#define NUM_DPPCLK_DPM_LEVELS 8
77#define NUM_SOCCLK_DPM_LEVELS 8
78#define NUM_VCN_DPM_LEVELS 8
79#define NUM_SOC_VOLTAGE_LEVELS 8
80#define NUM_VPE_DPM_LEVELS 8
81#define NUM_FCLK_DPM_LEVELS 8
82#define NUM_MEM_PSTATE_LEVELS 4
83
84typedef enum {
85 WCK_RATIO_1_1 = 0, // DDR5, Wck:ck is always 1:1;
86 WCK_RATIO_1_2,
87 WCK_RATIO_1_4,
88 WCK_RATIO_MAX
89} WCK_RATIO_e;
90
91typedef struct {
92 uint32_t UClk;
93 uint32_t MemClk;
94 uint32_t Voltage;
95 uint8_t WckRatio;
96 uint8_t Spare[3];
97} MemPstateTable_t;
98
99
100 // Watermarks
101
102
103// Freq in MHz
104// Voltage in milli volts with 2 fractional bits
105typedef struct {
106 uint32_t DcfClocks[NUM_DCFCLK_DPM_LEVELS];
107 uint32_t DispClocks[NUM_DISPCLK_DPM_LEVELS];
108 uint32_t DppClocks[NUM_DPPCLK_DPM_LEVELS];
109 uint32_t SocClocks[NUM_SOCCLK_DPM_LEVELS];
110 uint32_t VClocks[NUM_VCN_DPM_LEVELS];
111 uint32_t DClocks[NUM_VCN_DPM_LEVELS];
112 uint32_t VPEClocks[NUM_VPE_DPM_LEVELS];
113 uint32_t FclkClocks_Freq[NUM_FCLK_DPM_LEVELS];
114 uint32_t FclkClocks_Voltage[NUM_FCLK_DPM_LEVELS];
115 uint32_t SocVoltage[NUM_SOC_VOLTAGE_LEVELS];
116 MemPstateTable_t MemPstateTable[NUM_MEM_PSTATE_LEVELS];
117
118 uint8_t NumDcfClkLevelsEnabled;
119 uint8_t NumDispClkLevelsEnabled; //Applies to both Dispclk and Dppclk
120 uint8_t NumSocClkLevelsEnabled;
121 uint8_t VcnClkLevelsEnabled; //Applies to both Vclk and Dclk
122
123 uint8_t VpeClkLevelsEnabled;
124 uint8_t NumMemPstatesEnabled;
125 uint8_t NumFclkLevelsEnabled;
126 uint8_t spare;
127
128 uint32_t MinGfxClk;
129 uint32_t MaxGfxClk;
130} DpmClocks_t_dcn42;
131
132// Throttler Status Bitmask
133
134
135#define TABLE_BIOS_IF 0 // Called by BIOS
136#define TABLE_WATERMARKS 1 // Called by DAL through VBIOS
137#define TABLE_CUSTOM_DPM 2 // Called by Driver
138#define TABLE_SPARE1 3
139#define TABLE_DPMCLOCKS 4 // Called by Driver
140#define TABLE_MOMENTARY_PM 5 // Called by Tools
141#define TABLE_MODERN_STDBY 6 // Called by Tools for Modern Standby Log
142#define TABLE_SMU_METRICS 7 // Called by Driver
143#define TABLE_COUNT 8
144
145#endif
146
147struct dcn42_watermarks {
148 // Watermarks
149 WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES];
150 uint32_t MmHubPadding[7]; // SMU internal use
151};
152
153struct dcn42_smu_dpm_clks {
154 DpmClocks_t_dcn42 *dpm_clks;
155 union large_integer mc_address;
156};
157
158struct display_idle_optimization {
159 unsigned int df_request_disabled : 1;
160 unsigned int phy_ref_clk_off : 1;
161 unsigned int s0i2_rdy : 1;
162 unsigned int reserved : 29;
163};
164
165union display_idle_optimization_u {
166 struct display_idle_optimization idle_info;
167 uint32_t data;
168};
169
170int dcn42_smu_get_pmfw_version(struct clk_mgr_internal *clk_mgr);
171int dcn42_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz);
172int dcn42_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz);
173int dcn42_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz);
174int dcn42_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz);
175void dcn42_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info);
176void dcn42_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
177void dcn42_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr);
178void dcn42_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high);
179void dcn42_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low);
180void dcn42_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr);
181void dcn42_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr);
182
183void dcn42_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zstate_support_state support);
184void dcn42_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable);
185void dcn42_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
186
187int dcn42_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr);
188int dcn42_smu_get_dprefclk(struct clk_mgr_internal *clk_mgr);
189
190#endif /* DAL_DC_42_SMU_H_ */
drivers/gpu/drm/amd/display/dc/core/dc.c+85−72
@@ -442,75 +442,6 @@ static bool set_long_vtotal(struct dc *dc, struct dc_stream_state *stream, struc · 441 unmodified lines
442 return false;442 return false;
443}443}
444 444
445/**
446 * dc_stream_adjust_vmin_vmax - look up pipe context & update parts of DRR
447 * @dc: dc reference
448 * @stream: Initial dc stream state
449 * @adjust: Updated parameters for vertical_total_min and vertical_total_max
450 *
451 * Looks up the pipe context of dc_stream_state and updates the
452 * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh
453 * Rate, which is a power-saving feature that targets reducing panel
454 * refresh rate while the screen is static
455 *
456 * Return: %true if the pipe context is found and adjusted;
457 * %false if the pipe context is not found.
458 */
459bool dc_stream_adjust_vmin_vmax(struct dc *dc,
460 struct dc_stream_state *stream,
461 struct dc_crtc_timing_adjust *adjust)
462{
463 int i;
464
465 /*
466 * Don't adjust DRR while there's bandwidth optimizations pending to
467 * avoid conflicting with firmware updates.
468 */
469 if (dc->ctx->dce_version > DCE_VERSION_MAX) {
470 if (dc->optimized_required &&
471 (stream->adjust.v_total_max != adjust->v_total_max ||
472 stream->adjust.v_total_min != adjust->v_total_min)) {
473 stream->adjust.timing_adjust_pending = true;
474 return false;
475 }
476 }
477
478 dc_exit_ips_for_hw_access(dc);
479
480 stream->adjust.v_total_max = adjust->v_total_max;
481 stream->adjust.v_total_mid = adjust->v_total_mid;
482 stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
483 stream->adjust.v_total_min = adjust->v_total_min;
484 stream->adjust.allow_otg_v_count_halt = adjust->allow_otg_v_count_halt;
485
486 if (dc->caps.max_v_total != 0 &&
487 (adjust->v_total_max > dc->caps.max_v_total || adjust->v_total_min > dc->caps.max_v_total)) {
488 stream->adjust.timing_adjust_pending = false;
489 if (adjust->allow_otg_v_count_halt)
490 return set_long_vtotal(dc, stream, adjust);
491 else
492 return false;
493 }
494
495 for (i = 0; i < MAX_PIPES; i++) {
496 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
497
498 if (pipe->stream == stream && pipe->stream_res.tg) {
499 dc->hwss.set_drr(&pipe,
500 1,
501 *adjust);
502 stream->adjust.timing_adjust_pending = false;
503
504 if (dc->hwss.notify_cursor_offload_drr_update)
505 dc->hwss.notify_cursor_offload_drr_update(dc, dc->current_state, stream);
506
507 return true;
508 }
509 }
510
511 return false;
512}
513
514/**445/**
515 * dc_stream_get_last_used_drr_vtotal - Looks up the pipe context of446 * dc_stream_get_last_used_drr_vtotal - Looks up the pipe context of
516 * dc_stream_state and gets the last VTOTAL used by DRR (Dynamic Refresh Rate)447 * dc_stream_state and gets the last VTOTAL used by DRR (Dynamic Refresh Rate)
@@ -1274,6 +1205,8 @@ static void dc_update_visual_confirm_color(struct dc *dc, struct dc_state *conte · 757 unmodified lines
1274 get_fams2_visual_confirm_color(dc, context, pipe_ctx, &(pipe_ctx->visual_confirm_color));1205 get_fams2_visual_confirm_color(dc, context, pipe_ctx, &(pipe_ctx->visual_confirm_color));
1275 else if (dc->debug.visual_confirm == VISUAL_CONFIRM_VABC)1206 else if (dc->debug.visual_confirm == VISUAL_CONFIRM_VABC)
1276 get_vabc_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));1207 get_vabc_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));
1208 else if (dc->debug.visual_confirm == VISUAL_CONFIRM_BOOSTED_REFRESH_RATE)
1209 get_refresh_rate_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));
1277 }1210 }
1278 }1211 }
1279}1212}
@@ -1323,6 +1256,83 @@ void dc_get_visual_confirm_for_stream( · 43 unmodified lines
1323 }1256 }
1324}1257}
1325 1258
1259/**
1260 * dc_stream_adjust_vmin_vmax - look up pipe context & update parts of DRR
1261 * @dc: dc reference
1262 * @stream: Initial dc stream state
1263 * @adjust: Updated parameters for vertical_total_min and vertical_total_max
1264 *
1265 * Looks up the pipe context of dc_stream_state and updates the
1266 * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh
1267 * Rate, which is a power-saving feature that targets reducing panel
1268 * refresh rate while the screen is static
1269 *
1270 * Return: %true if the pipe context is found and adjusted;
1271 * %false if the pipe context is not found.
1272 */
1273bool dc_stream_adjust_vmin_vmax(struct dc *dc,
1274 struct dc_stream_state *stream,
1275 struct dc_crtc_timing_adjust *adjust)
1276{
1277 int i;
1278
1279 /*
1280 * Don't adjust DRR while there's bandwidth optimizations pending to
1281 * avoid conflicting with firmware updates.
1282 */
1283 if (dc->ctx->dce_version > DCE_VERSION_MAX) {
1284 if (dc->optimized_required &&
1285 (stream->adjust.v_total_max != adjust->v_total_max ||
1286 stream->adjust.v_total_min != adjust->v_total_min)) {
1287 stream->adjust.timing_adjust_pending = true;
1288 return false;
1289 }
1290 }
1291
1292 dc_exit_ips_for_hw_access(dc);
1293
1294 stream->adjust.v_total_max = adjust->v_total_max;
1295 stream->adjust.v_total_mid = adjust->v_total_mid;
1296 stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
1297 stream->adjust.v_total_min = adjust->v_total_min;
1298 stream->adjust.allow_otg_v_count_halt = adjust->allow_otg_v_count_halt;
1299
1300 if (dc->caps.max_v_total != 0 &&
1301 (adjust->v_total_max > dc->caps.max_v_total || adjust->v_total_min > dc->caps.max_v_total)) {
1302 stream->adjust.timing_adjust_pending = false;
1303 if (adjust->allow_otg_v_count_halt)
1304 return set_long_vtotal(dc, stream, adjust);
1305 else
1306 return false;
1307 }
1308
1309 for (i = 0; i < MAX_PIPES; i++) {
1310 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
1311
1312 if (pipe->stream == stream && pipe->stream_res.tg) {
1313 dc->hwss.set_drr(&pipe,
1314 1,
1315 *adjust);
1316 stream->adjust.timing_adjust_pending = false;
1317
1318 if (dc->debug.visual_confirm == VISUAL_CONFIRM_BOOSTED_REFRESH_RATE) {
1319 if (pipe->stream && pipe->plane_state) {
1320 dc_update_visual_confirm_color(dc, dc->current_state, pipe);
1321 dc->hwss.update_visual_confirm_color(dc, pipe, pipe->plane_res.hubp->mpcc_id);
1322
1323 }
1324 }
1325
1326 if (dc->hwss.notify_cursor_offload_drr_update)
1327 dc->hwss.notify_cursor_offload_drr_update(dc, dc->current_state, stream);
1328
1329 return true;
1330 }
1331 }
1332
1333 return false;
1334}
1335
1326static void disable_dangling_plane(struct dc *dc, struct dc_state *context)1336static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
1327{1337{
1328 int i, j;1338 int i, j;
@@ -3064,7 +3074,7 @@ struct surface_update_descriptor dc_check_update_surfaces_for_stream( · 1735 unmodified lines
3064{3074{
3065 if (stream_update)3075 if (stream_update)
3066 stream_update->stream->update_flags.raw = 0;3076 stream_update->stream->update_flags.raw = 0;
3067 for (size_t i = 0; i < surface_count; i++)3077 for (int i = 0; i < surface_count; i++)
3068 updates[i].surface->update_flags.raw = 0;3078 updates[i].surface->update_flags.raw = 0;
3069 3079
3070 return check_update_surfaces_for_stream(check_config, updates, surface_count, stream_update);3080 return check_update_surfaces_for_stream(check_config, updates, surface_count, stream_update);
@@ -5540,6 +5550,9 @@ void dc_power_down_on_boot(struct dc *dc) · 2469 unmodified lines
5540{5550{
5541 if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW &&5551 if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW &&
5542 dc->hwss.power_down_on_boot) {5552 dc->hwss.power_down_on_boot) {
5553 if (dc->current_state->stream_count > 0)
5554 return;
5555
5543 if (dc->caps.ips_support)5556 if (dc->caps.ips_support)
5544 dc_exit_ips_for_hw_access(dc);5557 dc_exit_ips_for_hw_access(dc);
5545 dc->hwss.power_down_on_boot(dc);5558 dc->hwss.power_down_on_boot(dc);
@@ -5551,12 +5564,12 @@ void dc_set_power_state(struct dc *dc, enum dc_acpi_cm_power_state power_state) · 5 unmodified lines
5551 if (!dc->current_state)5564 if (!dc->current_state)
5552 return;5565 return;
5553 5566
5567 dc_exit_ips_for_hw_access(dc);
5568
5554 switch (power_state) {5569 switch (power_state) {
5555 case DC_ACPI_CM_POWER_STATE_D0:5570 case DC_ACPI_CM_POWER_STATE_D0:
5556 dc_state_construct(dc, dc->current_state);5571 dc_state_construct(dc, dc->current_state);
5557 5572
5558 dc_exit_ips_for_hw_access(dc);
5559
5560 dc_z10_restore(dc);5573 dc_z10_restore(dc);
5561 5574
5562 dc_dmub_srv_notify_fw_dc_power_state(dc->ctx->dmub_srv, power_state);5575 dc_dmub_srv_notify_fw_dc_power_state(dc->ctx->dmub_srv, power_state);
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c+59−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.2 * Copyright 2015-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -846,6 +846,16 @@ void hwss_build_fast_sequence(struct dc *dc, · 840 unmodified lines
846 block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;846 block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;
847 (*num_steps)++;847 (*num_steps)++;
848 }848 }
849 if (current_mpc_pipe->plane_state->update_flags.bits.cm_hist_change) {
850 block_sequence[*num_steps].params.control_cm_hist_params.dpp
851 = current_mpc_pipe->plane_res.dpp;
852 block_sequence[*num_steps].params.control_cm_hist_params.cm_hist_control
853 = current_mpc_pipe->plane_state->cm_hist_control;
854 block_sequence[*num_steps].params.control_cm_hist_params.color_space
855 = current_mpc_pipe->plane_state->color_space;
856 block_sequence[*num_steps].func = DPP_PROGRAM_CM_HIST;
857 (*num_steps)++;
858 }
849 }859 }
850 if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) {860 if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) {
851 block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc;861 block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc;
@@ -1029,6 +1039,9 @@ void hwss_execute_sequence(struct dc *dc, · 177 unmodified lines
1029 case HUBP_PROGRAM_MCACHE_ID:1039 case HUBP_PROGRAM_MCACHE_ID:
1030 hwss_program_mcache_id_and_split_coordinate(params);1040 hwss_program_mcache_id_and_split_coordinate(params);
1031 break;1041 break;
1042 case DPP_PROGRAM_CM_HIST:
1043 hwss_program_cm_hist(params);
1044 break;
1032 case PROGRAM_CURSOR_UPDATE_NOW:1045 case PROGRAM_CURSOR_UPDATE_NOW:
1033 dc->hwss.program_cursor_offload_now(1046 dc->hwss.program_cursor_offload_now(
1034 params->program_cursor_update_now_params.dc,1047 params->program_cursor_update_now_params.dc,
@@ -2054,6 +2067,16 @@ void hwss_program_mcache_id_and_split_coordinate(union block_sequence_params *pa · 1019 unmodified lines
2054 2067
2055}2068}
2056 2069
2070void hwss_program_cm_hist(union block_sequence_params *params)
2071{
2072 struct dpp *dpp = params->control_cm_hist_params.dpp;
2073
2074 if (dpp && dpp->funcs->dpp_cm_hist_control)
2075 dpp->funcs->dpp_cm_hist_control(dpp,
2076 params->control_cm_hist_params.cm_hist_control,
2077 params->control_cm_hist_params.color_space);
2078}
2079
2057void get_surface_tile_visual_confirm_color(2080void get_surface_tile_visual_confirm_color(
2058 struct pipe_ctx *pipe_ctx,2081 struct pipe_ctx *pipe_ctx,
2059 struct tg_color *color)2082 struct tg_color *color)
@@ -3370,6 +3393,20 @@ void hwss_add_opp_program_bit_depth_reduction(struct block_sequence_state *seq_s · 1310 unmodified lines
3370 }3393 }
3371}3394}
3372 3395
3396void hwss_add_dpp_program_cm_hist(struct block_sequence_state *seq_state,
3397 struct dpp *dpp,
3398 struct cm_hist_control cm_hist_control,
3399 enum dc_color_space color_space)
3400{
3401 if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
3402 seq_state->steps[*seq_state->num_steps].func = DPP_PROGRAM_CM_HIST;
3403 seq_state->steps[*seq_state->num_steps].params.control_cm_hist_params.dpp = dpp;
3404 seq_state->steps[*seq_state->num_steps].params.control_cm_hist_params.cm_hist_control = cm_hist_control;
3405 seq_state->steps[*seq_state->num_steps].params.control_cm_hist_params.color_space = color_space;
3406 (*seq_state->num_steps)++;
3407 }
3408}
3409
3373void hwss_add_dc_ip_request_cntl(struct block_sequence_state *seq_state,3410void hwss_add_dc_ip_request_cntl(struct block_sequence_state *seq_state,
3374 struct dc *dc,3411 struct dc *dc,
3375 bool enable)3412 bool enable)
@@ -4071,3 +4108,24 @@ void hwss_add_tg_get_frame_count(struct block_sequence_state *seq_state, · 695 unmodified lines
4071 (*seq_state->num_steps)++;4108 (*seq_state->num_steps)++;
4072 }4109 }
4073}4110}
4111
4112
4113void get_refresh_rate_confirm_color(struct pipe_ctx *pipe_ctx, struct tg_color *color)
4114{
4115 uint32_t color_value = MAX_TG_COLOR_VALUE;
4116 unsigned int refresh_rate = 0;
4117 uint32_t scaling_factor = 0;
4118 if (pipe_ctx && pipe_ctx->stream && color) {
4119 refresh_rate = (pipe_ctx->stream->timing.pix_clk_100hz * 100) / (pipe_ctx->stream->adjust.v_total_max * pipe_ctx->stream->timing.h_total);
4120
4121 uint32_t min_refresh_rate = pipe_ctx->stream->timing.min_refresh_in_uhz / 1000000;
4122 uint32_t max_refresh_rate = pipe_ctx->stream->timing.max_refresh_in_uhz / 1000000;
4123
4124 if (max_refresh_rate - min_refresh_rate)
4125 scaling_factor = MAX_TG_COLOR_VALUE * (refresh_rate - min_refresh_rate) / (max_refresh_rate - min_refresh_rate);
4126
4127 pipe_ctx->visual_confirm_color.color_r_cr = color_value;
4128 pipe_ctx->visual_confirm_color.color_g_y = scaling_factor;
4129 pipe_ctx->visual_confirm_color.color_b_cb = color_value;
4130 }
4131}
drivers/gpu/drm/amd/display/dc/core/dc_resource.c+7−0
@@ -78,6 +78,7 @@ · 77 unmodified lines
78#include "dcn351/dcn351_resource.h"78#include "dcn351/dcn351_resource.h"
79#include "dcn36/dcn36_resource.h"79#include "dcn36/dcn36_resource.h"
80#include "dcn401/dcn401_resource.h"80#include "dcn401/dcn401_resource.h"
81#include "dcn42/dcn42_resource.h"
81#if defined(CONFIG_DRM_AMD_DC_FP)82#if defined(CONFIG_DRM_AMD_DC_FP)
82#include "dc_spl_translate.h"83#include "dc_spl_translate.h"
83#endif84#endif
@@ -252,6 +253,9 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) · 168 unmodified lines
252 ASICREV_IS_GC_12_0_0_A0(asic_id.hw_internal_rev))253 ASICREV_IS_GC_12_0_0_A0(asic_id.hw_internal_rev))
253 dc_version = DCN_VERSION_4_01;254 dc_version = DCN_VERSION_4_01;
254 break;255 break;
256 case AMDGPU_FAMILY_GC_11_5_4:
257 dc_version = DCN_VERSION_4_2;
258 break;
255 default:259 default:
256 dc_version = DCE_VERSION_UNKNOWN;260 dc_version = DCE_VERSION_UNKNOWN;
257 break;261 break;
@@ -368,6 +372,9 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, · 110 unmodified lines
368 case DCN_VERSION_4_01:372 case DCN_VERSION_4_01:
369 res_pool = dcn401_create_resource_pool(init_data, dc);373 res_pool = dcn401_create_resource_pool(init_data, dc);
370 break;374 break;
375 case DCN_VERSION_4_2:
376 res_pool = dcn42_create_resource_pool(init_data, dc);
377 break;
371#endif /* CONFIG_DRM_AMD_DC_FP */378#endif /* CONFIG_DRM_AMD_DC_FP */
372 default:379 default:
373 break;380 break;
drivers/gpu/drm/amd/display/dc/dc.h+15−2
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012-2023 Advanced Micro Devices, Inc.2 * Copyright 2012-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -63,7 +63,7 @@ struct dcn_dsc_reg_state; · 57 unmodified lines
63struct dcn_optc_reg_state;63struct dcn_optc_reg_state;
64struct dcn_dccg_reg_state;64struct dcn_dccg_reg_state;
65 65
66#define DC_VER "3.2.369"66#define DC_VER "3.2.372"
67 67
68/**68/**
69 * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC69 * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC
@@ -581,6 +581,7 @@ enum visual_confirm { · 511 unmodified lines
581 VISUAL_CONFIRM_HW_CURSOR = 20,581 VISUAL_CONFIRM_HW_CURSOR = 20,
582 VISUAL_CONFIRM_VABC = 21,582 VISUAL_CONFIRM_VABC = 21,
583 VISUAL_CONFIRM_DCC = 22,583 VISUAL_CONFIRM_DCC = 22,
584 VISUAL_CONFIRM_BOOSTED_REFRESH_RATE = 23,
584 VISUAL_CONFIRM_EXPLICIT = 0x80000000,585 VISUAL_CONFIRM_EXPLICIT = 0x80000000,
585};586};
586 587
@@ -733,6 +734,8 @@ struct dc_clocks { · 146 unmodified lines
733 struct {734 struct {
734 uint8_t base_efficiency; //LP1735 uint8_t base_efficiency; //LP1
735 uint8_t low_power_efficiency; //LP2736 uint8_t low_power_efficiency; //LP2
737 uint8_t z8_stutter_efficiency;
738 int z8_stutter_period;
736 } stutter_efficiency;739 } stutter_efficiency;
737};740};
738 741
@@ -1211,6 +1214,7 @@ struct dc_debug_options { · 472 unmodified lines
1211 unsigned int num_fast_flips_to_steady_state_override;1214 unsigned int num_fast_flips_to_steady_state_override;
1212 bool enable_dmu_recovery;1215 bool enable_dmu_recovery;
1213 unsigned int force_vmin_threshold;1216 unsigned int force_vmin_threshold;
1217 bool enable_otg_frame_sync_pwa;
1214};1218};
1215 1219
1216 1220
@@ -1419,6 +1423,7 @@ struct dc_plane_status { · 202 unmodified lines
1419 struct dc_plane_address current_address;1423 struct dc_plane_address current_address;
1420 bool is_flip_pending;1424 bool is_flip_pending;
1421 bool is_right_eye;1425 bool is_right_eye;
1426 struct cm_hist cm_hist;
1422};1427};
1423 1428
1424union surface_update_flags {1429union surface_update_flags {
@@ -1455,6 +1460,7 @@ union surface_update_flags { · 30 unmodified lines
1455 uint32_t mcm_transfer_function_enable_change:1; /* disable or enable MCM transfer func */1460 uint32_t mcm_transfer_function_enable_change:1; /* disable or enable MCM transfer func */
1456 uint32_t full_update:1;1461 uint32_t full_update:1;
1457 uint32_t sdr_white_level_nits:1;1462 uint32_t sdr_white_level_nits:1;
1463 uint32_t cm_hist_change:1;
1458 } bits;1464 } bits;
1459 1465
1460 uint32_t raw;1466 uint32_t raw;
@@ -1539,6 +1545,7 @@ struct dc_plane_state { · 78 unmodified lines
1539 int sharpness_level;1545 int sharpness_level;
1540 enum linear_light_scaling linear_light_scaling;1546 enum linear_light_scaling linear_light_scaling;
1541 unsigned int sdr_white_level_nits;1547 unsigned int sdr_white_level_nits;
1548 struct cm_hist_control cm_hist_control;
1542 struct spl_sharpness_range sharpness_range;1549 struct spl_sharpness_range sharpness_range;
1543 enum sharpness_range_source sharpness_source;1550 enum sharpness_range_source sharpness_source;
1544};1551};
@@ -1682,6 +1689,10 @@ struct dc_scratch_space { · 137 unmodified lines
1682 struct panel_cntl *panel_cntl;1689 struct panel_cntl *panel_cntl;
1683 struct link_encoder *link_enc;1690 struct link_encoder *link_enc;
1684 struct graphics_object_id link_id;1691 struct graphics_object_id link_id;
1692
1693 /* External encoder eg. NUTMEG or TRAVIS used on CIK APUs. */
1694 struct graphics_object_id ext_enc_id;
1695
1685 /* Endpoint type distinguishes display endpoints which do not have entries1696 /* Endpoint type distinguishes display endpoints which do not have entries
1686 * in the BIOS connector table from those that do. Helps when tracking link1697 * in the BIOS connector table from those that do. Helps when tracking link
1687 * encoder to display endpoint assignments.1698 * encoder to display endpoint assignments.
@@ -1843,6 +1854,7 @@ struct dc_fast_update { · 155 unmodified lines
1843 struct dc_transfer_func *out_transfer_func;1854 struct dc_transfer_func *out_transfer_func;
1844 struct dc_csc_transform *output_csc_transform;1855 struct dc_csc_transform *output_csc_transform;
1845 const struct dc_csc_transform *cursor_csc_color_matrix;1856 const struct dc_csc_transform *cursor_csc_color_matrix;
1857 struct cm_hist_control *cm_hist_control;
1846};1858};
1847 1859
1848struct dc_surface_update {1860struct dc_surface_update {
@@ -1875,6 +1887,7 @@ struct dc_surface_update { · 26 unmodified lines
1875 const struct dc_csc_transform *cursor_csc_color_matrix;1887 const struct dc_csc_transform *cursor_csc_color_matrix;
1876 unsigned int sdr_white_level_nits;1888 unsigned int sdr_white_level_nits;
1877 struct dc_bias_and_scale bias_and_scale;1889 struct dc_bias_and_scale bias_and_scale;
1890 struct cm_hist_control *cm_hist_control;
1878};1891};
1879 1892
1880struct dc_underflow_debug_data {1893struct dc_underflow_debug_data {
drivers/gpu/drm/amd/display/dc/dc_bios_types.h+4−2
@@ -97,11 +97,13 @@ struct dc_vbios_funcs { · 96 unmodified lines
97 enum bp_result (*encoder_control)(97 enum bp_result (*encoder_control)(
98 struct dc_bios *bios,98 struct dc_bios *bios,
99 struct bp_encoder_control *cntl);99 struct bp_encoder_control *cntl);
100 enum bp_result (*external_encoder_control)(
101 struct dc_bios *bios,
102 struct bp_external_encoder_control *cntl);
100 enum bp_result (*dac_load_detection)(103 enum bp_result (*dac_load_detection)(
101 struct dc_bios *bios,104 struct dc_bios *bios,
102 enum engine_id engine_id,105 enum engine_id engine_id,
103 enum dal_device_type device_type,106 struct graphics_object_id ext_enc_id);
104 uint32_t enum_id);
105 enum bp_result (*transmitter_control)(107 enum bp_result (*transmitter_control)(
106 struct dc_bios *bios,108 struct dc_bios *bios,
107 struct bp_transmitter_control *cntl);109 struct bp_transmitter_control *cntl);
drivers/gpu/drm/amd/display/dc/dc_dp_types.h+2−2
@@ -947,8 +947,8 @@ union dp_tun_cap_support { · 946 unmodified lines
947/* DPCD[0xE000E] DP_IN_ADAPTER_INFO register. */947/* DPCD[0xE000E] DP_IN_ADAPTER_INFO register. */
948union dpia_info {948union dpia_info {
949 struct {949 struct {
950 uint8_t dpia_num :5;950 uint8_t dpia_num :6;
951 uint8_t rsvd :3;951 uint8_t rsvd :2;
952 } bits;952 } bits;
953 uint8_t raw;953 uint8_t raw;
954};954};
drivers/gpu/drm/amd/display/dc/dc_helper.c+2−0
@@ -751,6 +751,8 @@ char *dce_version_to_string(const int version) · 750 unmodified lines
751 return "DCN 3.6";751 return "DCN 3.6";
752 case DCN_VERSION_4_01:752 case DCN_VERSION_4_01:
753 return "DCN 4.0.1";753 return "DCN 4.0.1";
754 case DCN_VERSION_4_2:
755 return "DCN 4.2";
754 default:756 default:
755 return "Unknown";757 return "Unknown";
756 }758 }
drivers/gpu/drm/amd/display/dc/dc_hw_types.h+73−0
@@ -271,6 +271,15 @@ enum tile_split_values_new { · 270 unmodified lines
271 DC_SURF_TILE_SPLIT_1KB = 0x4,271 DC_SURF_TILE_SPLIT_1KB = 0x4,
272};272};
273 273
274enum otg_pwa_sync_mode {
275 DC_OTG_PWA_FRAME_SYNC_MODE_VSYNC = 0x0,
276 DC_OTG_PWA_FRAME_SYNC_MODE_VSTARTUP = 0x1,
277};
278struct otc_pwa_frame_sync {
279 enum otg_pwa_sync_mode pwa_sync_mode;
280 uint32_t pwa_frame_sync_line_offset;
281};
282
274/* TODO: These values come from hardware spec. We need to readdress this283/* TODO: These values come from hardware spec. We need to readdress this
275 * if they ever change.284 * if they ever change.
276 */285 */
@@ -1137,6 +1146,7 @@ struct mcif_buf_params { · 860 unmodified lines
1137 unsigned int warmup_pitch;1146 unsigned int warmup_pitch;
1138 unsigned int swlock;1147 unsigned int swlock;
1139 unsigned int p_vmid;1148 unsigned int p_vmid;
1149 uint8_t tmz_id;
1140};1150};
1141 1151
1142 1152
@@ -1162,5 +1172,68 @@ struct phy_state { · 19 unmodified lines
1162 enum symclk_state symclk_state;1172 enum symclk_state symclk_state;
1163};1173};
1164 1174
1175enum cm_hist_tap_point {
1176 CM_HIST_TAP_POINT_1,
1177 CM_HIST_TAP_POINT_2,
1178 CM_HIST_TAP_POINT_3,
1179 CM_HIST_TAP_POINT_4,
1180};
1181
1182enum cm_hist_src {
1183 CM_HIST_SRC1,
1184 CM_HIST_SRC2,
1185 CM_HIST_SRC3,
1186};
1187
1188enum cm_hist_format {
1189 CM_HIST_FORMAT_FIXED_POINT,
1190 CM_HIST_FORMAT_FP16_POS,
1191 CM_HIST_FORMAT_FP16_POS_AND_NEG,
1192};
1193
1194enum cm_hist_read_channel_mask {
1195 CM_HIST_READ_DISABLED,
1196 CM_HIST_READ_CH1,
1197 CM_HIST_READ_CH2,
1198 CM_HIST_READ_CH1_CH2,
1199 CM_HIST_READ_CH3,
1200 CM_HIST_READ_CH1_CH3,
1201 CM_HIST_READ_CH2_CH3,
1202 CM_HIST_READ_ALL,
1203};
1204
1205enum cm_hist_src1_mode {
1206 CM_HIST_SRC1_MODE_R_OR_CR,
1207 CM_HIST_SRC1_MODE_MAX_RGB,
1208};
1209
1210enum cm_hist_src2_mode {
1211 CM_HIST_SRC2_MODE_G_OR_Y,
1212 CM_HIST_SRC2_MODE_RGB_TO_Y,
1213};
1214
1215enum cm_hist_src3_mode {
1216 CM_HIST_SRC3_MODE_B_OR_CB,
1217 CM_HIST_SRC3_MODE_MIN_RGB,
1218};
1219
1220struct cm_hist_control {
1221 enum cm_hist_tap_point tap_point;
1222 uint32_t channels_enabled;
1223 enum cm_hist_src1_mode src_1_select;
1224 enum cm_hist_src2_mode src_2_select;
1225 enum cm_hist_src3_mode src_3_select;
1226 enum cm_hist_src ch1_src;
1227 enum cm_hist_src ch2_src;
1228 enum cm_hist_src ch3_src;
1229 enum cm_hist_format format;
1230 enum cm_hist_read_channel_mask read_channel_mask;
1231};
1232
1233struct cm_hist {
1234 uint32_t ch1[256];
1235 uint32_t ch2[256];
1236 uint32_t ch3[256];
1237};
1165#endif /* DC_HW_TYPES_H */1238#endif /* DC_HW_TYPES_H */
1166 1239
drivers/gpu/drm/amd/display/dc/dc_types.h+5−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.2 * Copyright 2012-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -1346,6 +1346,7 @@ enum dc_cm2_gpu_mem_layout { · 1340 unmodified lines
1346 1346
1347enum dc_cm2_gpu_mem_pixel_component_order {1347enum dc_cm2_gpu_mem_pixel_component_order {
1348 DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA,1348 DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA,
1349 DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_BGRA
1349};1350};
1350 1351
1351enum dc_cm2_gpu_mem_format {1352enum dc_cm2_gpu_mem_format {
@@ -1367,6 +1368,9 @@ struct dc_cm2_gpu_mem_format_parameters { · 15 unmodified lines
1367 1368
1368enum dc_cm2_gpu_mem_size {1369enum dc_cm2_gpu_mem_size {
1369 DC_CM2_GPU_MEM_SIZE_171717,1370 DC_CM2_GPU_MEM_SIZE_171717,
1371 DC_CM2_GPU_MEM_SIZE_333333,
1372 DC_CM2_GPU_MEM_SIZE_454545,
1373 DC_CM2_GPU_MEM_SIZE_656565,
1370 DC_CM2_GPU_MEM_SIZE_TRANSFORMED,1374 DC_CM2_GPU_MEM_SIZE_TRANSFORMED,
1371};1375};
1372 1376
drivers/gpu/drm/amd/display/dc/dccg/Makefile+10−1
@@ -1,5 +1,5 @@
1 1
2# Copyright 2022 Advanced Micro Devices, Inc.2# Copyright 2022-2026 Advanced Micro Devices, Inc.
3#3#
4# Permission is hereby granted, free of charge, to any person obtaining a4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),5# copy of this software and associated documentation files (the "Software"),
@@ -100,4 +100,13 @@ DCCG_DCN401 = dcn401_dccg.o · 94 unmodified lines
100AMD_DAL_DCCG_DCN401 = $(addprefix $(AMDDALPATH)/dc/dccg/dcn401/,$(DCCG_DCN401))100AMD_DAL_DCCG_DCN401 = $(addprefix $(AMDDALPATH)/dc/dccg/dcn401/,$(DCCG_DCN401))
101 101
102AMD_DISPLAY_FILES += $(AMD_DAL_DCCG_DCN401)102AMD_DISPLAY_FILES += $(AMD_DAL_DCCG_DCN401)
103
104###############################################################################
105# DCN42
106###############################################################################
107DCCG_DCN42 = dcn42_dccg.o
108
109AMD_DAL_DCCG_DCN42 = $(addprefix $(AMDDALPATH)/dc/dccg/dcn42/,$(DCCG_DCN42))
110
111AMD_DISPLAY_FILES += $(AMD_DAL_DCCG_DCN42)
103endif112endif
drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h+14−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2018 Advanced Micro Devices, Inc.2 * Copyright 2018-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -362,6 +362,16 @@ · 356 unmodified lines
362 type SYMCLK32_LE3_EN;\362 type SYMCLK32_LE3_EN;\
363 type DP_DTO_ENABLE[MAX_PIPES];363 type DP_DTO_ENABLE[MAX_PIPES];
364 364
365#define DCCG42_REG_FIELD_LIST(type) \
366 type OTG0_ADD_PIXEL;\
367 type OTG1_ADD_PIXEL;\
368 type OTG2_ADD_PIXEL;\
369 type OTG0_DROP_PIXEL;\
370 type OTG1_DROP_PIXEL;\
371 type OTG2_DROP_PIXEL;\
372 type OTG3_ADD_PIXEL;\
373 type OTG3_DROP_PIXEL;
374
365struct dccg_shift {375struct dccg_shift {
366 DCCG_REG_FIELD_LIST(uint8_t)376 DCCG_REG_FIELD_LIST(uint8_t)
367 DCCG3_REG_FIELD_LIST(uint8_t)377 DCCG3_REG_FIELD_LIST(uint8_t)
@@ -370,6 +380,7 @@ struct dccg_shift { · 2 unmodified lines
370 DCCG32_REG_FIELD_LIST(uint8_t)380 DCCG32_REG_FIELD_LIST(uint8_t)
371 DCCG35_REG_FIELD_LIST(uint8_t)381 DCCG35_REG_FIELD_LIST(uint8_t)
372 DCCG401_REG_FIELD_LIST(uint8_t)382 DCCG401_REG_FIELD_LIST(uint8_t)
383 DCCG42_REG_FIELD_LIST(uint8_t)
373};384};
374 385
375struct dccg_mask {386struct dccg_mask {
@@ -380,6 +391,7 @@ struct dccg_mask { · 4 unmodified lines
380 DCCG32_REG_FIELD_LIST(uint32_t)391 DCCG32_REG_FIELD_LIST(uint32_t)
381 DCCG35_REG_FIELD_LIST(uint32_t)392 DCCG35_REG_FIELD_LIST(uint32_t)
382 DCCG401_REG_FIELD_LIST(uint32_t)393 DCCG401_REG_FIELD_LIST(uint32_t)
394 DCCG42_REG_FIELD_LIST(uint32_t)
383};395};
384 396
385#define DCCG_REG_VARIABLE_LIST \397#define DCCG_REG_VARIABLE_LIST \
@@ -493,6 +505,7 @@ struct dccg_mask { · 107 unmodified lines
493 505
494struct dccg_registers {506struct dccg_registers {
495 DCCG_REG_VARIABLE_LIST;507 DCCG_REG_VARIABLE_LIST;
508 uint32_t OTG_ADD_DROP_PIXEL_CNTL;
496};509};
497 510
498struct dcn_dccg {511struct dcn_dccg {
drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.c+278−0
@@ -0,0 +1,278 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "reg_helper.h"
6#include "core_types.h"
7#include "dcn35/dcn35_dccg.h"
8#include "dcn42_dccg.h"
9
10#define TO_DCN_DCCG(dccg)\
11 container_of(dccg, struct dcn_dccg, base)
12
13#define REG(reg) \
14 (dccg_dcn->regs->reg)
15
16#undef FN
17#define FN(reg_name, field_name) \
18 dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
19
20#define CTX \
21 dccg_dcn->base.ctx
22#define DC_LOGGER \
23 dccg->ctx->logger
24
25void dccg42_otg_add_pixel(struct dccg *dccg,
26 uint32_t otg_inst)
27{
28 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
29
30 switch (otg_inst) {
31 case 0:
32 REG_UPDATE(OTG_ADD_DROP_PIXEL_CNTL,
33 OTG0_ADD_PIXEL, 1);
34 break;
35 case 1:
36 REG_UPDATE(OTG_ADD_DROP_PIXEL_CNTL,
37 OTG1_ADD_PIXEL, 1);
38 break;
39 case 2:
40 REG_UPDATE(OTG_ADD_DROP_PIXEL_CNTL,
41 OTG2_ADD_PIXEL, 1);
42 break;
43 case 3:
44 REG_UPDATE(OTG_ADD_DROP_PIXEL_CNTL,
45 OTG3_ADD_PIXEL, 1);
46 break;
47 default:
48 ASSERT(0);
49 }
50}
51
52void dccg42_otg_drop_pixel(struct dccg *dccg,
53 uint32_t otg_inst)
54{
55 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
56
57 switch (otg_inst) {
58 case 0:
59 REG_UPDATE(OTG_ADD_DROP_PIXEL_CNTL,
60 OTG0_DROP_PIXEL, 1);
61 break;
62 case 1:
63 REG_UPDATE(OTG_ADD_DROP_PIXEL_CNTL,
64 OTG1_DROP_PIXEL, 1);
65 break;
66 case 2:
67 REG_UPDATE(OTG_ADD_DROP_PIXEL_CNTL,
68 OTG2_DROP_PIXEL, 1);
69 break;
70 case 3:
71 REG_UPDATE(OTG_ADD_DROP_PIXEL_CNTL,
72 OTG3_DROP_PIXEL, 1);
73 break;
74 default:
75 ASSERT(0);
76 }
77}
78
79void dccg42_enable_global_fgcg(struct dccg *dccg, bool value)
80{
81 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
82
83 if (dccg->ctx->dc->debug.disable_clock_gate)
84 value = false;
85 REG_UPDATE(DCCG_GLOBAL_FGCG_REP_CNTL, DCCG_GLOBAL_FGCG_REP_DIS, !value);
86}
87
88void dccg42_set_physymclk(
89 struct dccg *dccg,
90 int phy_inst,
91 enum physymclk_clock_source clk_src,
92 bool force_enable)
93{
94 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
95
96 switch (phy_inst) {
97 case 0:
98 if (force_enable) {
99 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
100 PHYASYMCLK_ROOT_GATE_DISABLE, 1);
101 REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
102 PHYASYMCLK_EN, 1,
103 PHYASYMCLK_SRC_SEL, clk_src);
104 } else {
105 REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
106 PHYASYMCLK_EN, 0,
107 PHYASYMCLK_SRC_SEL, 0);
108 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
109 PHYASYMCLK_ROOT_GATE_DISABLE,
110 dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk ? 0 : 1);
111 }
112 break;
113 case 1:
114 if (force_enable) {
115 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
116 PHYBSYMCLK_ROOT_GATE_DISABLE, 1);
117 REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
118 PHYBSYMCLK_EN, 1,
119 PHYBSYMCLK_SRC_SEL, clk_src);
120 } else {
121 REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
122 PHYBSYMCLK_EN, 0,
123 PHYBSYMCLK_SRC_SEL, 0);
124 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
125 PHYBSYMCLK_ROOT_GATE_DISABLE,
126 dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk ? 0 : 1);
127 }
128 break;
129 case 2:
130 if (force_enable) {
131 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
132 PHYCSYMCLK_ROOT_GATE_DISABLE, 1);
133 REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
134 PHYCSYMCLK_EN, 1,
135 PHYCSYMCLK_SRC_SEL, clk_src);
136 } else {
137 REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
138 PHYCSYMCLK_EN, 0,
139 PHYCSYMCLK_SRC_SEL, 0);
140 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
141 PHYCSYMCLK_ROOT_GATE_DISABLE,
142 dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk ? 0 : 1);
143 }
144 break;
145 case 3:
146 if (force_enable) {
147 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
148 PHYDSYMCLK_ROOT_GATE_DISABLE, 1);
149 REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
150 PHYDSYMCLK_EN, 1,
151 PHYDSYMCLK_SRC_SEL, clk_src);
152 } else {
153 REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
154 PHYDSYMCLK_EN, 0,
155 PHYDSYMCLK_SRC_SEL, 0);
156 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
157 PHYDSYMCLK_ROOT_GATE_DISABLE,
158 dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk ? 0 : 1);
159 }
160 break;
161 case 4:
162 if (force_enable) {
163 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
164 PHYESYMCLK_ROOT_GATE_DISABLE, 1);
165 REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
166 PHYESYMCLK_EN, 1,
167 PHYESYMCLK_SRC_SEL, clk_src);
168 } else {
169 REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
170 PHYESYMCLK_EN, 0,
171 PHYESYMCLK_SRC_SEL, 0);
172 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
173 PHYESYMCLK_ROOT_GATE_DISABLE,
174 dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk ? 0 : 1);
175 }
176 break;
177 default:
178 BREAK_TO_DEBUGGER();
179 return;
180 }
181}
182
183static void dccg42_init(struct dccg *dccg)
184{
185 int otg_inst;
186 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
187
188 /* Set HPO stream encoder to use refclk to avoid case where PHY is
189 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
190 * will cause DCN to hang.
191 */
192 for (otg_inst = 0; otg_inst < 4; otg_inst++)
193 dccg35_disable_symclk32_se(dccg, otg_inst);
194
195 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) {
196 dccg401_disable_symclk32_le(dccg, 0);
197 dccg401_disable_symclk32_le(dccg, 1);
198 dccg401_disable_symclk32_le(dccg, 2);
199 dccg401_disable_symclk32_le(dccg, 3);
200 }
201
202 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
203 dccg401_disable_dpstreamclk(dccg, 0);
204 dccg401_disable_dpstreamclk(dccg, 1);
205 dccg401_disable_dpstreamclk(dccg, 2);
206 dccg401_disable_dpstreamclk(dccg, 3);
207 }
208 if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) {
209 REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2,
210 PHYASYMCLK_ROOT_GATE_DISABLE, 1,
211 PHYBSYMCLK_ROOT_GATE_DISABLE, 1,
212 PHYCSYMCLK_ROOT_GATE_DISABLE, 1,
213 PHYDSYMCLK_ROOT_GATE_DISABLE, 1,
214 PHYESYMCLK_ROOT_GATE_DISABLE, 1);
215 }
216}
217
218
219static const struct dccg_funcs dccg42_funcs = {
220 .update_dpp_dto = dccg35_update_dpp_dto,
221 .dpp_root_clock_control = dccg35_dpp_root_clock_control,
222 .get_dccg_ref_freq = dccg401_get_dccg_ref_freq,
223 .dccg_init = dccg42_init,
224 .set_dpstreamclk = dccg401_set_dpstreamclk,
225 /* Redundant with above^ */
226 /* .set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating, */
227 .enable_symclk32_se = dccg31_enable_symclk32_se,
228 .disable_symclk32_se = dccg35_disable_symclk32_se,
229 .enable_symclk32_le = dccg401_enable_symclk32_le,
230 .disable_symclk32_le = dccg401_disable_symclk32_le,
231 .set_symclk32_le_root_clock_gating = dccg31_set_symclk32_le_root_clock_gating,
232 .set_physymclk = dccg42_set_physymclk,
233 .set_dtbclk_dto = NULL,
234 .set_dto_dscclk = dccg401_set_dto_dscclk,
235 .set_ref_dscclk = dccg401_set_ref_dscclk,
236 .set_valid_pixel_rate = NULL,
237 .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
238 .set_audio_dtbclk_dto = NULL,
239 .otg_add_pixel = dccg42_otg_add_pixel,
240 .otg_drop_pixel = dccg42_otg_drop_pixel,
241 .disable_dsc = dccg35_disable_dscclk,
242 .enable_dsc = dccg35_enable_dscclk,
243 .set_pixel_rate_div = dccg401_set_pixel_rate_div,
244 .get_pixel_rate_div = dccg401_get_pixel_rate_div,
245 .trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync,
246 .set_dp_dto = dccg401_set_dp_dto,
247 .enable_symclk_se = dccg35_enable_symclk_se,
248 .disable_symclk_se = dccg35_disable_symclk_se,
249 .set_dtbclk_p_src = dccg401_set_dtbclk_p_src,
250 .dccg_root_gate_disable_control = dccg35_root_gate_disable_control,
251 .dccg_read_reg_state = dccg31_read_reg_state,
252 .dccg_enable_global_fgcg = dccg42_enable_global_fgcg,
253};
254
255struct dccg *dccg42_create(
256 struct dc_context *ctx,
257 const struct dccg_registers *regs,
258 const struct dccg_shift *dccg_shift,
259 const struct dccg_mask *dccg_mask)
260{
261 struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
262 struct dccg *base;
263
264 if (dccg_dcn == NULL) {
265 BREAK_TO_DEBUGGER();
266 return NULL;
267 }
268
269 base = &dccg_dcn->base;
270 base->ctx = ctx;
271 base->funcs = &dccg42_funcs;
272
273 dccg_dcn->regs = regs;
274 dccg_dcn->dccg_shift = dccg_shift;
275 dccg_dcn->dccg_mask = dccg_mask;
276
277 return &dccg_dcn->base;
278}
drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.h+263−0
@@ -0,0 +1,263 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2024-2026 Advanced Micro Devices, 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: AMD
24 *
25 */
26
27#ifndef __DCN42_DCCG_H__
28#define __DCN42_DCCG_H__
29
30#include "dcn401/dcn401_dccg.h"
31
32#define DCCG_MASK_SH_LIST_DCN42_COMMON(mask_sh) \
33 DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 0, mask_sh),\
34 DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 1, mask_sh),\
35 DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 2, mask_sh),\
36 DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 3, mask_sh),\
37 DCCG_SF(DPPCLK_CTRL, DPPCLK0_EN, mask_sh),\
38 DCCG_SF(DPPCLK_CTRL, DPPCLK1_EN, mask_sh),\
39 DCCG_SF(DPPCLK_CTRL, DPPCLK2_EN, mask_sh),\
40 DCCG_SF(DPPCLK_CTRL, DPPCLK3_EN, mask_sh),\
41 DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_STEP_DELAY, mask_sh),\
42 DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_STEP_SIZE, mask_sh),\
43 DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_FREQ_RAMP_DONE, mask_sh),\
44 DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_MAX_ERRDET_CYCLES, mask_sh),\
45 DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DCCG_FIFO_ERRDET_RESET, mask_sh),\
46 DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DCCG_FIFO_ERRDET_STATE, mask_sh),\
47 DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DCCG_FIFO_ERRDET_OVR_EN, mask_sh),\
48 DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_CHG_FWD_CORR_DISABLE, mask_sh),\
49 DCCG_SF(DPPCLK0_DTO_PARAM, DPPCLK0_DTO_PHASE, mask_sh),\
50 DCCG_SF(DPPCLK0_DTO_PARAM, DPPCLK0_DTO_MODULO, mask_sh),\
51 DCCG_SF(HDMICHARCLK0_CLOCK_CNTL, HDMICHARCLK0_EN, mask_sh),\
52 DCCG_SF(HDMICHARCLK0_CLOCK_CNTL, HDMICHARCLK0_SRC_SEL, mask_sh),\
53 DCCG_SF(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_EN, mask_sh),\
54 DCCG_SF(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_SRC_SEL, mask_sh),\
55 DCCG_SF(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_EN, mask_sh),\
56 DCCG_SF(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_SRC_SEL, mask_sh),\
57 DCCG_SF(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_EN, mask_sh),\
58 DCCG_SF(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_SRC_SEL, mask_sh),\
59 DCCG_SF(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_EN, mask_sh),\
60 DCCG_SF(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_SRC_SEL, mask_sh),\
61 DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN, mask_sh),\
62 DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN, mask_sh),\
63 DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN, mask_sh),\
64 DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN, mask_sh),\
65 DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK0_SRC_SEL, mask_sh),\
66 DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK1_SRC_SEL, mask_sh),\
67 DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK2_SRC_SEL, mask_sh),\
68 DCCG_SF(DPSTREAMCLK_CNTL, DPSTREAMCLK3_SRC_SEL, mask_sh),\
69 DCCG_SF(HDMISTREAMCLK_CNTL, HDMISTREAMCLK0_EN, mask_sh),\
70 DCCG_SF(HDMISTREAMCLK_CNTL, HDMISTREAMCLK0_SRC_SEL, mask_sh),\
71 DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE0_SRC_SEL, mask_sh),\
72 DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE1_SRC_SEL, mask_sh),\
73 DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE2_SRC_SEL, mask_sh),\
74 DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE3_SRC_SEL, mask_sh),\
75 DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE0_EN, mask_sh),\
76 DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE1_EN, mask_sh),\
77 DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE2_EN, mask_sh),\
78 DCCG_SF(SYMCLK32_SE_CNTL, SYMCLK32_SE3_EN, mask_sh),\
79 DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE0_SRC_SEL, mask_sh),\
80 DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE1_SRC_SEL, mask_sh),\
81 DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE2_SRC_SEL, mask_sh),\
82 DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE3_SRC_SEL, mask_sh),\
83 DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE0_EN, mask_sh),\
84 DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE1_EN, mask_sh),\
85 DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE2_EN, mask_sh),\
86 DCCG_SF(SYMCLK32_LE_CNTL, SYMCLK32_LE3_EN, mask_sh),\
87 DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 0, mask_sh),\
88 DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 1, mask_sh),\
89 DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 2, mask_sh),\
90 DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 3, mask_sh),\
91 DCCG_SF(OTG_ADD_DROP_PIXEL_CNTL, OTG0_ADD_PIXEL, mask_sh),\
92 DCCG_SF(OTG_ADD_DROP_PIXEL_CNTL, OTG1_ADD_PIXEL, mask_sh),\
93 DCCG_SF(OTG_ADD_DROP_PIXEL_CNTL, OTG2_ADD_PIXEL, mask_sh),\
94 DCCG_SF(OTG_ADD_DROP_PIXEL_CNTL, OTG3_ADD_PIXEL, mask_sh),\
95 DCCG_SF(OTG_ADD_DROP_PIXEL_CNTL, OTG0_DROP_PIXEL, mask_sh),\
96 DCCG_SF(OTG_ADD_DROP_PIXEL_CNTL, OTG1_DROP_PIXEL, mask_sh),\
97 DCCG_SF(OTG_ADD_DROP_PIXEL_CNTL, OTG2_DROP_PIXEL, mask_sh),\
98 DCCG_SF(OTG_ADD_DROP_PIXEL_CNTL, OTG3_DROP_PIXEL, mask_sh),\
99 DCCG_SF(OTG_PIXEL_RATE_DIV, OTG0_TMDS_PIXEL_RATE_DIV, mask_sh),\
100 DCCG_SF(OTG_PIXEL_RATE_DIV, DPDTO0_INT, mask_sh),\
101 DCCG_SF(OTG_PIXEL_RATE_DIV, OTG1_TMDS_PIXEL_RATE_DIV, mask_sh),\
102 DCCG_SF(OTG_PIXEL_RATE_DIV, DPDTO1_INT, mask_sh),\
103 DCCG_SF(OTG_PIXEL_RATE_DIV, OTG2_TMDS_PIXEL_RATE_DIV, mask_sh),\
104 DCCG_SF(OTG_PIXEL_RATE_DIV, DPDTO2_INT, mask_sh),\
105 DCCG_SF(OTG_PIXEL_RATE_DIV, OTG3_TMDS_PIXEL_RATE_DIV, mask_sh),\
106 DCCG_SF(OTG_PIXEL_RATE_DIV, DPDTO3_INT, mask_sh),\
107 DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P0_SRC_SEL, mask_sh),\
108 DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P0_EN, mask_sh),\
109 DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P1_SRC_SEL, mask_sh),\
110 DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P1_EN, mask_sh),\
111 DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P2_SRC_SEL, mask_sh),\
112 DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P2_EN, mask_sh),\
113 DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_SRC_SEL, mask_sh),\
114 DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_EN, mask_sh),\
115 DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\
116 DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\
117 DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh),\
118 DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, mask_sh),\
119 DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\
120 DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, mask_sh),\
121 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, mask_sh),\
122 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_ROOT_GATE_DISABLE, mask_sh),\
123 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_ROOT_GATE_DISABLE, mask_sh),\
124 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_ROOT_GATE_DISABLE, mask_sh),\
125 DCCG_SFII(OTG, PIXEL_RATE_CNTL, DP_DTO, ENABLE, 0, mask_sh),\
126 DCCG_SFII(OTG, PIXEL_RATE_CNTL, DP_DTO, ENABLE, 1, mask_sh),\
127 DCCG_SFII(OTG, PIXEL_RATE_CNTL, DP_DTO, ENABLE, 2, mask_sh),\
128 DCCG_SFII(OTG, PIXEL_RATE_CNTL, DP_DTO, ENABLE, 3, mask_sh),\
129 DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 0, mask_sh),\
130 DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 1, mask_sh),\
131 DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 2, mask_sh),\
132 DCCG_SFII(OTG, PIXEL_RATE_CNTL, PIPE, DTO_SRC_SEL, 3, mask_sh),\
133 DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK0_EN, mask_sh),\
134 DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK1_EN, mask_sh),\
135 DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK2_EN, mask_sh),\
136 DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK3_EN, mask_sh),\
137 DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_PHASE, mask_sh),\
138 DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_MODULO, mask_sh),\
139 DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_PHASE, mask_sh),\
140 DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_MODULO, mask_sh),\
141 DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_PHASE, mask_sh),\
142 DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_MODULO, mask_sh),\
143 DCCG_SF(DCCG_GATE_DISABLE_CNTL, DISPCLK_DCCG_GATE_DISABLE, mask_sh),\
144 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, HDMICHARCLK0_GATE_DISABLE, mask_sh),\
145 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, HDMISTREAMCLK0_GATE_DISABLE, mask_sh),\
146 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_FE_GATE_DISABLE, mask_sh),\
147 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, SYMCLKB_FE_GATE_DISABLE, mask_sh),\
148 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, SYMCLKC_FE_GATE_DISABLE, mask_sh),\
149 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, SYMCLKD_FE_GATE_DISABLE, mask_sh),\
150 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_GATE_DISABLE, mask_sh),\
151 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, SYMCLKB_GATE_DISABLE, mask_sh),\
152 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, SYMCLKC_GATE_DISABLE, mask_sh),\
153 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, SYMCLKD_GATE_DISABLE, mask_sh),\
154 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, mask_sh),\
155 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_ROOT_GATE_DISABLE, mask_sh),\
156 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_ROOT_GATE_DISABLE, mask_sh),\
157 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_ROOT_GATE_DISABLE, mask_sh),\
158 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE0_GATE_DISABLE, mask_sh),\
159 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE1_GATE_DISABLE, mask_sh),\
160 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE2_GATE_DISABLE, mask_sh),\
161 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE3_GATE_DISABLE, mask_sh),\
162 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE0_GATE_DISABLE, mask_sh),\
163 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE1_GATE_DISABLE, mask_sh),\
164 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE2_GATE_DISABLE, mask_sh),\
165 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE3_GATE_DISABLE, mask_sh),\
166 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_SE0_GATE_DISABLE, mask_sh),\
167 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_SE1_GATE_DISABLE, mask_sh),\
168 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_SE2_GATE_DISABLE, mask_sh),\
169 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_SE3_GATE_DISABLE, mask_sh),\
170 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_LE0_GATE_DISABLE, mask_sh),\
171 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_LE1_GATE_DISABLE, mask_sh),\
172 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_LE2_GATE_DISABLE, mask_sh),\
173 DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_LE3_GATE_DISABLE, mask_sh),\
174 DCCG_SF(DCCG_GATE_DISABLE_CNTL4, HDMICHARCLK0_ROOT_GATE_DISABLE, mask_sh),\
175 DCCG_SF(DCCG_GATE_DISABLE_CNTL4, PHYA_REFCLK_ROOT_GATE_DISABLE, mask_sh),\
176 DCCG_SF(DCCG_GATE_DISABLE_CNTL4, PHYB_REFCLK_ROOT_GATE_DISABLE, mask_sh),\
177 DCCG_SF(DCCG_GATE_DISABLE_CNTL4, PHYC_REFCLK_ROOT_GATE_DISABLE, mask_sh),\
178 DCCG_SF(DCCG_GATE_DISABLE_CNTL4, PHYD_REFCLK_ROOT_GATE_DISABLE, mask_sh),\
179 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, mask_sh),\
180 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, mask_sh),\
181 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, mask_sh),\
182 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, mask_sh),\
183 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_FE_ROOT_GATE_DISABLE, mask_sh),\
184 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_FE_ROOT_GATE_DISABLE, mask_sh),\
185 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_FE_ROOT_GATE_DISABLE, mask_sh),\
186 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, mask_sh),\
187 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, mask_sh),\
188 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, mask_sh),\
189 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, mask_sh),\
190 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, mask_sh),\
191 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_ROOT_GATE_DISABLE, mask_sh),\
192 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_ROOT_GATE_DISABLE, mask_sh),\
193 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_ROOT_GATE_DISABLE, mask_sh),\
194 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_ROOT_GATE_DISABLE, mask_sh),\
195 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_GATE_DISABLE, mask_sh),\
196 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_GATE_DISABLE, mask_sh),\
197 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_GATE_DISABLE, mask_sh),\
198 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_GATE_DISABLE, mask_sh),\
199 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, mask_sh),\
200 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, mask_sh),\
201 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, mask_sh),\
202 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, mask_sh),\
203 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, mask_sh),\
204 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, mask_sh),\
205 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, mask_sh),\
206 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, HDMISTREAMCLK0_ROOT_GATE_DISABLE, mask_sh),\
207 DCCG_SF(SYMCLKA_CLOCK_ENABLE, SYMCLKA_CLOCK_ENABLE, mask_sh),\
208 DCCG_SF(SYMCLKB_CLOCK_ENABLE, SYMCLKB_CLOCK_ENABLE, mask_sh),\
209 DCCG_SF(SYMCLKC_CLOCK_ENABLE, SYMCLKC_CLOCK_ENABLE, mask_sh),\
210 DCCG_SF(SYMCLKD_CLOCK_ENABLE, SYMCLKD_CLOCK_ENABLE, mask_sh),\
211 DCCG_SF(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, mask_sh),\
212 DCCG_SF(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, mask_sh),\
213 DCCG_SF(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, mask_sh),\
214 DCCG_SF(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_EN, mask_sh),\
215 DCCG_SF(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_SRC_SEL, mask_sh),\
216 DCCG_SF(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_SRC_SEL, mask_sh),\
217 DCCG_SF(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_SRC_SEL, mask_sh),\
218 DCCG_SF(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_SRC_SEL, mask_sh)
219
220#define DCCG_MASK_SH_LIST_DCN42(mask_sh) \
221 DCCG_MASK_SH_LIST_DCN42_COMMON(mask_sh),\
222 DCCG_SF(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_EN, mask_sh),\
223 DCCG_SF(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_SRC_SEL, mask_sh),\
224 DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_PHASE, mask_sh),\
225 DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_MODULO, mask_sh),\
226 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_ROOT_GATE_DISABLE, mask_sh),\
227 DCCG_SF(DSCCLK3_DTO_PARAM, DSCCLK3_DTO_PHASE, mask_sh),\
228 DCCG_SF(DSCCLK3_DTO_PARAM, DSCCLK3_DTO_MODULO, mask_sh),\
229 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_ROOT_GATE_DISABLE, mask_sh),\
230 DCCG_SF(DCCG_GATE_DISABLE_CNTL4, PHYE_REFCLK_ROOT_GATE_DISABLE, mask_sh),\
231 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, mask_sh),\
232 DCCG_SF(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_ROOT_GATE_DISABLE, mask_sh),\
233 DCCG_SF(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, mask_sh),\
234 DCCG_SF(SYMCLKA_CLOCK_ENABLE, SYMCLKA_SRC_SEL, mask_sh),\
235 DCCG_SF(SYMCLKB_CLOCK_ENABLE, SYMCLKB_SRC_SEL, mask_sh),\
236 DCCG_SF(SYMCLKC_CLOCK_ENABLE, SYMCLKC_SRC_SEL, mask_sh),\
237 DCCG_SF(SYMCLKD_CLOCK_ENABLE, SYMCLKD_SRC_SEL, mask_sh),\
238 DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_SRC_SEL, mask_sh),\
239 DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_CLOCK_ENABLE, mask_sh),\
240 DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_EN, mask_sh),\
241 DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_SRC_SEL, mask_sh)
242
243
244void dccg42_otg_add_pixel(struct dccg *dccg,
245 uint32_t otg_inst);
246
247void dccg42_otg_drop_pixel(struct dccg *dccg,
248 uint32_t otg_inst);
249void dccg42_enable_global_fgcg(struct dccg *dccg, bool value);
250
251void dccg42_set_physymclk(
252 struct dccg *dccg,
253 int phy_inst,
254 enum physymclk_clock_source clk_src,
255 bool force_enable);
256
257struct dccg *dccg42_create(
258 struct dc_context *ctx,
259 const struct dccg_registers *regs,
260 const struct dccg_shift *dccg_shift,
261 const struct dccg_mask *dccg_mask);
262
263#endif //__DCN42_DCCG_H__
drivers/gpu/drm/amd/display/dc/dce/dce_abm.h+59−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012-16 Advanced Micro Devices, Inc.2 * Copyright 2012-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -300,6 +300,64 @@ · 294 unmodified lines
300 ABM_SF(ABM0_DC_ABM1_HG_BIN_57_64_SHIFT_INDEX, \300 ABM_SF(ABM0_DC_ABM1_HG_BIN_57_64_SHIFT_INDEX, \
301 ABM1_HG_BIN_57_64_SHIFT_INDEX, mask_sh)301 ABM1_HG_BIN_57_64_SHIFT_INDEX, mask_sh)
302 302
303#define ABM_MASK_SH_LIST_DCN42(mask_sh) \
304 ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \
305 ABM1_HG_NUM_OF_BINS_SEL, mask_sh), \
306 ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \
307 ABM1_HG_VMAX_SEL, mask_sh), \
308 ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \
309 ABM1_HG_BIN_BITWIDTH_SIZE_SEL, mask_sh), \
310 ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \
311 ABM1_IPCSC_COEFF_SEL_R, mask_sh), \
312 ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \
313 ABM1_IPCSC_COEFF_SEL_G, mask_sh), \
314 ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \
315 ABM1_IPCSC_COEFF_SEL_B, mask_sh), \
316 ABM_SF(ABM0_BL1_PWM_CURRENT_ABM_LEVEL, \
317 BL1_PWM_CURRENT_ABM_LEVEL, mask_sh), \
318 ABM_SF(ABM0_BL1_PWM_TARGET_ABM_LEVEL, \
319 BL1_PWM_TARGET_ABM_LEVEL, mask_sh), \
320 ABM_SF(ABM0_BL1_PWM_USER_LEVEL, \
321 BL1_PWM_USER_LEVEL, mask_sh), \
322 ABM_SF(ABM0_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \
323 ABM1_LS_MIN_PIXEL_VALUE_THRES, mask_sh), \
324 ABM_SF(ABM0_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \
325 ABM1_LS_MAX_PIXEL_VALUE_THRES, mask_sh), \
326 ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \
327 ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
328 ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \
329 ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
330 ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \
331 ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
332 ABM_SF(ABM0_DC_ABM1_ACE_OFFSET_SLOPE_DATA, \
333 ABM1_ACE_SLOPE_DATA, mask_sh), \
334 ABM_SF(ABM0_DC_ABM1_ACE_OFFSET_SLOPE_DATA, \
335 ABM1_ACE_OFFSET_DATA, mask_sh), \
336 ABM_SF(ABM0_DC_ABM1_ACE_PWL_CNTL, \
337 ABM1_ACE_OFFSET_SLOPE_INDEX, mask_sh), \
338 ABM_SF(ABM0_DC_ABM1_ACE_PWL_CNTL, \
339 ABM1_ACE_IGNORE_MASTER_LOCK_EN, mask_sh), \
340 ABM_SF(ABM0_DC_ABM1_ACE_PWL_CNTL, \
341 ABM1_ACE_READBACK_DB_REG_VALUE_EN, mask_sh), \
342 ABM_SF(ABM0_DC_ABM1_ACE_PWL_CNTL, \
343 ABM1_ACE_DBUF_REG_UPDATE_PENDING, mask_sh), \
344 ABM_SF(ABM0_DC_ABM1_ACE_PWL_CNTL, \
345 ABM1_ACE_LOCK, mask_sh), \
346 ABM_SF(ABM0_DC_ABM1_HG_RESULT_DATA, \
347 ABM1_HG_RESULT_DATA, mask_sh), \
348 ABM_SF(ABM0_DC_ABM1_HG_RESULT_INDEX, \
349 ABM1_HG_RESULT_INDEX, mask_sh), \
350 ABM_SF(ABM0_DC_ABM1_HG_BIN_33_40_SHIFT_INDEX, \
351 ABM1_HG_BIN_33_40_SHIFT_INDEX, mask_sh), \
352 ABM_SF(ABM0_DC_ABM1_HG_BIN_33_64_SHIFT_FLAG, \
353 ABM1_HG_BIN_33_64_SHIFT_FLAG, mask_sh), \
354 ABM_SF(ABM0_DC_ABM1_HG_BIN_41_48_SHIFT_INDEX, \
355 ABM1_HG_BIN_41_48_SHIFT_INDEX, mask_sh), \
356 ABM_SF(ABM0_DC_ABM1_HG_BIN_49_56_SHIFT_INDEX, \
357 ABM1_HG_BIN_49_56_SHIFT_INDEX, mask_sh), \
358 ABM_SF(ABM0_DC_ABM1_HG_BIN_57_64_SHIFT_INDEX, \
359 ABM1_HG_BIN_57_64_SHIFT_INDEX, mask_sh)
360
303#define ABM_REG_FIELD_LIST(type) \361#define ABM_REG_FIELD_LIST(type) \
304 type ABM1_HG_NUM_OF_BINS_SEL; \362 type ABM1_HG_NUM_OF_BINS_SEL; \
305 type ABM1_HG_VMAX_SEL; \363 type ABM1_HG_VMAX_SEL; \
drivers/gpu/drm/amd/display/dc/dce/dce_audio.c+0−131
@@ -1150,98 +1150,6 @@ void dce_aud_wall_dto_setup( · 1149 unmodified lines
1150 }1150 }
1151}1151}
1152 1152
1153#if defined(CONFIG_DRM_AMD_DC_SI)
1154static void dce60_aud_wall_dto_setup(
1155 struct audio *audio,
1156 enum signal_type signal,
1157 const struct audio_crtc_info *crtc_info,
1158 const struct audio_pll_info *pll_info)
1159{
1160 struct dce_audio *aud = DCE_AUD(audio);
1161
1162 struct azalia_clock_info clock_info = { 0 };
1163
1164 if (dc_is_hdmi_signal(signal)) {
1165 uint32_t src_sel;
1166
1167 /*DTO0 Programming goal:
1168 -generate 24MHz, 128*Fs from 24MHz
1169 -use DTO0 when an active HDMI port is connected
1170 (optionally a DP is connected) */
1171
1172 /* calculate DTO settings */
1173 get_azalia_clock_info_hdmi(
1174 crtc_info->requested_pixel_clock_100Hz,
1175 crtc_info->calculated_pixel_clock_100Hz,
1176 &clock_info);
1177
1178 DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
1179 "calculated_pixel_clock_100Hz =%d\n"\
1180 "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
1181 crtc_info->requested_pixel_clock_100Hz,\
1182 crtc_info->calculated_pixel_clock_100Hz,\
1183 clock_info.audio_dto_module,\
1184 clock_info.audio_dto_phase);
1185
1186 /* On TN/SI, Program DTO source select and DTO select before
1187 programming DTO modulo and DTO phase. These bits must be
1188 programmed first, otherwise there will be no HDMI audio at boot
1189 up. This is a HW sequence change (different from old ASICs).
1190 Caution when changing this programming sequence.
1191
1192 HDMI enabled, using DTO0
1193 program master CRTC for DTO0 */
1194 src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
1195 REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
1196 DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
1197 DCCG_AUDIO_DTO_SEL, 0);
1198
1199 /* module */
1200 REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
1201 DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
1202
1203 /* phase */
1204 REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
1205 DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
1206 } else {
1207 /*DTO1 Programming goal:
1208 -generate 24MHz, 128*Fs from 24MHz (DCE6 does not support 512*Fs)
1209 -default is to used DTO1, and switch to DTO0 when an audio
1210 master HDMI port is connected
1211 -use as default for DP
1212
1213 calculate DTO settings */
1214 get_azalia_clock_info_dp(
1215 crtc_info->requested_pixel_clock_100Hz,
1216 pll_info,
1217 &clock_info);
1218
1219 /* Program DTO select before programming DTO modulo and DTO
1220 phase. default to use DTO1 */
1221
1222 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
1223 DCCG_AUDIO_DTO_SEL, 1);
1224
1225 /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
1226 * Cannot select 512fs for DP
1227 *
1228 * DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask
1229 */
1230
1231 /* module */
1232 REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
1233 DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
1234
1235 /* phase */
1236 REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
1237 DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
1238
1239 /* DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask in DCCG_AUDIO_DTO_SOURCE reg */
1240
1241 }
1242}
1243#endif
1244
1245static bool dce_aud_endpoint_valid(struct audio *audio)1153static bool dce_aud_endpoint_valid(struct audio *audio)
1246{1154{
1247 uint32_t value;1155 uint32_t value;
@@ -1303,18 +1211,6 @@ static const struct audio_funcs funcs = { · 55 unmodified lines
1303 .destroy = dce_aud_destroy,1211 .destroy = dce_aud_destroy,
1304};1212};
1305 1213
1306#if defined(CONFIG_DRM_AMD_DC_SI)
1307static const struct audio_funcs dce60_funcs = {
1308 .endpoint_valid = dce_aud_endpoint_valid,
1309 .hw_init = dce_aud_hw_init,
1310 .wall_dto_setup = dce60_aud_wall_dto_setup,
1311 .az_enable = dce_aud_az_enable,
1312 .az_disable = dce_aud_az_disable,
1313 .az_configure = dce_aud_az_configure,
1314 .destroy = dce_aud_destroy,
1315};
1316#endif
1317
1318void dce_aud_destroy(struct audio **audio)1214void dce_aud_destroy(struct audio **audio)
1319{1215{
1320 struct dce_audio *aud = DCE_AUD(*audio);1216 struct dce_audio *aud = DCE_AUD(*audio);
@@ -1347,30 +1243,3 @@ struct audio *dce_audio_create( · 26 unmodified lines
1347 audio->masks = masks;1243 audio->masks = masks;
1348 return &audio->base;1244 return &audio->base;
1349}1245}
1350
1351#if defined(CONFIG_DRM_AMD_DC_SI)
1352struct audio *dce60_audio_create(
1353 struct dc_context *ctx,
1354 unsigned int inst,
1355 const struct dce_audio_registers *reg,
1356 const struct dce_audio_shift *shifts,
1357 const struct dce_audio_mask *masks
1358 )
1359{
1360 struct dce_audio *audio = kzalloc_obj(*audio);
1361
1362 if (audio == NULL) {
1363 ASSERT_CRITICAL(audio);
1364 return NULL;
1365 }
1366
1367 audio->base.ctx = ctx;
1368 audio->base.inst = inst;
1369 audio->base.funcs = &dce60_funcs;
1370
1371 audio->regs = reg;
1372 audio->shifts = shifts;
1373 audio->masks = masks;
1374 return &audio->base;
1375}
1376#endif
drivers/gpu/drm/amd/display/dc/dce/dce_audio.h+0−9
@@ -151,15 +151,6 @@ struct audio *dce_audio_create( · 150 unmodified lines
151 const struct dce_audio_shift *shifts,151 const struct dce_audio_shift *shifts,
152 const struct dce_audio_mask *masks);152 const struct dce_audio_mask *masks);
153 153
154#if defined(CONFIG_DRM_AMD_DC_SI)
155struct audio *dce60_audio_create(
156 struct dc_context *ctx,
157 unsigned int inst,
158 const struct dce_audio_registers *reg,
159 const struct dce_audio_shift *shifts,
160 const struct dce_audio_mask *masks);
161#endif
162
163void dce_aud_destroy(struct audio **audio);154void dce_aud_destroy(struct audio **audio);
164 155
165void dce_aud_hw_init(struct audio *audio);156void dce_aud_hw_init(struct audio *audio);
drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c+0−966
@@ -1,966 +0,0 @@
1/*
2 * Copyright 2012-16 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: AMD
23 *
24 */
25
26#include <linux/slab.h>
27
28#include "dce_clk_mgr.h"
29
30#include "reg_helper.h"
31#include "dmcu.h"
32#include "core_types.h"
33#include "dal_asic_id.h"
34
35#define TO_DCE_CLK_MGR(clocks)\
36 container_of(clocks, struct dce_clk_mgr, base)
37
38#define REG(reg) \
39 (clk_mgr_dce->regs->reg)
40
41#undef FN
42#define FN(reg_name, field_name) \
43 clk_mgr_dce->clk_mgr_shift->field_name, clk_mgr_dce->clk_mgr_mask->field_name
44
45#define CTX \
46 clk_mgr_dce->base.ctx
47#define DC_LOGGER \
48 clk_mgr->ctx->logger
49
50/* Max clock values for each state indexed by "enum clocks_state": */
51static const struct state_dependent_clocks dce80_max_clks_by_state[] = {
52/* ClocksStateInvalid - should not be used */
53{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
54/* ClocksStateUltraLow - not expected to be used for DCE 8.0 */
55{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
56/* ClocksStateLow */
57{ .display_clk_khz = 352000, .pixel_clk_khz = 330000},
58/* ClocksStateNominal */
59{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 },
60/* ClocksStatePerformance */
61{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 } };
62
63static const struct state_dependent_clocks dce110_max_clks_by_state[] = {
64/*ClocksStateInvalid - should not be used*/
65{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
66/*ClocksStateUltraLow - currently by HW design team not supposed to be used*/
67{ .display_clk_khz = 352000, .pixel_clk_khz = 330000 },
68/*ClocksStateLow*/
69{ .display_clk_khz = 352000, .pixel_clk_khz = 330000 },
70/*ClocksStateNominal*/
71{ .display_clk_khz = 467000, .pixel_clk_khz = 400000 },
72/*ClocksStatePerformance*/
73{ .display_clk_khz = 643000, .pixel_clk_khz = 400000 } };
74
75static const struct state_dependent_clocks dce112_max_clks_by_state[] = {
76/*ClocksStateInvalid - should not be used*/
77{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
78/*ClocksStateUltraLow - currently by HW design team not supposed to be used*/
79{ .display_clk_khz = 389189, .pixel_clk_khz = 346672 },
80/*ClocksStateLow*/
81{ .display_clk_khz = 459000, .pixel_clk_khz = 400000 },
82/*ClocksStateNominal*/
83{ .display_clk_khz = 667000, .pixel_clk_khz = 600000 },
84/*ClocksStatePerformance*/
85{ .display_clk_khz = 1132000, .pixel_clk_khz = 600000 } };
86
87static const struct state_dependent_clocks dce120_max_clks_by_state[] = {
88/*ClocksStateInvalid - should not be used*/
89{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
90/*ClocksStateUltraLow - currently by HW design team not supposed to be used*/
91{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
92/*ClocksStateLow*/
93{ .display_clk_khz = 460000, .pixel_clk_khz = 400000 },
94/*ClocksStateNominal*/
95{ .display_clk_khz = 670000, .pixel_clk_khz = 600000 },
96/*ClocksStatePerformance*/
97{ .display_clk_khz = 1133000, .pixel_clk_khz = 600000 } };
98
99int dentist_get_divider_from_did(int did)
100{
101 if (did < DENTIST_BASE_DID_1)
102 did = DENTIST_BASE_DID_1;
103 if (did > DENTIST_MAX_DID)
104 did = DENTIST_MAX_DID;
105
106 if (did < DENTIST_BASE_DID_2) {
107 return DENTIST_DIVIDER_RANGE_1_START + DENTIST_DIVIDER_RANGE_1_STEP
108 * (did - DENTIST_BASE_DID_1);
109 } else if (did < DENTIST_BASE_DID_3) {
110 return DENTIST_DIVIDER_RANGE_2_START + DENTIST_DIVIDER_RANGE_2_STEP
111 * (did - DENTIST_BASE_DID_2);
112 } else if (did < DENTIST_BASE_DID_4) {
113 return DENTIST_DIVIDER_RANGE_3_START + DENTIST_DIVIDER_RANGE_3_STEP
114 * (did - DENTIST_BASE_DID_3);
115 } else {
116 return DENTIST_DIVIDER_RANGE_4_START + DENTIST_DIVIDER_RANGE_4_STEP
117 * (did - DENTIST_BASE_DID_4);
118 }
119}
120
121/* SW will adjust DP REF Clock average value for all purposes
122 * (DP DTO / DP Audio DTO and DP GTC)
123 if clock is spread for all cases:
124 -if SS enabled on DP Ref clock and HW de-spreading enabled with SW
125 calculations for DS_INCR/DS_MODULO (this is planned to be default case)
126 -if SS enabled on DP Ref clock and HW de-spreading enabled with HW
127 calculations (not planned to be used, but average clock should still
128 be valid)
129 -if SS enabled on DP Ref clock and HW de-spreading disabled
130 (should not be case with CIK) then SW should program all rates
131 generated according to average value (case as with previous ASICs)
132 */
133static int clk_mgr_adjust_dp_ref_freq_for_ss(struct dce_clk_mgr *clk_mgr_dce, int dp_ref_clk_khz)
134{
135 if (clk_mgr_dce->ss_on_dprefclk && clk_mgr_dce->dprefclk_ss_divider != 0) {
136 struct fixed31_32 ss_percentage = dc_fixpt_div_int(
137 dc_fixpt_from_fraction(clk_mgr_dce->dprefclk_ss_percentage,
138 clk_mgr_dce->dprefclk_ss_divider), 200);
139 struct fixed31_32 adj_dp_ref_clk_khz;
140
141 ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage);
142 adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz);
143 dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz);
144 }
145 return dp_ref_clk_khz;
146}
147
148static int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr)
149{
150 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
151 int dprefclk_wdivider;
152 int dprefclk_src_sel;
153 int dp_ref_clk_khz = 600000;
154 int target_div;
155
156 /* ASSERT DP Reference Clock source is from DFS*/
157 REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel);
158 ASSERT(dprefclk_src_sel == 0);
159
160 /* Read the mmDENTIST_DISPCLK_CNTL to get the currently
161 * programmed DID DENTIST_DPREFCLK_WDIVIDER*/
162 REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider);
163
164 /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/
165 target_div = dentist_get_divider_from_did(dprefclk_wdivider);
166
167 /* Calculate the current DFS clock, in kHz.*/
168 dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
169 * clk_mgr_dce->dentist_vco_freq_khz) / target_div;
170
171 return clk_mgr_adjust_dp_ref_freq_for_ss(clk_mgr_dce, dp_ref_clk_khz);
172}
173
174int dce12_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr)
175{
176 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
177
178 return clk_mgr_adjust_dp_ref_freq_for_ss(clk_mgr_dce, clk_mgr_dce->dprefclk_khz);
179}
180
181/* unit: in_khz before mode set, get pixel clock from context. ASIC register
182 * may not be programmed yet
183 */
184static uint32_t get_max_pixel_clock_for_all_paths(struct dc_state *context)
185{
186 uint32_t max_pix_clk = 0;
187 int i;
188
189 for (i = 0; i < MAX_PIPES; i++) {
190 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
191
192 if (pipe_ctx->stream == NULL)
193 continue;
194
195 /* do not check under lay */
196 if (pipe_ctx->top_pipe)
197 continue;
198
199 if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10 > max_pix_clk)
200 max_pix_clk = pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10;
201
202 /* raise clock state for HBR3/2 if required. Confirmed with HW DCE/DPCS
203 * logic for HBR3 still needs Nominal (0.8V) on VDDC rail
204 */
205 if (dc_is_dp_signal(pipe_ctx->stream->signal) &&
206 pipe_ctx->stream_res.pix_clk_params.requested_sym_clk > max_pix_clk)
207 max_pix_clk = pipe_ctx->stream_res.pix_clk_params.requested_sym_clk;
208 }
209
210 return max_pix_clk;
211}
212
213static enum dm_pp_clocks_state dce_get_required_clocks_state(
214 struct clk_mgr *clk_mgr,
215 struct dc_state *context)
216{
217 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
218 int i;
219 enum dm_pp_clocks_state low_req_clk;
220 int max_pix_clk = get_max_pixel_clock_for_all_paths(context);
221
222 /* Iterate from highest supported to lowest valid state, and update
223 * lowest RequiredState with the lowest state that satisfies
224 * all required clocks
225 */
226 for (i = clk_mgr_dce->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--)
227 if (context->bw_ctx.bw.dce.dispclk_khz >
228 clk_mgr_dce->max_clks_by_state[i].display_clk_khz
229 || max_pix_clk >
230 clk_mgr_dce->max_clks_by_state[i].pixel_clk_khz)
231 break;
232
233 low_req_clk = i + 1;
234 if (low_req_clk > clk_mgr_dce->max_clks_state) {
235 /* set max clock state for high phyclock, invalid on exceeding display clock */
236 if (clk_mgr_dce->max_clks_by_state[clk_mgr_dce->max_clks_state].display_clk_khz
237 < context->bw_ctx.bw.dce.dispclk_khz)
238 low_req_clk = DM_PP_CLOCKS_STATE_INVALID;
239 else
240 low_req_clk = clk_mgr_dce->max_clks_state;
241 }
242
243 return low_req_clk;
244}
245
246static int dce_set_clock(
247 struct clk_mgr *clk_mgr,
248 int requested_clk_khz)
249{
250 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
251 struct bp_pixel_clock_parameters pxl_clk_params = { 0 };
252 struct dc_bios *bp = clk_mgr->ctx->dc_bios;
253 int actual_clock = requested_clk_khz;
254 struct dmcu *dmcu = clk_mgr_dce->base.ctx->dc->res_pool->dmcu;
255
256 /* Make sure requested clock isn't lower than minimum threshold*/
257 if (requested_clk_khz > 0)
258 requested_clk_khz = max(requested_clk_khz,
259 clk_mgr_dce->dentist_vco_freq_khz / 64);
260
261 /* Prepare to program display clock*/
262 pxl_clk_params.target_pixel_clock_100hz = requested_clk_khz * 10;
263 pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
264
265 if (clk_mgr_dce->dfs_bypass_active)
266 pxl_clk_params.flags.SET_DISPCLK_DFS_BYPASS = true;
267
268 bp->funcs->program_display_engine_pll(bp, &pxl_clk_params);
269
270 if (clk_mgr_dce->dfs_bypass_active) {
271 /* Cache the fixed display clock*/
272 clk_mgr_dce->dfs_bypass_disp_clk =
273 pxl_clk_params.dfs_bypass_display_clock;
274 actual_clock = pxl_clk_params.dfs_bypass_display_clock;
275 }
276
277 /* from power down, we need mark the clock state as ClocksStateNominal
278 * from HWReset, so when resume we will call pplib voltage regulator.*/
279 if (requested_clk_khz == 0)
280 clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL;
281
282 if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu))
283 dmcu->funcs->set_psr_wait_loop(dmcu, actual_clock / 1000 / 7);
284
285 return actual_clock;
286}
287
288int dce112_set_clock(struct clk_mgr *clk_mgr, int requested_clk_khz)
289{
290 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
291 struct bp_set_dce_clock_parameters dce_clk_params;
292 struct dc_bios *bp = clk_mgr->ctx->dc_bios;
293 struct dc *core_dc = clk_mgr->ctx->dc;
294 struct dmcu *dmcu = core_dc->res_pool->dmcu;
295 int actual_clock = requested_clk_khz;
296 /* Prepare to program display clock*/
297 memset(&dce_clk_params, 0, sizeof(dce_clk_params));
298
299 /* Make sure requested clock isn't lower than minimum threshold*/
300 if (requested_clk_khz > 0)
301 requested_clk_khz = max(requested_clk_khz,
302 clk_mgr_dce->dentist_vco_freq_khz / 62);
303
304 dce_clk_params.target_clock_frequency = requested_clk_khz;
305 dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
306 dce_clk_params.clock_type = DCECLOCK_TYPE_DISPLAY_CLOCK;
307
308 bp->funcs->set_dce_clock(bp, &dce_clk_params);
309 actual_clock = dce_clk_params.target_clock_frequency;
310
311 /* from power down, we need mark the clock state as ClocksStateNominal
312 * from HWReset, so when resume we will call pplib voltage regulator.*/
313 if (requested_clk_khz == 0)
314 clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL;
315
316 /*Program DP ref Clock*/
317 /*VBIOS will determine DPREFCLK frequency, so we don't set it*/
318 dce_clk_params.target_clock_frequency = 0;
319 dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK;
320
321 if (!((clk_mgr->ctx->asic_id.chip_family == FAMILY_AI) &&
322 ASICREV_IS_VEGA20_P(clk_mgr->ctx->asic_id.hw_internal_rev)))
323 dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK =
324 (dce_clk_params.pll_id ==
325 CLOCK_SOURCE_COMBO_DISPLAY_PLL0);
326 else
327 dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = false;
328
329 bp->funcs->set_dce_clock(bp, &dce_clk_params);
330
331 if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
332 if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
333 if (clk_mgr_dce->dfs_bypass_disp_clk != actual_clock)
334 dmcu->funcs->set_psr_wait_loop(dmcu,
335 actual_clock / 1000 / 7);
336 }
337 }
338
339 clk_mgr_dce->dfs_bypass_disp_clk = actual_clock;
340 return actual_clock;
341}
342
343static void dce_clock_read_integrated_info(struct dce_clk_mgr *clk_mgr_dce)
344{
345 struct dc_debug_options *debug = &clk_mgr_dce->base.ctx->dc->debug;
346 struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios;
347 struct integrated_info info = { { { 0 } } };
348 struct dc_firmware_info fw_info = { { 0 } };
349 int i;
350
351 if (bp->integrated_info)
352 info = *bp->integrated_info;
353
354 clk_mgr_dce->dentist_vco_freq_khz = info.dentist_vco_freq;
355 if (clk_mgr_dce->dentist_vco_freq_khz == 0) {
356 bp->funcs->get_firmware_info(bp, &fw_info);
357 clk_mgr_dce->dentist_vco_freq_khz =
358 fw_info.smu_gpu_pll_output_freq;
359 if (clk_mgr_dce->dentist_vco_freq_khz == 0)
360 clk_mgr_dce->dentist_vco_freq_khz = 3600000;
361 }
362
363 /*update the maximum display clock for each power state*/
364 for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
365 enum dm_pp_clocks_state clk_state = DM_PP_CLOCKS_STATE_INVALID;
366
367 switch (i) {
368 case 0:
369 clk_state = DM_PP_CLOCKS_STATE_ULTRA_LOW;
370 break;
371
372 case 1:
373 clk_state = DM_PP_CLOCKS_STATE_LOW;
374 break;
375
376 case 2:
377 clk_state = DM_PP_CLOCKS_STATE_NOMINAL;
378 break;
379
380 case 3:
381 clk_state = DM_PP_CLOCKS_STATE_PERFORMANCE;
382 break;
383
384 default:
385 clk_state = DM_PP_CLOCKS_STATE_INVALID;
386 break;
387 }
388
389 /*Do not allow bad VBIOS/SBIOS to override with invalid values,
390 * check for > 100MHz*/
391 if (info.disp_clk_voltage[i].max_supported_clk >= 100000)
392 clk_mgr_dce->max_clks_by_state[clk_state].display_clk_khz =
393 info.disp_clk_voltage[i].max_supported_clk;
394 }
395
396 if (!debug->disable_dfs_bypass && bp->integrated_info)
397 if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE)
398 clk_mgr_dce->dfs_bypass_enabled = true;
399}
400
401void dce_clock_read_ss_info(struct dce_clk_mgr *clk_mgr_dce)
402{
403 struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios;
404 int ss_info_num = bp->funcs->get_ss_entry_number(
405 bp, AS_SIGNAL_TYPE_GPU_PLL);
406
407 if (ss_info_num) {
408 struct spread_spectrum_info info = { { 0 } };
409 enum bp_result result = bp->funcs->get_spread_spectrum_info(
410 bp, AS_SIGNAL_TYPE_GPU_PLL, 0, &info);
411
412 /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS
413 * even if SS not enabled and in that case
414 * SSInfo.spreadSpectrumPercentage !=0 would be sign
415 * that SS is enabled
416 */
417 if (result == BP_RESULT_OK &&
418 info.spread_spectrum_percentage != 0) {
419 clk_mgr_dce->ss_on_dprefclk = true;
420 clk_mgr_dce->dprefclk_ss_divider = info.spread_percentage_divider;
421
422 if (info.type.CENTER_MODE == 0) {
423 /* TODO: Currently for DP Reference clock we
424 * need only SS percentage for
425 * downspread */
426 clk_mgr_dce->dprefclk_ss_percentage =
427 info.spread_spectrum_percentage;
428 }
429
430 return;
431 }
432
433 result = bp->funcs->get_spread_spectrum_info(
434 bp, AS_SIGNAL_TYPE_DISPLAY_PORT, 0, &info);
435
436 /* Based on VBIOS, VBIOS will keep entry for DPREFCLK SS
437 * even if SS not enabled and in that case
438 * SSInfo.spreadSpectrumPercentage !=0 would be sign
439 * that SS is enabled
440 */
441 if (result == BP_RESULT_OK &&
442 info.spread_spectrum_percentage != 0) {
443 clk_mgr_dce->ss_on_dprefclk = true;
444 clk_mgr_dce->dprefclk_ss_divider = info.spread_percentage_divider;
445
446 if (info.type.CENTER_MODE == 0) {
447 /* Currently for DP Reference clock we
448 * need only SS percentage for
449 * downspread */
450 clk_mgr_dce->dprefclk_ss_percentage =
451 info.spread_spectrum_percentage;
452 }
453 if (clk_mgr_dce->base.ctx->dc->debug.ignore_dpref_ss)
454 clk_mgr_dce->dprefclk_ss_percentage = 0;
455 }
456 }
457}
458
459/**
460 * dce121_clock_patch_xgmi_ss_info() - Save XGMI spread spectrum info
461 * @clk_mgr: clock manager base structure
462 *
463 * Reads from VBIOS the XGMI spread spectrum info and saves it within
464 * the dce clock manager. This operation will overwrite the existing dprefclk
465 * SS values if the vBIOS query succeeds. Otherwise, it does nothing. It also
466 * sets the ->xgmi_enabled flag.
467 */
468void dce121_clock_patch_xgmi_ss_info(struct clk_mgr *clk_mgr)
469{
470 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
471 enum bp_result result;
472 struct spread_spectrum_info info = { { 0 } };
473 struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios;
474
475 clk_mgr_dce->xgmi_enabled = false;
476
477 result = bp->funcs->get_spread_spectrum_info(bp, AS_SIGNAL_TYPE_XGMI,
478 0, &info);
479 if (result == BP_RESULT_OK && info.spread_spectrum_percentage != 0) {
480 clk_mgr_dce->xgmi_enabled = true;
481 clk_mgr_dce->ss_on_dprefclk = true;
482 clk_mgr_dce->dprefclk_ss_divider =
483 info.spread_percentage_divider;
484
485 if (info.type.CENTER_MODE == 0) {
486 /* Currently for DP Reference clock we
487 * need only SS percentage for
488 * downspread */
489 clk_mgr_dce->dprefclk_ss_percentage =
490 info.spread_spectrum_percentage;
491 }
492 }
493}
494
495void dce110_fill_display_configs(
496 const struct dc_state *context,
497 struct dm_pp_display_configuration *pp_display_cfg)
498{
499 int j;
500 int num_cfgs = 0;
501
502 for (j = 0; j < context->stream_count; j++) {
503 int k;
504
505 const struct dc_stream_state *stream = context->streams[j];
506 struct dm_pp_single_disp_config *cfg =
507 &pp_display_cfg->disp_configs[num_cfgs];
508 const struct pipe_ctx *pipe_ctx = NULL;
509
510 for (k = 0; k < MAX_PIPES; k++)
511 if (stream == context->res_ctx.pipe_ctx[k].stream) {
512 pipe_ctx = &context->res_ctx.pipe_ctx[k];
513 break;
514 }
515
516 ASSERT(pipe_ctx != NULL);
517
518 /* only notify active stream */
519 if (stream->dpms_off)
520 continue;
521
522 num_cfgs++;
523 cfg->signal = pipe_ctx->stream->signal;
524 cfg->pipe_idx = pipe_ctx->stream_res.tg->inst;
525 cfg->src_height = stream->src.height;
526 cfg->src_width = stream->src.width;
527 cfg->ddi_channel_mapping =
528 stream->link->ddi_channel_mapping.raw;
529 cfg->transmitter =
530 stream->link->link_enc->transmitter;
531 cfg->link_settings.lane_count =
532 stream->link->cur_link_settings.lane_count;
533 cfg->link_settings.link_rate =
534 stream->link->cur_link_settings.link_rate;
535 cfg->link_settings.link_spread =
536 stream->link->cur_link_settings.link_spread;
537 cfg->sym_clock = stream->phy_pix_clk;
538 /* Round v_refresh*/
539 cfg->v_refresh = stream->timing.pix_clk_100hz * 100;
540 cfg->v_refresh /= stream->timing.h_total;
541 cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2)
542 / stream->timing.v_total;
543 }
544
545 pp_display_cfg->display_count = num_cfgs;
546}
547
548static uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context)
549{
550 uint8_t j;
551 uint32_t min_vertical_blank_time = -1;
552
553 for (j = 0; j < context->stream_count; j++) {
554 struct dc_stream_state *stream = context->streams[j];
555 uint32_t vertical_blank_in_pixels = 0;
556 uint32_t vertical_blank_time = 0;
557
558 vertical_blank_in_pixels = stream->timing.h_total *
559 (stream->timing.v_total
560 - stream->timing.v_addressable);
561
562 vertical_blank_time = vertical_blank_in_pixels
563 * 10000 / stream->timing.pix_clk_100hz;
564
565 if (min_vertical_blank_time > vertical_blank_time)
566 min_vertical_blank_time = vertical_blank_time;
567 }
568
569 return min_vertical_blank_time;
570}
571
572static int determine_sclk_from_bounding_box(
573 const struct dc *dc,
574 int required_sclk)
575{
576 int i;
577
578 /*
579 * Some asics do not give us sclk levels, so we just report the actual
580 * required sclk
581 */
582 if (dc->sclk_lvls.num_levels == 0)
583 return required_sclk;
584
585 for (i = 0; i < dc->sclk_lvls.num_levels; i++) {
586 if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk)
587 return dc->sclk_lvls.clocks_in_khz[i];
588 }
589 /*
590 * even maximum level could not satisfy requirement, this
591 * is unexpected at this stage, should have been caught at
592 * validation time
593 */
594 ASSERT(0);
595 return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1];
596}
597
598static void dce_pplib_apply_display_requirements(
599 struct dc *dc,
600 struct dc_state *context)
601{
602 struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
603
604 pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context);
605
606 dce110_fill_display_configs(context, pp_display_cfg);
607
608 if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0)
609 dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
610}
611
612static void dce11_pplib_apply_display_requirements(
613 struct dc *dc,
614 struct dc_state *context)
615{
616 struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
617
618 pp_display_cfg->all_displays_in_sync =
619 context->bw_ctx.bw.dce.all_displays_in_sync;
620 pp_display_cfg->nb_pstate_switch_disable =
621 context->bw_ctx.bw.dce.nbp_state_change_enable == false;
622 pp_display_cfg->cpu_cc6_disable =
623 context->bw_ctx.bw.dce.cpuc_state_change_enable == false;
624 pp_display_cfg->cpu_pstate_disable =
625 context->bw_ctx.bw.dce.cpup_state_change_enable == false;
626 pp_display_cfg->cpu_pstate_separation_time =
627 context->bw_ctx.bw.dce.blackout_recovery_time_us;
628
629 pp_display_cfg->min_memory_clock_khz = context->bw_ctx.bw.dce.yclk_khz
630 / MEMORY_TYPE_MULTIPLIER_CZ;
631
632 pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box(
633 dc,
634 context->bw_ctx.bw.dce.sclk_khz);
635
636 /*
637 * As workaround for >4x4K lightup set dcfclock to min_engine_clock value.
638 * This is not required for less than 5 displays,
639 * thus don't request decfclk in dc to avoid impact
640 * on power saving.
641 *
642 */
643 pp_display_cfg->min_dcfclock_khz = (context->stream_count > 4) ?
644 pp_display_cfg->min_engine_clock_khz : 0;
645
646 pp_display_cfg->min_engine_clock_deep_sleep_khz
647 = context->bw_ctx.bw.dce.sclk_deep_sleep_khz;
648
649 pp_display_cfg->avail_mclk_switch_time_us =
650 dce110_get_min_vblank_time_us(context);
651 /* TODO: dce11.2*/
652 pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0;
653
654 pp_display_cfg->disp_clk_khz = dc->res_pool->clk_mgr->clks.dispclk_khz;
655
656 dce110_fill_display_configs(context, pp_display_cfg);
657
658 /* TODO: is this still applicable?*/
659 if (pp_display_cfg->display_count == 1) {
660 const struct dc_crtc_timing *timing =
661 &context->streams[0]->timing;
662
663 pp_display_cfg->crtc_index =
664 pp_display_cfg->disp_configs[0].pipe_idx;
665 pp_display_cfg->line_time_in_us = timing->h_total * 10000 / timing->pix_clk_100hz;
666 }
667
668 if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0)
669 dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
670}
671
672static void dce_update_clocks(struct clk_mgr *clk_mgr,
673 struct dc_state *context,
674 bool safe_to_lower)
675{
676 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
677 struct dm_pp_power_level_change_request level_change_req;
678 int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz;
679
680 /*TODO: W/A for dal3 linux, investigate why this works */
681 if (!clk_mgr_dce->dfs_bypass_active)
682 patched_disp_clk = patched_disp_clk * 115 / 100;
683
684 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context);
685 /* get max clock state from PPLIB */
686 if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower)
687 || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) {
688 if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req))
689 clk_mgr_dce->cur_min_clks_state = level_change_req.power_level;
690 }
691
692 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) {
693 patched_disp_clk = dce_set_clock(clk_mgr, patched_disp_clk);
694 clk_mgr->clks.dispclk_khz = patched_disp_clk;
695 }
696 dce_pplib_apply_display_requirements(clk_mgr->ctx->dc, context);
697}
698
699static void dce11_update_clocks(struct clk_mgr *clk_mgr,
700 struct dc_state *context,
701 bool safe_to_lower)
702{
703 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
704 struct dm_pp_power_level_change_request level_change_req;
705 int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz;
706
707 /*TODO: W/A for dal3 linux, investigate why this works */
708 if (!clk_mgr_dce->dfs_bypass_active)
709 patched_disp_clk = patched_disp_clk * 115 / 100;
710
711 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context);
712 /* get max clock state from PPLIB */
713 if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower)
714 || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) {
715 if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req))
716 clk_mgr_dce->cur_min_clks_state = level_change_req.power_level;
717 }
718
719 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) {
720 context->bw_ctx.bw.dce.dispclk_khz = dce_set_clock(clk_mgr, patched_disp_clk);
721 clk_mgr->clks.dispclk_khz = patched_disp_clk;
722 }
723 dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context);
724}
725
726static void dce112_update_clocks(struct clk_mgr *clk_mgr,
727 struct dc_state *context,
728 bool safe_to_lower)
729{
730 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
731 struct dm_pp_power_level_change_request level_change_req;
732 int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz;
733
734 /*TODO: W/A for dal3 linux, investigate why this works */
735 if (!clk_mgr_dce->dfs_bypass_active)
736 patched_disp_clk = patched_disp_clk * 115 / 100;
737
738 level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context);
739 /* get max clock state from PPLIB */
740 if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower)
741 || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) {
742 if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req))
743 clk_mgr_dce->cur_min_clks_state = level_change_req.power_level;
744 }
745
746 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) {
747 patched_disp_clk = dce112_set_clock(clk_mgr, patched_disp_clk);
748 clk_mgr->clks.dispclk_khz = patched_disp_clk;
749 }
750 dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context);
751}
752
753static void dce12_update_clocks(struct clk_mgr *clk_mgr,
754 struct dc_state *context,
755 bool safe_to_lower)
756{
757 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr);
758 struct dm_pp_clock_for_voltage_req clock_voltage_req = {0};
759 int max_pix_clk = get_max_pixel_clock_for_all_paths(context);
760 int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz;
761
762 /*TODO: W/A for dal3 linux, investigate why this works */
763 if (!clk_mgr_dce->dfs_bypass_active)
764 patched_disp_clk = patched_disp_clk * 115 / 100;
765
766 if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) {
767 clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK;
768 /*
769 * When xGMI is enabled, the display clk needs to be adjusted
770 * with the WAFL link's SS percentage.
771 */
772 if (clk_mgr_dce->xgmi_enabled)
773 patched_disp_clk = clk_mgr_adjust_dp_ref_freq_for_ss(
774 clk_mgr_dce, patched_disp_clk);
775 clock_voltage_req.clocks_in_khz = patched_disp_clk;
776 clk_mgr->clks.dispclk_khz = dce112_set_clock(clk_mgr, patched_disp_clk);
777
778 dm_pp_apply_clock_for_voltage_request(clk_mgr->ctx, &clock_voltage_req);
779 }
780
781 if (should_set_clock(safe_to_lower, max_pix_clk, clk_mgr->clks.phyclk_khz)) {
782 clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK;
783 clock_voltage_req.clocks_in_khz = max_pix_clk;
784 clk_mgr->clks.phyclk_khz = max_pix_clk;
785
786 dm_pp_apply_clock_for_voltage_request(clk_mgr->ctx, &clock_voltage_req);
787 }
788 dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context);
789}
790
791static const struct clk_mgr_funcs dce120_funcs = {
792 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
793 .update_clocks = dce12_update_clocks
794};
795
796static const struct clk_mgr_funcs dce112_funcs = {
797 .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz,
798 .update_clocks = dce112_update_clocks
799};
800
801static const struct clk_mgr_funcs dce110_funcs = {
802 .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz,
803 .update_clocks = dce11_update_clocks,
804};
805
806static const struct clk_mgr_funcs dce_funcs = {
807 .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz,
808 .update_clocks = dce_update_clocks
809};
810
811static void dce_clk_mgr_construct(
812 struct dce_clk_mgr *clk_mgr_dce,
813 struct dc_context *ctx,
814 const struct clk_mgr_registers *regs,
815 const struct clk_mgr_shift *clk_shift,
816 const struct clk_mgr_mask *clk_mask)
817{
818 struct clk_mgr *base = &clk_mgr_dce->base;
819 struct dm_pp_static_clock_info static_clk_info = {0};
820
821 base->ctx = ctx;
822 base->funcs = &dce_funcs;
823
824 clk_mgr_dce->regs = regs;
825 clk_mgr_dce->clk_mgr_shift = clk_shift;
826 clk_mgr_dce->clk_mgr_mask = clk_mask;
827
828 clk_mgr_dce->dfs_bypass_disp_clk = 0;
829
830 clk_mgr_dce->dprefclk_ss_percentage = 0;
831 clk_mgr_dce->dprefclk_ss_divider = 1000;
832 clk_mgr_dce->ss_on_dprefclk = false;
833
834
835 if (dm_pp_get_static_clocks(ctx, &static_clk_info))
836 clk_mgr_dce->max_clks_state = static_clk_info.max_clocks_state;
837 else
838 clk_mgr_dce->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL;
839 clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID;
840
841 dce_clock_read_integrated_info(clk_mgr_dce);
842 dce_clock_read_ss_info(clk_mgr_dce);
843}
844
845struct clk_mgr *dce_clk_mgr_create(
846 struct dc_context *ctx,
847 const struct clk_mgr_registers *regs,
848 const struct clk_mgr_shift *clk_shift,
849 const struct clk_mgr_mask *clk_mask)
850{
851 struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce);
852
853 if (clk_mgr_dce == NULL) {
854 BREAK_TO_DEBUGGER();
855 return NULL;
856 }
857
858 memcpy(clk_mgr_dce->max_clks_by_state,
859 dce80_max_clks_by_state,
860 sizeof(dce80_max_clks_by_state));
861
862 dce_clk_mgr_construct(
863 clk_mgr_dce, ctx, regs, clk_shift, clk_mask);
864
865 return &clk_mgr_dce->base;
866}
867
868struct clk_mgr *dce110_clk_mgr_create(
869 struct dc_context *ctx,
870 const struct clk_mgr_registers *regs,
871 const struct clk_mgr_shift *clk_shift,
872 const struct clk_mgr_mask *clk_mask)
873{
874 struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce);
875
876 if (clk_mgr_dce == NULL) {
877 BREAK_TO_DEBUGGER();
878 return NULL;
879 }
880
881 memcpy(clk_mgr_dce->max_clks_by_state,
882 dce110_max_clks_by_state,
883 sizeof(dce110_max_clks_by_state));
884
885 dce_clk_mgr_construct(
886 clk_mgr_dce, ctx, regs, clk_shift, clk_mask);
887
888 clk_mgr_dce->base.funcs = &dce110_funcs;
889
890 return &clk_mgr_dce->base;
891}
892
893struct clk_mgr *dce112_clk_mgr_create(
894 struct dc_context *ctx,
895 const struct clk_mgr_registers *regs,
896 const struct clk_mgr_shift *clk_shift,
897 const struct clk_mgr_mask *clk_mask)
898{
899 struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce);
900
901 if (clk_mgr_dce == NULL) {
902 BREAK_TO_DEBUGGER();
903 return NULL;
904 }
905
906 memcpy(clk_mgr_dce->max_clks_by_state,
907 dce112_max_clks_by_state,
908 sizeof(dce112_max_clks_by_state));
909
910 dce_clk_mgr_construct(
911 clk_mgr_dce, ctx, regs, clk_shift, clk_mask);
912
913 clk_mgr_dce->base.funcs = &dce112_funcs;
914
915 return &clk_mgr_dce->base;
916}
917
918struct clk_mgr *dce120_clk_mgr_create(struct dc_context *ctx)
919{
920 struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce);
921
922 if (clk_mgr_dce == NULL) {
923 BREAK_TO_DEBUGGER();
924 return NULL;
925 }
926
927 memcpy(clk_mgr_dce->max_clks_by_state,
928 dce120_max_clks_by_state,
929 sizeof(dce120_max_clks_by_state));
930
931 dce_clk_mgr_construct(
932 clk_mgr_dce, ctx, NULL, NULL, NULL);
933
934 clk_mgr_dce->dprefclk_khz = 600000;
935 clk_mgr_dce->base.funcs = &dce120_funcs;
936
937 return &clk_mgr_dce->base;
938}
939
940struct clk_mgr *dce121_clk_mgr_create(struct dc_context *ctx)
941{
942 struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce);
943
944 if (clk_mgr_dce == NULL) {
945 BREAK_TO_DEBUGGER();
946 return NULL;
947 }
948
949 memcpy(clk_mgr_dce->max_clks_by_state, dce120_max_clks_by_state,
950 sizeof(dce120_max_clks_by_state));
951
952 dce_clk_mgr_construct(clk_mgr_dce, ctx, NULL, NULL, NULL);
953
954 clk_mgr_dce->dprefclk_khz = 625000;
955 clk_mgr_dce->base.funcs = &dce120_funcs;
956
957 return &clk_mgr_dce->base;
958}
959
960void dce_clk_mgr_destroy(struct clk_mgr **clk_mgr)
961{
962 struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(*clk_mgr);
963
964 kfree(clk_mgr_dce);
965 *clk_mgr = NULL;
966}
drivers/gpu/drm/amd/display/dc/dio/Makefile+10−1
@@ -1,5 +1,5 @@
1#1#
2# Copyright 2020 Advanced Micro Devices, Inc.2# Copyright 2020-2026 Advanced Micro Devices, Inc.
3#3#
4# Permission is hereby granted, free of charge, to any person obtaining a4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),5# copy of this software and associated documentation files (the "Software"),
@@ -123,4 +123,13 @@ DIO_DCN401 = dcn401_dio_link_encoder.o dcn401_dio_stream_encoder.o · 117 unmodified lines
123AMD_DAL_DIO_DCN401 = $(addprefix $(AMDDALPATH)/dc/dio/dcn401/,$(DIO_DCN401))123AMD_DAL_DIO_DCN401 = $(addprefix $(AMDDALPATH)/dc/dio/dcn401/,$(DIO_DCN401))
124 124
125AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN401)125AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN401)
126
127###############################################################################
128# DCN42
129###############################################################################
130DIO_DCN42 = dcn42_dio_link_encoder.o dcn42_dio_stream_encoder.o
131
132AMD_DAL_DIO_DCN42 = $(addprefix $(AMDDALPATH)/dc/dio/dcn42/,$(DIO_DCN42))
133
134AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN42)
126endif135endif
drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_stream_encoder.h+9−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.2 * Copyright 2012-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -190,6 +190,7 @@ struct dcn10_stream_enc_registers { · 184 unmodified lines
190 uint32_t DIG_FE_CLK_CNTL;190 uint32_t DIG_FE_CLK_CNTL;
191 uint32_t DIG_FE_EN_CNTL;191 uint32_t DIG_FE_EN_CNTL;
192 uint32_t STREAM_MAPPER_CONTROL;192 uint32_t STREAM_MAPPER_CONTROL;
193 uint32_t DIG_FE_AUDIO_CNTL;
193};194};
194 195
195 196
@@ -598,6 +599,11 @@ struct dcn10_stream_enc_registers { · 402 unmodified lines
598 type DP_VID_N_INTERVAL;\599 type DP_VID_N_INTERVAL;\
599 type DIG_FIFO_OUTPUT_PIXEL_PER_CYCLE;\600 type DIG_FIFO_OUTPUT_PIXEL_PER_CYCLE;\
600 type DP_STEER_FIFO_ENABLE601 type DP_STEER_FIFO_ENABLE
602
603#define SE_REG_FIELD_LIST_DCN_AUDIO_COMMON(type) \
604 type DIG_FE_INPUT_MUX_AUDIO_STREAM_SOURCE_SEL;\
605 type APG_CLOCK_ENABLE
606
601struct dcn10_stream_encoder_shift {607struct dcn10_stream_encoder_shift {
602 SE_REG_FIELD_LIST_DCN1_0(uint8_t);608 SE_REG_FIELD_LIST_DCN1_0(uint8_t);
603 uint8_t HDMI_ACP_SEND;609 uint8_t HDMI_ACP_SEND;
@@ -606,6 +612,7 @@ struct dcn10_stream_encoder_shift { · 2 unmodified lines
606 SE_REG_FIELD_LIST_DCN3_1_COMMON(uint8_t);612 SE_REG_FIELD_LIST_DCN3_1_COMMON(uint8_t);
607 SE_REG_FIELD_LIST_DCN3_5_COMMON(uint8_t);613 SE_REG_FIELD_LIST_DCN3_5_COMMON(uint8_t);
608 SE_REG_FIELD_LIST_DCN4_01_COMMON(uint32_t);614 SE_REG_FIELD_LIST_DCN4_01_COMMON(uint32_t);
615 SE_REG_FIELD_LIST_DCN_AUDIO_COMMON(uint32_t);
609};616};
610 617
611struct dcn10_stream_encoder_mask {618struct dcn10_stream_encoder_mask {
@@ -616,6 +623,7 @@ struct dcn10_stream_encoder_mask { · 4 unmodified lines
616 SE_REG_FIELD_LIST_DCN3_1_COMMON(uint32_t);623 SE_REG_FIELD_LIST_DCN3_1_COMMON(uint32_t);
617 SE_REG_FIELD_LIST_DCN3_5_COMMON(uint32_t);624 SE_REG_FIELD_LIST_DCN3_5_COMMON(uint32_t);
618 SE_REG_FIELD_LIST_DCN4_01_COMMON(uint32_t);625 SE_REG_FIELD_LIST_DCN4_01_COMMON(uint32_t);
626 SE_REG_FIELD_LIST_DCN_AUDIO_COMMON(uint32_t);
619};627};
620 628
621struct dcn10_stream_encoder {629struct dcn10_stream_encoder {
drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_link_encoder.c+205−0
@@ -0,0 +1,205 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "reg_helper.h"
6
7#include "core_types.h"
8#include "link_encoder.h"
9#include "dcn35/dcn35_dio_link_encoder.h"
10#include "dcn42_dio_link_encoder.h"
11
12#ifndef MIN
13#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
14#endif
15
16#define CTX \
17 enc10->base.ctx
18#define DC_LOGGER \
19 enc10->base.ctx->logger
20
21#define REG(reg)\
22 (enc10->link_regs->reg)
23
24#undef FN
25#define FN(reg_name, field_name) \
26 enc10->link_shift->field_name, enc10->link_mask->field_name
27
28#define HPD_REG(reg)\
29 (enc10->hpd_regs->reg)
30
31#define HPD_REG_GET(reg_name, field, val) \
32 generic_reg_get(CTX, HPD_REG(reg_name), \
33 FN(reg_name, field), val)
34
35#define HPD_REG_SET_N(reg_name, n, initial_val, ...) \
36 generic_reg_set_ex(CTX, \
37 HPD_REG(reg_name), \
38 initial_val, \
39 n, __VA_ARGS__)
40
41#define HPD_REG_SET_2(reg, init_value, f1, v1, f2, v2) \
42 HPD_REG_SET_N(reg, 2, init_value, \
43 FN(reg, f1), v1,\
44 FN(reg, f2), v2)
45
46bool dcn42_get_hpd_state(struct link_encoder *enc)
47{
48 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
49 uint32_t state;
50
51 HPD_REG_GET(DC_HPD_INT_STATUS, DC_HPD_SENSE, &state);
52
53 return state;
54}
55
56bool dcn42_program_hpd_filter(struct link_encoder *enc, int delay_on_connect_in_ms, int delay_on_disconnect_in_ms)
57{
58 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
59
60 HPD_REG_SET_2(DC_HPD_TOGGLE_FILT_CNTL, 0,
61 DC_HPD_CONNECT_INT_DELAY, delay_on_connect_in_ms,
62 DC_HPD_DISCONNECT_INT_DELAY, delay_on_disconnect_in_ms);
63
64 return true;
65}
66
67static const struct link_encoder_funcs dcn42_link_enc_funcs = {
68 .read_state = link_enc2_read_state,
69 .validate_output_with_stream =
70 dcn30_link_encoder_validate_output_with_stream,
71 .hw_init = dcn35_link_encoder_init,
72 .setup = dcn35_link_encoder_setup,
73 .enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
74 .enable_dp_output = dcn35_link_encoder_enable_dp_output,
75 .enable_dp_mst_output = dcn35_link_encoder_enable_dp_mst_output,
76 .disable_output = dcn35_link_encoder_disable_output,
77 .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
78 .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
79 .update_mst_stream_allocation_table =
80 dcn10_link_encoder_update_mst_stream_allocation_table,
81 .psr_program_dp_dphy_fast_training =
82 dcn10_psr_program_dp_dphy_fast_training,
83 .psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
84 .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
85 .enable_hpd = dcn10_link_encoder_enable_hpd,
86 .disable_hpd = dcn10_link_encoder_disable_hpd,
87 .is_dig_enabled = dcn35_is_dig_enabled,
88 .destroy = dcn10_link_encoder_destroy,
89 .fec_set_enable = enc2_fec_set_enable,
90 .fec_set_ready = enc2_fec_set_ready,
91 .fec_is_active = enc2_fec_is_active,
92 .get_dig_frontend = dcn10_get_dig_frontend,
93 .get_dig_mode = dcn401_get_dig_mode,
94 .is_in_alt_mode = dcn32_link_encoder_is_in_alt_mode,
95 .get_max_link_cap = dcn32_link_encoder_get_max_link_cap,
96 .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
97 .enable_dpia_output = dcn35_link_encoder_enable_dpia_output,
98 .disable_dpia_output = dcn35_link_encoder_disable_dpia_output,
99 .get_hpd_state = dcn42_get_hpd_state,
100 .program_hpd_filter = dcn42_program_hpd_filter,
101};
102
103void dcn42_link_encoder_construct(
104 struct dcn20_link_encoder *enc20,
105 const struct encoder_init_data *init_data,
106 const struct encoder_feature_support *enc_features,
107 const struct dcn10_link_enc_registers *link_regs,
108 const struct dcn10_link_enc_aux_registers *aux_regs,
109 const struct dcn10_link_enc_hpd_registers *hpd_regs,
110 const struct dcn10_link_enc_shift *link_shift,
111 const struct dcn10_link_enc_mask *link_mask)
112{
113 struct bp_connector_speed_cap_info bp_cap_info = {0};
114 const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
115 enum bp_result result = BP_RESULT_OK;
116 struct dcn10_link_encoder *enc10 = &enc20->enc10;
117
118 enc10->base.funcs = &dcn42_link_enc_funcs;
119 enc10->base.ctx = init_data->ctx;
120 enc10->base.id = init_data->encoder;
121
122 enc10->base.hpd_source = init_data->hpd_source;
123 enc10->base.connector = init_data->connector;
124
125
126 enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
127
128 enc10->base.features = *enc_features;
129 if (enc10->base.connector.id == CONNECTOR_ID_USBC)
130 enc10->base.features.flags.bits.DP_IS_USB_C = 1;
131
132 enc10->base.transmitter = init_data->transmitter;
133
134 /* set the flag to indicate whether driver poll the I2C data pin
135 * while doing the DP sink detect
136 */
137
138/* if (dal_adapter_service_is_feature_supported(as,
139 FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
140 enc10->base.features.flags.bits.
141 DP_SINK_DETECT_POLL_DATA_PIN = true;*/
142
143 enc10->base.output_signals =
144 SIGNAL_TYPE_DVI_SINGLE_LINK |
145 SIGNAL_TYPE_DVI_DUAL_LINK |
146 SIGNAL_TYPE_LVDS |
147 SIGNAL_TYPE_DISPLAY_PORT |
148 SIGNAL_TYPE_DISPLAY_PORT_MST |
149 SIGNAL_TYPE_EDP |
150 SIGNAL_TYPE_HDMI_TYPE_A;
151
152 enc10->link_regs = link_regs;
153 enc10->aux_regs = aux_regs;
154 enc10->hpd_regs = hpd_regs;
155 enc10->link_shift = link_shift;
156 enc10->link_mask = link_mask;
157
158 switch (enc10->base.transmitter) {
159 case TRANSMITTER_UNIPHY_A:
160 enc10->base.preferred_engine = ENGINE_ID_DIGA;
161 break;
162 case TRANSMITTER_UNIPHY_B:
163 enc10->base.preferred_engine = ENGINE_ID_DIGB;
164 break;
165 case TRANSMITTER_UNIPHY_C:
166 enc10->base.preferred_engine = ENGINE_ID_DIGC;
167 break;
168 case TRANSMITTER_UNIPHY_D:
169 enc10->base.preferred_engine = ENGINE_ID_DIGD;
170 break;
171 case TRANSMITTER_UNIPHY_E:
172 enc10->base.preferred_engine = ENGINE_ID_DIGE;
173 break;
174 default:
175 ASSERT_CRITICAL(false);
176 enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
177 }
178
179 /* default to one to mirror Windows behavior */
180 enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
181
182 if (bp_funcs->get_connector_speed_cap_info)
183 result = bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios,
184 enc10->base.connector, &bp_cap_info);
185
186 /* Override features with DCE-specific values */
187 if (result == BP_RESULT_OK) {
188 enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
189 bp_cap_info.DP_HBR2_EN;
190 enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
191 bp_cap_info.DP_HBR3_EN;
192 enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
193 enc10->base.features.flags.bits.IS_DP2_CAPABLE = 1;
194 enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN;
195 enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN;
196 enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN;
197 } else {
198 DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
199 __func__,
200 result);
201 }
202 if (enc10->base.ctx->dc->debug.hdmi20_disable) {
203 enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
204 }
205}
drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_link_encoder.h+140−0
@@ -0,0 +1,140 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2026 Advanced Micro Devices, 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 */
24
25#ifndef __DC_LINK_ENCODER__DCN42_H__
26#define __DC_LINK_ENCODER__DCN42_H__
27
28#include "dcn401/dcn401_dio_link_encoder.h"
29
30#define LINK_ENCODER_MASK_SH_LIST_DCN42(mask_sh) \
31 LE_SF(DIG0_DIG_BE_EN_CNTL, DIG_BE_ENABLE, mask_sh),\
32 LE_SF(DIG0_DIG_BE_CNTL, DIG_RB_SWITCH_EN, mask_sh),\
33 LE_SF(DIG0_DIG_BE_CNTL, DIG_HPD_SELECT, mask_sh),\
34 LE_SF(DIG0_DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, mask_sh),\
35 LE_SF(DIG0_DIG_BE_CLK_CNTL, DIG_BE_MODE, mask_sh),\
36 LE_SF(DIG0_DIG_BE_CLK_CNTL, DIG_BE_CLK_EN, mask_sh),\
37 LE_SF(DIG0_DIG_BE_CLK_CNTL, DIG_BE_SOFT_RESET, mask_sh),\
38 LE_SF(DIG0_DIG_BE_CLK_CNTL, HDCP_SOFT_RESET, mask_sh),\
39 LE_SF(DIG0_DIG_BE_CLK_CNTL, DIG_BE_SYMCLK_G_CLOCK_ON, mask_sh),\
40 LE_SF(DIG0_DIG_BE_CLK_CNTL, DIG_BE_SYMCLK_G_HDCP_CLOCK_ON, mask_sh),\
41 LE_SF(DIG0_DIG_BE_CLK_CNTL, DIG_BE_SYMCLK_G_TMDS_CLOCK_ON, mask_sh),\
42 LE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh),\
43 LE_SF(DIG0_TMDS_CTL_BITS, TMDS_CTL0, mask_sh), \
44 LE_SF(DP0_DP_DPHY_CNTL, DPHY_BYPASS, mask_sh),\
45 LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE0, mask_sh),\
46 LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE1, mask_sh),\
47 LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE2, mask_sh),\
48 LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE3, mask_sh),\
49 LE_SF(DP0_DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, mask_sh),\
50 LE_SF(DP0_DP_DPHY_PRBS_CNTL, DPHY_PRBS_SEL, mask_sh),\
51 LE_SF(DP0_DP_DPHY_SYM0, DPHY_SYM1, mask_sh),\
52 LE_SF(DP0_DP_DPHY_SYM0, DPHY_SYM2, mask_sh),\
53 LE_SF(DP0_DP_DPHY_SYM0, DPHY_SYM3, mask_sh),\
54 LE_SF(DP0_DP_DPHY_SYM1, DPHY_SYM4, mask_sh),\
55 LE_SF(DP0_DP_DPHY_SYM1, DPHY_SYM5, mask_sh),\
56 LE_SF(DP0_DP_DPHY_SYM1, DPHY_SYM6, mask_sh),\
57 LE_SF(DP0_DP_DPHY_SYM2, DPHY_SYM7, mask_sh),\
58 LE_SF(DP0_DP_DPHY_SYM2, DPHY_SYM8, mask_sh),\
59 LE_SF(DP0_DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, mask_sh),\
60 LE_SF(DP0_DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, mask_sh),\
61 LE_SF(DP0_DP_DPHY_FAST_TRAINING, DPHY_RX_FAST_TRAINING_CAPABLE, mask_sh),\
62 LE_SF(DP0_DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, mask_sh),\
63 LE_SF(DP0_DP_DPHY_TRAINING_PATTERN_SEL, DPHY_TRAINING_PATTERN_SEL, mask_sh),\
64 LE_SF(DP0_DP_DPHY_HBR2_PATTERN_CONTROL, DP_DPHY_HBR2_PATTERN_CONTROL, mask_sh),\
65 LE_SF(DP0_DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, mask_sh),\
66 LE_SF(DP0_DP_LINK_FRAMING_CNTL, DP_IDLE_BS_INTERVAL, mask_sh),\
67 LE_SF(DP0_DP_LINK_FRAMING_CNTL, DP_VBID_DISABLE, mask_sh),\
68 LE_SF(DP0_DP_LINK_FRAMING_CNTL, DP_VID_ENHANCED_FRAME_MODE, mask_sh),\
69 LE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, mask_sh),\
70 LE_SF(DP0_DP_CONFIG, DP_UDI_LANES, mask_sh),\
71 LE_SF(DP0_DP_SEC_CNTL1, DP_SEC_GSP0_LINE_NUM, mask_sh),\
72 LE_SF(DP0_DP_SEC_CNTL1, DP_SEC_GSP0_PRIORITY, mask_sh),\
73 LE_SF(DP0_DP_MSE_SAT0, DP_MSE_SAT_SRC0, mask_sh),\
74 LE_SF(DP0_DP_MSE_SAT0, DP_MSE_SAT_SRC1, mask_sh),\
75 LE_SF(DP0_DP_MSE_SAT0, DP_MSE_SAT_SLOT_COUNT0, mask_sh),\
76 LE_SF(DP0_DP_MSE_SAT0, DP_MSE_SAT_SLOT_COUNT1, mask_sh),\
77 LE_SF(DP0_DP_MSE_SAT1, DP_MSE_SAT_SRC2, mask_sh),\
78 LE_SF(DP0_DP_MSE_SAT1, DP_MSE_SAT_SRC3, mask_sh),\
79 LE_SF(DP0_DP_MSE_SAT1, DP_MSE_SAT_SLOT_COUNT2, mask_sh),\
80 LE_SF(DP0_DP_MSE_SAT1, DP_MSE_SAT_SLOT_COUNT3, mask_sh),\
81 LE_SF(DP0_DP_MSE_SAT_UPDATE, DP_MSE_SAT_UPDATE, mask_sh),\
82 LE_SF(DP0_DP_MSE_SAT_UPDATE, DP_MSE_16_MTP_KEEPOUT, mask_sh),\
83 LE_SF(DP_AUX0_AUX_CONTROL, AUX_HPD_SEL, mask_sh),\
84 LE_SF(DP_AUX0_AUX_CONTROL, AUX_LS_READ_EN, mask_sh),\
85 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_RECEIVE_WINDOW, mask_sh),\
86 LE_SF(HPD0_DC_HPD_CONTROL, DC_HPD_EN, mask_sh),\
87 LE_SF(HPD0_DC_HPD_INT_STATUS, DC_HPD_SENSE, mask_sh),\
88 LE_SF(HPD0_DC_HPD_TOGGLE_FILT_CNTL, DC_HPD_CONNECT_INT_DELAY, mask_sh),\
89 LE_SF(HPD0_DC_HPD_TOGGLE_FILT_CNTL, DC_HPD_DISCONNECT_INT_DELAY, mask_sh),\
90 LE_SF(DP0_DP_DPHY_CNTL, DPHY_FEC_EN, mask_sh),\
91 LE_SF(DP0_DP_DPHY_CNTL, DPHY_FEC_READY_SHADOW, mask_sh),\
92 LE_SF(DP0_DP_DPHY_CNTL, DPHY_FEC_ACTIVE_STATUS, mask_sh),\
93 LE_SF(DIG0_TMDS_CTL_BITS, TMDS_CTL0, mask_sh), \
94 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_START_WINDOW, mask_sh),\
95 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_HALF_SYM_DETECT_LEN, mask_sh),\
96 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_TRANSITION_FILTER_EN, mask_sh),\
97 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_ALLOW_BELOW_THRESHOLD_PHASE_DETECT, mask_sh),\
98 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_ALLOW_BELOW_THRESHOLD_START, mask_sh),\
99 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_ALLOW_BELOW_THRESHOLD_STOP, mask_sh),\
100 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_PHASE_DETECT_LEN, mask_sh),\
101 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_DETECTION_THRESHOLD, mask_sh), \
102 LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_TX_PRECHARGE_LEN, mask_sh),\
103 LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_TX_PRECHARGE_SYMBOLS, mask_sh),\
104 LE_SF(DP_AUX0_AUX_DPHY_TX_CONTROL, AUX_MODE_DET_CHECK_DELAY, mask_sh),\
105 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_PRECHARGE_SKIP, mask_sh),\
106 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, mask_sh),\
107 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN_MUL, mask_sh),\
108 LE_SF(DIO_CLK_CNTL, DISPCLK_R_GATE_DIS, mask_sh),\
109 LE_SF(DIO_CLK_CNTL, DISPCLK_G_GATE_DIS, mask_sh),\
110 LE_SF(DIO_CLK_CNTL, REFCLK_R_GATE_DIS, mask_sh),\
111 LE_SF(DIO_CLK_CNTL, REFCLK_G_GATE_DIS, mask_sh),\
112 LE_SF(DIO_CLK_CNTL, SOCCLK_G_GATE_DIS, mask_sh),\
113 LE_SF(DIO_CLK_CNTL, SYMCLK_FE_R_GATE_DIS, mask_sh),\
114 LE_SF(DIO_CLK_CNTL, SYMCLK_FE_G_GATE_DIS, mask_sh),\
115 LE_SF(DIO_CLK_CNTL, SYMCLK_R_GATE_DIS, mask_sh),\
116 LE_SF(DIO_CLK_CNTL, SYMCLK_G_GATE_DIS, mask_sh),\
117 LE_SF(DIO_CLK_CNTL, DIO_FGCG_REP_DIS, mask_sh),\
118 LE_SF(DIO_CLK_CNTL, DISPCLK_G_HDCP_GATE_DIS, mask_sh),\
119 LE_SF(DIO_CLK_CNTL, SYMCLKA_G_HDCP_GATE_DIS, mask_sh),\
120 LE_SF(DIO_CLK_CNTL, SYMCLKB_G_HDCP_GATE_DIS, mask_sh),\
121 LE_SF(DIO_CLK_CNTL, SYMCLKC_G_HDCP_GATE_DIS, mask_sh),\
122 LE_SF(DIO_CLK_CNTL, SYMCLKD_G_HDCP_GATE_DIS, mask_sh),\
123 LE_SF(DIO_CLK_CNTL, SYMCLKE_G_HDCP_GATE_DIS, mask_sh),\
124 LE_SF(DIO_CLK_CNTL, SYMCLKF_G_HDCP_GATE_DIS, mask_sh),\
125 LE_SF(DIO_CLK_CNTL, SYMCLKG_G_HDCP_GATE_DIS, mask_sh)
126
127void dcn42_link_encoder_construct(
128 struct dcn20_link_encoder *enc20,
129 const struct encoder_init_data *init_data,
130 const struct encoder_feature_support *enc_features,
131 const struct dcn10_link_enc_registers *link_regs,
132 const struct dcn10_link_enc_aux_registers *aux_regs,
133 const struct dcn10_link_enc_hpd_registers *hpd_regs,
134 const struct dcn10_link_enc_shift *link_shift,
135 const struct dcn10_link_enc_mask *link_mask);
136
137bool dcn42_get_hpd_state(struct link_encoder *enc);
138bool dcn42_program_hpd_filter(struct link_encoder *enc, int delay_on_connect_in_ms, int delay_on_disconnect_in_ms);
139
140#endif /* __DC_LINK_ENCODER__DCN42_H__ */
drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_stream_encoder.c+522−0
@@ -0,0 +1,522 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "dc_bios_types.h"
6#include "dcn30/dcn30_dio_stream_encoder.h"
7#include "dcn32/dcn32_dio_stream_encoder.h"
8#include "dcn35/dcn35_dio_stream_encoder.h"
9#include "dcn401/dcn401_dio_stream_encoder.h"
10#include "dcn31/dcn31_apg.h"
11
12#include "dcn42_dio_stream_encoder.h"
13#include "reg_helper.h"
14#include "hw_shared.h"
15#include "link_service.h"
16#include "dpcd_defs.h"
17
18#define DC_LOGGER \
19 enc1->base.ctx->logger
20
21#define REG(reg)\
22 (enc1->regs->reg)
23
24#undef FN
25#define FN(reg_name, field_name) \
26 enc1->se_shift->field_name, enc1->se_mask->field_name
27
28#define VBI_LINE_0 0
29#define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000
30
31#define CTX \
32 enc1->base.ctx
33
34/* setup stream encoder in hdmi mode */
35static void enc42_stream_encoder_hdmi_set_stream_attribute(
36 struct stream_encoder *enc,
37 struct dc_crtc_timing *crtc_timing,
38 int actual_pix_clk_khz,
39 bool enable_audio)
40{
41 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
42
43 if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
44 struct bp_encoder_control cntl = {0};
45
46 cntl.action = ENCODER_CONTROL_SETUP;
47 cntl.engine_id = enc1->base.id;
48 cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
49 cntl.enable_dp_audio = enable_audio;
50 cntl.pixel_clock = actual_pix_clk_khz;
51 cntl.lanes_number = LANE_COUNT_FOUR;
52
53 if (enc1->base.bp->funcs->encoder_control(
54 enc1->base.bp, &cntl) != BP_RESULT_OK)
55 return;
56
57 } else {
58
59 //Set pattern for clock channel, default vlue 0x63 does not work
60 REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
61
62 //DIG_BE_TMDS_HDMI_MODE : TMDS-HDMI mode is already set in link_encoder_setup
63
64 //DIG_SOURCE_SELECT is already set in dig_connect_to_otg
65
66 /* DIG_START is removed from the register spec */
67 }
68
69 /* Configure pixel encoding */
70 enc401_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
71
72 /* setup HDMI engine */
73 REG_UPDATE_4(HDMI_CONTROL,
74 HDMI_DEEP_COLOR_ENABLE, 0,
75 HDMI_DATA_SCRAMBLE_EN, 0,
76 HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1,
77 HDMI_CLOCK_CHANNEL_RATE, 0);
78
79 /* Configure color depth */
80 switch (crtc_timing->display_color_depth) {
81 case COLOR_DEPTH_888:
82 REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0);
83 break;
84 case COLOR_DEPTH_101010:
85 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
86 REG_UPDATE_2(HDMI_CONTROL,
87 HDMI_DEEP_COLOR_DEPTH, 1,
88 HDMI_DEEP_COLOR_ENABLE, 0);
89 } else {
90 REG_UPDATE_2(HDMI_CONTROL,
91 HDMI_DEEP_COLOR_DEPTH, 1,
92 HDMI_DEEP_COLOR_ENABLE, 1);
93 }
94 break;
95 case COLOR_DEPTH_121212:
96 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
97 REG_UPDATE_2(HDMI_CONTROL,
98 HDMI_DEEP_COLOR_DEPTH, 2,
99 HDMI_DEEP_COLOR_ENABLE, 0);
100 } else {
101 REG_UPDATE_2(HDMI_CONTROL,
102 HDMI_DEEP_COLOR_DEPTH, 2,
103 HDMI_DEEP_COLOR_ENABLE, 1);
104 }
105 break;
106 case COLOR_DEPTH_161616:
107 REG_UPDATE_2(HDMI_CONTROL,
108 HDMI_DEEP_COLOR_DEPTH, 3,
109 HDMI_DEEP_COLOR_ENABLE, 1);
110 break;
111 default:
112 break;
113 }
114
115 if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) {
116 /* enable HDMI data scrambler
117 * HDMI_CLOCK_CHANNEL_RATE_MORE_340M
118 * Clock channel frequency is 1/4 of character rate.
119 */
120 REG_UPDATE_2(HDMI_CONTROL,
121 HDMI_DATA_SCRAMBLE_EN, 1,
122 HDMI_CLOCK_CHANNEL_RATE, 1);
123 } else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) {
124
125 /* TODO: New feature for DCE11, still need to implement */
126
127 /* enable HDMI data scrambler
128 * HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE
129 * Clock channel frequency is the same
130 * as character rate
131 */
132 REG_UPDATE_2(HDMI_CONTROL,
133 HDMI_DATA_SCRAMBLE_EN, 1,
134 HDMI_CLOCK_CHANNEL_RATE, 0);
135 }
136
137 /* Enable transmission of General Control packet on every frame */
138 REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL,
139 HDMI_GC_CONT, 1,
140 HDMI_GC_SEND, 1,
141 HDMI_NULL_SEND, 1);
142
143 /* Disable Audio Content Protection packet transmission */
144 REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0);
145 /* following belongs to audio */
146 /* Enable Audio InfoFrame packet transmission. */
147 REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1);
148
149 /* Select line number on which to send Audio InfoFrame packets */
150 REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_LINE,
151 VBI_LINE_0 + 2);
152
153 /* set HDMI GC AVMUTE */
154 REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0);
155}
156
157static void enc42_stream_encoder_stop_dp_info_packets(
158 struct stream_encoder *enc)
159{
160 /* stop generic packets on DP */
161 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
162 uint32_t value = 0;
163
164 REG_SET_9(DP_SEC_CNTL, 0,
165 DP_SEC_GSP0_ENABLE, 0,
166 DP_SEC_GSP1_ENABLE, 0,
167 DP_SEC_GSP2_ENABLE, 0,
168 DP_SEC_GSP3_ENABLE, 0,
169 DP_SEC_GSP4_ENABLE, 0,
170 DP_SEC_GSP5_ENABLE, 0,
171 DP_SEC_GSP6_ENABLE, 0,
172 DP_SEC_GSP7_ENABLE, 0,
173 DP_SEC_STREAM_ENABLE, 0);
174
175 /* this register shared with audio info frame.
176 * therefore we need to keep master enabled
177 * if at least one of the fields is not 0
178 */
179 value = REG_READ(DP_SEC_CNTL);
180 if (value)
181 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
182}
183
184static void enc42_stream_encoder_update_hdmi_info_packets(
185 struct stream_encoder *enc,
186 const struct encoder_info_frame *info_frame)
187{
188 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
189
190 REG_UPDATE(HDMI_DB_CONTROL, HDMI_DB_DISABLE, 1);
191 REG_UPDATE(DIG_FE_AUDIO_CNTL, APG_CLOCK_ENABLE, 1);
192
193 /*Always add mandatory packets first followed by optional ones*/
194 enc3_update_hdmi_info_packet(enc1, 0, &info_frame->avi);
195 enc3_update_hdmi_info_packet(enc1, 5, &info_frame->hfvsif);
196 enc3_update_hdmi_info_packet(enc1, 2, &info_frame->gamut);
197 enc3_update_hdmi_info_packet(enc1, 1, &info_frame->vendor);
198 enc3_update_hdmi_info_packet(enc1, 3, &info_frame->spd);
199 enc3_update_hdmi_info_packet(enc1, 4, &info_frame->hdrsmd);
200 enc3_update_hdmi_info_packet(enc1, 6, &info_frame->vtem);
201}
202
203static void enc42_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
204 bool enable,
205 uint8_t *dsc_packed_pps,
206 bool immediate_update)
207{
208 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
209
210 if (enable) {
211 struct dc_info_packet pps_sdp;
212 int i;
213
214 /* Configure for PPS packet size (128 bytes) */
215 REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP11_PPS, 1);
216
217 /* Load PPS into infoframe (SDP) registers */
218 pps_sdp.valid = true;
219 pps_sdp.hb0 = 0;
220 pps_sdp.hb1 = DC_DP_INFOFRAME_TYPE_PPS;
221 pps_sdp.hb2 = 127;
222 pps_sdp.hb3 = 0;
223
224 for (i = 0; i < 4; i++) {
225 memcpy(pps_sdp.sb, &dsc_packed_pps[i * 32], 32);
226 enc1->base.vpg->funcs->update_generic_info_packet(
227 enc1->base.vpg,
228 11 + i,
229 &pps_sdp,
230 immediate_update);
231 }
232
233 /* SW should make sure VBID[6] update line number is bigger
234 * than PPS transmit line number
235 */
236 REG_UPDATE(DP_GSP11_CNTL,
237 DP_SEC_GSP11_LINE_NUM, 2);
238 REG_UPDATE_2(DP_MSA_VBID_MISC,
239 DP_VBID6_LINE_REFERENCE, 0,
240 DP_VBID6_LINE_NUM, 3);
241
242 /* Send PPS data at the line number specified above.
243 * DP spec requires PPS to be sent only when it changes, however since
244 * decoder has to be able to handle its change on every frame, we're
245 * sending it always (i.e. on every frame) to reduce the chance it'd be
246 * missed by decoder. If it turns out required to send PPS only when it
247 * changes, we can use DP_SEC_GSP11_SEND register.
248 */
249 REG_UPDATE(DP_GSP11_CNTL,
250 DP_SEC_GSP11_ENABLE, 1);
251 REG_UPDATE(DP_SEC_CNTL,
252 DP_SEC_STREAM_ENABLE, 1);
253 } else {
254 /* Disable Generic Stream Packet 11 (GSP) transmission */
255 REG_UPDATE(DP_GSP11_CNTL, DP_SEC_GSP11_ENABLE, 0);
256 REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP11_PPS, 0);
257 }
258}
259
260static void enc42_se_dp_audio_setup(
261 struct stream_encoder *enc,
262 unsigned int az_inst,
263 struct audio_info *info)
264{
265 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
266 enc42_se_enable_audio_clock(enc, true);
267
268 REG_UPDATE(DIG_FE_AUDIO_CNTL,
269 DIG_FE_INPUT_MUX_AUDIO_STREAM_SOURCE_SEL, az_inst);
270
271 enc->apg->funcs->se_audio_setup(enc->apg, az_inst, info);
272}
273
274#define DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT 0x8000
275#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC 1
276
277static void enc42_se_setup_dp_audio(
278 struct stream_encoder *enc)
279{
280 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
281
282 /* --- DP Audio packet configurations --- */
283
284 /* ATP Configuration */
285 REG_SET(DP_SEC_AUD_N, 0,
286 DP_SEC_AUD_N, DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT);
287
288 /* Async/auto-calc timestamp mode */
289 REG_SET(DP_SEC_TIMESTAMP, 0, DP_SEC_TIMESTAMP_MODE,
290 DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC);
291}
292
293static void enc42_se_dp_audio_enable(
294 struct stream_encoder *enc)
295{
296 ASSERT (enc->apg);
297 enc42_se_enable_audio_clock(enc, true);
298 /*APG_CONTROL2 for DP*/
299 enc42_se_setup_dp_audio(enc);
300 /*DP_SEC_CNTL programming*/
301 enc1_se_enable_dp_audio(enc);
302 /*APG_en*/
303 enc->apg->funcs->enable_apg(enc->apg);
304
305}
306
307static void enc42_se_disable_dp_audio(
308 struct stream_encoder *enc)
309{
310 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
311 uint32_t value = 0;
312
313 /* Disable Audio packets */
314 REG_UPDATE_5(DP_SEC_CNTL,
315 DP_SEC_ASP_ENABLE, 0,
316 DP_SEC_ATP_ENABLE, 0,
317 DP_SEC_AIP_ENABLE, 0,
318 DP_SEC_ACM_ENABLE, 0,
319 DP_SEC_STREAM_ENABLE, 0);
320
321 /* This register shared with encoder info frame. Therefore we need to
322 * keep master enabled if at least on of the fields is not 0
323 */
324 value = REG_READ(DP_SEC_CNTL);
325 if (value != 0)
326 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
327}
328
329static void enc42_se_dp_audio_disable(
330 struct stream_encoder *enc)
331{
332
333 enc->apg->funcs->disable_apg(enc->apg);
334 enc42_se_disable_dp_audio(enc);
335 enc42_se_enable_audio_clock(enc, false);
336}
337
338static void enc42_se_setup_hdmi_audio(
339 struct stream_encoder *enc,
340 const struct audio_crtc_info *crtc_info)
341{
342 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
343
344 struct audio_clock_info audio_clock_info = {0};
345
346 /* HDMI_AUDIO_PACKET_CONTROL */
347 REG_UPDATE(HDMI_AUDIO_PACKET_CONTROL,
348 HDMI_AUDIO_DELAY_EN, 1);
349
350 /* HDMI_ACR_PACKET_CONTROL */
351 REG_UPDATE_2(HDMI_ACR_PACKET_CONTROL,
352 HDMI_ACR_AUTO_SEND, 1,
353 HDMI_ACR_SOURCE, 0);
354
355 /* Program audio clock sample/regeneration parameters */
356 get_audio_clock_info(crtc_info->color_depth,
357 crtc_info->requested_pixel_clock_100Hz,
358 crtc_info->calculated_pixel_clock_100Hz,
359 &audio_clock_info);
360 DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d" \
361 "calculated_pixel_clock_100Hz = %d\n", __func__,\
362 crtc_info->requested_pixel_clock_100Hz, \
363 crtc_info->calculated_pixel_clock_100Hz);
364
365 /* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */
366 REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz);
367
368 /* HDMI_ACR_32_1__HDMI_ACR_N_32_MASK */
369 REG_UPDATE(HDMI_ACR_32_1, HDMI_ACR_N_32, audio_clock_info.n_32khz);
370
371 /* HDMI_ACR_44_0__HDMI_ACR_CTS_44_MASK */
372 REG_UPDATE(HDMI_ACR_44_0, HDMI_ACR_CTS_44, audio_clock_info.cts_44khz);
373
374 /* HDMI_ACR_44_1__HDMI_ACR_N_44_MASK */
375 REG_UPDATE(HDMI_ACR_44_1, HDMI_ACR_N_44, audio_clock_info.n_44khz);
376
377 /* HDMI_ACR_48_0__HDMI_ACR_CTS_48_MASK */
378 REG_UPDATE(HDMI_ACR_48_0, HDMI_ACR_CTS_48, audio_clock_info.cts_48khz);
379
380 /* HDMI_ACR_48_1__HDMI_ACR_N_48_MASK */
381 REG_UPDATE(HDMI_ACR_48_1, HDMI_ACR_N_48, audio_clock_info.n_48khz);
382
383 /* Video driver cannot know in advance which sample rate will
384 * be used by HD Audio driver
385 * HDMI_ACR_PACKET_CONTROL__HDMI_ACR_N_MULTIPLE field is
386 * programmed below in interruppt callback
387 */
388}
389
390static void enc42_se_hdmi_audio_disable(
391 struct stream_encoder *enc)
392{
393 ASSERT (enc->apg);
394 enc->apg->funcs->disable_apg(enc->apg);
395 enc42_se_enable_audio_clock(enc, false);
396}
397
398void enc42_se_enable_audio_clock(
399 struct stream_encoder *enc,
400 bool enable)
401{
402 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
403
404 REG_UPDATE(DIG_FE_AUDIO_CNTL, APG_CLOCK_ENABLE, !!enable);
405}
406
407
408static void enc42_se_hdmi_audio_setup(
409 struct stream_encoder *enc,
410 unsigned int az_inst,
411 struct audio_info *info,
412 struct audio_crtc_info *audio_crtc_info)
413{
414 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
415
416 ASSERT (enc->apg);
417 enc42_se_enable_audio_clock(enc, true);
418 /*ACR setup*/
419 enc42_se_setup_hdmi_audio(enc, audio_crtc_info);
420
421 REG_UPDATE(DIG_FE_AUDIO_CNTL,
422 DIG_FE_INPUT_MUX_AUDIO_STREAM_SOURCE_SEL, az_inst);
423
424 /*APG_DBG_GEN_CONTROL*/
425 enc->apg->funcs->se_audio_setup(enc->apg, az_inst, info);
426 /*APG enable*/
427 enc->apg->funcs->enable_apg(enc->apg);
428}
429
430static void enc42_audio_mute_control(
431 struct stream_encoder *enc,
432 bool mute)
433{
434 if (mute)
435 enc->apg->funcs->disable_apg(enc->apg);
436 else
437 enc->apg->funcs->enable_apg(enc->apg);
438}
439void enc42_reset_hdmi_stream_attribute(
440 struct stream_encoder *enc)
441{
442 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
443
444 REG_UPDATE_3(HDMI_CONTROL,
445 HDMI_DEEP_COLOR_ENABLE, 0,
446 HDMI_DATA_SCRAMBLE_EN, 0,
447 HDMI_CLOCK_CHANNEL_RATE, 0);
448}
449
450static const struct stream_encoder_funcs dcn42_str_enc_funcs = {
451 .dp_set_stream_attribute =
452 enc401_stream_encoder_dp_set_stream_attribute,
453 .hdmi_set_stream_attribute =
454 enc42_stream_encoder_hdmi_set_stream_attribute,
455 .dvi_set_stream_attribute =
456 enc401_stream_encoder_dvi_set_stream_attribute,
457 .set_throttled_vcp_size =
458 enc1_stream_encoder_set_throttled_vcp_size,
459 .update_hdmi_info_packets =
460 enc42_stream_encoder_update_hdmi_info_packets,
461 .stop_hdmi_info_packets =
462 enc3_stream_encoder_stop_hdmi_info_packets,
463 .update_dp_info_packets_sdp_line_num =
464 enc3_stream_encoder_update_dp_info_packets_sdp_line_num,
465 .update_dp_info_packets =
466 enc3_stream_encoder_update_dp_info_packets,
467 .stop_dp_info_packets =
468 enc42_stream_encoder_stop_dp_info_packets,
469 .dp_blank =
470 enc1_stream_encoder_dp_blank,
471 .dp_unblank =
472 enc401_stream_encoder_dp_unblank,
473 .audio_mute_control = enc42_audio_mute_control,
474
475 .dp_audio_setup = enc42_se_dp_audio_setup,
476 .dp_audio_enable = enc42_se_dp_audio_enable,
477 .dp_audio_disable = enc42_se_dp_audio_disable,
478
479 .hdmi_audio_setup = enc42_se_hdmi_audio_setup,
480 .hdmi_audio_disable = enc42_se_hdmi_audio_disable,
481 .setup_stereo_sync = enc1_setup_stereo_sync,
482 .set_avmute = enc1_stream_encoder_set_avmute,
483 .dig_connect_to_otg = enc1_dig_connect_to_otg,
484 .dig_source_otg = enc1_dig_source_otg,
485
486 .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format,
487
488 .enc_read_state = enc401_read_state,
489 .dp_set_dsc_config = NULL,
490 .dp_set_dsc_pps_info_packet = enc42_dp_set_dsc_pps_info_packet,
491 .set_dynamic_metadata = enc401_set_dynamic_metadata,
492 .hdmi_reset_stream_attribute = enc42_reset_hdmi_stream_attribute,
493 .enable_stream = enc401_stream_encoder_enable,
494
495 .set_input_mode = enc401_set_dig_input_mode,
496 .enable_fifo = enc35_enable_fifo,
497 .disable_fifo = enc35_disable_fifo,
498 .map_stream_to_link = enc401_stream_encoder_map_to_link,
499};
500
501void dcn42_dio_stream_encoder_construct(
502 struct dcn10_stream_encoder *enc1,
503 struct dc_context *ctx,
504 struct dc_bios *bp,
505 enum engine_id eng_id,
506 struct vpg *vpg,
507 struct apg *apg,
508 const struct dcn10_stream_enc_registers *regs,
509 const struct dcn10_stream_encoder_shift *se_shift,
510 const struct dcn10_stream_encoder_mask *se_mask)
511{
512 enc1->base.funcs = &dcn42_str_enc_funcs;
513 enc1->base.ctx = ctx;
514 enc1->base.id = eng_id;
515 enc1->base.bp = bp;
516 enc1->base.vpg = vpg;
517 enc1->base.apg = apg;
518 enc1->regs = regs;
519 enc1->se_shift = se_shift;
520 enc1->se_mask = se_mask;
521 enc1->base.stream_enc_inst = vpg->inst;
522}
drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_stream_encoder.h+206−0
@@ -0,0 +1,206 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2026 - Advanced Micro Devices, 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: AMD
24 *
25 */
26
27#ifndef __DC_DIO_STREAM_ENCODER_DCN42_H__
28#define __DC_DIO_STREAM_ENCODER_DCN42_H__
29
30#include "dcn30/dcn30_vpg.h"
31#include "stream_encoder.h"
32#include "dcn20/dcn20_stream_encoder.h"
33
34#define SE_COMMON_MASK_SH_LIST_DCN42(mask_sh)\
35 SE_SF(DP0_DP_PIXEL_FORMAT, PIXEL_ENCODING_TYPE, mask_sh),\
36 SE_SF(DP0_DP_PIXEL_FORMAT, UNCOMPRESSED_PIXEL_FORMAT, mask_sh),\
37 SE_SF(DP0_DP_PIXEL_FORMAT, UNCOMPRESSED_COMPONENT_DEPTH, mask_sh),\
38 SE_SF(DP0_DP_PIXEL_FORMAT, COMPRESSED_PIXEL_FORMAT, mask_sh),\
39 SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_ENABLE, mask_sh),\
40 SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, mask_sh),\
41 SE_SF(DIG0_HDMI_CONTROL, HDMI_DATA_SCRAMBLE_EN, mask_sh),\
42 SE_SF(DIG0_HDMI_CONTROL, HDMI_NO_EXTRA_NULL_PACKET_FILLED, mask_sh),\
43 SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_CONT, mask_sh),\
44 SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_SEND, mask_sh),\
45 SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_NULL_SEND, mask_sh),\
46 SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, mask_sh),\
47 SE_SF(DIG0_HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, mask_sh),\
48 SE_SF(DIG0_HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_LINE, mask_sh),\
49 SE_SF(DIG0_HDMI_GC, HDMI_GC_AVMUTE, mask_sh),\
50 SE_SF(DP0_DP_MSE_RATE_CNTL, DP_MSE_RATE_X, mask_sh),\
51 SE_SF(DP0_DP_MSE_RATE_CNTL, DP_MSE_RATE_Y, mask_sh),\
52 SE_SF(DP0_DP_MSE_RATE_UPDATE, DP_MSE_RATE_UPDATE_PENDING, mask_sh),\
53 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, mask_sh),\
54 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, mask_sh),\
55 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP1_ENABLE, mask_sh),\
56 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, mask_sh),\
57 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, mask_sh),\
58 SE_SF(DP0_DP_SEC_CNTL1, DP_SEC_GSP5_LINE_REFERENCE, mask_sh),\
59 SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND, mask_sh),\
60 SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND_PENDING, mask_sh),\
61 SE_SF(DP0_DP_SEC_CNTL4, DP_SEC_GSP4_LINE_NUM, mask_sh),\
62 SE_SF(DP0_DP_SEC_CNTL5, DP_SEC_GSP5_LINE_NUM, mask_sh),\
63 SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND_ANY_LINE, mask_sh),\
64 SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, mask_sh),\
65 SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, mask_sh),\
66 SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, mask_sh),\
67 SE_SF(DP0_DP_STEER_FIFO, DP_STEER_FIFO_RESET, mask_sh),\
68 SE_SF(DP0_DP_STEER_FIFO, DP_STEER_FIFO_ENABLE, mask_sh),\
69 SE_SF(DP0_DP_VID_TIMING, DP_VID_M_N_GEN_EN, mask_sh),\
70 SE_SF(DP0_DP_VID_N, DP_VID_N, mask_sh),\
71 SE_SF(DP0_DP_VID_M, DP_VID_M, mask_sh),\
72 SE_SF(DIG0_HDMI_AUDIO_PACKET_CONTROL, HDMI_AUDIO_DELAY_EN, mask_sh),\
73 SE_SF(DIG0_HDMI_ACR_PACKET_CONTROL, HDMI_ACR_AUTO_SEND, mask_sh),\
74 SE_SF(DIG0_HDMI_ACR_PACKET_CONTROL, HDMI_ACR_SOURCE, mask_sh),\
75 SE_SF(DIG0_HDMI_ACR_32_0, HDMI_ACR_CTS_32, mask_sh),\
76 SE_SF(DIG0_HDMI_ACR_32_1, HDMI_ACR_N_32, mask_sh),\
77 SE_SF(DIG0_HDMI_ACR_44_0, HDMI_ACR_CTS_44, mask_sh),\
78 SE_SF(DIG0_HDMI_ACR_44_1, HDMI_ACR_N_44, mask_sh),\
79 SE_SF(DIG0_HDMI_ACR_48_0, HDMI_ACR_CTS_48, mask_sh),\
80 SE_SF(DIG0_HDMI_ACR_48_1, HDMI_ACR_N_48, mask_sh),\
81 SE_SF(DP0_DP_SEC_AUD_N, DP_SEC_AUD_N, mask_sh),\
82 SE_SF(DP0_DP_SEC_TIMESTAMP, DP_SEC_TIMESTAMP_MODE, mask_sh),\
83 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ASP_ENABLE, mask_sh),\
84 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ATP_ENABLE, mask_sh),\
85 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_AIP_ENABLE, mask_sh),\
86 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ACM_ENABLE, mask_sh),\
87 SE_SF(DIG0_HDMI_CONTROL, HDMI_CLOCK_CHANNEL_RATE, mask_sh),\
88 SE_SF(DIG1_HDMI_CONTROL, TMDS_PIXEL_ENCODING, mask_sh),\
89 SE_SF(DIG1_HDMI_CONTROL, TMDS_COLOR_FORMAT, mask_sh),\
90 SE_SF(DIG0_DIG_FE_CNTL, DIG_STEREOSYNC_SELECT, mask_sh),\
91 SE_SF(DIG0_DIG_FE_CNTL, DIG_STEREOSYNC_GATE_EN, mask_sh),\
92 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP4_ENABLE, mask_sh),\
93 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP5_ENABLE, mask_sh),\
94 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP6_ENABLE, mask_sh),\
95 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, mask_sh),\
96 SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP7_SEND, mask_sh),\
97 SE_SF(DP0_DP_SEC_CNTL6, DP_SEC_GSP7_LINE_NUM, mask_sh),\
98 SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP11_PPS, mask_sh),\
99 SE_SF(DP0_DP_GSP11_CNTL, DP_SEC_GSP11_ENABLE, mask_sh),\
100 SE_SF(DP0_DP_GSP11_CNTL, DP_SEC_GSP11_LINE_NUM, mask_sh),\
101 SE_SF(DP0_DP_DB_CNTL, DP_DB_DISABLE, mask_sh),\
102 SE_SF(DP0_DP_MSA_COLORIMETRY, DP_MSA_MISC0, mask_sh),\
103 SE_SF(DP0_DP_MSA_TIMING_PARAM1, DP_MSA_HTOTAL, mask_sh),\
104 SE_SF(DP0_DP_MSA_TIMING_PARAM1, DP_MSA_VTOTAL, mask_sh),\
105 SE_SF(DP0_DP_MSA_TIMING_PARAM2, DP_MSA_HSTART, mask_sh),\
106 SE_SF(DP0_DP_MSA_TIMING_PARAM2, DP_MSA_VSTART, mask_sh),\
107 SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_HSYNCWIDTH, mask_sh),\
108 SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_HSYNCPOLARITY, mask_sh),\
109 SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_VSYNCWIDTH, mask_sh),\
110 SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_VSYNCPOLARITY, mask_sh),\
111 SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_HWIDTH, mask_sh),\
112 SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_VHEIGHT, mask_sh),\
113 SE_SF(DIG0_HDMI_DB_CONTROL, HDMI_DB_DISABLE, mask_sh),\
114 SE_SF(DP0_DP_VID_TIMING, DP_VID_N_INTERVAL, mask_sh),\
115 SE_SF(DIG0_DIG_FE_CNTL, DIG_SOURCE_SELECT, mask_sh), \
116 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_CONT, mask_sh),\
117 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_SEND, mask_sh),\
118 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_CONT, mask_sh),\
119 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_SEND, mask_sh),\
120 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC2_CONT, mask_sh),\
121 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC2_SEND, mask_sh),\
122 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC3_CONT, mask_sh),\
123 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC3_SEND, mask_sh),\
124 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC4_CONT, mask_sh),\
125 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC4_SEND, mask_sh),\
126 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC5_CONT, mask_sh),\
127 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC5_SEND, mask_sh),\
128 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC6_CONT, mask_sh),\
129 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC6_SEND, mask_sh),\
130 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC7_CONT, mask_sh),\
131 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC7_SEND, mask_sh),\
132 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC8_CONT, mask_sh),\
133 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC8_SEND, mask_sh),\
134 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC9_CONT, mask_sh),\
135 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC9_SEND, mask_sh),\
136 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC10_CONT, mask_sh),\
137 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC10_SEND, mask_sh),\
138 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC11_CONT, mask_sh),\
139 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC11_SEND, mask_sh),\
140 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC12_CONT, mask_sh),\
141 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC12_SEND, mask_sh),\
142 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC13_CONT, mask_sh),\
143 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC13_SEND, mask_sh),\
144 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC14_CONT, mask_sh),\
145 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL6, HDMI_GENERIC14_SEND, mask_sh),\
146 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL1, HDMI_GENERIC0_LINE, mask_sh),\
147 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL1, HDMI_GENERIC1_LINE, mask_sh),\
148 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL2, HDMI_GENERIC2_LINE, mask_sh),\
149 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL2, HDMI_GENERIC3_LINE, mask_sh),\
150 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL3, HDMI_GENERIC4_LINE, mask_sh),\
151 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL3, HDMI_GENERIC5_LINE, mask_sh),\
152 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL4, HDMI_GENERIC6_LINE, mask_sh),\
153 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL4, HDMI_GENERIC7_LINE, mask_sh),\
154 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL7, HDMI_GENERIC8_LINE, mask_sh),\
155 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL7, HDMI_GENERIC9_LINE, mask_sh),\
156 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL8, HDMI_GENERIC10_LINE, mask_sh),\
157 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL8, HDMI_GENERIC11_LINE, mask_sh),\
158 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL9, HDMI_GENERIC12_LINE, mask_sh),\
159 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL9, HDMI_GENERIC13_LINE, mask_sh),\
160 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL10, HDMI_GENERIC14_LINE, mask_sh),\
161 SE_SF(DP0_DP_MSA_VBID_MISC, DP_VBID6_LINE_REFERENCE, mask_sh),\
162 SE_SF(DP0_DP_MSA_VBID_MISC, DP_VBID6_LINE_NUM, mask_sh),\
163 SE_SF(DME0_DME_CONTROL, METADATA_ENGINE_EN, mask_sh),\
164 SE_SF(DME0_DME_CONTROL, METADATA_HUBP_REQUESTOR_ID, mask_sh),\
165 SE_SF(DME0_DME_CONTROL, METADATA_STREAM_TYPE, mask_sh),\
166 SE_SF(DP0_DP_SEC_METADATA_TRANSMISSION, DP_SEC_METADATA_PACKET_ENABLE, mask_sh),\
167 SE_SF(DP0_DP_SEC_METADATA_TRANSMISSION, DP_SEC_METADATA_PACKET_LINE_REFERENCE, mask_sh),\
168 SE_SF(DP0_DP_SEC_METADATA_TRANSMISSION, DP_SEC_METADATA_PACKET_LINE, mask_sh),\
169 SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_ENABLE, mask_sh),\
170 SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_LINE_REFERENCE, mask_sh),\
171 SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_LINE, mask_sh),\
172 SE_SF(DIG0_HDMI_CONTROL, DOLBY_VISION_EN, mask_sh),\
173 SE_SF(DIG0_DIG_FE_EN_CNTL, DIG_FE_ENABLE, mask_sh),\
174 SE_SF(DIG0_DIG_FE_CLK_CNTL, DIG_FE_MODE, mask_sh),\
175 SE_SF(DIG0_DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, mask_sh),\
176 SE_SF(DIG0_DIG_FE_CLK_CNTL, DIG_FE_SOFT_RESET, mask_sh),\
177 SE_SF(DIG0_DIG_FE_CNTL, DIG_STEREOSYNC_GATE_EN, mask_sh),\
178 SE_SF(DP0_DP_SEC_FRAMING4, DP_SST_SDP_SPLITTING, mask_sh),\
179 SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh),\
180 SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_OUTPUT_PIXEL_PER_CYCLE, mask_sh),\
181 SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, mask_sh),\
182 SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, mask_sh),\
183 SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_RESET, mask_sh),\
184 SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, mask_sh),\
185 SE_SF(DIG0_STREAM_MAPPER_CONTROL, DIG_STREAM_LINK_TARGET, mask_sh),\
186 SE_SF(DIG0_DIG_FE_AUDIO_CNTL, DIG_FE_INPUT_MUX_AUDIO_STREAM_SOURCE_SEL, mask_sh),\
187 SE_SF(DIG0_DIG_FE_AUDIO_CNTL, APG_CLOCK_ENABLE, mask_sh)
188
189void dcn42_dio_stream_encoder_construct(
190 struct dcn10_stream_encoder *enc1,
191 struct dc_context *ctx,
192 struct dc_bios *bp,
193 enum engine_id eng_id,
194 struct vpg *vpg,
195 struct apg *apg,
196 const struct dcn10_stream_enc_registers *regs,
197 const struct dcn10_stream_encoder_shift *se_shift,
198 const struct dcn10_stream_encoder_mask *se_mask);
199
200void enc42_se_enable_audio_clock(
201 struct stream_encoder *enc,
202 bool enable);
203
204void enc42_reset_hdmi_stream_attribute(
205 struct stream_encoder *enc);
206#endif /* __DC_DIO_STREAM_ENCODER_DCN42_H__ */
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c+6−2
@@ -734,8 +734,12 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s · 733 unmodified lines
734 memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping));734 memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping));
735 735
736 dml_dispcfg->gpuvm_enable = dml_ctx->config.gpuvm_enable;736 dml_dispcfg->gpuvm_enable = dml_ctx->config.gpuvm_enable;
737 dml_dispcfg->gpuvm_max_page_table_levels = 4;737 if (dml_ctx->v21.dml_init.soc_bb.gpuvm_max_page_table_levels)
738 dml_dispcfg->hostvm_enable = false;738 dml_dispcfg->gpuvm_max_page_table_levels = dml_ctx->v21.dml_init.soc_bb.gpuvm_max_page_table_levels;
739 else
740 dml_dispcfg->gpuvm_max_page_table_levels = 4;
741 dml_dispcfg->hostvm_enable = dml_ctx->config.hostvm_enable;
742 dml_dispcfg->hostvm_max_non_cached_page_table_levels = dml_ctx->v21.dml_init.soc_bb.hostvm_max_non_cached_page_table_levels;
739 dml_dispcfg->minimize_det_reallocation = true;743 dml_dispcfg->minimize_det_reallocation = true;
740 dml_dispcfg->overrides.enable_subvp_implicit_pmo = true;744 dml_dispcfg->overrides.enable_subvp_implicit_pmo = true;
741 745
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c+106−99
@@ -374,128 +374,135 @@ void dml21_handle_phantom_streams_planes(const struct dc *dc, struct dc_state *c · 373 unmodified lines
374 dml2_map_dc_pipes(dml_ctx, context, NULL, &dml_ctx->v21.dml_to_dc_pipe_mapping, dc->current_state);374 dml2_map_dc_pipes(dml_ctx, context, NULL, &dml_ctx->v21.dml_to_dc_pipe_mapping, dc->current_state);
375}375}
376 376
377void dml21_build_fams2_programming(const struct dc *dc,377static unsigned int dml21_build_fams2_stream_programming_v2(const struct dc *dc,
378 struct dc_state *context,378 struct dc_state *context,
379 struct dml2_context *dml_ctx)379 struct dml2_context *dml_ctx)
380{380{
381 int i, j, k;381 int dc_stream_idx, dc_plane_idx, dc_pipe_idx;
382 unsigned int num_fams2_streams = 0;382 unsigned int num_fams2_streams = 0;
383 383
384 /* reset fams2 data */384 for (dc_stream_idx = 0; dc_stream_idx < context->stream_count; dc_stream_idx++) {
385 memset(&context->bw_ctx.bw.dcn.fams2_stream_base_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);385 int dml_stream_idx;
386 memset(&context->bw_ctx.bw.dcn.fams2_stream_sub_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);386 struct dc_stream_state *phantom_stream;
387 memset(&context->bw_ctx.bw.dcn.fams2_stream_sub_params_v2, 0, sizeof(union dmub_fams2_stream_static_sub_state_v2) * DML2_MAX_PLANES);387 struct dc_stream_status *phantom_status;
388 memset(&context->bw_ctx.bw.dcn.fams2_global_config, 0, sizeof(struct dmub_cmd_fams2_global_config));388 enum fams2_stream_type type = 0;
389 389
390 if ((dml_ctx->v21.mode_programming.programming->fams2_required) ||390 union dmub_cmd_fams2_config *static_base_state = &context->bw_ctx.bw.dcn.fams2_stream_base_params[num_fams2_streams];
391 (dml_ctx->v21.mode_programming.programming->legacy_pstate_info_for_dmu)) {391 union dmub_cmd_fams2_config *static_sub_state = &context->bw_ctx.bw.dcn.fams2_stream_sub_params[num_fams2_streams];
392 for (i = 0; i < context->stream_count; i++) {
393 int dml_stream_idx;
394 struct dc_stream_state *phantom_stream;
395 struct dc_stream_status *phantom_status;
396 enum fams2_stream_type type = 0;
397 392
398 union dmub_cmd_fams2_config *static_base_state = &context->bw_ctx.bw.dcn.fams2_stream_base_params[num_fams2_streams];393 struct dc_stream_state *stream = context->streams[dc_stream_idx];
399 union dmub_cmd_fams2_config *static_sub_state = &context->bw_ctx.bw.dcn.fams2_stream_sub_params[num_fams2_streams];
400 394
401 struct dc_stream_state *stream = context->streams[i];395 if (context->stream_status[dc_stream_idx].plane_count == 0 ||
396 dml_ctx->config.svp_pstate.callbacks.get_stream_subvp_type(context, stream) == SUBVP_PHANTOM) {
397 /* can ignore blanked or phantom streams */
398 continue;
399 }
402 400
403 if (context->stream_status[i].plane_count == 0 ||401 dml_stream_idx = dml21_helper_find_dml_pipe_idx_by_stream_id(dml_ctx, stream->stream_id);
404 dml_ctx->config.svp_pstate.callbacks.get_stream_subvp_type(context, stream) == SUBVP_PHANTOM) {402 if (dml_stream_idx < 0) {
405 /* can ignore blanked or phantom streams */403 ASSERT(dml_stream_idx >= 0);
406 continue;404 continue;
407 }405 }
408 406
409 dml_stream_idx = dml21_helper_find_dml_pipe_idx_by_stream_id(dml_ctx, stream->stream_id);407 /* copy static state from PMO */
410 if (dml_stream_idx < 0) {408 memcpy(static_base_state,
411 ASSERT(dml_stream_idx >= 0);409 &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_base_params,
412 continue;410 sizeof(union dmub_cmd_fams2_config));
411
412 memcpy(static_sub_state,
413 &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_sub_params,
414 sizeof(union dmub_cmd_fams2_config));
415
416 switch (dc->debug.fams_version.minor) {
417 case 1:
418 default:
419 type = static_base_state->stream_v1.base.type;
420
421 /* get information from context */
422 static_base_state->stream_v1.base.num_planes = context->stream_status[dc_stream_idx].plane_count;
423 static_base_state->stream_v1.base.otg_inst = context->stream_status[dc_stream_idx].primary_otg_inst;
424
425 /* populate pipe masks for planes */
426 for (dc_plane_idx = 0; dc_plane_idx < context->stream_status[dc_stream_idx].plane_count; dc_plane_idx++) {
427 for (dc_pipe_idx = 0; dc_pipe_idx < dc->res_pool->pipe_count; dc_pipe_idx++) {
428 if (context->res_ctx.pipe_ctx[dc_pipe_idx].stream &&
429 context->res_ctx.pipe_ctx[dc_pipe_idx].stream->stream_id == stream->stream_id &&
430 context->res_ctx.pipe_ctx[dc_pipe_idx].plane_state == context->stream_status[dc_stream_idx].plane_states[dc_plane_idx]) {
431 static_base_state->stream_v1.base.pipe_mask |= (1 << dc_pipe_idx);
432 static_base_state->stream_v1.base.plane_pipe_masks[dc_plane_idx] |= (1 << dc_pipe_idx);
433 }
434 }
413 }435 }
436 }
414 437
415 /* copy static state from PMO */438
416 memcpy(static_base_state,439 /* get per method programming */
417 &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_base_params,440 switch (type) {
418 sizeof(union dmub_cmd_fams2_config));441 case FAMS2_STREAM_TYPE_VBLANK:
419 442 case FAMS2_STREAM_TYPE_VACTIVE:
420 if (dc->debug.fams_version.major == 3) {443 case FAMS2_STREAM_TYPE_DRR:
421 memcpy(&context->bw_ctx.bw.dcn.fams2_stream_sub_params_v2[num_fams2_streams],444 break;
422 &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_sub_params_v2,445 case FAMS2_STREAM_TYPE_SUBVP:
423 sizeof(union dmub_fams2_stream_static_sub_state_v2));446 phantom_stream = dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);
424 } else {447 if (!phantom_stream)
425 memcpy(static_sub_state,448 break;
426 &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_sub_params,449
427 sizeof(union dmub_cmd_fams2_config));450 phantom_status = dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);
428 }451
452 /* phantom status should always be present */
453 ASSERT(phantom_status);
454 if (!phantom_status)
455 break;
429 456
430 switch (dc->debug.fams_version.minor) {457 switch (dc->debug.fams_version.minor) {
431 case 1:458 case 1:
432 default:459 default:
433 type = static_base_state->stream_v1.base.type;460 static_sub_state->stream_v1.sub_state.subvp.phantom_otg_inst = phantom_status->primary_otg_inst;
434 461
435 /* get information from context */462 /* populate pipe masks for phantom planes */
436 static_base_state->stream_v1.base.num_planes = context->stream_status[i].plane_count;463 for (dc_plane_idx = 0; dc_plane_idx < phantom_status->plane_count; dc_plane_idx++) {
437 static_base_state->stream_v1.base.otg_inst = context->stream_status[i].primary_otg_inst;464 for (dc_pipe_idx = 0; dc_pipe_idx < dc->res_pool->pipe_count; dc_pipe_idx++) {
438 465 if (context->res_ctx.pipe_ctx[dc_pipe_idx].stream &&
439 /* populate pipe masks for planes */466 context->res_ctx.pipe_ctx[dc_pipe_idx].stream->stream_id == phantom_stream->stream_id &&
440 for (j = 0; j < context->stream_status[i].plane_count; j++) {467 context->res_ctx.pipe_ctx[dc_pipe_idx].plane_state == phantom_status->plane_states[dc_plane_idx]) {
441 for (k = 0; k < dc->res_pool->pipe_count; k++) {468 switch (dc->debug.fams_version.minor) {
442 if (context->res_ctx.pipe_ctx[k].stream &&469 case 1:
443 context->res_ctx.pipe_ctx[k].stream->stream_id == stream->stream_id &&470 default:
444 context->res_ctx.pipe_ctx[k].plane_state == context->stream_status[i].plane_states[j]) {471 static_sub_state->stream_v1.sub_state.subvp.phantom_pipe_mask |= (1 << dc_pipe_idx);
445 static_base_state->stream_v1.base.pipe_mask |= (1 << k);472 static_sub_state->stream_v1.sub_state.subvp.phantom_plane_pipe_masks[dc_plane_idx] |= (1 << dc_pipe_idx);
446 static_base_state->stream_v1.base.plane_pipe_masks[j] |= (1 << k);473 }
447 }474 }
448 }475 }
449 }476 }
450 }477 }
478 break;
479 default:
480 ASSERT(false);
481 break;
482 }
451 483
484 num_fams2_streams++;
485 }
452 486
453 /* get per method programming */487 return num_fams2_streams;
454 switch (type) {488}
455 case FAMS2_STREAM_TYPE_VBLANK:489
456 case FAMS2_STREAM_TYPE_VACTIVE:490void dml21_build_fams2_programming(const struct dc *dc,
457 case FAMS2_STREAM_TYPE_DRR:491 struct dc_state *context,
458 break;492 struct dml2_context *dml_ctx)
459 case FAMS2_STREAM_TYPE_SUBVP:493{
460 phantom_stream = dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);494 unsigned int num_fams2_streams = 0;
461 if (!phantom_stream)495
462 break;496 /* reset fams2 data */
463 497 memset(&context->bw_ctx.bw.dcn.fams2_stream_base_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);
464 phantom_status = dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);498 memset(&context->bw_ctx.bw.dcn.fams2_stream_sub_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);
465 499 memset(&context->bw_ctx.bw.dcn.fams2_stream_sub_params_v2, 0, sizeof(union dmub_fams2_stream_static_sub_state_v2) * DML2_MAX_PLANES);
466 /* phantom status should always be present */500 memset(&context->bw_ctx.bw.dcn.fams2_global_config, 0, sizeof(struct dmub_cmd_fams2_global_config));
467 ASSERT(phantom_status);
468 if (!phantom_status)
469 break;
470
471 switch (dc->debug.fams_version.minor) {
472 case 1:
473 default:
474 static_sub_state->stream_v1.sub_state.subvp.phantom_otg_inst = phantom_status->primary_otg_inst;
475
476 /* populate pipe masks for phantom planes */
477 for (j = 0; j < phantom_status->plane_count; j++) {
478 for (k = 0; k < dc->res_pool->pipe_count; k++) {
479 if (context->res_ctx.pipe_ctx[k].stream &&
480 context->res_ctx.pipe_ctx[k].stream->stream_id == phantom_stream->stream_id &&
481 context->res_ctx.pipe_ctx[k].plane_state == phantom_status->plane_states[j]) {
482 switch (dc->debug.fams_version.minor) {
483 case 1:
484 default:
485 static_sub_state->stream_v1.sub_state.subvp.phantom_pipe_mask |= (1 << k);
486 static_sub_state->stream_v1.sub_state.subvp.phantom_plane_pipe_masks[j] |= (1 << k);
487 }
488 }
489 }
490 }
491 }
492 break;
493 default:
494 ASSERT(false);
495 break;
496 }
497 501
498 num_fams2_streams++;502 if (dml_ctx->v21.mode_programming.programming->fams2_required ||
503 dml_ctx->v21.mode_programming.programming->legacy_pstate_info_for_dmu) {
504 if (dc->debug.fams_version.major == 2) {
505 num_fams2_streams = dml21_build_fams2_stream_programming_v2(dc, context, dml_ctx);
499 }506 }
500 }507 }
501 508
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.h+1−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
9struct dc_state;9struct dc_state;
10struct dc_plane_state;10struct dc_plane_state;
11struct pipe_ctx;11struct pipe_ctx;
12struct dc_dmub_srv;
12 13
13struct dml2_context;14struct dml2_context;
14struct dml2_display_rq_regs;15struct dml2_display_rq_regs;
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h+2−0
@@ -160,6 +160,8 @@ struct dml2_soc_bb { · 159 unmodified lines
160 unsigned long return_bus_width_bytes;160 unsigned long return_bus_width_bytes;
161 unsigned long hostvm_min_page_size_kbytes;161 unsigned long hostvm_min_page_size_kbytes;
162 unsigned long gpuvm_min_page_size_kbytes;162 unsigned long gpuvm_min_page_size_kbytes;
163 unsigned int hostvm_max_non_cached_page_table_levels;
164 unsigned int gpuvm_max_page_table_levels;
163 double phy_downspread_percent;165 double phy_downspread_percent;
164 double dcn_downspread_percent;166 double dcn_downspread_percent;
165 double dispclk_dppclk_vco_speed_mhz;167 double dispclk_dppclk_vco_speed_mhz;
drivers/gpu/drm/amd/display/dc/dml2_0/dml2_dc_resource_mgmt.c+3−3
@@ -909,10 +909,10 @@ static unsigned int get_source_mpc_factor(const struct dml2_context *ctx, · 908 unmodified lines
909 const struct dc_plane_state *plane)909 const struct dc_plane_state *plane)
910{910{
911 struct pipe_ctx *dpp_pipes[MAX_PIPES] = {0};911 struct pipe_ctx *dpp_pipes[MAX_PIPES] = {0};
912 int dpp_pipe_count = ctx->config.callbacks.get_dpp_pipes_for_plane(plane,
913 &state->res_ctx, dpp_pipes);
914 912
915 ASSERT(dpp_pipe_count > 0);913 if (ctx->config.callbacks.get_dpp_pipes_for_plane(plane, &state->res_ctx, dpp_pipes) <= 0)
914 ASSERT(false);
915
916 return ctx->config.callbacks.get_mpc_slice_count(dpp_pipes[0]);916 return ctx->config.callbacks.get_mpc_slice_count(dpp_pipes[0]);
917}917}
918 918
drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.h+1−0
@@ -239,6 +239,7 @@ struct dml2_configuration_options { · 238 unmodified lines
239 239
240 bool use_clock_dc_limits;240 bool use_clock_dc_limits;
241 bool gpuvm_enable;241 bool gpuvm_enable;
242 bool hostvm_enable;
242 bool force_tdlut_enable;243 bool force_tdlut_enable;
243 void *bb_from_dmub;244 void *bb_from_dmub;
244};245};
drivers/gpu/drm/amd/display/dc/dpp/Makefile+9−1
@@ -1,5 +1,5 @@
1 1
2# Copyright 2022 Advanced Micro Devices, Inc.2# Copyright 2022-2026 Advanced Micro Devices, Inc.
3#3#
4# Permission is hereby granted, free of charge, to any person obtaining a4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),5# copy of this software and associated documentation files (the "Software"),
@@ -80,4 +80,12 @@ AMD_DAL_DPP_DCN401 = $(addprefix $(AMDDALPATH)/dc/dpp/dcn401/,$(DPP_DCN401)) · 74 unmodified lines
80 80
81AMD_DISPLAY_FILES += $(AMD_DAL_DPP_DCN401)81AMD_DISPLAY_FILES += $(AMD_DAL_DPP_DCN401)
82 82
83###############################################################################
84# DCN42
85###############################################################################
86DPP_DCN42 = dcn42_dpp.o
87
88AMD_DAL_DPP_DCN42 = $(addprefix $(AMDDALPATH)/dc/dpp/dcn42/,$(DPP_DCN42))
89
90AMD_DISPLAY_FILES += $(AMD_DAL_DPP_DCN42)
83endif91endif
drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h+4−1
@@ -1,4 +1,5 @@
1/* Copyright 2023 Advanced Micro Devices, Inc.1/* SPDX-License-Identifier: MIT */
2/* Copyright 2023-2026 Advanced Micro Devices, Inc.
2 *3 *
3 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -653,6 +654,8 @@ · 648 unmodified lines
653 654
654struct dcn401_dpp_registers {655struct dcn401_dpp_registers {
655 DPP_REG_VARIABLE_LIST_DCN401;656 DPP_REG_VARIABLE_LIST_DCN401;
657 uint32_t ALPHA_2BIT_LUT01;
658 uint32_t ALPHA_2BIT_LUT23;
656};659};
657 660
658struct dcn401_dpp_shift {661struct dcn401_dpp_shift {
drivers/gpu/drm/amd/display/dc/dpp/dcn42/dcn42_dpp.c+333−0
@@ -0,0 +1,333 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "dm_services.h"
6#include "core_types.h"
7#include "reg_helper.h"
8#include "dcn42_dpp.h"
9#include "dcn35/dcn35_dpp.h"
10
11#define REG(reg)\
12 dpp->tf_regs->reg
13
14#define CTX \
15 dpp->base.ctx
16
17#undef FN
18#define FN(reg_name, field_name) \
19 dpp->tf_shift->field_name, dpp->tf_mask->field_name
20
21static const uint32_t *get_hist_rgb_luma_coefs(enum dc_color_space color_space)
22{
23 // Coefs in s.6.12.
24 // Y = 0.2126R + 0.7152G + 0.0722B
25 static const uint32_t luma_transform_bt_709[] = {0x1cb36, 0x1e6e2, 0x1b27b};
26 // Y = 0.2627R + 0.678G + 0.0593B
27 static const uint32_t luma_transform_bt_2020[] = {0x1d0d0, 0x1e5b2, 0x1ae5c};
28
29 switch (color_space) {
30 case COLOR_SPACE_2020_RGB_FULLRANGE:
31 case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
32 return luma_transform_bt_2020;
33 default:
34 return luma_transform_bt_709;
35 }
36}
37
38static void dpp42_dpp_cm_hist_control(
39 struct dpp *dpp_base,
40 struct cm_hist_control cntl,
41 enum dc_color_space color_space)
42{
43 struct dcn42_dpp *dpp = TO_DCN42_DPP(dpp_base);
44
45 REG_UPDATE_10(
46 CM_HIST_CNTL,
47 CM_HIST_SEL, cntl.tap_point,
48 CM_HIST_CH_EN, cntl.channels_enabled,
49 CM_HIST_SRC1_SEL, cntl.src_1_select,
50 CM_HIST_SRC2_SEL, cntl.src_2_select,
51 CM_HIST_SRC3_SEL, cntl.src_3_select,
52 CM_HIST_CH1_XBAR, cntl.ch1_src,
53 CM_HIST_CH2_XBAR, cntl.ch2_src,
54 CM_HIST_CH3_XBAR, cntl.ch3_src,
55 CM_HIST_FORMAT, cntl.format,
56 CM_HIST_READ_CHANNEL_MASK, cntl.read_channel_mask);
57
58 if (cntl.src_2_select == CM_HIST_SRC2_MODE_RGB_TO_Y) {
59 const uint32_t *luma_transform = get_hist_rgb_luma_coefs(color_space);
60
61 REG_UPDATE(CM_HIST_COEFA_SRC2, CM_HIST_COEFA_SRC2, luma_transform[0]);
62 REG_UPDATE(CM_HIST_COEFB_SRC2, CM_HIST_COEFB_SRC2, luma_transform[1]);
63 REG_UPDATE(CM_HIST_COEFC_SRC2, CM_HIST_COEFC_SRC2, luma_transform[2]);
64 } else {
65 REG_UPDATE(CM_HIST_COEFA_SRC2, CM_HIST_COEFA_SRC2, 0);
66 REG_UPDATE(CM_HIST_COEFB_SRC2, CM_HIST_COEFB_SRC2, 0x1f000); // 1 in s.6.12
67 REG_UPDATE(CM_HIST_COEFC_SRC2, CM_HIST_COEFC_SRC2, 0);
68 }
69}
70
71static bool dpp42_dpp_cm_hist_read(struct dpp *dpp_base, struct cm_hist *hist_out)
72{
73 struct dcn42_dpp *dpp = TO_DCN42_DPP(dpp_base);
74 uint32_t channel_mask = 0;
75 uint32_t rdy_status = 0, rdy_status_a = 0, rdy_status_b = 0;
76 bool ch1, ch2, ch3;
77
78 if (hist_out == NULL)
79 return false;
80
81
82 REG_GET(CM_HIST_CNTL, CM_HIST_READ_CHANNEL_MASK, &channel_mask);
83 ch1 = (channel_mask & 1) > 0;
84 ch2 = (channel_mask & 2) > 0;
85 ch3 = (channel_mask & 4) > 0;
86
87 REG_GET(CM_HIST_STATUS, CM_HIST_BUFA_RDY_STATUS, &rdy_status_a);
88 REG_GET(CM_HIST_STATUS, CM_HIST_BUFB_RDY_STATUS, &rdy_status_b);
89
90 rdy_status = rdy_status_a || rdy_status_b;
91
92 if (rdy_status) {
93 REG_UPDATE(CM_HIST_LOCK, CM_HIST_LOCK, 1);
94 REG_UPDATE(CM_HIST_INDEX, CM_HIST_INDEX, 0);
95 for (int i = 0; i < 256; i++) {
96 uint32_t temp;
97
98 if (ch1) {
99 REG_GET(CM_HIST_DATA, CM_HIST_DATA, &temp);
100 hist_out->ch1[i] += temp;
101 }
102 if (ch2) {
103 REG_GET(CM_HIST_DATA, CM_HIST_DATA, &temp);
104 hist_out->ch2[i] += temp;
105 }
106 if (ch3) {
107 REG_GET(CM_HIST_DATA, CM_HIST_DATA, &temp);
108 hist_out->ch3[i] += temp;
109 }
110 }
111 REG_UPDATE(CM_HIST_LOCK, CM_HIST_LOCK, 0);
112 return true;
113 } else {
114 return false;
115 }
116}
117
118static void dpp42_dpp_setup(
119 struct dpp *dpp_base,
120 enum surface_pixel_format format,
121 enum expansion_mode mode,
122 struct dc_csc_transform input_csc_color_matrix,
123 enum dc_color_space input_color_space,
124 struct cnv_alpha_2bit_lut *alpha_2bit_lut)
125{
126 struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
127 uint32_t pixel_format = 0;
128 uint32_t alpha_en = 1;
129 enum dc_color_space color_space = COLOR_SPACE_SRGB;
130 enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS;
131 uint32_t is_2bit = 0;
132 uint32_t alpha_plane_enable = 0;
133 uint32_t dealpha_en = 0, dealpha_ablnd_en = 0;
134 uint32_t realpha_en = 0, realpha_ablnd_en = 0;
135 struct out_csc_color_matrix tbl_entry;
136 int i;
137
138 REG_SET_2(FORMAT_CONTROL, 0,
139 CNVC_BYPASS, 0,
140 FORMAT_EXPANSION_MODE, mode);
141
142 REG_UPDATE(FORMAT_CONTROL, FORMAT_CNV16, 0);
143 REG_UPDATE(FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, 0);
144 REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE, 0);
145 REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE_C, 0);
146
147 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_R, 0);
148 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_G, 1);
149 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_B, 2);
150
151 switch (format) {
152 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
153 pixel_format = 1;
154 break;
155 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
156 pixel_format = 3;
157 alpha_en = 0;
158 break;
159 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
160 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
161 pixel_format = 8;
162 break;
163 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
164 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
165 pixel_format = 10;
166 is_2bit = 1;
167 break;
168 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
169 pixel_format = 65;
170 color_space = COLOR_SPACE_YCBCR709;
171 select = INPUT_CSC_SELECT_ICSC;
172 break;
173 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
174 pixel_format = 64;
175 color_space = COLOR_SPACE_YCBCR709;
176 select = INPUT_CSC_SELECT_ICSC;
177 break;
178 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
179 pixel_format = 67;
180 color_space = COLOR_SPACE_YCBCR709;
181 select = INPUT_CSC_SELECT_ICSC;
182 break;
183 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
184 pixel_format = 66;
185 color_space = COLOR_SPACE_YCBCR709;
186 select = INPUT_CSC_SELECT_ICSC;
187 break;
188 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
189 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
190 pixel_format = 26; /* ARGB16161616_UNORM */
191 break;
192 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
193 pixel_format = 24;
194 break;
195 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
196 pixel_format = 25;
197 break;
198 case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
199 pixel_format = 12;
200 color_space = COLOR_SPACE_YCBCR709;
201 select = INPUT_CSC_SELECT_ICSC;
202 break;
203 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
204 pixel_format = 112;
205 alpha_en = 0;
206 break;
207 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
208 pixel_format = 113;
209 alpha_en = 0;
210 break;
211 case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
212 pixel_format = 114;
213 color_space = COLOR_SPACE_YCBCR709;
214 select = INPUT_CSC_SELECT_ICSC;
215 is_2bit = 1;
216 break;
217 case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
218 pixel_format = 115;
219 color_space = COLOR_SPACE_YCBCR709;
220 select = INPUT_CSC_SELECT_ICSC;
221 is_2bit = 1;
222 break;
223 case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
224 pixel_format = 116;
225 alpha_plane_enable = 0;
226 break;
227 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
228 pixel_format = 116;
229 alpha_plane_enable = 1;
230 break;
231 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
232 pixel_format = 118;
233 alpha_en = 0;
234 break;
235 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
236 pixel_format = 119;
237 alpha_en = 0;
238 break;
239 default:
240 break;
241 }
242
243 /* Set default color space based on format if none is given. */
244 color_space = input_color_space ? input_color_space : color_space;
245
246 if (is_2bit == 1 && alpha_2bit_lut != NULL) {
247 REG_UPDATE(ALPHA_2BIT_LUT01, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0);
248 REG_UPDATE(ALPHA_2BIT_LUT01, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1);
249 REG_UPDATE(ALPHA_2BIT_LUT23, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2);
250 REG_UPDATE(ALPHA_2BIT_LUT23, ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3);
251 }
252
253 REG_SET_2(CNVC_SURFACE_PIXEL_FORMAT, 0,
254 CNVC_SURFACE_PIXEL_FORMAT, pixel_format,
255 CNVC_ALPHA_PLANE_ENABLE, alpha_plane_enable);
256 REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
257
258 REG_SET_2(PRE_DEALPHA, 0,
259 PRE_DEALPHA_EN, dealpha_en,
260 PRE_DEALPHA_ABLND_EN, dealpha_ablnd_en);
261 REG_SET_2(PRE_REALPHA, 0,
262 PRE_REALPHA_EN, realpha_en,
263 PRE_REALPHA_ABLND_EN, realpha_ablnd_en);
264
265 /* If input adjustment exists, program the ICSC with those values. */
266 if (input_csc_color_matrix.enable_adjustment == true) {
267 for (i = 0; i < 12; i++)
268 tbl_entry.regval[i] = input_csc_color_matrix.matrix[i];
269
270 tbl_entry.color_space = input_color_space;
271
272 if (color_space >= COLOR_SPACE_YCBCR601)
273 select = INPUT_CSC_SELECT_ICSC;
274 else
275 select = INPUT_CSC_SELECT_BYPASS;
276
277 dpp3_program_post_csc(dpp_base, color_space, select,
278 &tbl_entry);
279 } else {
280 dpp3_program_post_csc(dpp_base, color_space, select, NULL);
281 }
282}
283
284static struct dpp_funcs dcn42_dpp_funcs = {
285 .dpp_program_gamcor_lut = dpp3_program_gamcor_lut,
286 .dpp_read_state = dpp401_read_state,
287 .dpp_reset = dpp_reset,
288 .dpp_set_scaler = dpp401_dscl_set_scaler_manual_scale,
289 .dpp_get_optimal_number_of_taps = dpp3_get_optimal_number_of_taps,
290 .dpp_set_pre_degam = dpp3_set_pre_degam,
291 .dpp_setup = dpp42_dpp_setup,
292 .dpp_program_cm_dealpha = dpp3_program_cm_dealpha,
293 .dpp_program_cm_bias = dpp3_program_cm_bias,
294 .dpp_program_bias_and_scale = dpp35_program_bias_and_scale_fcnv,
295 .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer,
296 .set_cursor_attributes = dpp401_set_cursor_attributes,
297 .set_cursor_position = dpp401_set_cursor_position,
298 .set_optional_cursor_attributes = dpp401_set_optional_cursor_attributes,
299 .dpp_dppclk_control = dpp35_dppclk_control,
300 .dpp_set_hdr_multiplier = dpp3_set_hdr_multiplier,
301 .set_cursor_matrix = dpp401_set_cursor_matrix,
302 .dpp_cm_hist_control = dpp42_dpp_cm_hist_control,
303 .dpp_cm_hist_read = dpp42_dpp_cm_hist_read,
304 .dpp_read_reg_state = dpp30_read_reg_state,
305};
306
307
308static struct dpp_caps dcn42_dpp_cap = {
309 .dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT,
310 .max_lb_partitions = 63,
311 .dscl_calc_lb_num_partitions = dscl401_calc_lb_num_partitions,
312};
313
314bool dpp42_construct(
315 struct dcn42_dpp *dpp,
316 struct dc_context *ctx,
317 uint32_t inst,
318 const struct dcn42_dpp_registers *tf_regs,
319 const struct dcn42_dpp_shift *tf_shift,
320 const struct dcn42_dpp_mask *tf_mask)
321{
322 dpp->base.ctx = ctx;
323
324 dpp->base.inst = inst;
325 dpp->base.funcs = &dcn42_dpp_funcs;
326 dpp->base.caps = &dcn42_dpp_cap;
327
328 dpp->tf_regs = tf_regs;
329 dpp->tf_shift = tf_shift;
330 dpp->tf_mask = tf_mask;
331
332 return true;
333}
drivers/gpu/drm/amd/display/dc/dpp/dcn42/dcn42_dpp.h+469−0
@@ -0,0 +1,469 @@
1/* SPDX-License-Identifier: MIT */
2/* Copyright 2026 Advanced Micro Devices, Inc. */
3
4#ifndef __DCN42_DPP_H__
5#define __DCN42_DPP_H__
6
7#include "dcn401/dcn401_dpp.h"
8
9#define TO_DCN42_DPP(dpp)\
10 container_of(dpp, struct dcn42_dpp, base)
11
12#define DPP_REG_LIST_SH_MASK_DCN42_COMMON(mask_sh)\
13 TF_SF(CM0_CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, mask_sh),\
14 TF_SF(CM0_CM_DEALPHA, CM_DEALPHA_EN, mask_sh),\
15 TF_SF(CM0_CM_DEALPHA, CM_DEALPHA_ABLND, mask_sh),\
16 TF_SF(CM0_CM_BIAS_CR_R, CM_BIAS_CR_R, mask_sh),\
17 TF_SF(CM0_CM_BIAS_Y_G_CB_B, CM_BIAS_Y_G, mask_sh),\
18 TF_SF(CM0_CM_BIAS_Y_G_CB_B, CM_BIAS_CB_B, mask_sh),\
19 TF_SF(CM0_CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_DIS, mask_sh),\
20 TF_SF(CM0_CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, mask_sh),\
21 TF_SF(CM0_CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_DIS, mask_sh),\
22 TF_SF(CNVC_CFG0_PRE_DEGAM, PRE_DEGAM_MODE, mask_sh),\
23 TF_SF(CNVC_CFG0_PRE_DEGAM, PRE_DEGAM_SELECT, mask_sh),\
24 TF_SF(CM0_CM_GAMCOR_CONTROL, CM_GAMCOR_MODE, mask_sh),\
25 TF_SF(CM0_CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT, mask_sh),\
26 TF_SF(CM0_CM_GAMCOR_CONTROL, CM_GAMCOR_PWL_DISABLE, mask_sh),\
27 TF_SF(CM0_CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, mask_sh),\
28 TF_SF(CM0_CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT_CURRENT, mask_sh),\
29 TF_SF(CM0_CM_GAMCOR_LUT_INDEX, CM_GAMCOR_LUT_INDEX, mask_sh),\
30 TF_SF(CM0_CM_GAMCOR_LUT_DATA, CM_GAMCOR_LUT_DATA, mask_sh),\
31 TF_SF(CM0_CM_GAMCOR_LUT_CONTROL, CM_GAMCOR_LUT_WRITE_COLOR_MASK, mask_sh),\
32 TF_SF(CM0_CM_GAMCOR_LUT_CONTROL, CM_GAMCOR_LUT_READ_COLOR_SEL, mask_sh),\
33 TF_SF(CM0_CM_GAMCOR_LUT_CONTROL, CM_GAMCOR_LUT_READ_DBG, mask_sh),\
34 TF_SF(CM0_CM_GAMCOR_LUT_CONTROL, CM_GAMCOR_LUT_HOST_SEL, mask_sh),\
35 TF_SF(CM0_CM_GAMCOR_LUT_CONTROL, CM_GAMCOR_LUT_CONFIG_MODE, mask_sh),\
36 TF_SF(CM0_CM_GAMCOR_RAMA_START_CNTL_B, CM_GAMCOR_RAMA_EXP_REGION_START_B, mask_sh),\
37 TF_SF(CM0_CM_GAMCOR_RAMA_START_CNTL_B, CM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B, mask_sh),\
38 TF_SF(CM0_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B, CM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B, mask_sh),\
39 TF_SF(CM0_CM_GAMCOR_RAMA_START_BASE_CNTL_B, CM_GAMCOR_RAMA_EXP_REGION_START_BASE_B, mask_sh),\
40 TF_SF(CM0_CM_GAMCOR_RAMA_END_CNTL1_B, CM_GAMCOR_RAMA_EXP_REGION_END_BASE_B, mask_sh),\
41 TF_SF(CM0_CM_GAMCOR_RAMA_END_CNTL2_B, CM_GAMCOR_RAMA_EXP_REGION_END_B, mask_sh),\
42 TF_SF(CM0_CM_GAMCOR_RAMA_END_CNTL2_B, CM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B, mask_sh),\
43 TF_SF(CM0_CM_GAMCOR_RAMA_OFFSET_B, CM_GAMCOR_RAMA_OFFSET_B, mask_sh),\
44 TF_SF(CM0_CM_GAMCOR_RAMA_REGION_0_1, CM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET, mask_sh),\
45 TF_SF(CM0_CM_GAMCOR_RAMA_REGION_0_1, CM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS, mask_sh),\
46 TF_SF(CM0_CM_GAMCOR_RAMA_REGION_0_1, CM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET, mask_sh),\
47 TF_SF(CM0_CM_GAMCOR_RAMA_REGION_0_1, CM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS, mask_sh),\
48 TF_SF(DSCL0_DSCL_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT, mask_sh),\
49 TF_SF(DSCL0_DSCL_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT, mask_sh),\
50 TF_SF(DSCL0_DSCL_EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM, mask_sh),\
51 TF_SF(DSCL0_DSCL_EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP, mask_sh),\
52 TF_SF(DSCL0_OTG_H_BLANK, OTG_H_BLANK_START, mask_sh),\
53 TF_SF(DSCL0_OTG_H_BLANK, OTG_H_BLANK_END, mask_sh),\
54 TF_SF(DSCL0_OTG_V_BLANK, OTG_V_BLANK_START, mask_sh),\
55 TF_SF(DSCL0_OTG_V_BLANK, OTG_V_BLANK_END, mask_sh),\
56 TF_SF(DSCL0_LB_DATA_FORMAT, INTERLEAVE_EN, mask_sh),\
57 TF2_SF(DSCL0, LB_DATA_FORMAT__ALPHA_EN, mask_sh),\
58 TF_SF(DSCL0_LB_MEMORY_CTRL, MEMORY_CONFIG, mask_sh),\
59 TF_SF(DSCL0_LB_MEMORY_CTRL, LB_MAX_PARTITIONS, mask_sh),\
60 TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_MODE, mask_sh),\
61 TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_NUM_PIPE, mask_sh),\
62 TF_SF(DSCL0_DSCL_CONTROL, SCL_BOUNDARY_MODE, mask_sh),\
63 TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_PIPE_ID, mask_sh),\
64 TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_V_NUM_TAPS, mask_sh),\
65 TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_H_NUM_TAPS, mask_sh),\
66 TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_V_NUM_TAPS_C, mask_sh),\
67 TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_H_NUM_TAPS_C, mask_sh),\
68 TF_SF(DSCL0_SCL_COEF_RAM_TAP_SELECT, SCL_COEF_RAM_TAP_PAIR_IDX, mask_sh),\
69 TF_SF(DSCL0_SCL_COEF_RAM_TAP_SELECT, SCL_COEF_RAM_PHASE, mask_sh),\
70 TF_SF(DSCL0_SCL_COEF_RAM_TAP_SELECT, SCL_COEF_RAM_FILTER_TYPE, mask_sh),\
71 TF_SF(DSCL0_SCL_COEF_RAM_TAP_DATA, SCL_COEF_RAM_EVEN_TAP_COEF, mask_sh),\
72 TF_SF(DSCL0_SCL_COEF_RAM_TAP_DATA, SCL_COEF_RAM_EVEN_TAP_COEF_EN, mask_sh),\
73 TF_SF(DSCL0_SCL_COEF_RAM_TAP_DATA, SCL_COEF_RAM_ODD_TAP_COEF, mask_sh),\
74 TF_SF(DSCL0_SCL_COEF_RAM_TAP_DATA, SCL_COEF_RAM_ODD_TAP_COEF_EN, mask_sh),\
75 TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_H_2TAP_HARDCODE_COEF_EN, mask_sh),\
76 TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_H_2TAP_SHARP_EN, mask_sh),\
77 TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_H_2TAP_SHARP_FACTOR, mask_sh),\
78 TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_V_2TAP_HARDCODE_COEF_EN, mask_sh),\
79 TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_V_2TAP_SHARP_EN, mask_sh),\
80 TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_V_2TAP_SHARP_FACTOR, mask_sh),\
81 TF_SF(DSCL0_SCL_MODE, SCL_COEF_RAM_SELECT, mask_sh),\
82 TF_SF(DSCL0_SCL_MODE, DSCL_MODE, mask_sh),\
83 TF_SF(DSCL0_RECOUT_START, RECOUT_START_X, mask_sh),\
84 TF_SF(DSCL0_RECOUT_START, RECOUT_START_Y, mask_sh),\
85 TF_SF(DSCL0_RECOUT_SIZE, RECOUT_WIDTH, mask_sh),\
86 TF_SF(DSCL0_RECOUT_SIZE, RECOUT_HEIGHT, mask_sh),\
87 TF_SF(DSCL0_MPC_SIZE, MPC_WIDTH, mask_sh),\
88 TF_SF(DSCL0_MPC_SIZE, MPC_HEIGHT, mask_sh),\
89 TF_SF(DSCL0_SCL_HORZ_FILTER_SCALE_RATIO, SCL_H_SCALE_RATIO, mask_sh),\
90 TF_SF(DSCL0_SCL_VERT_FILTER_SCALE_RATIO, SCL_V_SCALE_RATIO, mask_sh),\
91 TF_SF(DSCL0_SCL_HORZ_FILTER_SCALE_RATIO_C, SCL_H_SCALE_RATIO_C, mask_sh),\
92 TF_SF(DSCL0_SCL_VERT_FILTER_SCALE_RATIO_C, SCL_V_SCALE_RATIO_C, mask_sh),\
93 TF_SF(DSCL0_SCL_HORZ_FILTER_INIT, SCL_H_INIT_FRAC, mask_sh),\
94 TF_SF(DSCL0_SCL_HORZ_FILTER_INIT, SCL_H_INIT_INT, mask_sh),\
95 TF_SF(DSCL0_SCL_HORZ_FILTER_INIT_C, SCL_H_INIT_FRAC_C, mask_sh),\
96 TF_SF(DSCL0_SCL_HORZ_FILTER_INIT_C, SCL_H_INIT_INT_C, mask_sh),\
97 TF_SF(DSCL0_SCL_VERT_FILTER_INIT, SCL_V_INIT_FRAC, mask_sh),\
98 TF_SF(DSCL0_SCL_VERT_FILTER_INIT, SCL_V_INIT_INT, mask_sh),\
99 TF_SF(DSCL0_SCL_VERT_FILTER_INIT_C, SCL_V_INIT_FRAC_C, mask_sh),\
100 TF_SF(DSCL0_SCL_VERT_FILTER_INIT_C, SCL_V_INIT_INT_C, mask_sh),\
101 TF_SF(DSCL0_SCL_MODE, SCL_CHROMA_COEF_MODE, mask_sh),\
102 TF_SF(DSCL0_SCL_MODE, SCL_COEF_RAM_SELECT_CURRENT, mask_sh), \
103 TF_SF(CNVC_CFG0_PRE_DEALPHA, PRE_DEALPHA_EN, mask_sh), \
104 TF_SF(CNVC_CFG0_PRE_DEALPHA, PRE_DEALPHA_ABLND_EN, mask_sh), \
105 TF_SF(CNVC_CFG0_PRE_REALPHA, PRE_REALPHA_EN, mask_sh), \
106 TF_SF(CNVC_CFG0_PRE_REALPHA, PRE_REALPHA_ABLND_EN, mask_sh), \
107 TF_SF(CNVC_CFG0_PRE_CSC_MODE, PRE_CSC_MODE, mask_sh), \
108 TF_SF(CNVC_CFG0_PRE_CSC_MODE, PRE_CSC_MODE_CURRENT, mask_sh), \
109 TF_SF(CNVC_CFG0_PRE_CSC_C11_C12, PRE_CSC_C11, mask_sh), \
110 TF_SF(CNVC_CFG0_PRE_CSC_C11_C12, PRE_CSC_C12, mask_sh), \
111 TF_SF(CNVC_CFG0_PRE_CSC_C33_C34, PRE_CSC_C33, mask_sh), \
112 TF_SF(CNVC_CFG0_PRE_CSC_C33_C34, PRE_CSC_C34, mask_sh), \
113 TF_SF(CM0_CM_POST_CSC_CONTROL, CM_POST_CSC_MODE, mask_sh), \
114 TF_SF(CM0_CM_POST_CSC_CONTROL, CM_POST_CSC_MODE_CURRENT, mask_sh), \
115 TF_SF(CM0_CM_POST_CSC_C11_C12, CM_POST_CSC_C11, mask_sh), \
116 TF_SF(CM0_CM_POST_CSC_C11_C12, CM_POST_CSC_C12, mask_sh), \
117 TF_SF(CM0_CM_POST_CSC_C33_C34, CM_POST_CSC_C33, mask_sh), \
118 TF_SF(CM0_CM_POST_CSC_C33_C34, CM_POST_CSC_C34, mask_sh), \
119 TF_SF(CM0_CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_INDEX, mask_sh), \
120 TF_SF(CNVC_CFG0_FORMAT_CONTROL, CNVC_BYPASS, mask_sh), \
121 TF2_SF(CNVC_CFG0, FORMAT_CONTROL__ALPHA_EN, mask_sh), \
122 TF_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_EXPANSION_MODE, mask_sh), \
123 TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
124 TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_ALPHA_PLANE_ENABLE, mask_sh), \
125 TF_SF(CM_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
126 TF_SF(CM_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
127 TF_SF(CM_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
128 TF_SF(CM_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
129 TF_SF(CM_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh), \
130 TF_SF(CM_CUR0_CURSOR0_FP_SCALE_BIAS_G_Y, CUR0_FP_BIAS_G_Y, mask_sh), \
131 TF_SF(CM_CUR0_CURSOR0_FP_SCALE_BIAS_G_Y, CUR0_FP_SCALE_G_Y, mask_sh), \
132 TF_SF(CM_CUR0_CURSOR0_FP_SCALE_BIAS_RB_CRCB, CUR0_FP_BIAS_RB_CRCB, mask_sh), \
133 TF_SF(CM_CUR0_CURSOR0_FP_SCALE_BIAS_RB_CRCB, CUR0_FP_SCALE_RB_CRCB, mask_sh), \
134 TF_SF(CM_CUR0_CUR0_MATRIX_MODE, CUR0_MATRIX_MODE, mask_sh), \
135 TF_SF(CM_CUR0_CUR0_MATRIX_MODE, CUR0_MATRIX_MODE_CURRENT, mask_sh), \
136 TF_SF(CM_CUR0_CUR0_MATRIX_MODE, CUR0_MATRIX_COEF_FORMAT, mask_sh), \
137 TF_SF(CM_CUR0_CUR0_MATRIX_C11_C12_A, CUR0_MATRIX_C11_A, mask_sh), \
138 TF_SF(CM_CUR0_CUR0_MATRIX_C11_C12_A, CUR0_MATRIX_C12_A, mask_sh), \
139 TF_SF(CM_CUR0_CUR0_MATRIX_C13_C14_A, CUR0_MATRIX_C13_A, mask_sh), \
140 TF_SF(CM_CUR0_CUR0_MATRIX_C13_C14_A, CUR0_MATRIX_C14_A, mask_sh), \
141 TF_SF(CM_CUR0_CUR0_MATRIX_C21_C22_A, CUR0_MATRIX_C21_A, mask_sh), \
142 TF_SF(CM_CUR0_CUR0_MATRIX_C21_C22_A, CUR0_MATRIX_C22_A, mask_sh), \
143 TF_SF(CM_CUR0_CUR0_MATRIX_C23_C24_A, CUR0_MATRIX_C23_A, mask_sh), \
144 TF_SF(CM_CUR0_CUR0_MATRIX_C23_C24_A, CUR0_MATRIX_C24_A, mask_sh), \
145 TF_SF(CM_CUR0_CUR0_MATRIX_C31_C32_A, CUR0_MATRIX_C31_A, mask_sh), \
146 TF_SF(CM_CUR0_CUR0_MATRIX_C31_C32_A, CUR0_MATRIX_C32_A, mask_sh), \
147 TF_SF(CM_CUR0_CUR0_MATRIX_C33_C34_A, CUR0_MATRIX_C33_A, mask_sh), \
148 TF_SF(CM_CUR0_CUR0_MATRIX_C33_C34_A, CUR0_MATRIX_C34_A, mask_sh), \
149 TF_SF(DPP_TOP0_DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \
150 TF_SF(CM0_CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, mask_sh), \
151 TF_SF(CM0_CM_CONTROL, CM_BYPASS, mask_sh), \
152 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_SEL, mask_sh), \
153 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_CH_EN, mask_sh), \
154 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_SRC1_SEL, mask_sh), \
155 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_SRC2_SEL, mask_sh), \
156 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_SRC3_SEL, mask_sh), \
157 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_CH1_XBAR, mask_sh), \
158 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_CH2_XBAR, mask_sh), \
159 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_CH3_XBAR, mask_sh), \
160 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_FORMAT, mask_sh), \
161 TF_SF(CM0_CM_HIST_CNTL, CM_HIST_READ_CHANNEL_MASK, mask_sh), \
162 TF_SF(CM0_CM_HIST_LOCK, CM_HIST_LOCK, mask_sh), \
163 TF_SF(CM0_CM_HIST_INDEX, CM_HIST_INDEX, mask_sh), \
164 TF_SF(CM0_CM_HIST_DATA, CM_HIST_DATA, mask_sh), \
165 TF_SF(CM0_CM_HIST_DATA, CM_HIST_DATA, mask_sh), \
166 TF_SF(CM0_CM_HIST_STATUS, CM_HIST_BUFA_RDY_STATUS, mask_sh), \
167 TF_SF(CM0_CM_HIST_STATUS, CM_HIST_BUFB_RDY_STATUS, mask_sh), \
168 TF_SF(CM0_CM_HIST_SCALE_SRC1, CM_HIST_SCALE_SRC1, mask_sh), \
169 TF_SF(CM0_CM_HIST_COEFA_SRC2, CM_HIST_COEFA_SRC2, mask_sh), \
170 TF_SF(CM0_CM_HIST_COEFB_SRC2, CM_HIST_COEFB_SRC2, mask_sh), \
171 TF_SF(CM0_CM_HIST_COEFC_SRC2, CM_HIST_COEFC_SRC2, mask_sh), \
172 TF_SF(CM0_CM_HIST_SCALE_SRC3, CM_HIST_SCALE_SRC3, mask_sh), \
173 TF_SF(CM0_CM_HIST_BIAS_SRC1, CM_HIST_BIAS_SRC1, mask_sh), \
174 TF_SF(CM0_CM_HIST_BIAS_SRC2, CM_HIST_BIAS_SRC2, mask_sh), \
175 TF_SF(CM0_CM_HIST_BIAS_SRC3, CM_HIST_BIAS_SRC3, mask_sh), \
176 TF_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
177 TF_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
178 TF_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
179 TF_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
180 TF_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_CNV16, mask_sh), \
181 TF_SF(CNVC_CFG0_FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, mask_sh), \
182 TF_SF(CNVC_CFG0_FORMAT_CONTROL, CLAMP_POSITIVE, mask_sh), \
183 TF_SF(CNVC_CFG0_FORMAT_CONTROL, CLAMP_POSITIVE_C, mask_sh), \
184 TF_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_CROSSBAR_R, mask_sh), \
185 TF_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_CROSSBAR_G, mask_sh), \
186 TF_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_CROSSBAR_B, mask_sh), \
187 TF_SF(CNVC_CFG0_ALPHA_2BIT_LUT01, ALPHA_2BIT_LUT0, mask_sh), \
188 TF_SF(CNVC_CFG0_ALPHA_2BIT_LUT01, ALPHA_2BIT_LUT1, mask_sh), \
189 TF_SF(CNVC_CFG0_ALPHA_2BIT_LUT23, ALPHA_2BIT_LUT2, mask_sh), \
190 TF_SF(CNVC_CFG0_ALPHA_2BIT_LUT23, ALPHA_2BIT_LUT3, mask_sh), \
191 TF_SF(CNVC_CFG0_FCNV_FP_BIAS_R, FCNV_FP_BIAS_R, mask_sh), \
192 TF_SF(CNVC_CFG0_FCNV_FP_BIAS_G, FCNV_FP_BIAS_G, mask_sh), \
193 TF_SF(CNVC_CFG0_FCNV_FP_BIAS_B, FCNV_FP_BIAS_B, mask_sh), \
194 TF_SF(CNVC_CFG0_FCNV_FP_SCALE_R, FCNV_FP_SCALE_R, mask_sh), \
195 TF_SF(CNVC_CFG0_FCNV_FP_SCALE_G, FCNV_FP_SCALE_G, mask_sh), \
196 TF_SF(CNVC_CFG0_FCNV_FP_SCALE_B, FCNV_FP_SCALE_B, mask_sh), \
197 TF_SF(CNVC_CFG0_COLOR_KEYER_CONTROL, COLOR_KEYER_EN, mask_sh), \
198 TF_SF(CNVC_CFG0_COLOR_KEYER_CONTROL, LUMA_KEYER_EN, mask_sh), \
199 TF_SF(CNVC_CFG0_COLOR_KEYER_CONTROL, COLOR_KEYER_MODE, mask_sh), \
200 TF_SF(CNVC_CFG0_COLOR_KEYER_ALPHA, COLOR_KEYER_ALPHA_LOW, mask_sh), \
201 TF_SF(CNVC_CFG0_COLOR_KEYER_ALPHA, COLOR_KEYER_ALPHA_HIGH, mask_sh), \
202 TF_SF(CNVC_CFG0_COLOR_KEYER_RED, COLOR_KEYER_RED_LOW, mask_sh), \
203 TF_SF(CNVC_CFG0_COLOR_KEYER_RED, COLOR_KEYER_RED_HIGH, mask_sh), \
204 TF_SF(CNVC_CFG0_COLOR_KEYER_GREEN, COLOR_KEYER_GREEN_LOW, mask_sh), \
205 TF_SF(CNVC_CFG0_COLOR_KEYER_GREEN, COLOR_KEYER_GREEN_HIGH, mask_sh), \
206 TF_SF(CNVC_CFG0_COLOR_KEYER_BLUE, COLOR_KEYER_BLUE_LOW, mask_sh), \
207 TF_SF(CNVC_CFG0_COLOR_KEYER_BLUE, COLOR_KEYER_BLUE_HIGH, mask_sh), \
208 TF_SF(CM_CUR0_CURSOR0_CONTROL, CUR0_PIX_INV_MODE, mask_sh), \
209 TF_SF(CM_CUR0_CURSOR0_CONTROL, CUR0_PIXEL_ALPHA_MOD_EN, mask_sh), \
210 TF_SF(CM_CUR0_CURSOR0_CONTROL, CUR0_ROM_EN, mask_sh),\
211 TF_SF(DSCL0_OBUF_MEM_PWR_CTRL, OBUF_MEM_PWR_FORCE, mask_sh),\
212 TF_SF(DSCL0_DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, mask_sh),\
213 TF_SF(DSCL0_DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_DIS, mask_sh),\
214 TF_SF(DSCL0_DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, mask_sh),\
215 TF_SF(DSCL0_DSCL_SC_MODE, SCL_SC_MATRIX_MODE, mask_sh),\
216 TF_SF(DSCL0_DSCL_SC_MODE, SCL_SC_LTONL_EN, mask_sh),\
217 TF_SF(DSCL0_DSCL_EASF_H_MODE, SCL_EASF_H_EN, mask_sh),\
218 TF_SF(DSCL0_DSCL_EASF_H_MODE, SCL_EASF_H_RINGEST_FORCE_EN, mask_sh),\
219 TF_SF(DSCL0_DSCL_EASF_H_MODE, SCL_EASF_H_2TAP_SHARP_FACTOR, mask_sh),\
220 TF_SF(DSCL0_DSCL_EASF_H_BF_CNTL, SCL_EASF_H_BF1_EN, mask_sh),\
221 TF_SF(DSCL0_DSCL_EASF_H_BF_CNTL, SCL_EASF_H_BF2_MODE, mask_sh),\
222 TF_SF(DSCL0_DSCL_EASF_H_BF_CNTL, SCL_EASF_H_BF3_MODE, mask_sh),\
223 TF_SF(DSCL0_DSCL_EASF_H_BF_CNTL, SCL_EASF_H_BF2_FLAT1_GAIN, mask_sh),\
224 TF_SF(DSCL0_DSCL_EASF_H_BF_CNTL, SCL_EASF_H_BF2_FLAT2_GAIN, mask_sh),\
225 TF_SF(DSCL0_DSCL_EASF_H_BF_CNTL, SCL_EASF_H_BF2_ROC_GAIN, mask_sh),\
226 TF_SF(DSCL0_DSCL_EASF_H_RINGEST_EVENTAP_REDUCE, SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1, mask_sh),\
227 TF_SF(DSCL0_DSCL_EASF_H_RINGEST_EVENTAP_REDUCE, SCL_EASF_H_RINGEST_EVENTAP_REDUCEG2, mask_sh),\
228 TF_SF(DSCL0_DSCL_EASF_H_RINGEST_EVENTAP_GAIN, SCL_EASF_H_RINGEST_EVENTAP_GAIN1, mask_sh),\
229 TF_SF(DSCL0_DSCL_EASF_H_RINGEST_EVENTAP_GAIN, SCL_EASF_H_RINGEST_EVENTAP_GAIN2, mask_sh),\
230 TF_SF(DSCL0_DSCL_EASF_H_BF_FINAL_MAX_MIN, SCL_EASF_H_BF_MAXA, mask_sh),\
231 TF_SF(DSCL0_DSCL_EASF_H_BF_FINAL_MAX_MIN, SCL_EASF_H_BF_MAXB, mask_sh),\
232 TF_SF(DSCL0_DSCL_EASF_H_BF_FINAL_MAX_MIN, SCL_EASF_H_BF_MINA, mask_sh),\
233 TF_SF(DSCL0_DSCL_EASF_H_BF_FINAL_MAX_MIN, SCL_EASF_H_BF_MINB, mask_sh),\
234 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG0, SCL_EASF_H_BF1_PWL_IN_SEG0, mask_sh),\
235 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG0, SCL_EASF_H_BF1_PWL_BASE_SEG0, mask_sh),\
236 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG0, SCL_EASF_H_BF1_PWL_SLOPE_SEG0, mask_sh),\
237 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG1, SCL_EASF_H_BF1_PWL_IN_SEG1, mask_sh),\
238 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG1, SCL_EASF_H_BF1_PWL_BASE_SEG1, mask_sh),\
239 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG1, SCL_EASF_H_BF1_PWL_SLOPE_SEG1, mask_sh),\
240 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG2, SCL_EASF_H_BF1_PWL_IN_SEG2, mask_sh),\
241 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG2, SCL_EASF_H_BF1_PWL_BASE_SEG2, mask_sh),\
242 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG2, SCL_EASF_H_BF1_PWL_SLOPE_SEG2, mask_sh),\
243 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG3, SCL_EASF_H_BF1_PWL_IN_SEG3, mask_sh),\
244 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG3, SCL_EASF_H_BF1_PWL_BASE_SEG3, mask_sh),\
245 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG3, SCL_EASF_H_BF1_PWL_SLOPE_SEG3, mask_sh),\
246 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG4, SCL_EASF_H_BF1_PWL_IN_SEG4, mask_sh),\
247 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG4, SCL_EASF_H_BF1_PWL_BASE_SEG4, mask_sh),\
248 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG4, SCL_EASF_H_BF1_PWL_SLOPE_SEG4, mask_sh),\
249 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG5, SCL_EASF_H_BF1_PWL_IN_SEG5, mask_sh),\
250 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG5, SCL_EASF_H_BF1_PWL_BASE_SEG5, mask_sh),\
251 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG5, SCL_EASF_H_BF1_PWL_SLOPE_SEG5, mask_sh),\
252 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG6, SCL_EASF_H_BF1_PWL_IN_SEG6, mask_sh),\
253 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG6, SCL_EASF_H_BF1_PWL_BASE_SEG6, mask_sh),\
254 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG6, SCL_EASF_H_BF1_PWL_SLOPE_SEG6, mask_sh),\
255 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG7, SCL_EASF_H_BF1_PWL_IN_SEG7, mask_sh),\
256 TF_SF(DSCL0_DSCL_EASF_H_BF1_PWL_SEG7, SCL_EASF_H_BF1_PWL_BASE_SEG7, mask_sh),\
257 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG0, SCL_EASF_H_BF3_PWL_IN_SEG0, mask_sh),\
258 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG0, SCL_EASF_H_BF3_PWL_BASE_SEG0, mask_sh),\
259 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG0, SCL_EASF_H_BF3_PWL_SLOPE_SEG0, mask_sh),\
260 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG1, SCL_EASF_H_BF3_PWL_IN_SEG1, mask_sh),\
261 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG1, SCL_EASF_H_BF3_PWL_BASE_SEG1, mask_sh),\
262 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG1, SCL_EASF_H_BF3_PWL_SLOPE_SEG1, mask_sh),\
263 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG2, SCL_EASF_H_BF3_PWL_IN_SEG2, mask_sh),\
264 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG2, SCL_EASF_H_BF3_PWL_BASE_SEG2, mask_sh),\
265 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG2, SCL_EASF_H_BF3_PWL_SLOPE_SEG2, mask_sh),\
266 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG3, SCL_EASF_H_BF3_PWL_IN_SEG3, mask_sh),\
267 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG3, SCL_EASF_H_BF3_PWL_BASE_SEG3, mask_sh),\
268 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG3, SCL_EASF_H_BF3_PWL_SLOPE_SEG3, mask_sh),\
269 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG4, SCL_EASF_H_BF3_PWL_IN_SEG4, mask_sh),\
270 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG4, SCL_EASF_H_BF3_PWL_BASE_SEG4, mask_sh),\
271 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG4, SCL_EASF_H_BF3_PWL_SLOPE_SEG4, mask_sh),\
272 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG5, SCL_EASF_H_BF3_PWL_IN_SEG5, mask_sh),\
273 TF_SF(DSCL0_DSCL_EASF_H_BF3_PWL_SEG5, SCL_EASF_H_BF3_PWL_BASE_SEG5, mask_sh),\
274 TF_SF(DSCL0_DSCL_EASF_V_MODE, SCL_EASF_V_EN, mask_sh),\
275 TF_SF(DSCL0_DSCL_EASF_V_MODE, SCL_EASF_V_RINGEST_FORCE_EN, mask_sh),\
276 TF_SF(DSCL0_DSCL_EASF_V_MODE, SCL_EASF_V_2TAP_SHARP_FACTOR, mask_sh),\
277 TF_SF(DSCL0_DSCL_EASF_V_BF_CNTL, SCL_EASF_V_BF1_EN, mask_sh),\
278 TF_SF(DSCL0_DSCL_EASF_V_BF_CNTL, SCL_EASF_V_BF2_MODE, mask_sh),\
279 TF_SF(DSCL0_DSCL_EASF_V_BF_CNTL, SCL_EASF_V_BF3_MODE, mask_sh),\
280 TF_SF(DSCL0_DSCL_EASF_V_BF_CNTL, SCL_EASF_V_BF2_FLAT1_GAIN, mask_sh),\
281 TF_SF(DSCL0_DSCL_EASF_V_BF_CNTL, SCL_EASF_V_BF2_FLAT2_GAIN, mask_sh),\
282 TF_SF(DSCL0_DSCL_EASF_V_BF_CNTL, SCL_EASF_V_BF2_ROC_GAIN, mask_sh),\
283 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_3TAP_CNTL1, SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT, mask_sh),\
284 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_3TAP_CNTL1, SCL_EASF_V_RINGEST_3TAP_UPTILT_MAXVAL, mask_sh),\
285 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_3TAP_CNTL2, SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE, mask_sh),\
286 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_3TAP_CNTL2, SCL_EASF_V_RINGEST_3TAP_UPTILT1_SLOPE, mask_sh),\
287 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_3TAP_CNTL3, SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE, mask_sh),\
288 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_3TAP_CNTL3, SCL_EASF_V_RINGEST_3TAP_UPTILT2_OFFSET, mask_sh),\
289 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_EVENTAP_REDUCE, SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1, mask_sh),\
290 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_EVENTAP_REDUCE, SCL_EASF_V_RINGEST_EVENTAP_REDUCEG2, mask_sh),\
291 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_EVENTAP_GAIN, SCL_EASF_V_RINGEST_EVENTAP_GAIN1, mask_sh),\
292 TF_SF(DSCL0_DSCL_EASF_V_RINGEST_EVENTAP_GAIN, SCL_EASF_V_RINGEST_EVENTAP_GAIN2, mask_sh),\
293 TF_SF(DSCL0_DSCL_EASF_V_BF_FINAL_MAX_MIN, SCL_EASF_V_BF_MAXA, mask_sh),\
294 TF_SF(DSCL0_DSCL_EASF_V_BF_FINAL_MAX_MIN, SCL_EASF_V_BF_MAXB, mask_sh),\
295 TF_SF(DSCL0_DSCL_EASF_V_BF_FINAL_MAX_MIN, SCL_EASF_V_BF_MINA, mask_sh),\
296 TF_SF(DSCL0_DSCL_EASF_V_BF_FINAL_MAX_MIN, SCL_EASF_V_BF_MINB, mask_sh),\
297 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG0, SCL_EASF_V_BF1_PWL_IN_SEG0, mask_sh),\
298 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG0, SCL_EASF_V_BF1_PWL_BASE_SEG0, mask_sh),\
299 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG0, SCL_EASF_V_BF1_PWL_SLOPE_SEG0, mask_sh),\
300 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG1, SCL_EASF_V_BF1_PWL_IN_SEG1, mask_sh),\
301 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG1, SCL_EASF_V_BF1_PWL_BASE_SEG1, mask_sh),\
302 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG1, SCL_EASF_V_BF1_PWL_SLOPE_SEG1, mask_sh),\
303 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG2, SCL_EASF_V_BF1_PWL_IN_SEG2, mask_sh),\
304 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG2, SCL_EASF_V_BF1_PWL_BASE_SEG2, mask_sh),\
305 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG2, SCL_EASF_V_BF1_PWL_SLOPE_SEG2, mask_sh),\
306 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG3, SCL_EASF_V_BF1_PWL_IN_SEG3, mask_sh),\
307 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG3, SCL_EASF_V_BF1_PWL_BASE_SEG3, mask_sh),\
308 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG3, SCL_EASF_V_BF1_PWL_SLOPE_SEG3, mask_sh),\
309 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG4, SCL_EASF_V_BF1_PWL_IN_SEG4, mask_sh),\
310 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG4, SCL_EASF_V_BF1_PWL_BASE_SEG4, mask_sh),\
311 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG4, SCL_EASF_V_BF1_PWL_SLOPE_SEG4, mask_sh),\
312 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG5, SCL_EASF_V_BF1_PWL_IN_SEG5, mask_sh),\
313 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG5, SCL_EASF_V_BF1_PWL_BASE_SEG5, mask_sh),\
314 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG5, SCL_EASF_V_BF1_PWL_SLOPE_SEG5, mask_sh),\
315 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG6, SCL_EASF_V_BF1_PWL_IN_SEG6, mask_sh),\
316 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG6, SCL_EASF_V_BF1_PWL_BASE_SEG6, mask_sh),\
317 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG6, SCL_EASF_V_BF1_PWL_SLOPE_SEG6, mask_sh),\
318 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG7, SCL_EASF_V_BF1_PWL_IN_SEG7, mask_sh),\
319 TF_SF(DSCL0_DSCL_EASF_V_BF1_PWL_SEG7, SCL_EASF_V_BF1_PWL_BASE_SEG7, mask_sh),\
320 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG0, SCL_EASF_V_BF3_PWL_IN_SEG0, mask_sh),\
321 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG0, SCL_EASF_V_BF3_PWL_BASE_SEG0, mask_sh),\
322 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG0, SCL_EASF_V_BF3_PWL_SLOPE_SEG0, mask_sh),\
323 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG1, SCL_EASF_V_BF3_PWL_IN_SEG1, mask_sh),\
324 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG1, SCL_EASF_V_BF3_PWL_BASE_SEG1, mask_sh),\
325 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG1, SCL_EASF_V_BF3_PWL_SLOPE_SEG1, mask_sh),\
326 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG2, SCL_EASF_V_BF3_PWL_IN_SEG2, mask_sh),\
327 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG2, SCL_EASF_V_BF3_PWL_BASE_SEG2, mask_sh),\
328 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG2, SCL_EASF_V_BF3_PWL_SLOPE_SEG2, mask_sh),\
329 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG3, SCL_EASF_V_BF3_PWL_IN_SEG3, mask_sh),\
330 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG3, SCL_EASF_V_BF3_PWL_BASE_SEG3, mask_sh),\
331 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG3, SCL_EASF_V_BF3_PWL_SLOPE_SEG3, mask_sh),\
332 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG4, SCL_EASF_V_BF3_PWL_IN_SEG4, mask_sh),\
333 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG4, SCL_EASF_V_BF3_PWL_BASE_SEG4, mask_sh),\
334 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG4, SCL_EASF_V_BF3_PWL_SLOPE_SEG4, mask_sh),\
335 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG5, SCL_EASF_V_BF3_PWL_IN_SEG5, mask_sh),\
336 TF_SF(DSCL0_DSCL_EASF_V_BF3_PWL_SEG5, SCL_EASF_V_BF3_PWL_BASE_SEG5, mask_sh),\
337 TF_SF(DSCL0_DSCL_SC_MATRIX_C0C1, SCL_SC_MATRIX_C0, mask_sh),\
338 TF_SF(DSCL0_DSCL_SC_MATRIX_C0C1, SCL_SC_MATRIX_C1, mask_sh),\
339 TF_SF(DSCL0_DSCL_SC_MATRIX_C2C3, SCL_SC_MATRIX_C2, mask_sh),\
340 TF_SF(DSCL0_DSCL_SC_MATRIX_C2C3, SCL_SC_MATRIX_C3, mask_sh),\
341 TF_SF(DSCL0_ISHARP_DELTA_CTRL, ISHARP_DELTA_LUT_HOST_SELECT, mask_sh),\
342 TF_SF(DSCL0_ISHARP_DELTA_LUT_MEM_PWR_CTRL, ISHARP_DELTA_LUT_MEM_PWR_DIS, mask_sh),\
343 TF_SF(DSCL0_ISHARP_DELTA_LUT_MEM_PWR_CTRL, ISHARP_DELTA_LUT_MEM_PWR_FORCE, mask_sh),\
344 TF_SF(DSCL0_ISHARP_DELTA_LUT_MEM_PWR_CTRL, ISHARP_DELTA_LUT_MEM_PWR_STATE, mask_sh),\
345 TF_SF(DSCL0_ISHARP_DELTA_DATA, ISHARP_DELTA_DATA, mask_sh),\
346 TF_SF(DSCL0_ISHARP_DELTA_INDEX, ISHARP_DELTA_INDEX, mask_sh),\
347 TF_SF(DSCL0_ISHARP_MODE, ISHARP_EN, mask_sh),\
348 TF_SF(DSCL0_ISHARP_MODE, ISHARP_NOISEDET_EN, mask_sh),\
349 TF_SF(DSCL0_ISHARP_MODE, ISHARP_NOISEDET_MODE, mask_sh),\
350 TF_SF(DSCL0_ISHARP_MODE, ISHARP_LBA_MODE, mask_sh),\
351 TF_SF(DSCL0_ISHARP_MODE, ISHARP_DELTA_LUT_SELECT, mask_sh),\
352 TF_SF(DSCL0_ISHARP_MODE, ISHARP_FMT_MODE, mask_sh),\
353 TF_SF(DSCL0_ISHARP_MODE, ISHARP_FMT_NORM, mask_sh),\
354 TF_SF(DSCL0_ISHARP_MODE, ISHARP_DELTA_LUT_SELECT_CURRENT, mask_sh),\
355 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG0, ISHARP_LBA_PWL_IN_SEG0, mask_sh),\
356 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG0, ISHARP_LBA_PWL_BASE_SEG0, mask_sh),\
357 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG0, ISHARP_LBA_PWL_SLOPE_SEG0, mask_sh), \
358 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG1, ISHARP_LBA_PWL_IN_SEG1, mask_sh),\
359 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG1, ISHARP_LBA_PWL_BASE_SEG1, mask_sh),\
360 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG1, ISHARP_LBA_PWL_SLOPE_SEG1, mask_sh),\
361 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG2, ISHARP_LBA_PWL_IN_SEG2, mask_sh),\
362 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG2, ISHARP_LBA_PWL_BASE_SEG2, mask_sh),\
363 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG2, ISHARP_LBA_PWL_SLOPE_SEG2, mask_sh),\
364 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG3, ISHARP_LBA_PWL_IN_SEG3, mask_sh),\
365 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG3, ISHARP_LBA_PWL_BASE_SEG3, mask_sh),\
366 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG3, ISHARP_LBA_PWL_SLOPE_SEG3, mask_sh),\
367 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG4, ISHARP_LBA_PWL_IN_SEG4, mask_sh),\
368 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG4, ISHARP_LBA_PWL_BASE_SEG4, mask_sh),\
369 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG4, ISHARP_LBA_PWL_SLOPE_SEG4, mask_sh),\
370 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG5, ISHARP_LBA_PWL_IN_SEG5, mask_sh),\
371 TF_SF(DSCL0_ISHARP_LBA_PWL_SEG5, ISHARP_LBA_PWL_BASE_SEG5, mask_sh),\
372 TF_SF(DSCL0_ISHARP_NOISEDET_THRESHOLD, ISHARP_NOISEDET_UTHRE, mask_sh),\
373 TF_SF(DSCL0_ISHARP_NOISEDET_THRESHOLD, ISHARP_NOISEDET_DTHRE, mask_sh), \
374 TF_SF(DSCL0_ISHARP_NOISE_GAIN_PWL, ISHARP_NOISEDET_PWL_START_IN, mask_sh), \
375 TF_SF(DSCL0_ISHARP_NOISE_GAIN_PWL, ISHARP_NOISEDET_PWL_END_IN, mask_sh), \
376 TF_SF(DSCL0_ISHARP_NOISE_GAIN_PWL, ISHARP_NOISEDET_PWL_SLOPE, mask_sh), \
377 TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_EN_P, mask_sh), \
378 TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_PIVOT_P, mask_sh), \
379 TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_SLOPE_P, mask_sh), \
380 TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_EN_N, mask_sh), \
381 TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_PIVOT_N, mask_sh), \
382 TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_SLOPE_N, mask_sh), \
383 TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT, SCL_V_INIT_FRAC_BOT, mask_sh),\
384 TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT, SCL_V_INIT_INT_BOT, mask_sh),\
385 TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT_C, SCL_V_INIT_FRAC_BOT_C, mask_sh),\
386 TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT_C, SCL_V_INIT_INT_BOT_C, mask_sh)
387
388#define DPP_REG_FIELD_LIST_DCN42(type) \
389 DPP_REG_FIELD_LIST_DCN401(type); \
390 type CM_HIST_SEL; \
391 type CM_HIST_CH_EN; \
392 type CM_HIST_SRC1_SEL; \
393 type CM_HIST_SRC2_SEL; \
394 type CM_HIST_SRC3_SEL; \
395 type CM_HIST_CH1_XBAR; \
396 type CM_HIST_CH2_XBAR; \
397 type CM_HIST_CH3_XBAR; \
398 type CM_HIST_FORMAT; \
399 type CM_HIST_READ_CHANNEL_MASK; \
400 type CM_HIST_LOCK; \
401 type CM_HIST_INDEX; \
402 type CM_HIST_DATA; \
403 type CM_HIST_BUFA_RDY_STATUS; \
404 type CM_HIST_BUFB_RDY_STATUS; \
405 type CM_HIST_SCALE_SRC1; \
406 type CM_HIST_COEFA_SRC2; \
407 type CM_HIST_COEFB_SRC2; \
408 type CM_HIST_COEFC_SRC2; \
409 type CM_HIST_SCALE_SRC3; \
410 type CM_HIST_BIAS_SRC1; \
411 type CM_HIST_BIAS_SRC2; \
412 type CM_HIST_BIAS_SRC3
413
414
415#define DPP_REG_VARIABLE_LIST_DCN42 \
416 DPP_REG_VARIABLE_LIST_DCN401; \
417 uint32_t ALPHA_2BIT_LUT01; \
418 uint32_t ALPHA_2BIT_LUT23; \
419 uint32_t CM_HIST_CNTL; \
420 uint32_t CM_HIST_INDEX; \
421 uint32_t CM_HIST_LOCK; \
422 uint32_t CM_HIST_DATA; \
423 uint32_t CM_HIST_STATUS; \
424 uint32_t CM_HIST_SCALE_SRC1; \
425 uint32_t CM_HIST_COEFA_SRC2; \
426 uint32_t CM_HIST_COEFB_SRC2; \
427 uint32_t CM_HIST_COEFC_SRC2; \
428 uint32_t CM_HIST_SCALE_SRC3; \
429 uint32_t CM_HIST_BIAS_SRC1; \
430 uint32_t CM_HIST_BIAS_SRC2; \
431 uint32_t CM_HIST_BIAS_SRC3
432
433struct dcn42_dpp_registers {
434 DPP_REG_VARIABLE_LIST_DCN42;
435};
436
437struct dcn42_dpp_shift {
438 DPP_REG_FIELD_LIST_DCN42(uint8_t);
439};
440
441struct dcn42_dpp_mask {
442 DPP_REG_FIELD_LIST_DCN42(uint32_t);
443};
444struct dcn42_dpp {
445 struct dpp base;
446 const struct dcn42_dpp_registers *tf_regs;
447 const struct dcn42_dpp_shift *tf_shift;
448 const struct dcn42_dpp_mask *tf_mask;
449 const uint16_t *filter_v;
450 const uint16_t *filter_h;
451 const uint16_t *filter_v_c;
452 const uint16_t *filter_h_c;
453 int lb_pixel_depth_supported;
454 int lb_memory_size;
455 int lb_bits_per_entry;
456 bool is_write_to_ram_a_safe;
457 struct scaler_data scl_data;
458 struct pwl_params pwl_data;
459};
460
461bool dpp42_construct(struct dcn42_dpp *dpp42,
462 struct dc_context *ctx,
463 uint32_t inst,
464 const struct dcn42_dpp_registers *tf_regs,
465 const struct dcn42_dpp_shift *tf_shift,
466 const struct dcn42_dpp_mask *tf_mask);
467
468
469#endif /* __DCN42_DPP_H__ */
drivers/gpu/drm/amd/display/dc/gpio/Makefile+12−1
@@ -1,5 +1,5 @@
1#1#
2# Copyright 2017 Advanced Micro Devices, Inc.2# Copyright 2017-2026 Advanced Micro Devices, Inc.
3#3#
4# Permission is hereby granted, free of charge, to any person obtaining a4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),5# copy of this software and associated documentation files (the "Software"),
@@ -132,3 +132,14 @@ AMD_DAL_GPIO_DCN401 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn401/,$(GPIO_DCN401)) · 126 unmodified lines
132 132
133AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN401)133AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN401)
134 134
135###############################################################################
136# DCN 4.2
137###############################################################################
138
139GPIO_DCN42 = hw_translate_dcn42.o hw_factory_dcn42.o
140
141AMD_DAL_GPIO_DCN42 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn42/,$(GPIO_DCN42))
142
143AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN42)
144
145
drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_factory_dcn42.c+254−0
@@ -0,0 +1,254 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "dm_services.h"
6#include "include/gpio_types.h"
7#include "../hw_factory.h"
8
9
10#include "../hw_gpio.h"
11#include "../hw_ddc.h"
12#include "../hw_hpd.h"
13#include "../hw_generic.h"
14
15
16
17#include "dcn/dcn_4_2_0_offset.h"
18#include "dcn/dcn_4_2_0_sh_mask.h"
19#include "dpcs/dpcs_4_0_0_offset.h"
20#include "dpcs/dpcs_4_0_0_sh_mask.h"
21
22#include "reg_helper.h"
23#include "../hpd_regs.h"
24#include "hw_factory_dcn42.h"
25
26#define DCN_BASE__INST0_SEG2 0x000034C0
27
28/* begin *********************
29 * macros to expend register list macro defined in HW object header file */
30
31/* DCN */
32#define block HPD
33#define reg_num 0
34
35#undef BASE_INNER
36#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
37
38#define BASE(seg) BASE_INNER(seg)
39
40
41
42#define REG(reg_name)\
43 (BASE(reg ## reg_name ## _BASE_IDX) + reg ## reg_name)
44
45#define SF_HPD(reg_name, field_name, post_fix)\
46 .field_name = HPD0_ ## reg_name ## __ ## field_name ## post_fix
47
48#define REGI(reg_name, block, id)\
49 (BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
50 reg ## block ## id ## _ ## reg_name)
51
52#define SF(reg_name, field_name, post_fix)\
53 .field_name = reg_name ## __ ## field_name ## post_fix
54
55/* macros to expend register list macro defined in HW object header file
56 * end *********************/
57
58// DC_GPIO_HPD_* registers are gone.
59#undef HPD_REG_LIST
60#define HPD_REG_LIST(id) \
61 .int_status = REGI(DC_HPD_INT_STATUS, HPD, id),\
62 .toggle_filt_cntl = REGI(DC_HPD_TOGGLE_FILT_CNTL, HPD, id)
63
64#define hpd_regs(id) \
65{\
66 HPD_REG_LIST(id)\
67}
68
69static const struct hpd_registers hpd_regs[] = {
70 hpd_regs(0),
71 hpd_regs(1),
72 hpd_regs(2),
73 hpd_regs(3),
74 hpd_regs(4),
75};
76
77static const struct hpd_sh_mask hpd_shift = {
78 HPD_MASK_SH_LIST(__SHIFT)
79};
80
81static const struct hpd_sh_mask hpd_mask = {
82 HPD_MASK_SH_LIST(_MASK)
83};
84
85#include "../ddc_regs.h"
86
87 /* set field name */
88#define SF_DDC(reg_name, field_name, post_fix)\
89 .field_name = reg_name ## __ ## field_name ## post_fix
90
91static const struct ddc_registers ddc_data_regs_dcn[] = {
92 ddc_data_regs_dcn2(1),
93 ddc_data_regs_dcn2(2),
94 ddc_data_regs_dcn2(3),
95 ddc_data_regs_dcn2(4),
96 ddc_data_regs_dcn2(5),
97 {
98 // add a dummy entry for cases no such port
99 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
100 .ddc_setup = 0,
101 .phy_aux_cntl = 0,
102 .dc_gpio_aux_ctrl_5 = 0
103 },
104 {
105 DDC_GPIO_VGA_REG_LIST(DATA),
106 .ddc_setup = 0,
107 .phy_aux_cntl = 0,
108 .dc_gpio_aux_ctrl_5 = 0
109 }
110};
111
112static const struct ddc_registers ddc_clk_regs_dcn[] = {
113 ddc_clk_regs_dcn2(1),
114 ddc_clk_regs_dcn2(2),
115 ddc_clk_regs_dcn2(3),
116 ddc_clk_regs_dcn2(4),
117 ddc_clk_regs_dcn2(5),
118 {
119 // add a dummy entry for cases no such port
120 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
121 .ddc_setup = 0,
122 .phy_aux_cntl = 0,
123 .dc_gpio_aux_ctrl_5 = 0
124 },
125 {
126 DDC_GPIO_VGA_REG_LIST(CLK),
127 .ddc_setup = 0,
128 .phy_aux_cntl = 0,
129 .dc_gpio_aux_ctrl_5 = 0
130 }
131};
132
133static const struct ddc_sh_mask ddc_shift[] = {
134 DDC_MASK_SH_LIST_DCN2(__SHIFT, 1),
135 DDC_MASK_SH_LIST_DCN2(__SHIFT, 2),
136 DDC_MASK_SH_LIST_DCN2(__SHIFT, 3),
137 DDC_MASK_SH_LIST_DCN2(__SHIFT, 4),
138 DDC_MASK_SH_LIST_DCN2(__SHIFT, 5),
139 DDC_MASK_SH_LIST_DCN2(__SHIFT, 6),
140 DDC_MASK_SH_LIST_DCN2_VGA(__SHIFT)
141};
142
143static const struct ddc_sh_mask ddc_mask[] = {
144 DDC_MASK_SH_LIST_DCN2(_MASK, 1),
145 DDC_MASK_SH_LIST_DCN2(_MASK, 2),
146 DDC_MASK_SH_LIST_DCN2(_MASK, 3),
147 DDC_MASK_SH_LIST_DCN2(_MASK, 4),
148 DDC_MASK_SH_LIST_DCN2(_MASK, 5),
149 DDC_MASK_SH_LIST_DCN2(_MASK, 6),
150 DDC_MASK_SH_LIST_DCN2_VGA(_MASK)
151};
152
153#include "../generic_regs.h"
154
155/* set field name */
156#define SF_GENERIC(reg_name, field_name, post_fix)\
157 .field_name = 0
158
159static const struct generic_registers generic_regs[] = {
160 {{ 0 }},
161 {{ 0 }},
162};
163
164static const struct generic_sh_mask generic_shift[] = {
165 { 0 },
166 { 0 },
167};
168
169static const struct generic_sh_mask generic_mask[] = {
170 { 0 },
171 { 0 },
172};
173
174static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en)
175{
176 struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin);
177
178 generic->regs = &generic_regs[en];
179 generic->shifts = &generic_shift[en];
180 generic->masks = &generic_mask[en];
181 generic->base.regs = &generic_regs[en].gpio;
182}
183
184static void define_ddc_registers(
185 struct hw_gpio_pin *pin,
186 uint32_t en)
187{
188 struct hw_ddc *ddc = HW_DDC_FROM_BASE(pin);
189
190 switch (pin->id) {
191 case GPIO_ID_DDC_DATA:
192 ddc->regs = &ddc_data_regs_dcn[en];
193 ddc->base.regs = &ddc_data_regs_dcn[en].gpio;
194 break;
195 case GPIO_ID_DDC_CLOCK:
196 ddc->regs = &ddc_clk_regs_dcn[en];
197 ddc->base.regs = &ddc_clk_regs_dcn[en].gpio;
198 break;
199 default:
200 ASSERT_CRITICAL(false);
201 return;
202 }
203
204 ddc->shifts = &ddc_shift[en];
205 ddc->masks = &ddc_mask[en];
206
207}
208
209static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en)
210{
211 struct hw_hpd *hpd = HW_HPD_FROM_BASE(pin);
212
213 hpd->regs = &hpd_regs[en];
214 hpd->shifts = &hpd_shift;
215 hpd->masks = &hpd_mask;
216 hpd->base.regs = &hpd_regs[en].gpio;
217}
218
219
220/* function table */
221static const struct hw_factory_funcs funcs = {
222 .init_ddc_data = dal_hw_ddc_init,
223 .init_generic = dal_hw_generic_init,
224 .init_hpd = dal_hw_hpd_init,
225 .get_ddc_pin = dal_hw_ddc_get_pin,
226 .get_hpd_pin = dal_hw_hpd_get_pin,
227 .get_generic_pin = dal_hw_generic_get_pin,
228 .define_hpd_registers = define_hpd_registers,
229 .define_ddc_registers = define_ddc_registers,
230 .define_generic_registers = define_generic_registers
231};
232
233/*
234 * dal_hw_factory_dcn42_init
235 *
236 * @brief
237 * Initialize HW factory function pointers and pin info
238 *
239 * @param
240 * struct hw_factory *factory - [out] struct of function pointers
241 */
242void dal_hw_factory_dcn42_init(struct hw_factory *factory)
243{
244 factory->number_of_pins[GPIO_ID_DDC_DATA] = 8;
245 factory->number_of_pins[GPIO_ID_DDC_CLOCK] = 8;
246 factory->number_of_pins[GPIO_ID_GENERIC] = 4;
247 factory->number_of_pins[GPIO_ID_HPD] = 5;
248 factory->number_of_pins[GPIO_ID_GPIO_PAD] = 28;
249 factory->number_of_pins[GPIO_ID_VIP_PAD] = 0;
250 factory->number_of_pins[GPIO_ID_SYNC] = 0;
251 factory->number_of_pins[GPIO_ID_GSL] = 0;/*add this*/
252
253 factory->funcs = &funcs;
254}
drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_factory_dcn42.h+31−0
@@ -0,0 +1,31 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2026 Advanced Micro Devices, 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 */
24
25#ifndef __DAL_HW_FACTORY_DCN42_H__
26#define __DAL_HW_FACTORY_DCN42_H__
27
28/* Initialize HW factory function pointers and pin info */
29void dal_hw_factory_dcn42_init(struct hw_factory *factory);
30
31#endif /* __DAL_HW_FACTORY_DCN42_H__ */
drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.c+205−0
@@ -0,0 +1,205 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "hw_translate_dcn42.h"
6
7#include "dm_services.h"
8#include "include/gpio_types.h"
9#include "../hw_translate.h"
10
11
12#include "dcn/dcn_4_2_0_offset.h"
13#include "dcn/dcn_4_2_0_sh_mask.h"
14#include "dpcs/dpcs_4_0_0_offset.h"
15#include "dpcs/dpcs_4_0_0_sh_mask.h"
16
17#define DCN_BASE__INST0_SEG2 0x000034C0
18
19/* begin *********************
20 * macros to expend register list macro defined in HW object header file */
21
22/* DCN */
23#define block HPD
24#define reg_num 0
25
26#undef BASE_INNER
27#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
28
29#define BASE(seg) BASE_INNER(seg)
30
31#undef REG
32#define REG(reg_name)\
33 (BASE(reg ## reg_name ## _BASE_IDX) + reg ## reg_name)
34#define SF_HPD(reg_name, field_name, post_fix)\
35 .field_name = reg_name ## __ ## field_name ## post_fix
36
37
38/* macros to expend register list macro defined in HW object header file
39 * end *********************/
40
41
42static bool offset_to_id(
43 uint32_t offset,
44 uint32_t mask,
45 enum gpio_id *id,
46 uint32_t *en)
47{
48 switch (offset) {
49 /* HPD */
50 case REG(HPD0_DC_HPD_INT_STATUS):
51 *id = GPIO_ID_HPD;
52 *en = GPIO_HPD_1;
53 return true;
54 case REG(HPD1_DC_HPD_INT_STATUS):
55 *id = GPIO_ID_HPD;
56 *en = GPIO_HPD_2;
57 return true;
58 case REG(HPD2_DC_HPD_INT_STATUS):
59 *id = GPIO_ID_HPD;
60 *en = GPIO_HPD_3;
61 return true;
62 case REG(HPD3_DC_HPD_INT_STATUS):
63 *id = GPIO_ID_HPD;
64 *en = GPIO_HPD_4;
65 return true;
66 case REG(HPD4_DC_HPD_INT_STATUS):
67 *id = GPIO_ID_HPD;
68 *en = GPIO_HPD_5;
69 return true;
70 /* DDC */
71 /* we don't care about the GPIO_ID for DDC
72 * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
73 * directly in the create method
74 */
75 case REG(DC_GPIO_DDC1_A):
76 *en = GPIO_DDC_LINE_DDC1;
77 return true;
78 case REG(DC_GPIO_DDC2_A):
79 *en = GPIO_DDC_LINE_DDC2;
80 return true;
81 case REG(DC_GPIO_DDC3_A):
82 *en = GPIO_DDC_LINE_DDC3;
83 return true;
84 case REG(DC_GPIO_DDC4_A):
85 *en = GPIO_DDC_LINE_DDC4;
86 return true;
87 case REG(DC_GPIO_DDC5_A):
88 *en = GPIO_DDC_LINE_DDC5;
89 return true;
90 case REG(DC_GPIO_DDCVGA_A):
91 *en = GPIO_DDC_LINE_DDC_VGA;
92 return true;
93 default:
94 ASSERT_CRITICAL(false);
95 return false;
96 }
97}
98
99
100static bool id_to_offset(
101 enum gpio_id id,
102 uint32_t en,
103 struct gpio_pin_info *info)
104{
105 bool result = true;
106
107 switch (id) {
108 case GPIO_ID_DDC_DATA:
109 info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK;
110 switch (en) {
111 case GPIO_DDC_LINE_DDC1:
112 info->offset = REG(DC_GPIO_DDC1_A);
113 break;
114 case GPIO_DDC_LINE_DDC2:
115 info->offset = REG(DC_GPIO_DDC2_A);
116 break;
117 case GPIO_DDC_LINE_DDC3:
118 info->offset = REG(DC_GPIO_DDC3_A);
119 break;
120 case GPIO_DDC_LINE_DDC4:
121 info->offset = REG(DC_GPIO_DDC4_A);
122 break;
123 case GPIO_DDC_LINE_DDC5:
124 info->offset = REG(DC_GPIO_DDC5_A);
125 break;
126 case GPIO_DDC_LINE_DDC_VGA:
127 info->offset = REG(DC_GPIO_DDCVGA_A);
128 break;
129 case GPIO_DDC_LINE_I2C_PAD:
130 default:
131 ASSERT_CRITICAL(false);
132 result = false;
133 }
134 break;
135 case GPIO_ID_DDC_CLOCK:
136 info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK;
137 switch (en) {
138 case GPIO_DDC_LINE_DDC1:
139 info->offset = REG(DC_GPIO_DDC1_A);
140 break;
141 case GPIO_DDC_LINE_DDC2:
142 info->offset = REG(DC_GPIO_DDC2_A);
143 break;
144 case GPIO_DDC_LINE_DDC3:
145 info->offset = REG(DC_GPIO_DDC3_A);
146 break;
147 case GPIO_DDC_LINE_DDC4:
148 info->offset = REG(DC_GPIO_DDC4_A);
149 break;
150 case GPIO_DDC_LINE_DDC5:
151 info->offset = REG(DC_GPIO_DDC5_A);
152 break;
153 case GPIO_DDC_LINE_DDC_VGA:
154 info->offset = REG(DC_GPIO_DDCVGA_A);
155 break;
156 case GPIO_DDC_LINE_I2C_PAD:
157 default:
158 ASSERT_CRITICAL(false);
159 result = false;
160 }
161 break;
162 case GPIO_ID_SYNC:
163 case GPIO_ID_VIP_PAD:
164 default:
165 ASSERT_CRITICAL(false);
166 result = false;
167 }
168
169 if (result) {
170 info->offset_y = info->offset + 2;
171 info->offset_en = info->offset + 1;
172 info->offset_mask = info->offset - 1;
173
174 info->mask_y = info->mask;
175 info->mask_en = info->mask;
176 info->mask_mask = info->mask;
177 }
178
179 return result;
180}
181
182
183/* function table */
184static const struct hw_translate_funcs funcs = {
185 .offset_to_id = offset_to_id,
186 .id_to_offset = id_to_offset,
187};
188
189
190/*
191 * dal_hw_translate_dcn42_init
192 *
193 * @brief
194 * Initialize Hw translate function pointers.
195 *
196 * @param
197 * struct hw_translate *tr - [out] struct of function pointers
198 *
199 */
200void dal_hw_translate_dcn42_init(struct hw_translate *tr)
201{
202 tr->funcs = &funcs;
203}
204
205
drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.h+36−0
@@ -0,0 +1,36 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2026 Advanced Micro Devices, 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 */
24
25#ifndef __DAL_HW_TRANSLATE_DCN42_H__
26#define __DAL_HW_TRANSLATE_DCN42_H__
27
28struct hw_translate;
29
30/* Initialize Hw translate function pointers */
31void dal_hw_translate_dcn42_init(struct hw_translate *tr);
32#ifdef DAL_EMULATION_SUPPORTED
33void dal_emulated_hw_translate_dcn42_init(struct hw_translate *tr);
34#endif
35
36#endif /* __DAL_HW_TRANSLATE_DCN42_H__ */
drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c+4−0
@@ -53,6 +53,7 @@ · 52 unmodified lines
53#include "dcn315/hw_factory_dcn315.h"53#include "dcn315/hw_factory_dcn315.h"
54#include "dcn32/hw_factory_dcn32.h"54#include "dcn32/hw_factory_dcn32.h"
55#include "dcn401/hw_factory_dcn401.h"55#include "dcn401/hw_factory_dcn401.h"
56#include "dcn42/hw_factory_dcn42.h"
56 57
57bool dal_hw_factory_init(58bool dal_hw_factory_init(
58 struct hw_factory *factory,59 struct hw_factory *factory,
@@ -118,6 +119,9 @@ bool dal_hw_factory_init( · 59 unmodified lines
118 case DCN_VERSION_4_01:119 case DCN_VERSION_4_01:
119 dal_hw_factory_dcn401_init(factory);120 dal_hw_factory_dcn401_init(factory);
120 return true;121 return true;
122 case DCN_VERSION_4_2:
123 dal_hw_factory_dcn42_init(factory);
124 return true;
121 default:125 default:
122 ASSERT_CRITICAL(false);126 ASSERT_CRITICAL(false);
123 return false;127 return false;
drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c+4−0
@@ -53,6 +53,7 @@ · 52 unmodified lines
53#include "dcn315/hw_translate_dcn315.h"53#include "dcn315/hw_translate_dcn315.h"
54#include "dcn32/hw_translate_dcn32.h"54#include "dcn32/hw_translate_dcn32.h"
55#include "dcn401/hw_translate_dcn401.h"55#include "dcn401/hw_translate_dcn401.h"
56#include "dcn42/hw_translate_dcn42.h"
56 57
57/*58/*
58 * This unit59 * This unit
@@ -119,6 +120,9 @@ bool dal_hw_translate_init( · 60 unmodified lines
119 case DCN_VERSION_4_01:120 case DCN_VERSION_4_01:
120 dal_hw_translate_dcn401_init(translate);121 dal_hw_translate_dcn401_init(translate);
121 return true;122 return true;
123 case DCN_VERSION_4_2:
124 dal_hw_translate_dcn42_init(translate);
125 return true;
122 default:126 default:
123 BREAK_TO_DEBUGGER();127 BREAK_TO_DEBUGGER();
124 return false;128 return false;
drivers/gpu/drm/amd/display/dc/hpo/Makefile+10−1
@@ -1,5 +1,5 @@
1#1#
2# Copyright 2020 Advanced Micro Devices, Inc.2# Copyright 2020-2026 Advanced Micro Devices, Inc.
3#3#
4# Permission is hereby granted, free of charge, to any person obtaining a4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),5# copy of this software and associated documentation files (the "Software"),
@@ -47,4 +47,13 @@ HPO_DCN32 = dcn32_hpo_dp_link_encoder.o · 41 unmodified lines
47AMD_DAL_HPO_DCN32 = $(addprefix $(AMDDALPATH)/dc/hpo/dcn32/,$(HPO_DCN32))47AMD_DAL_HPO_DCN32 = $(addprefix $(AMDDALPATH)/dc/hpo/dcn32/,$(HPO_DCN32))
48 48
49AMD_DISPLAY_FILES += $(AMD_DAL_HPO_DCN32)49AMD_DISPLAY_FILES += $(AMD_DAL_HPO_DCN32)
50
51###############################################################################
52# DCN42
53###############################################################################
54HPO_DCN42 = dcn42_hpo_dp_link_encoder.o
55
56AMD_DAL_HPO_DCN42 = $(addprefix $(AMDDALPATH)/dc/hpo/dcn42/,$(HPO_DCN42))
57
58AMD_DISPLAY_FILES += $(AMD_DAL_HPO_DCN42)
50endif59endif
drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.h+8−2
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2019 Advanced Micro Devices, Inc.2 * Copyright 2019-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -208,17 +208,24 @@ · 202 unmodified lines
208 type CRC_CONT_MODE_ENABLE;\208 type CRC_CONT_MODE_ENABLE;\
209 type HBLANK_MINIMUM_SYMBOL_WIDTH209 type HBLANK_MINIMUM_SYMBOL_WIDTH
210 210
211#define DCN4_2_HPO_DP_STREAM_ENC_REG_FIELD_LIST(type) \
212 type DP_STREAM_ENC_APG_CLOCK_EN
211 213
214#define DCN4_2_HPO_DP_STREAM_ENC_MASK_SH_LIST(mask_sh)\
215 DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(mask_sh),\
216 SE_SF(DP_STREAM_ENC0_DP_STREAM_ENC_AUDIO_CONTROL, DP_STREAM_ENC_APG_CLOCK_EN, mask_sh)
212struct dcn31_hpo_dp_stream_encoder_registers {217struct dcn31_hpo_dp_stream_encoder_registers {
213 DCN3_1_HPO_DP_STREAM_ENC_REGS;218 DCN3_1_HPO_DP_STREAM_ENC_REGS;
214};219};
215 220
216struct dcn31_hpo_dp_stream_encoder_shift {221struct dcn31_hpo_dp_stream_encoder_shift {
217 DCN3_1_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint8_t);222 DCN3_1_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint8_t);
223 DCN4_2_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint8_t);
218};224};
219 225
220struct dcn31_hpo_dp_stream_encoder_mask {226struct dcn31_hpo_dp_stream_encoder_mask {
221 DCN3_1_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint32_t);227 DCN3_1_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint32_t);
228 DCN4_2_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint32_t);
222};229};
223 230
224struct dcn31_hpo_dp_stream_encoder {231struct dcn31_hpo_dp_stream_encoder {
@@ -241,5 +248,4 @@ void dcn31_hpo_dp_stream_encoder_construct( · 16 unmodified lines
241 const struct dcn31_hpo_dp_stream_encoder_shift *hpo_se_shift,248 const struct dcn31_hpo_dp_stream_encoder_shift *hpo_se_shift,
242 const struct dcn31_hpo_dp_stream_encoder_mask *hpo_se_mask);249 const struct dcn31_hpo_dp_stream_encoder_mask *hpo_se_mask);
243 250
244
245#endif // __DAL_DCN31_HPO_STREAM_ENCODER_H__251#endif // __DAL_DCN31_HPO_STREAM_ENCODER_H__
drivers/gpu/drm/amd/display/dc/hpo/dcn42/dcn42_hpo_dp_link_encoder.c+93−0
@@ -0,0 +1,93 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "dc_bios_types.h"
6#include "dcn31/dcn31_hpo_dp_link_encoder.h"
7#include "dcn32/dcn32_hpo_dp_link_encoder.h"
8#include "dcn42_hpo_dp_link_encoder.h"
9#include "reg_helper.h"
10#include "stream_encoder.h"
11
12#define DC_LOGGER \
13 enc3->base.ctx->logger
14
15#define REG(reg)\
16 (enc3->regs->reg)
17
18#undef FN
19#define FN(reg_name, field_name) \
20 enc3->hpo_le_shift->field_name, enc3->hpo_le_mask->field_name
21
22
23#define CTX \
24 enc3->base.ctx
25
26
27static void dcn42_hpo_dp_link_enc_read_state(
28 struct hpo_dp_link_encoder *enc,
29 struct hpo_dp_link_enc_state *state)
30{
31 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
32
33 ASSERT(state);
34
35 REG_GET(DP_DPHY_SYM32_STATUS,
36 STATUS, &state->link_enc_enabled);
37 REG_GET(DP_DPHY_SYM32_CONTROL,
38 NUM_LANES, &state->lane_count);
39 REG_GET(DP_DPHY_SYM32_CONTROL,
40 MODE, (uint32_t *)&state->link_mode);
41
42 REG_GET_2(DP_DPHY_SYM32_SAT_VC0,
43 SAT_STREAM_SOURCE, &state->stream_src[0],
44 SAT_SLOT_COUNT, &state->slot_count[0]);
45 REG_GET_2(DP_DPHY_SYM32_SAT_VC1,
46 SAT_STREAM_SOURCE, &state->stream_src[1],
47 SAT_SLOT_COUNT, &state->slot_count[1]);
48 REG_GET_2(DP_DPHY_SYM32_SAT_VC2,
49 SAT_STREAM_SOURCE, &state->stream_src[2],
50 SAT_SLOT_COUNT, &state->slot_count[2]);
51
52 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL0,
53 STREAM_VC_RATE_X, &state->vc_rate_x[0],
54 STREAM_VC_RATE_Y, &state->vc_rate_y[0]);
55 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL1,
56 STREAM_VC_RATE_X, &state->vc_rate_x[1],
57 STREAM_VC_RATE_Y, &state->vc_rate_y[1]);
58 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL2,
59 STREAM_VC_RATE_X, &state->vc_rate_x[2],
60 STREAM_VC_RATE_Y, &state->vc_rate_y[2]);
61}
62
63static struct hpo_dp_link_encoder_funcs dcn42_hpo_dp_link_encoder_funcs = {
64 .enable_link_phy = dcn31_hpo_dp_link_enc_enable_dp_output,
65 .disable_link_phy = dcn31_hpo_dp_link_enc_disable_output,
66 .link_enable = dcn31_hpo_dp_link_enc_enable,
67 .link_disable = dcn31_hpo_dp_link_enc_disable,
68 .set_link_test_pattern = dcn31_hpo_dp_link_enc_set_link_test_pattern,
69 .update_stream_allocation_table = dcn31_hpo_dp_link_enc_update_stream_allocation_table,
70 .set_throttled_vcp_size = dcn31_hpo_dp_link_enc_set_throttled_vcp_size,
71 .is_in_alt_mode = dcn32_hpo_dp_link_enc_is_in_alt_mode,
72 .read_state = dcn42_hpo_dp_link_enc_read_state,
73 .set_ffe = dcn31_hpo_dp_link_enc_set_ffe,
74};
75
76void hpo_dp_link_encoder42_construct(struct dcn31_hpo_dp_link_encoder *enc31,
77 struct dc_context *ctx,
78 uint32_t inst,
79 const struct dcn31_hpo_dp_link_encoder_registers *hpo_le_regs,
80 const struct dcn31_hpo_dp_link_encoder_shift *hpo_le_shift,
81 const struct dcn31_hpo_dp_link_encoder_mask *hpo_le_mask)
82{
83 enc31->base.ctx = ctx;
84
85 enc31->base.inst = inst;
86 enc31->base.funcs = &dcn42_hpo_dp_link_encoder_funcs;
87 enc31->base.hpd_source = HPD_SOURCEID_UNKNOWN;
88 enc31->base.transmitter = TRANSMITTER_UNKNOWN;
89
90 enc31->regs = hpo_le_regs;
91 enc31->hpo_le_shift = hpo_le_shift;
92 enc31->hpo_le_mask = hpo_le_mask;
93}
drivers/gpu/drm/amd/display/dc/hpo/dcn42/dcn42_hpo_dp_link_encoder.h+17−0
@@ -0,0 +1,17 @@
1/* SPDX-License-Identifier: MIT */
2/* Copyright 2026 Advanced Micro Devices, Inc. */
3
4
5#ifndef __DAL_DCN42_HPO_DP_LINK_ENCODER_H__
6#define __DAL_DCN42_HPO_DP_LINK_ENCODER_H__
7
8#include "link_encoder.h"
9
10void hpo_dp_link_encoder42_construct(struct dcn31_hpo_dp_link_encoder *enc31,
11 struct dc_context *ctx,
12 uint32_t inst,
13 const struct dcn31_hpo_dp_link_encoder_registers *hpo_le_regs,
14 const struct dcn31_hpo_dp_link_encoder_shift *hpo_le_shift,
15 const struct dcn31_hpo_dp_link_encoder_mask *hpo_le_mask);
16
17#endif // __DAL_DCN32_HPO_DP_LINK_ENCODER_H__
drivers/gpu/drm/amd/display/dc/hubbub/Makefile+9−1
@@ -1,5 +1,5 @@
1 1
2# Copyright 2022 Advanced Micro Devices, Inc.2# Copyright 2022-2026 Advanced Micro Devices, Inc.
3#3#
4# Permission is hereby granted, free of charge, to any person obtaining a4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),5# copy of this software and associated documentation files (the "Software"),
@@ -101,4 +101,12 @@ AMD_DAL_HUBBUB_DCN401 = $(addprefix $(AMDDALPATH)/dc/hubbub/dcn401/,$(HUBBUB_DCN · 95 unmodified lines
101AMD_DISPLAY_FILES += $(AMD_DAL_HUBBUB_DCN401)101AMD_DISPLAY_FILES += $(AMD_DAL_HUBBUB_DCN401)
102 102
103###############################################################################103###############################################################################
104# DCN42
105###############################################################################
106HUBBUB_DCN42 = dcn42_hubbub.o
107
108AMD_DAL_HUBBUB_DCN42 = $(addprefix $(AMDDALPATH)/dc/hubbub/dcn42/,$(HUBBUB_DCN42))
109
110AMD_DISPLAY_FILES += $(AMD_DAL_HUBBUB_DCN42)
111
104endif112endif
drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h+5−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.2 * Copyright 2016-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -441,6 +441,8 @@ struct dcn_hubbub_registers { · 435 unmodified lines
441 type DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_VALUE;\441 type DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_VALUE;\
442 type DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_ENABLE442 type DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_ENABLE
443 443
444#define HUBBUB_REG_FIELD_LIST_DCN4_2(type) \
445 type URGENT_ZERO_SIZE_REQ_EN
444struct dcn_hubbub_shift {446struct dcn_hubbub_shift {
445 DCN_HUBBUB_REG_FIELD_LIST(uint8_t);447 DCN_HUBBUB_REG_FIELD_LIST(uint8_t);
446 HUBBUB_STUTTER_REG_FIELD_LIST(uint8_t);448 HUBBUB_STUTTER_REG_FIELD_LIST(uint8_t);
@@ -449,6 +451,7 @@ struct dcn_hubbub_shift { · 2 unmodified lines
449 HUBBUB_REG_FIELD_LIST_DCN32(uint8_t);451 HUBBUB_REG_FIELD_LIST_DCN32(uint8_t);
450 HUBBUB_REG_FIELD_LIST_DCN35(uint8_t);452 HUBBUB_REG_FIELD_LIST_DCN35(uint8_t);
451 HUBBUB_REG_FIELD_LIST_DCN4_01(uint8_t);453 HUBBUB_REG_FIELD_LIST_DCN4_01(uint8_t);
454 HUBBUB_REG_FIELD_LIST_DCN4_2(uint8_t);
452 455
453};456};
454 457
@@ -460,6 +463,7 @@ struct dcn_hubbub_mask { · 5 unmodified lines
460 HUBBUB_REG_FIELD_LIST_DCN32(uint32_t);463 HUBBUB_REG_FIELD_LIST_DCN32(uint32_t);
461 HUBBUB_REG_FIELD_LIST_DCN35(uint32_t);464 HUBBUB_REG_FIELD_LIST_DCN35(uint32_t);
462 HUBBUB_REG_FIELD_LIST_DCN4_01(uint32_t);465 HUBBUB_REG_FIELD_LIST_DCN4_01(uint32_t);
466 HUBBUB_REG_FIELD_LIST_DCN4_2(uint8_t);
463 467
464};468};
465 469
drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.c+539−0
@@ -0,0 +1,539 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "dcn30/dcn30_hubbub.h"
6#include "dcn31/dcn31_hubbub.h"
7#include "dcn32/dcn32_hubbub.h"
8#include "dcn35/dcn35_hubbub.h"
9#include "dcn42/dcn42_hubbub.h"
10#include "dm_services.h"
11#include "reg_helper.h"
12
13#define DCN42_CRB_SEGMENT_SIZE_KB 64
14
15#define CTX \
16 hubbub2->base.ctx
17#define DC_LOGGER \
18 hubbub2->base.ctx->logger
19#define REG(reg)\
20 hubbub2->regs->reg
21
22#undef FN
23#define FN(reg_name, field_name) \
24 hubbub2->shifts->field_name, hubbub2->masks->field_name
25
26static bool hubbub42_program_urgent_watermarks(
27 struct hubbub *hubbub,
28 union dcn_watermark_set *watermarks,
29 bool safe_to_lower)
30{
31 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
32 bool wm_pending = false;
33
34 /* Repeat for water mark set A, B, C and D. */
35 /* clock state A */
36 if (safe_to_lower || watermarks->dcn4x.a.urgent > hubbub2->watermarks.dcn4x.a.urgent) {
37 hubbub2->watermarks.dcn4x.a.urgent = watermarks->dcn4x.a.urgent;
38 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
39 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, watermarks->dcn4x.a.urgent);
40 } else if (watermarks->dcn4x.a.urgent < hubbub2->watermarks.dcn4x.a.urgent)
41 wm_pending = true;
42
43 /* determine the transfer time for a quantity of data for a particular requestor.*/
44 if (safe_to_lower || watermarks->dcn4x.a.frac_urg_bw_flip > hubbub2->watermarks.dcn4x.a.frac_urg_bw_flip) {
45 hubbub2->watermarks.dcn4x.a.frac_urg_bw_flip = watermarks->dcn4x.a.frac_urg_bw_flip;
46 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0,
47 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->dcn4x.a.frac_urg_bw_flip);
48 } else if (watermarks->dcn4x.a.frac_urg_bw_flip < hubbub2->watermarks.dcn4x.a.frac_urg_bw_flip)
49 wm_pending = true;
50
51 if (safe_to_lower || watermarks->dcn4x.a.frac_urg_bw_nom > hubbub2->watermarks.dcn4x.a.frac_urg_bw_nom) {
52 hubbub2->watermarks.dcn4x.a.frac_urg_bw_nom = watermarks->dcn4x.a.frac_urg_bw_nom;
53 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0,
54 DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->dcn4x.a.frac_urg_bw_nom);
55 } else if (watermarks->dcn4x.a.frac_urg_bw_nom < hubbub2->watermarks.dcn4x.a.frac_urg_bw_nom)
56 wm_pending = true;
57
58 if (safe_to_lower || watermarks->dcn4x.a.refcyc_per_trip_to_mem > hubbub2->watermarks.dcn4x.a.refcyc_per_trip_to_mem) {
59 hubbub2->watermarks.dcn4x.a.refcyc_per_trip_to_mem = watermarks->dcn4x.a.refcyc_per_trip_to_mem;
60 REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0,
61 DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, watermarks->dcn4x.a.refcyc_per_trip_to_mem);
62 } else if (watermarks->dcn4x.a.refcyc_per_trip_to_mem < hubbub2->watermarks.dcn4x.a.refcyc_per_trip_to_mem)
63 wm_pending = true;
64
65 /* clock state B */
66 if (safe_to_lower || watermarks->dcn4x.b.urgent > hubbub2->watermarks.dcn4x.b.urgent) {
67 hubbub2->watermarks.dcn4x.b.urgent = watermarks->dcn4x.b.urgent;
68 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
69 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, watermarks->dcn4x.b.urgent);
70 } else if (watermarks->dcn4x.b.urgent < hubbub2->watermarks.dcn4x.b.urgent)
71 wm_pending = true;
72
73 /* determine the transfer time for a quantity of data for a particular requestor.*/
74 if (safe_to_lower || watermarks->dcn4x.b.frac_urg_bw_flip > hubbub2->watermarks.dcn4x.b.frac_urg_bw_flip) {
75 hubbub2->watermarks.dcn4x.b.frac_urg_bw_flip = watermarks->dcn4x.b.frac_urg_bw_flip;
76 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0,
77 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->dcn4x.b.frac_urg_bw_flip);
78 } else if (watermarks->dcn4x.b.frac_urg_bw_flip < hubbub2->watermarks.dcn4x.b.frac_urg_bw_flip)
79 wm_pending = true;
80
81 if (safe_to_lower || watermarks->dcn4x.b.frac_urg_bw_nom > hubbub2->watermarks.dcn4x.b.frac_urg_bw_nom) {
82 hubbub2->watermarks.dcn4x.b.frac_urg_bw_nom = watermarks->dcn4x.b.frac_urg_bw_nom;
83 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0,
84 DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->dcn4x.b.frac_urg_bw_nom);
85 } else if (watermarks->dcn4x.b.frac_urg_bw_nom < hubbub2->watermarks.dcn4x.b.frac_urg_bw_nom)
86 wm_pending = true;
87
88 if (safe_to_lower || watermarks->dcn4x.b.refcyc_per_trip_to_mem > hubbub2->watermarks.dcn4x.b.refcyc_per_trip_to_mem) {
89 hubbub2->watermarks.dcn4x.b.refcyc_per_trip_to_mem = watermarks->dcn4x.b.refcyc_per_trip_to_mem;
90 REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0,
91 DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, watermarks->dcn4x.b.refcyc_per_trip_to_mem);
92 } else if (watermarks->dcn4x.b.refcyc_per_trip_to_mem < hubbub2->watermarks.dcn4x.b.refcyc_per_trip_to_mem)
93 wm_pending = true;
94
95 /* clock state C */
96 if (safe_to_lower || watermarks->dcn4x.c.urgent > hubbub2->watermarks.dcn4x.c.urgent) {
97 hubbub2->watermarks.dcn4x.c.urgent = watermarks->dcn4x.c.urgent;
98 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
99 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, watermarks->dcn4x.c.urgent);
100 } else if (watermarks->dcn4x.c.urgent < hubbub2->watermarks.dcn4x.c.urgent)
101 wm_pending = true;
102
103 /* determine the transfer time for a quantity of data for a particular requestor.*/
104 if (safe_to_lower || watermarks->dcn4x.c.frac_urg_bw_flip > hubbub2->watermarks.dcn4x.c.frac_urg_bw_flip) {
105 hubbub2->watermarks.dcn4x.c.frac_urg_bw_flip = watermarks->dcn4x.c.frac_urg_bw_flip;
106 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0,
107 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->dcn4x.c.frac_urg_bw_flip);
108 } else if (watermarks->dcn4x.c.frac_urg_bw_flip < hubbub2->watermarks.dcn4x.c.frac_urg_bw_flip)
109 wm_pending = true;
110
111 if (safe_to_lower || watermarks->dcn4x.c.frac_urg_bw_nom > hubbub2->watermarks.dcn4x.c.frac_urg_bw_nom) {
112 hubbub2->watermarks.dcn4x.c.frac_urg_bw_nom = watermarks->dcn4x.c.frac_urg_bw_nom;
113 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0,
114 DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->dcn4x.c.frac_urg_bw_nom);
115 } else if (watermarks->dcn4x.c.frac_urg_bw_nom < hubbub2->watermarks.dcn4x.c.frac_urg_bw_nom)
116 wm_pending = true;
117
118 if (safe_to_lower || watermarks->dcn4x.c.refcyc_per_trip_to_mem > hubbub2->watermarks.dcn4x.c.refcyc_per_trip_to_mem) {
119 hubbub2->watermarks.dcn4x.c.refcyc_per_trip_to_mem = watermarks->dcn4x.c.refcyc_per_trip_to_mem;
120 REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0,
121 DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, watermarks->dcn4x.c.refcyc_per_trip_to_mem);
122 } else if (watermarks->dcn4x.c.refcyc_per_trip_to_mem < hubbub2->watermarks.dcn4x.c.refcyc_per_trip_to_mem)
123 wm_pending = true;
124
125 /* clock state D */
126 if (safe_to_lower || watermarks->dcn4x.d.urgent > hubbub2->watermarks.dcn4x.d.urgent) {
127 hubbub2->watermarks.dcn4x.d.urgent = watermarks->dcn4x.d.urgent;
128 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
129 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, watermarks->dcn4x.d.urgent);
130 } else if (watermarks->dcn4x.d.urgent < hubbub2->watermarks.dcn4x.d.urgent)
131 wm_pending = true;
132
133 /* determine the transfer time for a quantity of data for a particular requestor.*/
134 if (safe_to_lower || watermarks->dcn4x.d.frac_urg_bw_flip > hubbub2->watermarks.dcn4x.d.frac_urg_bw_flip) {
135 hubbub2->watermarks.dcn4x.d.frac_urg_bw_flip = watermarks->dcn4x.d.frac_urg_bw_flip;
136 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0,
137 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->dcn4x.d.frac_urg_bw_flip);
138 } else if (watermarks->dcn4x.d.frac_urg_bw_flip < hubbub2->watermarks.dcn4x.d.frac_urg_bw_flip)
139 wm_pending = true;
140
141 if (safe_to_lower || watermarks->dcn4x.d.frac_urg_bw_nom > hubbub2->watermarks.dcn4x.d.frac_urg_bw_nom) {
142 hubbub2->watermarks.dcn4x.d.frac_urg_bw_nom = watermarks->dcn4x.d.frac_urg_bw_nom;
143 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0,
144 DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->dcn4x.d.frac_urg_bw_nom);
145 } else if (watermarks->dcn4x.d.frac_urg_bw_nom < hubbub2->watermarks.dcn4x.d.frac_urg_bw_nom)
146 wm_pending = true;
147
148 if (safe_to_lower || watermarks->dcn4x.d.refcyc_per_trip_to_mem > hubbub2->watermarks.dcn4x.d.refcyc_per_trip_to_mem) {
149 hubbub2->watermarks.dcn4x.d.refcyc_per_trip_to_mem = watermarks->dcn4x.d.refcyc_per_trip_to_mem;
150 REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0,
151 DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, watermarks->dcn4x.d.refcyc_per_trip_to_mem);
152 } else if (watermarks->dcn4x.d.refcyc_per_trip_to_mem < hubbub2->watermarks.dcn4x.d.refcyc_per_trip_to_mem)
153 wm_pending = true;
154
155 return wm_pending;
156}
157
158static bool hubbub42_program_stutter_watermarks(
159 struct hubbub *hubbub,
160 union dcn_watermark_set *watermarks,
161 bool safe_to_lower)
162{
163 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
164 bool wm_pending = false;
165
166 /* clock state A */
167 if (safe_to_lower || watermarks->dcn4x.a.sr_enter > hubbub2->watermarks.dcn4x.a.sr_enter) {
168 hubbub2->watermarks.dcn4x.a.sr_enter = watermarks->dcn4x.a.sr_enter;
169 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
170 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, watermarks->dcn4x.a.sr_enter);
171 } else if (watermarks->dcn4x.a.sr_enter < hubbub2->watermarks.dcn4x.a.sr_enter)
172 wm_pending = true;
173
174 if (safe_to_lower || watermarks->dcn4x.a.sr_exit > hubbub2->watermarks.dcn4x.a.sr_exit) {
175 hubbub2->watermarks.dcn4x.a.sr_exit = watermarks->dcn4x.a.sr_exit;
176 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
177 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, watermarks->dcn4x.a.sr_exit);
178 } else if (watermarks->dcn4x.a.sr_exit < hubbub2->watermarks.dcn4x.a.sr_exit)
179 wm_pending = true;
180
181 /* clock state B */
182 if (safe_to_lower || watermarks->dcn4x.b.sr_enter > hubbub2->watermarks.dcn4x.b.sr_enter) {
183 hubbub2->watermarks.dcn4x.b.sr_enter = watermarks->dcn4x.b.sr_enter;
184 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
185 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, watermarks->dcn4x.b.sr_enter);
186 } else if (watermarks->dcn4x.b.sr_enter < hubbub2->watermarks.dcn4x.b.sr_enter)
187 wm_pending = true;
188
189 if (safe_to_lower || watermarks->dcn4x.b.sr_exit > hubbub2->watermarks.dcn4x.b.sr_exit) {
190 hubbub2->watermarks.dcn4x.b.sr_exit = watermarks->dcn4x.b.sr_exit;
191 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
192 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, watermarks->dcn4x.b.sr_exit);
193 } else if (watermarks->dcn4x.b.sr_exit < hubbub2->watermarks.dcn4x.b.sr_exit)
194 wm_pending = true;
195
196 /* clock state C */
197 if (safe_to_lower || watermarks->dcn4x.c.sr_enter > hubbub2->watermarks.dcn4x.c.sr_enter) {
198 hubbub2->watermarks.dcn4x.c.sr_enter = watermarks->dcn4x.c.sr_enter;
199 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
200 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, watermarks->dcn4x.c.sr_enter);
201 } else if (watermarks->dcn4x.c.sr_enter < hubbub2->watermarks.dcn4x.c.sr_enter)
202 wm_pending = true;
203
204 if (safe_to_lower || watermarks->dcn4x.c.sr_exit > hubbub2->watermarks.dcn4x.c.sr_exit) {
205 hubbub2->watermarks.dcn4x.c.sr_exit = watermarks->dcn4x.c.sr_exit;
206 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
207 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, watermarks->dcn4x.c.sr_exit);
208 } else if (watermarks->dcn4x.c.sr_exit < hubbub2->watermarks.dcn4x.c.sr_exit)
209 wm_pending = true;
210
211 /* clock state D */
212 if (safe_to_lower || watermarks->dcn4x.d.sr_enter > hubbub2->watermarks.dcn4x.d.sr_enter) {
213 hubbub2->watermarks.dcn4x.d.sr_enter = watermarks->dcn4x.d.sr_enter;
214 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
215 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, watermarks->dcn4x.d.sr_enter);
216 } else if (watermarks->dcn4x.d.sr_enter < hubbub2->watermarks.dcn4x.d.sr_enter)
217 wm_pending = true;
218
219 if (safe_to_lower || watermarks->dcn4x.d.sr_exit > hubbub2->watermarks.dcn4x.d.sr_exit) {
220 hubbub2->watermarks.dcn4x.d.sr_exit = watermarks->dcn4x.d.sr_exit;
221 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
222 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, watermarks->dcn4x.d.sr_exit);
223 } else if (watermarks->dcn4x.d.sr_exit < hubbub2->watermarks.dcn4x.d.sr_exit)
224 wm_pending = true;
225
226 return wm_pending;
227}
228
229static bool hubbub42_program_pstate_watermarks(
230 struct hubbub *hubbub,
231 union dcn_watermark_set *watermarks,
232 bool safe_to_lower)
233{
234 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
235 bool wm_pending = false;
236
237 /* Section for UCLK_PSTATE_CHANGE_WATERMARKS */
238 /* UCLK state A */
239 if (safe_to_lower || watermarks->dcn4x.a.uclk_pstate > hubbub2->watermarks.dcn4x.a.uclk_pstate) {
240 hubbub2->watermarks.dcn4x.a.uclk_pstate = watermarks->dcn4x.a.uclk_pstate;
241 REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, 0,
242 DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, watermarks->dcn4x.a.uclk_pstate);
243 } else if (watermarks->dcn4x.a.uclk_pstate < hubbub2->watermarks.dcn4x.a.uclk_pstate)
244 wm_pending = true;
245
246 /* UCLK state B */
247 if (safe_to_lower || watermarks->dcn4x.b.uclk_pstate > hubbub2->watermarks.dcn4x.b.uclk_pstate) {
248 hubbub2->watermarks.dcn4x.b.uclk_pstate = watermarks->dcn4x.b.uclk_pstate;
249 REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, 0,
250 DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, watermarks->dcn4x.b.uclk_pstate);
251 } else if (watermarks->dcn4x.b.uclk_pstate < hubbub2->watermarks.dcn4x.b.uclk_pstate)
252 wm_pending = true;
253
254 /* UCLK state C */
255 if (safe_to_lower || watermarks->dcn4x.c.uclk_pstate > hubbub2->watermarks.dcn4x.c.uclk_pstate) {
256 hubbub2->watermarks.dcn4x.c.uclk_pstate = watermarks->dcn4x.c.uclk_pstate;
257 REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, 0,
258 DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, watermarks->dcn4x.c.uclk_pstate);
259 } else if (watermarks->dcn4x.c.uclk_pstate < hubbub2->watermarks.dcn4x.c.uclk_pstate)
260 wm_pending = true;
261
262 /* UCLK state D */
263 if (safe_to_lower || watermarks->dcn4x.d.uclk_pstate > hubbub2->watermarks.dcn4x.d.uclk_pstate) {
264 hubbub2->watermarks.dcn4x.d.uclk_pstate = watermarks->dcn4x.d.uclk_pstate;
265 REG_SET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, 0,
266 DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, watermarks->dcn4x.d.uclk_pstate);
267 } else if (watermarks->dcn4x.d.uclk_pstate < hubbub2->watermarks.dcn4x.d.uclk_pstate)
268 wm_pending = true;
269
270 /* Section for FCLK_PSTATE_CHANGE_WATERMARKS */
271 /* FCLK state A */
272 if (safe_to_lower || watermarks->dcn4x.a.fclk_pstate > hubbub2->watermarks.dcn4x.a.fclk_pstate) {
273 hubbub2->watermarks.dcn4x.a.fclk_pstate = watermarks->dcn4x.a.fclk_pstate;
274 REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, 0,
275 DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, watermarks->dcn4x.a.fclk_pstate);
276 } else if (watermarks->dcn4x.a.fclk_pstate < hubbub2->watermarks.dcn4x.a.fclk_pstate)
277 wm_pending = true;
278
279 /* FCLK state B */
280 if (safe_to_lower || watermarks->dcn4x.b.fclk_pstate > hubbub2->watermarks.dcn4x.b.fclk_pstate) {
281 hubbub2->watermarks.dcn4x.b.fclk_pstate = watermarks->dcn4x.b.fclk_pstate;
282 REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, 0,
283 DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, watermarks->dcn4x.b.fclk_pstate);
284 } else if (watermarks->dcn4x.b.fclk_pstate < hubbub2->watermarks.dcn4x.b.fclk_pstate)
285 wm_pending = true;
286
287 /* FCLK state C */
288 if (safe_to_lower || watermarks->dcn4x.c.fclk_pstate > hubbub2->watermarks.dcn4x.c.fclk_pstate) {
289 hubbub2->watermarks.dcn4x.c.fclk_pstate = watermarks->dcn4x.c.fclk_pstate;
290 REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, 0,
291 DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, watermarks->dcn4x.c.fclk_pstate);
292 } else if (watermarks->dcn4x.c.fclk_pstate < hubbub2->watermarks.dcn4x.c.fclk_pstate)
293 wm_pending = true;
294
295 /* FCLK state D */
296 if (safe_to_lower || watermarks->dcn4x.d.fclk_pstate > hubbub2->watermarks.dcn4x.d.fclk_pstate) {
297 hubbub2->watermarks.dcn4x.d.fclk_pstate = watermarks->dcn4x.d.fclk_pstate;
298 REG_SET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, 0,
299 DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, watermarks->dcn4x.d.fclk_pstate);
300 } else if (watermarks->dcn4x.d.fclk_pstate < hubbub2->watermarks.dcn4x.d.fclk_pstate)
301 wm_pending = true;
302
303 return wm_pending;
304}
305
306static bool hubbub42_program_usr_watermarks(
307 struct hubbub *hubbub,
308 union dcn_watermark_set *watermarks,
309 bool safe_to_lower)
310{
311 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
312 bool wm_pending = false;
313
314 /* clock state A */
315 if (safe_to_lower || watermarks->dcn4x.a.usr > hubbub2->watermarks.dcn4x.a.usr) {
316 hubbub2->watermarks.dcn4x.a.usr = watermarks->dcn4x.a.usr;
317 REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, 0,
318 DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, watermarks->dcn4x.a.usr);
319 } else if (watermarks->dcn4x.a.usr < hubbub2->watermarks.dcn4x.a.usr)
320 wm_pending = true;
321
322 /* clock state B */
323 if (safe_to_lower || watermarks->dcn4x.b.usr > hubbub2->watermarks.dcn4x.b.usr) {
324 hubbub2->watermarks.dcn4x.b.usr = watermarks->dcn4x.b.usr;
325 REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, 0,
326 DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, watermarks->dcn4x.b.usr);
327 } else if (watermarks->dcn4x.b.usr < hubbub2->watermarks.dcn4x.b.usr)
328 wm_pending = true;
329
330 /* clock state C */
331 if (safe_to_lower || watermarks->dcn4x.c.usr > hubbub2->watermarks.dcn4x.c.usr) {
332 hubbub2->watermarks.dcn4x.c.usr = watermarks->dcn4x.c.usr;
333 REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, 0,
334 DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, watermarks->dcn4x.c.usr);
335 } else if (watermarks->dcn4x.c.usr < hubbub2->watermarks.dcn4x.c.usr)
336 wm_pending = true;
337
338 /* clock state D */
339 if (safe_to_lower || watermarks->dcn4x.d.usr > hubbub2->watermarks.dcn4x.d.usr) {
340 hubbub2->watermarks.dcn4x.d.usr = watermarks->dcn4x.d.usr;
341 REG_SET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, 0,
342 DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, watermarks->dcn4x.d.usr);
343 } else if (watermarks->dcn4x.d.usr < hubbub2->watermarks.dcn4x.d.usr)
344 wm_pending = true;
345
346 return wm_pending;
347}
348
349static bool hubbub42_program_stutter_z8_watermarks(
350 struct hubbub *hubbub,
351 union dcn_watermark_set *watermarks,
352 bool safe_to_lower)
353{
354 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
355 bool wm_pending = false;
356
357 /* clock state A */
358 if (safe_to_lower || watermarks->dcn4x.a.sr_enter_z8 > hubbub2->watermarks.dcn4x.a.sr_enter_z8) {
359 hubbub2->watermarks.dcn4x.a.sr_enter_z8 = watermarks->dcn4x.a.sr_enter_z8;
360 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, 0,
361 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, watermarks->dcn4x.a.sr_enter_z8);
362 } else if (watermarks->dcn4x.a.sr_enter_z8 < hubbub2->watermarks.dcn4x.a.sr_enter_z8)
363 wm_pending = true;
364
365 if (safe_to_lower || watermarks->dcn4x.a.sr_exit_z8 > hubbub2->watermarks.dcn4x.a.sr_exit_z8) {
366 hubbub2->watermarks.dcn4x.a.sr_exit_z8 = watermarks->dcn4x.a.sr_exit_z8;
367 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, 0,
368 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, watermarks->dcn4x.a.sr_exit_z8);
369 } else if (watermarks->dcn4x.a.sr_exit_z8 < hubbub2->watermarks.dcn4x.a.sr_exit_z8)
370 wm_pending = true;
371
372 /* clock state B */
373 if (safe_to_lower || watermarks->dcn4x.b.sr_enter_z8 > hubbub2->watermarks.dcn4x.b.sr_enter_z8) {
374 hubbub2->watermarks.dcn4x.b.sr_enter_z8 = watermarks->dcn4x.b.sr_enter_z8;
375 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, 0,
376 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, watermarks->dcn4x.b.sr_enter_z8);
377 } else if (watermarks->dcn4x.b.sr_enter_z8 < hubbub2->watermarks.dcn4x.b.sr_enter_z8)
378 wm_pending = true;
379
380 if (safe_to_lower || watermarks->dcn4x.b.sr_exit_z8 > hubbub2->watermarks.dcn4x.b.sr_exit_z8) {
381 hubbub2->watermarks.dcn4x.b.sr_exit_z8 = watermarks->dcn4x.b.sr_exit_z8;
382 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, 0,
383 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, watermarks->dcn4x.b.sr_exit_z8);
384 } else if (watermarks->dcn4x.b.sr_exit_z8 < hubbub2->watermarks.dcn4x.b.sr_exit_z8)
385 wm_pending = true;
386
387 /* clock state C */
388 if (safe_to_lower || watermarks->dcn4x.c.sr_enter_z8 > hubbub2->watermarks.dcn4x.c.sr_enter_z8) {
389 hubbub2->watermarks.dcn4x.c.sr_enter_z8 = watermarks->dcn4x.c.sr_enter_z8;
390 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, 0,
391 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, watermarks->dcn4x.c.sr_enter_z8);
392 } else if (watermarks->dcn4x.c.sr_enter_z8 < hubbub2->watermarks.dcn4x.c.sr_enter_z8)
393 wm_pending = true;
394
395 if (safe_to_lower || watermarks->dcn4x.c.sr_exit_z8 > hubbub2->watermarks.dcn4x.c.sr_exit_z8) {
396 hubbub2->watermarks.dcn4x.c.sr_exit_z8 = watermarks->dcn4x.c.sr_exit_z8;
397 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, 0,
398 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, watermarks->dcn4x.c.sr_exit_z8);
399 } else if (watermarks->dcn4x.c.sr_exit_z8 < hubbub2->watermarks.dcn4x.c.sr_exit_z8)
400 wm_pending = true;
401
402 /* clock state D */
403 if (safe_to_lower || watermarks->dcn4x.d.sr_enter_z8 > hubbub2->watermarks.dcn4x.d.sr_enter_z8) {
404 hubbub2->watermarks.dcn4x.d.sr_enter_z8 = watermarks->dcn4x.d.sr_enter_z8;
405 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, 0,
406 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, watermarks->dcn4x.d.sr_enter_z8);
407 } else if (watermarks->dcn4x.d.sr_enter_z8 < hubbub2->watermarks.dcn4x.d.sr_enter_z8)
408 wm_pending = true;
409
410 if (safe_to_lower || watermarks->dcn4x.d.sr_exit_z8 > hubbub2->watermarks.dcn4x.d.sr_exit_z8) {
411 hubbub2->watermarks.dcn4x.d.sr_exit_z8 = watermarks->dcn4x.d.sr_exit_z8;
412 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, 0,
413 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, watermarks->dcn4x.d.sr_exit_z8);
414 } else if (watermarks->dcn4x.d.sr_exit_z8 < hubbub2->watermarks.dcn4x.d.sr_exit_z8)
415 wm_pending = true;
416
417 return wm_pending;
418}
419
420static void hubbub42_allow_self_refresh_control(struct hubbub *hubbub, bool allow)
421{
422 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
423
424 /*
425 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 1 means do not allow stutter
426 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0 means allow stutter
427 */
428
429 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
430 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
431 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow);
432
433 if (!allow && hubbub->ctx->dc->debug.disable_stutter) {/*controlled by registry key*/
434 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
435 DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_VALUE, 0,
436 DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_ENABLE, 1);
437 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
438 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
439 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
440 }
441}
442static void hubbub42_set_sdp_control(struct hubbub *hubbub, bool dc_control)
443{
444 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
445
446 REG_UPDATE(DCHUBBUB_SDPIF_CFG0,
447 SDPIF_PORT_CONTROL, dc_control);
448}
449
450static bool hubbub42_program_watermarks(
451 struct hubbub *hubbub,
452 union dcn_watermark_set *watermarks,
453 unsigned int refclk_mhz,
454 bool safe_to_lower)
455{
456 bool wm_pending = false;
457 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
458
459 if (!safe_to_lower && hubbub->ctx->dc->debug.disable_stutter_for_wm_program) {
460 /* before raising watermarks, SDP control give to DF, stutter must be disabled */
461 wm_pending = true;
462 hubbub42_set_sdp_control(hubbub, false);
463 hubbub42_allow_self_refresh_control(hubbub, false);
464 }
465 if (hubbub42_program_urgent_watermarks(hubbub, watermarks, safe_to_lower))
466 wm_pending = true;
467
468 if (hubbub42_program_stutter_watermarks(hubbub, watermarks, safe_to_lower))
469 wm_pending = true;
470
471 if (hubbub42_program_pstate_watermarks(hubbub, watermarks, safe_to_lower))
472 wm_pending = true;
473
474 if (hubbub42_program_usr_watermarks(hubbub, watermarks, safe_to_lower))
475 wm_pending = true;
476
477 if (hubbub42_program_stutter_z8_watermarks(hubbub, watermarks, safe_to_lower))
478 wm_pending = true;
479
480 REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,
481 DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
482 REG_UPDATE_2(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
483 DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0xFF,
484 DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA);/*hw delta*/
485 REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL, DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF);
486
487 if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter)
488 hubbub42_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
489 if (safe_to_lower && hubbub->ctx->dc->debug.disable_stutter_for_wm_program) {
490 hubbub42_set_sdp_control(hubbub, true);
491 }
492 hubbub32_force_usr_retraining_allow(hubbub, hubbub->ctx->dc->debug.force_usr_allow);
493
494 return wm_pending;
495}
496
497static const struct hubbub_funcs hubbub42_funcs = {
498 .update_dchub = hubbub2_update_dchub,
499 .init_dchub_sys_ctx = hubbub31_init_dchub_sys_ctx,
500 .init_vm_ctx = hubbub2_init_vm_ctx,
501 .dcc_support_swizzle = hubbub3_dcc_support_swizzle,
502 .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format,
503 .get_dcc_compression_cap = hubbub3_get_dcc_compression_cap,
504 .wm_read_state = hubbub35_wm_read_state,
505 .get_dchub_ref_freq = hubbub35_get_dchub_ref_freq,
506 .program_watermarks = hubbub42_program_watermarks,
507 .allow_self_refresh_control = hubbub42_allow_self_refresh_control,
508 .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
509 .force_wm_propagate_to_pipes = hubbub32_force_wm_propagate_to_pipes,
510 .force_pstate_change_control = hubbub3_force_pstate_change_control,
511 .init_watermarks = hubbub35_init_watermarks,
512 .program_det_size = dcn32_program_det_size,
513 .program_compbuf_size = dcn35_program_compbuf_size,
514 .init_crb = dcn35_init_crb,
515 .hubbub_read_state = hubbub2_read_state,
516 .force_usr_retraining_allow = hubbub32_force_usr_retraining_allow,
517 .dchubbub_init = hubbub35_init,
518 .dchvm_init = dcn35_dchvm_init,
519};
520
521void hubbub42_construct(struct dcn20_hubbub *hubbub2,
522 struct dc_context *ctx,
523 const struct dcn_hubbub_registers *hubbub_regs,
524 const struct dcn_hubbub_shift *hubbub_shift,
525 const struct dcn_hubbub_mask *hubbub_mask,
526 int det_size_kb,
527 int pixel_chunk_size_kb,
528 int config_return_buffer_size_kb)
529{
530 hubbub2->base.ctx = ctx;
531 hubbub2->base.funcs = &hubbub42_funcs;
532 hubbub2->regs = hubbub_regs;
533 hubbub2->shifts = hubbub_shift;
534 hubbub2->masks = hubbub_mask;
535
536 hubbub2->detile_buf_size = det_size_kb * 1024;
537 hubbub2->pixel_chunk_size = pixel_chunk_size_kb * 1024;
538 hubbub2->crb_size_segs = config_return_buffer_size_kb / DCN42_CRB_SEGMENT_SIZE_KB;
539}
drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.h+268−0
@@ -0,0 +1,268 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2026 Advanced Micro Devices, 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: AMD
24 *
25 */
26
27#ifndef __DC_HUBBUB_DCN42_H__
28#define __DC_HUBBUB_DCN42_H__
29
30#include "dcn32/dcn32_hubbub.h"
31
32#define DCN42_CRB_SIZE_KB 1792
33#define DCN42_DEFAULT_DET_SIZE 320
34#define DCN42_CRB_SEGMENT_SIZE_KB 64
35
36#define HUBBUB_REG_LIST_DCN42(id)\
37 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\
38 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\
39 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\
40 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\
41 SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\
42 SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\
43 SR(DCHUBBUB_ARB_SAT_LEVEL),\
44 SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND),\
45 SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
46 SR(DCHUBBUB_SOFT_RESET),\
47 SR(DCHUBBUB_CRC_CTRL), \
48 SR(DCN_VM_FB_LOCATION_BASE),\
49 SR(DCN_VM_FB_LOCATION_TOP),\
50 SR(DCN_VM_FB_OFFSET),\
51 SR(DCN_VM_AGP_BOT),\
52 SR(DCN_VM_AGP_TOP),\
53 SR(DCN_VM_AGP_BASE),\
54 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
55 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
56 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
57 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
58 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
59 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
60 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
61 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D),\
62 SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A),\
63 SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B),\
64 SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C),\
65 SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D),\
66 SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A),\
67 SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B),\
68 SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C),\
69 SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D),\
70 SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A),\
71 SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B),\
72 SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C),\
73 SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D),\
74 SR(DCHUBBUB_DET0_CTRL),\
75 SR(DCHUBBUB_DET1_CTRL),\
76 SR(DCHUBBUB_DET2_CTRL),\
77 SR(DCHUBBUB_DET3_CTRL),\
78 SR(DCHUBBUB_COMPBUF_CTRL),\
79 SR(COMPBUF_RESERVED_SPACE),\
80 SR(DCHUBBUB_DEBUG_CTRL_0),\
81 SR(DCHUBBUB_ARB_USR_RETRAINING_CNTL),\
82 SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A),\
83 SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B),\
84 SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C),\
85 SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D),\
86 SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A),\
87 SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B),\
88 SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C),\
89 SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D),\
90 SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A),\
91 SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B),\
92 SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C),\
93 SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D),\
94 SR(DCN_VM_FAULT_ADDR_MSB),\
95 SR(DCN_VM_FAULT_ADDR_LSB),\
96 SR(DCN_VM_FAULT_CNTL),\
97 SR(DCN_VM_FAULT_STATUS),\
98 SR(SDPIF_REQUEST_RATE_LIMIT),\
99 SR(DCHUBBUB_CLOCK_CNTL),\
100 SR(DCHUBBUB_SDPIF_CFG0),\
101 SR(DCHUBBUB_SDPIF_CFG1),\
102 SR(DCHUBBUB_MEM_PWR_MODE_CTRL),\
103 SR(DCHUBBUB_ARB_HOSTVM_CNTL),\
104 SR(DCHVM_CTRL0),\
105 SR(DCHVM_MEM_CTRL),\
106 SR(DCHVM_CLK_CTRL),\
107 SR(DCHVM_RIOMMU_CTRL0),\
108 SR(DCHVM_RIOMMU_STAT0),\
109 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A),\
110 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A),\
111 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B),\
112 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B),\
113 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C),\
114 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C),\
115 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D),\
116 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D),\
117 SR(DCHUBBUB_ARB_QOS_FORCE)
118
119#define HUBBUB_MASK_SH_LIST_DCN4_2(mask_sh)\
120 HUBBUB_MASK_SH_LIST_DCN32(mask_sh), \
121 HUBBUB_SF(DCHVM_CTRL0, HOSTVM_INIT_REQ, mask_sh),\
122 HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_PWR_REQ_DIS, mask_sh),\
123 HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_FORCE_REQ, mask_sh),\
124 HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_POWER_STATUS, mask_sh),\
125 HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DISPCLK_R_GATE_DIS, mask_sh),\
126 HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DISPCLK_G_GATE_DIS, mask_sh),\
127 HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DCFCLK_R_GATE_DIS, mask_sh),\
128 HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DCFCLK_G_GATE_DIS, mask_sh),\
129 HUBBUB_SF(DCHVM_CLK_CTRL, TR_REQ_REQCLKREQ_MODE, mask_sh),\
130 HUBBUB_SF(DCHVM_CLK_CTRL, TW_RSP_COMPCLKREQ_MODE, mask_sh),\
131 HUBBUB_SF(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, mask_sh),\
132 HUBBUB_SF(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, mask_sh),\
133 HUBBUB_SF(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, mask_sh),\
134 HUBBUB_SF(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, mask_sh),\
135 HUBBUB_SF(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE, mask_sh),\
136 HUBBUB_SF(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE_CURRENT, mask_sh),\
137 HUBBUB_SF(DCHUBBUB_COMPBUF_CTRL, CONFIG_ERROR, mask_sh),\
138 HUBBUB_SF(COMPBUF_RESERVED_SPACE, COMPBUF_RESERVED_SPACE_64B, mask_sh),\
139 HUBBUB_SF(COMPBUF_RESERVED_SPACE, COMPBUF_RESERVED_SPACE_ZS, mask_sh),\
140 HUBBUB_SF(DCHUBBUB_CLOCK_CNTL, DCHUBBUB_FGCG_REP_DIS, mask_sh),\
141 HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \
142 HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MAX_REQ_OUTSTAND, mask_sh), \
143 HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, mask_sh), \
144 HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, mask_sh), \
145 HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, mask_sh), \
146 HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, mask_sh), \
147 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, mask_sh), \
148 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, mask_sh), \
149 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, mask_sh), \
150 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, mask_sh), \
151 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, mask_sh), \
152 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, mask_sh), \
153 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, mask_sh), \
154 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, mask_sh), \
155 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_CSTATE_DEEPSLEEP_LEGACY_MODE, mask_sh), \
156 HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
157 HUBBUB_SF(DCHUBBUB_SOFT_RESET, DCHUBBUB_GLOBAL_SOFT_RESET, mask_sh), \
158 HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \
159 HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \
160 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \
161 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \
162 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_VALUE, mask_sh), \
163 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_ENABLE, mask_sh), \
164 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \
165 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \
166 HUBBUB_SF(DCHUBBUB_ARB_HOSTVM_CNTL, DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, mask_sh),\
167 HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, mask_sh),\
168 HUBBUB_SF(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
169 HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \
170 HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MAX_REQ_OUTSTAND, mask_sh), \
171 HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, mask_sh), \
172 HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, mask_sh), \
173 HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, mask_sh), \
174 HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, mask_sh), \
175 HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
176 HUBBUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE, mask_sh), \
177 HUBBUB_SF(DCN_VM_FB_LOCATION_TOP, FB_TOP, mask_sh), \
178 HUBBUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET, mask_sh), \
179 HUBBUB_SF(DCN_VM_AGP_BOT, AGP_BOT, mask_sh), \
180 HUBBUB_SF(DCN_VM_AGP_TOP, AGP_TOP, mask_sh), \
181 HUBBUB_SF(DCN_VM_AGP_BASE, AGP_BASE, mask_sh), \
182 HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, mask_sh), \
183 HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, mask_sh), \
184 HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, mask_sh), \
185 HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, mask_sh), \
186 HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, mask_sh), \
187 HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, mask_sh), \
188 HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, mask_sh), \
189 HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, mask_sh), \
190 HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, mask_sh), \
191 HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, mask_sh), \
192 HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, mask_sh), \
193 HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, mask_sh), \
194 HUBBUB_SF(DCHUBBUB_DEBUG_CTRL_0, DET_DEPTH, mask_sh),\
195 HUBBUB_SF(DCHUBBUB_DET0_CTRL, DET0_SIZE, mask_sh),\
196 HUBBUB_SF(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, mask_sh),\
197 HUBBUB_SF(DCHUBBUB_DET1_CTRL, DET1_SIZE, mask_sh),\
198 HUBBUB_SF(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, mask_sh),\
199 HUBBUB_SF(DCHUBBUB_DET2_CTRL, DET2_SIZE, mask_sh),\
200 HUBBUB_SF(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, mask_sh),\
201 HUBBUB_SF(DCHUBBUB_DET3_CTRL, DET3_SIZE, mask_sh),\
202 HUBBUB_SF(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, mask_sh),\
203 HUBBUB_SF(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE, mask_sh),\
204 HUBBUB_SF(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE_CURRENT, mask_sh),\
205 HUBBUB_SF(DCHUBBUB_COMPBUF_CTRL, CONFIG_ERROR, mask_sh),\
206 HUBBUB_SF(COMPBUF_RESERVED_SPACE, COMPBUF_RESERVED_SPACE_64B, mask_sh),\
207 HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_CNTL, DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_VALUE, mask_sh),\
208 HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_CNTL, DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_ENABLE, mask_sh),\
209 HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_CNTL, DCHUBBUB_ARB_DO_NOT_FORCE_ALLOW_USR_RETRAINING_DURING_PSTATE_CHANGE_REQUEST, mask_sh),\
210 HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_CNTL, DCHUBBUB_ARB_DO_NOT_FORCE_ALLOW_USR_RETRAINING_DURING_PRE_CSTATE, mask_sh),\
211 HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, mask_sh), \
212 HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, mask_sh), \
213 HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, mask_sh), \
214 HUBBUB_SF(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, mask_sh), \
215 HUBBUB_SF(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, mask_sh),\
216 HUBBUB_SF(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, mask_sh),\
217 HUBBUB_SF(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, mask_sh),\
218 HUBBUB_SF(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, mask_sh),\
219 HUBBUB_SF(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, mask_sh),\
220 HUBBUB_SF(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, mask_sh),\
221 HUBBUB_SF(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, mask_sh),\
222 HUBBUB_SF(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, mask_sh),\
223 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, mask_sh), \
224 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, mask_sh), \
225 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, mask_sh), \
226 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, mask_sh), \
227 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, mask_sh), \
228 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, mask_sh), \
229 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, mask_sh), \
230 HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, mask_sh), \
231 HUBBUB_SF(DCN_VM_FAULT_ADDR_MSB, DCN_VM_FAULT_ADDR_MSB, mask_sh), \
232 HUBBUB_SF(DCN_VM_FAULT_ADDR_LSB, DCN_VM_FAULT_ADDR_LSB, mask_sh), \
233 HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_ERROR_STATUS_CLEAR, mask_sh), \
234 HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_ERROR_STATUS_MODE, mask_sh), \
235 HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_ERROR_INTERRUPT_ENABLE, mask_sh), \
236 HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_RANGE_FAULT_DISABLE, mask_sh), \
237 HUBBUB_SF(DCN_VM_FAULT_CNTL, DCN_VM_PRQ_FAULT_DISABLE, mask_sh), \
238 HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_STATUS, mask_sh), \
239 HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_VMID, mask_sh), \
240 HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_TABLE_LEVEL, mask_sh), \
241 HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_PIPE, mask_sh), \
242 HUBBUB_SF(DCN_VM_FAULT_STATUS, DCN_VM_ERROR_INTERRUPT_STATUS, mask_sh),\
243 HUBBUB_SF(SDPIF_REQUEST_RATE_LIMIT, SDPIF_REQUEST_RATE_LIMIT, mask_sh),\
244 HUBBUB_SF(DCHUBBUB_CLOCK_CNTL, DISPCLK_R_DCHUBBUB_GATE_DIS, mask_sh),\
245 HUBBUB_SF(DCHUBBUB_CLOCK_CNTL, DCFCLK_R_DCHUBBUB_GATE_DIS, mask_sh),\
246 HUBBUB_SF(DCHUBBUB_SDPIF_CFG0, SDPIF_PORT_CONTROL, mask_sh),\
247 HUBBUB_SF(DCHUBBUB_SDPIF_CFG1, SDPIF_MAX_NUM_OUTSTANDING, mask_sh),\
248 HUBBUB_SF(DCHUBBUB_MEM_PWR_MODE_CTRL, DET_MEM_PWR_LS_MODE, mask_sh),\
249 HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL1, DCHUBBUB_TIMEOUT_ERROR_STATUS, mask_sh),\
250 HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL1, DCHUBBUB_TIMEOUT_REQ_STALL_THRESHOLD, mask_sh),\
251 HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_PSTATE_STALL_THRESHOLD, mask_sh),\
252 HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_DETECTION_EN, mask_sh),\
253 HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_TIMER_RESET, mask_sh),\
254 HUBBUB_SF(DCHUBBUB_CTRL_STATUS, ROB_OVERFLOW_STATUS, mask_sh),\
255 HUBBUB_SF(DCHUBBUB_CTRL_STATUS, ROB_OVERFLOW_CLEAR, mask_sh),\
256 HUBBUB_SF(DCHUBBUB_CTRL_STATUS, DCHUBBUB_HW_DEBUG, mask_sh),\
257 HUBBUB_SF(DCHUBBUB_CTRL_STATUS, URGENT_ZERO_SIZE_REQ_EN, mask_sh),\
258 HUBBUB_SF(DCHUBBUB_CTRL_STATUS, CSTATE_SWATH_CHK_GOOD_MODE, mask_sh)
259
260void hubbub42_construct(struct dcn20_hubbub *hubbub2,
261 struct dc_context *ctx,
262 const struct dcn_hubbub_registers *hubbub_regs,
263 const struct dcn_hubbub_shift *hubbub_shift,
264 const struct dcn_hubbub_mask *hubbub_mask,
265 int det_size_kb,
266 int pixel_chunk_size_kb,
267 int config_return_buffer_size_kb);
268#endif
drivers/gpu/drm/amd/display/dc/hubp/Makefile+9−1
@@ -1,5 +1,5 @@
1 1
2# Copyright 2022 Advanced Micro Devices, Inc.2# Copyright 2022-2026 Advanced Micro Devices, Inc.
3#3#
4# Permission is hereby granted, free of charge, to any person obtaining a4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),5# copy of this software and associated documentation files (the "Software"),
@@ -94,4 +94,12 @@ AMD_DAL_HUBP_DCN401 = $(addprefix $(AMDDALPATH)/dc/hubp/dcn401/,$(HUBP_DCN401)) · 88 unmodified lines
94 94
95AMD_DISPLAY_FILES += $(AMD_DAL_HUBP_DCN401)95AMD_DISPLAY_FILES += $(AMD_DAL_HUBP_DCN401)
96 96
97###############################################################################
98
99HUBP_DCN42 = dcn42_hubp.o
100
101AMD_DAL_HUBP_DCN42 = $(addprefix $(AMDDALPATH)/dc/hubp/dcn42/,$(HUBP_DCN42))
102
103AMD_DISPLAY_FILES += $(AMD_DAL_HUBP_DCN42)
104
97endif105endif
drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h+7−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012-17 Advanced Micro Devices, Inc.2 * Copyright 2012-2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -288,16 +288,22 @@ · 282 unmodified lines
288 type MCACHEID_MALL_PREF_2H_P1;\288 type MCACHEID_MALL_PREF_2H_P1;\
289 type HUBP_FGCG_REP_DIS289 type HUBP_FGCG_REP_DIS
290 290
291#define DCN42_HUBP_REG_FIELD_VARIABLE_LIST(type) \
292 type HUBP_3DLUT_CROSSBAR_SEL_G;\
293 type HUBP_3DLUT_CROSSBAR_SEL_B;\
294 type HUBP_3DLUT_CROSSBAR_SEL_R
291struct dcn_hubp2_registers {295struct dcn_hubp2_registers {
292 DCN401_HUBP_REG_COMMON_VARIABLE_LIST;296 DCN401_HUBP_REG_COMMON_VARIABLE_LIST;
293};297};
294 298
295struct dcn_hubp2_shift {299struct dcn_hubp2_shift {
296 DCN401_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);300 DCN401_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);
301 DCN42_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);
297};302};
298 303
299struct dcn_hubp2_mask {304struct dcn_hubp2_mask {
300 DCN401_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);305 DCN401_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);
306 DCN42_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);
301};307};
302 308
303struct dcn20_hubp {309struct dcn20_hubp {
drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c+643−0
@@ -0,0 +1,643 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "dcn401/dcn401_hubp.h"
6#include "dcn42_hubp.h"
7#include "reg_helper.h"
8
9#define REG(reg) \
10 hubp2->hubp_regs->reg
11
12#define CTX \
13 hubp2->base.ctx
14
15#undef FN
16#define FN(reg_name, field_name) \
17 hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name
18
19static void hubp42_set_fgcg(struct hubp *hubp, bool enable)
20{
21 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
22
23 REG_UPDATE(HUBP_CLK_CNTL, HUBP_FGCG_REP_DIS, !enable);
24}
25
26static void hubp42_init(struct hubp *hubp)
27{
28 hubp3_init(hubp);
29
30 hubp42_set_fgcg(hubp, hubp->ctx->dc->debug.enable_fine_grain_clock_gating.bits.dchub);
31
32 /*do nothing for now for dcn3.5 or later*/
33}
34
35static void hubp42_program_pixel_format(
36 struct hubp *hubp,
37 enum surface_pixel_format format)
38{
39 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
40 uint32_t green_bar = 1;
41 uint32_t red_bar = 3;
42 uint32_t blue_bar = 2;
43
44 /* swap for ABGR format */
45 if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
46 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
47 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
48 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616
49 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
50 red_bar = 2;
51 blue_bar = 3;
52 }
53
54 REG_UPDATE_3(HUBPRET_CONTROL,
55 CROSSBAR_SRC_Y_G, green_bar,
56 CROSSBAR_SRC_CB_B, blue_bar,
57 CROSSBAR_SRC_CR_R, red_bar);
58
59 /* Mapping is same as ipp programming (cnvc) */
60
61 switch (format) {
62 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
63 REG_UPDATE(DCSURF_SURFACE_CONFIG,
64 SURFACE_PIXEL_FORMAT, 1);
65 break;
66 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
67 REG_UPDATE(DCSURF_SURFACE_CONFIG,
68 SURFACE_PIXEL_FORMAT, 3);
69 break;
70 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
71 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
72 REG_UPDATE(DCSURF_SURFACE_CONFIG,
73 SURFACE_PIXEL_FORMAT, 8);
74 break;
75 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
76 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
77 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
78 REG_UPDATE(DCSURF_SURFACE_CONFIG,
79 SURFACE_PIXEL_FORMAT, 10);
80 break;
81 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
82 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /* we use crossbar already */
83 REG_UPDATE(DCSURF_SURFACE_CONFIG,
84 SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
85 break;
86 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
87 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
88 REG_UPDATE(DCSURF_SURFACE_CONFIG,
89 SURFACE_PIXEL_FORMAT, 24);
90 break;
91
92 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
93 REG_UPDATE(DCSURF_SURFACE_CONFIG,
94 SURFACE_PIXEL_FORMAT, 65);
95 break;
96 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
97 REG_UPDATE(DCSURF_SURFACE_CONFIG,
98 SURFACE_PIXEL_FORMAT, 64);
99 break;
100 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
101 REG_UPDATE(DCSURF_SURFACE_CONFIG,
102 SURFACE_PIXEL_FORMAT, 67);
103 break;
104 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
105 REG_UPDATE(DCSURF_SURFACE_CONFIG,
106 SURFACE_PIXEL_FORMAT, 66);
107 break;
108 case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
109 REG_UPDATE(DCSURF_SURFACE_CONFIG,
110 SURFACE_PIXEL_FORMAT, 12);
111 break;
112 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
113 REG_UPDATE(DCSURF_SURFACE_CONFIG,
114 SURFACE_PIXEL_FORMAT, 112);
115 break;
116 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
117 REG_UPDATE(DCSURF_SURFACE_CONFIG,
118 SURFACE_PIXEL_FORMAT, 113);
119 break;
120 case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
121 REG_UPDATE(DCSURF_SURFACE_CONFIG,
122 SURFACE_PIXEL_FORMAT, 114);
123 break;
124 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
125 REG_UPDATE(DCSURF_SURFACE_CONFIG,
126 SURFACE_PIXEL_FORMAT, 118);
127 break;
128 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
129 REG_UPDATE(DCSURF_SURFACE_CONFIG,
130 SURFACE_PIXEL_FORMAT, 119);
131 break;
132 case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
133 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
134 SURFACE_PIXEL_FORMAT, 116,
135 ALPHA_PLANE_EN, 0);
136 break;
137 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
138 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
139 SURFACE_PIXEL_FORMAT, 116,
140 ALPHA_PLANE_EN, 1);
141 break;
142 default:
143 BREAK_TO_DEBUGGER();
144 break;
145 }
146
147 /* don't see the need of program the xbar in DCN 1.0 */
148}
149
150void hubp42_program_deadline(
151 struct hubp *hubp,
152 struct dml2_display_dlg_regs *dlg_attr,
153 struct dml2_display_ttu_regs *ttu_attr)
154{
155 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
156
157 /* DLG - Per hubp */
158 REG_SET_2(BLANK_OFFSET_0, 0,
159 REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end,
160 DLG_V_BLANK_END, dlg_attr->dlg_vblank_end);
161
162 REG_SET(BLANK_OFFSET_1, 0,
163 MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start);
164
165 REG_SET(DST_DIMENSIONS, 0,
166 REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal);
167
168 REG_SET_2(DST_AFTER_SCALER, 0,
169 REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler,
170 DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler);
171
172 REG_SET(REF_FREQ_TO_PIX_FREQ, 0,
173 REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq);
174
175 /* DLG - Per luma/chroma */
176 REG_SET(VBLANK_PARAMETERS_1, 0,
177 REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l);
178
179 if (REG(NOM_PARAMETERS_0))
180 REG_SET(NOM_PARAMETERS_0, 0,
181 DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l);
182
183 if (REG(NOM_PARAMETERS_1))
184 REG_SET(NOM_PARAMETERS_1, 0,
185 REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l);
186
187 REG_SET(NOM_PARAMETERS_4, 0,
188 DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l);
189
190 REG_SET(NOM_PARAMETERS_5, 0,
191 REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l);
192
193 REG_SET_2(PER_LINE_DELIVERY, 0,
194 REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l,
195 REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c);
196
197 REG_SET(VBLANK_PARAMETERS_2, 0,
198 REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c);
199
200 if (REG(NOM_PARAMETERS_2))
201 REG_SET(NOM_PARAMETERS_2, 0,
202 DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c);
203
204 if (REG(NOM_PARAMETERS_3))
205 REG_SET(NOM_PARAMETERS_3, 0,
206 REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c);
207
208 REG_SET(NOM_PARAMETERS_6, 0,
209 DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c);
210
211 REG_SET(NOM_PARAMETERS_7, 0,
212 REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c);
213
214 /* TTU - per hubp */
215 REG_SET_2(DCN_TTU_QOS_WM, 0,
216 QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm,
217 QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm);
218
219 /* TTU - per luma/chroma */
220 /* Assumed surf0 is luma and 1 is chroma */
221
222 REG_SET_3(DCN_SURF0_TTU_CNTL0, 0,
223 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l,
224 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l,
225 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l);
226
227 REG_SET_3(DCN_SURF1_TTU_CNTL0, 0,
228 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c,
229 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c,
230 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c);
231
232 REG_SET_3(DCN_CUR0_TTU_CNTL0, 0,
233 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0,
234 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0,
235 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0);
236
237 REG_SET(FLIP_PARAMETERS_1, 0,
238 REFCYC_PER_PTE_GROUP_FLIP_L, dlg_attr->refcyc_per_pte_group_flip_l);
239 REG_SET(HUBP_3DLUT_DLG_PARAM, 0, REFCYC_PER_3DLUT_GROUP, dlg_attr->refcyc_per_tdlut_group);
240
241 REG_UPDATE(DCN_DMDATA_VM_CNTL,
242 REFCYC_PER_VM_DMDATA, dlg_attr->refcyc_per_vm_dmdata);
243}
244
245void hubp42_setup(
246 struct hubp *hubp,
247 struct dml2_dchub_per_pipe_register_set *pipe_regs,
248 union dml2_global_sync_programming *pipe_global_sync,
249 struct dc_crtc_timing *timing)
250{
251 /* otg is locked when this func is called. Register are double buffered.
252 * disable the requestors is not needed
253 */
254 hubp401_vready_at_or_After_vsync(hubp, pipe_global_sync, timing);
255 hubp401_program_requestor(hubp, &pipe_regs->rq_regs);
256 hubp42_program_deadline(hubp, &pipe_regs->dlg_regs, &pipe_regs->ttu_regs);
257}
258static void hubp42_program_surface_config(
259 struct hubp *hubp,
260 enum surface_pixel_format format,
261 struct dc_tiling_info *tiling_info,
262 struct plane_size *plane_size,
263 enum dc_rotation_angle rotation,
264 struct dc_plane_dcc_param *dcc,
265 bool horizontal_mirror,
266 unsigned int compat_level)
267{
268 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
269
270 hubp3_dcc_control_sienna_cichlid(hubp, dcc);
271 hubp3_program_tiling(hubp2, tiling_info, format);
272 hubp2_program_size(hubp, format, plane_size, dcc);
273 hubp2_program_rotation(hubp, rotation, horizontal_mirror);
274 hubp42_program_pixel_format(hubp, format);
275}
276
277void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
278 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
279 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
280 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b)
281{
282 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
283
284 REG_UPDATE_3(HUBP_3DLUT_CONTROL,
285 HUBP_3DLUT_CROSSBAR_SEL_R, bit_slice_r,
286 HUBP_3DLUT_CROSSBAR_SEL_G, bit_slice_g,
287 HUBP_3DLUT_CROSSBAR_SEL_B, bit_slice_b);
288}
289
290static bool hubp42_program_surface_flip_and_addr(
291 struct hubp *hubp,
292 const struct dc_plane_address *address,
293 bool flip_immediate)
294{
295 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
296
297 //program flip type
298 REG_UPDATE(DCSURF_FLIP_CONTROL,
299 SURFACE_FLIP_TYPE, flip_immediate);
300
301 // Program VMID reg
302 if (flip_immediate == 0)
303 REG_UPDATE(VMID_SETTINGS_0,
304 VMID, address->vmid);
305
306 if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) {
307 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0);
308 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1);
309
310 } else {
311 // turn off stereo if not in stereo
312 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0);
313 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0);
314 }
315
316 /* HW automatically latch rest of address register on write to
317 * DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used
318 *
319 * program high first and then the low addr, order matters!
320 */
321 switch (address->type) {
322 case PLN_ADDR_TYPE_GRAPHICS:
323 /* DCN1.0 does not support const color
324 * TODO: program DCHUBBUB_RET_PATH_DCC_CFGx_0/1
325 * base on address->grph.dcc_const_color
326 * x = 0, 2, 4, 6 for pipe 0, 1, 2, 3 for rgb and luma
327 * x = 1, 3, 5, 7 for pipe 0, 1, 2, 3 for chroma
328 */
329
330 if (address->grph.addr.quad_part == 0)
331 break;
332
333 REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
334 PRIMARY_SURFACE_TMZ, address->tmz_surface,
335 PRIMARY_META_SURFACE_TMZ, address->tmz_surface);
336
337 if (address->grph.meta_addr.quad_part != 0) {
338 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
339 PRIMARY_META_SURFACE_ADDRESS_HIGH,
340 address->grph.meta_addr.high_part);
341
342 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
343 PRIMARY_META_SURFACE_ADDRESS,
344 address->grph.meta_addr.low_part);
345 }
346
347 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
348 PRIMARY_SURFACE_ADDRESS_HIGH,
349 address->grph.addr.high_part);
350
351 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
352 PRIMARY_SURFACE_ADDRESS,
353 address->grph.addr.low_part);
354 break;
355 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
356 if (address->video_progressive.luma_addr.quad_part == 0
357 || address->video_progressive.chroma_addr.quad_part == 0)
358 break;
359
360 REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
361 PRIMARY_SURFACE_TMZ, address->tmz_surface,
362 PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
363 PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
364 PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
365
366 if (address->video_progressive.luma_meta_addr.quad_part != 0) {
367 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
368 PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
369 address->video_progressive.chroma_meta_addr.high_part);
370
371 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
372 PRIMARY_META_SURFACE_ADDRESS_C,
373 address->video_progressive.chroma_meta_addr.low_part);
374
375 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
376 PRIMARY_META_SURFACE_ADDRESS_HIGH,
377 address->video_progressive.luma_meta_addr.high_part);
378
379 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
380 PRIMARY_META_SURFACE_ADDRESS,
381 address->video_progressive.luma_meta_addr.low_part);
382 }
383
384 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
385 PRIMARY_SURFACE_ADDRESS_HIGH_C,
386 address->video_progressive.chroma_addr.high_part);
387
388 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
389 PRIMARY_SURFACE_ADDRESS_C,
390 address->video_progressive.chroma_addr.low_part);
391
392 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
393 PRIMARY_SURFACE_ADDRESS_HIGH,
394 address->video_progressive.luma_addr.high_part);
395
396 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
397 PRIMARY_SURFACE_ADDRESS,
398 address->video_progressive.luma_addr.low_part);
399 break;
400 case PLN_ADDR_TYPE_GRPH_STEREO:
401 if (address->grph_stereo.left_addr.quad_part == 0)
402 break;
403 if (address->grph_stereo.right_addr.quad_part == 0)
404 break;
405
406 REG_UPDATE_8(DCSURF_SURFACE_CONTROL,
407 PRIMARY_SURFACE_TMZ, address->tmz_surface,
408 PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
409 PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
410 PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface,
411 SECONDARY_SURFACE_TMZ, address->tmz_surface,
412 SECONDARY_SURFACE_TMZ_C, address->tmz_surface,
413 SECONDARY_META_SURFACE_TMZ, address->tmz_surface,
414 SECONDARY_META_SURFACE_TMZ_C, address->tmz_surface);
415
416 if (address->grph_stereo.right_meta_addr.quad_part != 0) {
417
418 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C, 0,
419 SECONDARY_META_SURFACE_ADDRESS_HIGH_C,
420 address->grph_stereo.right_alpha_meta_addr.high_part);
421
422 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_C, 0,
423 SECONDARY_META_SURFACE_ADDRESS_C,
424 address->grph_stereo.right_alpha_meta_addr.low_part);
425
426 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0,
427 SECONDARY_META_SURFACE_ADDRESS_HIGH,
428 address->grph_stereo.right_meta_addr.high_part);
429
430 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0,
431 SECONDARY_META_SURFACE_ADDRESS,
432 address->grph_stereo.right_meta_addr.low_part);
433 }
434 if (address->grph_stereo.left_meta_addr.quad_part != 0) {
435
436 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
437 PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
438 address->grph_stereo.left_alpha_meta_addr.high_part);
439
440 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
441 PRIMARY_META_SURFACE_ADDRESS_C,
442 address->grph_stereo.left_alpha_meta_addr.low_part);
443
444 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
445 PRIMARY_META_SURFACE_ADDRESS_HIGH,
446 address->grph_stereo.left_meta_addr.high_part);
447
448 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
449 PRIMARY_META_SURFACE_ADDRESS,
450 address->grph_stereo.left_meta_addr.low_part);
451 }
452
453 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C, 0,
454 SECONDARY_SURFACE_ADDRESS_HIGH_C,
455 address->grph_stereo.right_alpha_addr.high_part);
456
457 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_C, 0,
458 SECONDARY_SURFACE_ADDRESS_C,
459 address->grph_stereo.right_alpha_addr.low_part);
460
461 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
462 SECONDARY_SURFACE_ADDRESS_HIGH,
463 address->grph_stereo.right_addr.high_part);
464
465 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
466 SECONDARY_SURFACE_ADDRESS,
467 address->grph_stereo.right_addr.low_part);
468
469 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
470 PRIMARY_SURFACE_ADDRESS_HIGH_C,
471 address->grph_stereo.left_alpha_addr.high_part);
472
473 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
474 PRIMARY_SURFACE_ADDRESS_C,
475 address->grph_stereo.left_alpha_addr.low_part);
476
477 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
478 PRIMARY_SURFACE_ADDRESS_HIGH,
479 address->grph_stereo.left_addr.high_part);
480
481 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
482 PRIMARY_SURFACE_ADDRESS,
483 address->grph_stereo.left_addr.low_part);
484 break;
485 case PLN_ADDR_TYPE_RGBEA:
486 if (address->rgbea.addr.quad_part == 0
487 || address->rgbea.alpha_addr.quad_part == 0)
488 break;
489
490 REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
491 PRIMARY_SURFACE_TMZ, address->tmz_surface,
492 PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
493 PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
494 PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
495
496 if (address->rgbea.meta_addr.quad_part != 0) {
497
498 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
499 PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
500 address->rgbea.alpha_meta_addr.high_part);
501
502 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
503 PRIMARY_META_SURFACE_ADDRESS_C,
504 address->rgbea.alpha_meta_addr.low_part);
505
506 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
507 PRIMARY_META_SURFACE_ADDRESS_HIGH,
508 address->rgbea.meta_addr.high_part);
509
510 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
511 PRIMARY_META_SURFACE_ADDRESS,
512 address->rgbea.meta_addr.low_part);
513 }
514
515 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
516 PRIMARY_SURFACE_ADDRESS_HIGH_C,
517 address->rgbea.alpha_addr.high_part);
518
519 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
520 PRIMARY_SURFACE_ADDRESS_C,
521 address->rgbea.alpha_addr.low_part);
522
523 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
524 PRIMARY_SURFACE_ADDRESS_HIGH,
525 address->rgbea.addr.high_part);
526
527 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
528 PRIMARY_SURFACE_ADDRESS,
529 address->rgbea.addr.low_part);
530 break;
531 default:
532 BREAK_TO_DEBUGGER();
533 break;
534 }
535
536 hubp->request_address = *address;
537
538 return true;
539}
540
541struct hubp_funcs dcn42_hubp_funcs = {
542 .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
543 .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
544 .hubp_program_surface_flip_and_addr = hubp42_program_surface_flip_and_addr,
545 .hubp_program_surface_config = hubp42_program_surface_config,
546 .hubp_is_flip_pending = hubp2_is_flip_pending,
547 .hubp_setup2 = hubp42_setup,
548 .hubp_setup_interdependent2 = hubp401_setup_interdependent,
549 .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
550 .set_blank = hubp2_set_blank,
551 .dcc_control = hubp3_dcc_control,
552 .hubp_reset = hubp_reset,
553 .mem_program_viewport = min_set_viewport,
554 .set_cursor_attributes = hubp32_cursor_set_attributes,
555 .set_cursor_position = hubp401_cursor_set_position,
556 .hubp_clk_cntl = hubp2_clk_cntl,
557 .hubp_vtg_sel = hubp2_vtg_sel,
558 .dmdata_set_attributes = hubp3_dmdata_set_attributes,
559 .dmdata_load = hubp2_dmdata_load,
560 .dmdata_status_done = hubp2_dmdata_status_done,
561 .hubp_read_state = hubp42_read_state,
562 .hubp_clear_underflow = hubp2_clear_underflow,
563 .hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,
564 .hubp_init = hubp42_init,
565 .set_unbounded_requesting = hubp31_set_unbounded_requesting,
566 .hubp_soft_reset = hubp31_soft_reset,
567 .hubp_set_flip_int = hubp1_set_flip_int,
568 .hubp_in_blank = hubp1_in_blank,
569 .program_extended_blank = hubp31_program_extended_blank_value,
570 .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
571 .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
572 .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
573 .hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
574 .hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
575 .hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
576 .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
577 .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
578 .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
579 .hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
580 .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
581 .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
582 .hubp_read_reg_state = hubp3_read_reg_state
583};
584
585bool hubp42_construct(
586 struct dcn20_hubp *hubp2,
587 struct dc_context *ctx,
588 uint32_t inst,
589 const struct dcn_hubp2_registers *hubp_regs,
590 const struct dcn_hubp2_shift *hubp_shift,
591 const struct dcn_hubp2_mask *hubp_mask)
592{
593 hubp2->base.funcs = &dcn42_hubp_funcs;
594 hubp2->base.ctx = ctx;
595 hubp2->hubp_regs = hubp_regs;
596 hubp2->hubp_shift = hubp_shift;
597 hubp2->hubp_mask = hubp_mask;
598 hubp2->base.inst = inst;
599 hubp2->base.opp_id = OPP_ID_INVALID;
600 hubp2->base.mpcc_id = 0xf;
601
602 return true;
603}
604
605
606void hubp42_read_state(struct hubp *hubp)
607{
608 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
609 struct dcn_hubp_state *s = &hubp2->state;
610 struct dcn_fl_regs_st *fl_regs = &s->fl_regs;
611
612 hubp401_read_state(hubp);
613
614 /* CONTROL */
615 REG_GET_5(HUBP_3DLUT_CONTROL,
616 HUBP_3DLUT_ENABLE, &fl_regs->lut_enable,
617 HUBP_3DLUT_DONE, &fl_regs->lut_done,
618 HUBP_3DLUT_ADDRESSING_MODE, &fl_regs->lut_addr_mode,
619 HUBP_3DLUT_WIDTH, &fl_regs->lut_width,
620 HUBP_3DLUT_MPC_WIDTH, &fl_regs->lut_mpc_width);
621
622 REG_GET_4(HUBP_3DLUT_CONTROL,
623 HUBP_3DLUT_TMZ, &fl_regs->lut_tmz,
624 HUBP_3DLUT_CROSSBAR_SEL_R, &fl_regs->lut_crossbar_sel_r,
625 HUBP_3DLUT_CROSSBAR_SEL_G, &fl_regs->lut_crossbar_sel_g,
626 HUBP_3DLUT_CROSSBAR_SEL_B, &fl_regs->lut_crossbar_sel_b);
627
628 /* ADDR */
629 REG_GET(HUBP_3DLUT_ADDRESS_HIGH,
630 HUBP_3DLUT_ADDRESS_HIGH, &fl_regs->lut_addr_hi);
631 REG_GET(HUBP_3DLUT_ADDRESS_LOW,
632 HUBP_3DLUT_ADDRESS_LOW, &fl_regs->lut_addr_lo);
633 /* CLK */
634 REG_GET(HUBP_3DLUT_DLG_PARAM,
635 REFCYC_PER_3DLUT_GROUP, &fl_regs->refcyc_3dlut_group);
636 /* FL */
637 REG_GET_2(_3DLUT_FL_BIAS_SCALE,
638 HUBP0_3DLUT_FL_BIAS, &fl_regs->lut_fl_bias,
639 HUBP0_3DLUT_FL_SCALE, &fl_regs->lut_fl_scale);
640 REG_GET_2(_3DLUT_FL_CONFIG,
641 HUBP0_3DLUT_FL_MODE, &fl_regs->lut_fl_mode,
642 HUBP0_3DLUT_FL_FORMAT, &fl_regs->lut_fl_format);
643}
drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h+79−0
@@ -0,0 +1,79 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright 2026 Advanced Micro Devices, 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: AMD
24 *
25 */
26
27#ifndef __DC_HUBP_DCN42_H__
28#define __DC_HUBP_DCN42_H__
29
30#include "dcn35/dcn35_hubp.h"
31
32#define HUBP_MASK_SH_LIST_DCN42(mask_sh)\
33 HUBP_MASK_SH_LIST_DCN35(mask_sh),\
34 HUBP_SF(HUBP0_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mask_sh),\
35 HUBP_SF(HUBP0_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, mask_sh),\
36 HUBP_SF(HUBP0_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, mask_sh),\
37 HUBP_SF(HUBP0_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_SCALE, mask_sh),\
38 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_ENABLE, mask_sh),\
39 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_DONE, mask_sh),\
40 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, mask_sh),\
41 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_WIDTH, mask_sh),\
42 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_MPC_WIDTH, mask_sh),\
43 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, mask_sh),\
44 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_CROSSBAR_SEL_B, mask_sh),\
45 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_CROSSBAR_SEL_G, mask_sh),\
46 HUBP_SF(CURSOR0_0_HUBP_3DLUT_CONTROL, HUBP_3DLUT_CROSSBAR_SEL_R, mask_sh),\
47 HUBP_SF(CURSOR0_0_HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, mask_sh),\
48 HUBP_SF(CURSOR0_0_HUBP_3DLUT_ADDRESS_LOW, HUBP_3DLUT_ADDRESS_LOW, mask_sh),\
49 HUBP_SF(CURSOR0_0_HUBP_3DLUT_DLG_PARAM, REFCYC_PER_3DLUT_GROUP, mask_sh)
50
51bool hubp42_construct(
52 struct dcn20_hubp *hubp2,
53 struct dc_context *ctx,
54 uint32_t inst,
55 const struct dcn_hubp2_registers *hubp_regs,
56 const struct dcn_hubp2_shift *hubp_shift,
57 const struct dcn_hubp2_mask *hubp_mask);
58
59void hubp42_program_3dlut_fl_crossbar(
60 struct hubp *hubp,
61 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
62 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
63 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b);
64
65void hubp42_read_state(struct hubp *hubp);
66
67void hubp42_setup(
68 struct hubp *hubp,
69 struct dml2_dchub_per_pipe_register_set *pipe_regs,
70 union dml2_global_sync_programming *pipe_global_sync,
71 struct dc_crtc_timing *timing);
72
73void hubp42_program_deadline(
74 struct hubp *hubp,
75 struct dml2_display_dlg_regs *dlg_attr,
76 struct dml2_display_ttu_regs *ttu_attr);
77
78
79#endif /* __DC_HUBP_DCN42_H__ */
drivers/gpu/drm/amd/display/dc/hwss/Makefile+10−2
@@ -1,5 +1,4 @@
1 1# Copyright 2022-2026 Advanced Micro Devices, Inc.
2# Copyright 2022 Advanced Micro Devices, Inc.
3#2#
4# Permission is hereby granted, free of charge, to any person obtaining a3# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),4# copy of this software and associated documentation files (the "Software"),
@@ -199,4 +198,13 @@ HWSS_DCN401 = dcn401_hwseq.o dcn401_init.o · 193 unmodified lines
199AMD_DAL_HWSS_DCN401 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn401/,$(HWSS_DCN401))198AMD_DAL_HWSS_DCN401 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn401/,$(HWSS_DCN401))
200 199
201AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN401)200AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN401)
201
202###############################################################################
203
204HWSS_DCN42 = dcn42_hwseq.o dcn42_init.o
205
206AMD_DAL_HWSS_DCN42 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn42/,$(HWSS_DCN42))
207
208AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN42)
209
202endif210endif
drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h+12−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.2 * Copyright 2016, 2026 Advanced Micro Devices, Inc.
3 *3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),5 * copy of this software and associated documentation files (the "Software"),
@@ -700,6 +700,8 @@ struct dce_hwseq_registers { · 694 unmodified lines
700 uint32_t DOMAIN23_PG_STATUS;700 uint32_t DOMAIN23_PG_STATUS;
701 uint32_t DOMAIN24_PG_STATUS;701 uint32_t DOMAIN24_PG_STATUS;
702 uint32_t DOMAIN25_PG_STATUS;702 uint32_t DOMAIN25_PG_STATUS;
703 uint32_t DOMAIN26_PG_CONFIG;
704 uint32_t DOMAIN26_PG_STATUS;
703};705};
704 /* set field name */706 /* set field name */
705#define HWS_SF(blk_name, reg_name, field_name, post_fix)\707#define HWS_SF(blk_name, reg_name, field_name, post_fix)\
@@ -1245,6 +1247,13 @@ struct dce_hwseq_registers { · 539 unmodified lines
1245 type DOMAIN25_PGFSM_PWR_STATUS; \1247 type DOMAIN25_PGFSM_PWR_STATUS; \
1246 type DOMAIN_DESIRED_PWR_STATE;1248 type DOMAIN_DESIRED_PWR_STATE;
1247 1249
1250#define HWSEQ_DCN42_REG_FIELD_LIST(type) \
1251 type DPIASYMCLK4_GATE_DISABLE;\
1252 type DPIASYMCLK5_GATE_DISABLE;\
1253 type DOMAIN26_POWER_FORCEON; \
1254 type DOMAIN26_POWER_GATE; \
1255 type DOMAIN26_PGFSM_PWR_STATUS;
1256
1248struct dce_hwseq_shift {1257struct dce_hwseq_shift {
1249 HWSEQ_REG_FIELD_LIST(uint8_t)1258 HWSEQ_REG_FIELD_LIST(uint8_t)
1250 HWSEQ_DCN_REG_FIELD_LIST(uint8_t)1259 HWSEQ_DCN_REG_FIELD_LIST(uint8_t)
@@ -1253,6 +1262,7 @@ struct dce_hwseq_shift { · 2 unmodified lines
1253 HWSEQ_DCN31_REG_FIELD_LIST(uint8_t)1262 HWSEQ_DCN31_REG_FIELD_LIST(uint8_t)
1254 HWSEQ_DCN35_REG_FIELD_LIST(uint8_t)1263 HWSEQ_DCN35_REG_FIELD_LIST(uint8_t)
1255 HWSEQ_DCN401_REG_FIELD_LIST(uint8_t)1264 HWSEQ_DCN401_REG_FIELD_LIST(uint8_t)
1265 HWSEQ_DCN42_REG_FIELD_LIST(uint8_t)
1256};1266};
1257 1267
1258struct dce_hwseq_mask {1268struct dce_hwseq_mask {
@@ -1263,6 +1273,7 @@ struct dce_hwseq_mask { · 4 unmodified lines
1263 HWSEQ_DCN31_REG_FIELD_LIST(uint32_t)1273 HWSEQ_DCN31_REG_FIELD_LIST(uint32_t)
1264 HWSEQ_DCN35_REG_FIELD_LIST(uint32_t)1274 HWSEQ_DCN35_REG_FIELD_LIST(uint32_t)
1265 HWSEQ_DCN401_REG_FIELD_LIST(uint32_t)1275 HWSEQ_DCN401_REG_FIELD_LIST(uint32_t)
1276 HWSEQ_DCN42_REG_FIELD_LIST(uint32_t)
1266};1277};
1267 1278
1268 1279
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c+66−0
@@ -660,6 +660,60 @@ void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) · 659 unmodified lines
660 }660 }
661}661}
662 662
663static void
664dce110_external_encoder_control(enum bp_external_encoder_control_action action,
665 struct dc_link *link,
666 struct dc_crtc_timing *timing)
667{
668 struct dc *dc = link->ctx->dc;
669 struct dc_bios *bios = link->ctx->dc_bios;
670 const struct dc_link_settings *link_settings = &link->cur_link_settings;
671 enum bp_result bp_result = BP_RESULT_OK;
672 struct bp_external_encoder_control ext_cntl = {
673 .action = action,
674 .connector_obj_id = link->link_enc->connector,
675 .encoder_id = link->ext_enc_id,
676 .lanes_number = link_settings->lane_count,
677 .link_rate = link_settings->link_rate,
678
679 /* Use signal type of the real link encoder, ie. DP */
680 .signal = link->connector_signal,
681
682 /* We don't know the timing yet when executing the SETUP action,
683 * so use a reasonably high default value. It seems that ENABLE
684 * can change the actual pixel clock but doesn't work with higher
685 * pixel clocks than what SETUP was called with.
686 */
687 .pixel_clock = timing ? timing->pix_clk_100hz / 10 : 300000,
688 .color_depth = timing ? timing->display_color_depth : COLOR_DEPTH_888,
689 };
690 DC_LOGGER_INIT();
691
692 bp_result = bios->funcs->external_encoder_control(bios, &ext_cntl);
693
694 if (bp_result != BP_RESULT_OK)
695 DC_LOG_ERROR("Failed to execute external encoder action: 0x%x\n", action);
696}
697
698static void
699dce110_prepare_ddc(struct dc_link *link)
700{
701 if (link->ext_enc_id.id)
702 dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_DDC_SETUP, link, NULL);
703}
704
705static bool
706dce110_dac_load_detect(struct dc_link *link)
707{
708 struct dc_bios *bios = link->ctx->dc_bios;
709 struct link_encoder *link_enc = link->link_enc;
710 enum bp_result bp_result;
711
712 bp_result = bios->funcs->dac_load_detection(
713 bios, link_enc->analog_engine, link->ext_enc_id);
714 return bp_result == BP_RESULT_OK;
715}
716
663void dce110_enable_stream(struct pipe_ctx *pipe_ctx)717void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
664{718{
665 enum dc_lane_count lane_count =719 enum dc_lane_count lane_count =
@@ -690,6 +744,8 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) · 24 unmodified lines
690 744
691 tg->funcs->set_early_control(tg, early_control);745 tg->funcs->set_early_control(tg, early_control);
692 746
747 if (link->ext_enc_id.id)
748 dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_ENABLE, link, timing);
693}749}
694 750
695static enum bp_result link_transmitter_control(751static enum bp_result link_transmitter_control(
@@ -1183,6 +1239,9 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) · 487 unmodified lines
1183 dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,1239 dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
1184 link_enc->transmitter - TRANSMITTER_UNIPHY_A);1240 link_enc->transmitter - TRANSMITTER_UNIPHY_A);
1185 }1241 }
1242
1243 if (link->ext_enc_id.id)
1244 dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_DISABLE, link, NULL);
1186}1245}
1187 1246
1188void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,1247void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
@@ -3317,6 +3376,11 @@ void dce110_enable_dp_link_output( · 2128 unmodified lines
3317 }3376 }
3318 }3377 }
3319 3378
3379 if (link->ext_enc_id.id) {
3380 dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_INIT, link, NULL);
3381 dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_SETUP, link, NULL);
3382 }
3383
3320 if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {3384 if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
3321 if (dc->clk_mgr->funcs->notify_link_rate_change)3385 if (dc->clk_mgr->funcs->notify_link_rate_change)
3322 dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);3386 dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
@@ -3409,6 +3473,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { · 86 unmodified lines
3409 .enable_dp_link_output = dce110_enable_dp_link_output,3473 .enable_dp_link_output = dce110_enable_dp_link_output,
3410 .enable_analog_link_output = dce110_enable_analog_link_output,3474 .enable_analog_link_output = dce110_enable_analog_link_output,
3411 .disable_link_output = dce110_disable_link_output,3475 .disable_link_output = dce110_disable_link_output,
3476 .dac_load_detect = dce110_dac_load_detect,
3477 .prepare_ddc = dce110_prepare_ddc,
3412};3478};
3413 3479
3414static const struct hwseq_private_funcs dce110_private_funcs = {3480static const struct hwseq_private_funcs dce110_private_funcs = {
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c+26−3
@@ -72,7 +72,11 @@ void dcn401_initialize_min_clocks(struct dc *dc) · 71 unmodified lines
72 * audio corruption. Read current DISPCLK from DENTIST and request the same72 * audio corruption. Read current DISPCLK from DENTIST and request the same
73 * freq to ensure that the timing is valid and unchanged.73 * freq to ensure that the timing is valid and unchanged.
74 */74 */
75 clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);75 if (dc->clk_mgr->funcs->get_dispclk_from_dentist) {
76 clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);
77 } else {
78 clocks->dispclk_khz = dc->clk_mgr->boot_snapshot.dispclk * 1000;
79 }
76 }80 }
77 clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;81 clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
78 clocks->fclk_p_state_change_support = true;82 clocks->fclk_p_state_change_support = true;
@@ -1202,6 +1206,25 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) · 1123 unmodified lines
1202 x_pos = pos_cpy.x - param.recout.x;1206 x_pos = pos_cpy.x - param.recout.x;
1203 y_pos = pos_cpy.y - param.recout.y;1207 y_pos = pos_cpy.y - param.recout.y;
1204 1208
1209 /**
1210 * If the cursor position is negative after recout adjustment, we need
1211 * to shift the hotspot to compensate and clamp position to 0. This
1212 * handles the case where cursor straddles the left/top edge of an
1213 * overlay plane - the cursor is partially visible and needs correct
1214 * hotspot adjustment to render the visible portion.
1215 */
1216 if (x_pos < 0) {
1217 pos_cpy.x_hotspot -= x_pos;
1218 if (hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION)
1219 adjust_hotspot_between_slices_for_2x_magnify(hubp->curs_attr.width, &pos_cpy);
1220 x_pos = 0;
1221 }
1222
1223 if (y_pos < 0) {
1224 pos_cpy.y_hotspot -= y_pos;
1225 y_pos = 0;
1226 }
1227
1205 recout_x_pos = x_pos - pos_cpy.x_hotspot;1228 recout_x_pos = x_pos - pos_cpy.x_hotspot;
1206 recout_y_pos = y_pos - pos_cpy.y_hotspot;1229 recout_y_pos = y_pos - pos_cpy.y_hotspot;
1207 1230
@@ -1464,7 +1487,7 @@ void dcn401_optimize_bandwidth( · 256 unmodified lines
1464 dc->clk_mgr,1487 dc->clk_mgr,
1465 context,1488 context,
1466 true);1489 true);
1467 if (context->bw_ctx.bw.dcn.clk.zstate_support == DCN_ZSTATE_SUPPORT_ALLOW) {1490 if (context->bw_ctx.bw.dcn.clk.zstate_support != DCN_ZSTATE_SUPPORT_DISALLOW) {
1468 for (i = 0; i < dc->res_pool->pipe_count; ++i) {1491 for (i = 0; i < dc->res_pool->pipe_count; ++i) {
1469 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];1492 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
1470 1493
@@ -1472,7 +1495,7 @@ void dcn401_optimize_bandwidth( · 1 unmodified line
1472 && pipe_ctx->stream->adjust.v_total_min == pipe_ctx->stream->adjust.v_total_max1495 && pipe_ctx->stream->adjust.v_total_min == pipe_ctx->stream->adjust.v_total_max
1473 && pipe_ctx->stream->adjust.v_total_max > pipe_ctx->stream->timing.v_total)1496 && pipe_ctx->stream->adjust.v_total_max > pipe_ctx->stream->timing.v_total)
1474 pipe_ctx->plane_res.hubp->funcs->program_extended_blank(pipe_ctx->plane_res.hubp,1497 pipe_ctx->plane_res.hubp->funcs->program_extended_blank(pipe_ctx->plane_res.hubp,
1475 pipe_ctx->dlg_regs.min_dst_y_next_start);1498 pipe_ctx->hubp_regs.dlg_regs.min_dst_y_next_start);
1476 }1499 }
1477 }1500 }
1478}1501}
drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c+1472−0
@@ -0,0 +1,1472 @@
1// SPDX-License-Identifier: MIT
2//
3// Copyright 2026 Advanced Micro Devices, Inc.
4
5#include "dm_services.h"
6#include "dm_helpers.h"
7#include "core_types.h"
8#include "resource.h"
9#include "dccg.h"
10#include "dce/dce_hwseq.h"
11#include "dcn30/dcn30_cm_common.h"
12#include "reg_helper.h"
13#include "abm.h"
14#include "hubp.h"
15#include "dchubbub.h"
16#include "timing_generator.h"
17#include "opp.h"
18#include "ipp.h"
19#include "mpc.h"
20#include "mcif_wb.h"
21#include "dc_dmub_srv.h"
22#include "link_hwss.h"
23#include "dpcd_defs.h"
24#include "dcn401/dcn401_hwseq.h"
25#include "dcn42_hwseq.h"
26#include "clk_mgr.h"
27#include "dsc.h"
28#include "dcn20/dcn20_optc.h"
29#include "dce/dmub_hw_lock_mgr.h"
30#include "dcn42/dcn42_resource.h"
31#include "link_service.h"
32#include "../dcn10/dcn10_hwseq.h"
33#include "../dcn20/dcn20_hwseq.h"
34#include "dc_state_priv.h"
35#include "dc_stream_priv.h"
36#include "dcn35/dcn35_hwseq.h"
37#include "dcn42/dcn42_hwseq.h"
38#include "dce/dmub_hw_lock_mgr.h"
39#include "dio/dcn10/dcn10_dio.h"
40
41#define DC_LOGGER \
42 ctx->logger
43
44#define CTX \
45 hws->ctx
46
47#define REG(reg)\
48 hws->regs->reg
49
50#undef FN
51#define FN(reg_name, field_name) \
52 hws->shifts->field_name, hws->masks->field_name
53
54
55static void print_pg_status(struct dc *dc, const char *debug_func, const char *debug_log)
56{
57 if (dc->debug.enable_pg_cntl_debug_logs && dc->res_pool->pg_cntl) {
58 if (dc->res_pool->pg_cntl->funcs->print_pg_status)
59 dc->res_pool->pg_cntl->funcs->print_pg_status(dc->res_pool->pg_cntl, debug_func, debug_log);
60 }
61}
62void dcn42_init_hw(struct dc *dc)
63{
64 struct abm **abms = dc->res_pool->multiple_abms;
65 struct dce_hwseq *hws = dc->hwseq;
66 struct dc_bios *dcb = dc->ctx->dc_bios;
67 struct resource_pool *res_pool = dc->res_pool;
68 int i;
69 int edp_num;
70 uint32_t backlight = MAX_BACKLIGHT_LEVEL;
71 uint32_t user_level = MAX_BACKLIGHT_LEVEL;
72 int current_dchub_ref_freq = 0;
73
74 if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) {
75 dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
76
77 // mark dcmode limits present if any clock has distinct AC and DC values from SMU
78 dc->caps.dcmode_power_limits_present = dc->clk_mgr->funcs->is_dc_mode_present &&
79 dc->clk_mgr->funcs->is_dc_mode_present(dc->clk_mgr);
80 }
81
82 // Initialize the dccg
83 if (res_pool->dccg->funcs->dccg_init)
84 res_pool->dccg->funcs->dccg_init(res_pool->dccg);
85
86 // Disable DMUB Initialization until IPS state programming is finalized
87 //if (!dcb->funcs->is_accelerated_mode(dcb)) {
88 // hws->funcs.bios_golden_init(dc);
89 //}
90
91 // Set default OPTC memory power states
92 if (dc->debug.enable_mem_low_power.bits.optc) {
93 // Shutdown when unassigned and light sleep in VBLANK
94 REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
95 }
96
97 if (dc->debug.enable_mem_low_power.bits.vga) {
98 // Power down VGA memory
99 REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
100 }
101
102 if (dc->ctx->dc_bios->fw_info_valid) {
103 res_pool->ref_clocks.xtalin_clock_inKhz =
104 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
105
106 if (res_pool->hubbub) {
107 (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
108 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
109 &res_pool->ref_clocks.dccg_ref_clock_inKhz);
110
111 current_dchub_ref_freq = res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
112
113 (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
114 res_pool->ref_clocks.dccg_ref_clock_inKhz,
115 &res_pool->ref_clocks.dchub_ref_clock_inKhz);
116 } else {
117 // Not all ASICs have DCCG sw component
118 res_pool->ref_clocks.dccg_ref_clock_inKhz =
119 res_pool->ref_clocks.xtalin_clock_inKhz;
120 res_pool->ref_clocks.dchub_ref_clock_inKhz =
121 res_pool->ref_clocks.xtalin_clock_inKhz;
122 }

1350 more lines aren’t shown here.

drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h+53−0

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

drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c+167−0

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

drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.h+11−0

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

drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h+22−1

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

drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h+4−1

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

drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h+23−1

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

drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h+47−16

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

drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h+9−1

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

drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h+19−1

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

drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h+3−1

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

drivers/gpu/drm/amd/display/dc/irq/Makefile+9−0

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

drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.c+412−0

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

drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.h+15−0

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

drivers/gpu/drm/amd/display/dc/link/link_detection.c+27−31

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

drivers/gpu/drm/amd/display/dc/link/link_dpms.c+249−391

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

drivers/gpu/drm/amd/display/dc/link/link_factory.c+28−1

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

drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c+2−0

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

drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c+1−1

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

drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c+1−1

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

drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c+2−6

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

drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile+9−1

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

drivers/gpu/drm/amd/display/dc/mmhubbub/dcn42/dcn42_mmhubbub.c+25−0

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

drivers/gpu/drm/amd/display/dc/mmhubbub/dcn42/dcn42_mmhubbub.h+13−0

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

drivers/gpu/drm/amd/display/dc/mpc/Makefile+9−1

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

drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c+12−1

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

drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h+9−1

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

drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c+1121−0

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

drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h+1006−0

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

drivers/gpu/drm/amd/display/dc/optc/Makefile+9−1

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

drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h+19−1

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

drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.c+198−0

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

drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.h+211−0

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

drivers/gpu/drm/amd/display/dc/pg/Makefile+9−1

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

drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c+648−0

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

drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.h+175−0

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

drivers/gpu/drm/amd/display/dc/resource/Makefile+18−0

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

drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c+1−1

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

drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c+2337−0

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

drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.h+588−0

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

drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource_fpu.c+47−0

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

drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource_fpu.hrenamed from drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.h+7−10

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

drivers/gpu/drm/amd/display/dmub/dmub_srv.h+4−1

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

drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h+54−0

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

drivers/gpu/drm/amd/display/dmub/src/Makefile+2−1

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

drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.c+752−0

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

drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.h+171−0

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

drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c+62−2

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

drivers/gpu/drm/amd/display/include/bios_parser_types.h+2−0

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

drivers/gpu/drm/amd/display/include/dal_asic_id.h+1−0

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

drivers/gpu/drm/amd/display/include/dal_types.h+1−0

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

drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_2_0_offset.h+17872−0

This diff is large: its 17873 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.