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
219219 Danilo Krummrich <dakr@kernel.org> <dakr@redhat.com>
220220 David Brownell <david-b@pacbell.net>
221221 David Collins <quic_collinsd@quicinc.com> <collinsd@codeaurora.org>
222+David Gow <david@davidgow.net> <davidgow@google.com>
222223 David Heidelberg <david@ixit.cz> <d.okias@gmail.com>
223224 David Hildenbrand <david@kernel.org> <david@redhat.com>
224225 David Rheinsberg <david@readahead.eu> <dh.herrmann@gmail.com>
@@ -353,6 +354,7 @@ Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@opinsys.com> · 128 unmodified lines
353354 Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com>
354355 Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com>
355356 Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
357+Jason Xing <kerneljasonxing@gmail.com> <kernelxing@tencent.com>
356358 <javier@osg.samsung.com> <javier.martinez@collabora.co.uk>
357359 Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>
358360 Jayachandran C <c.jayachandran@gmail.com> <jayachandranc@netlogicmicro.com>
@@ -401,6 +403,7 @@ Jiri Slaby <jirislaby@kernel.org> <xslaby@fi.muni.cz> · 42 unmodified lines
401403 Jisheng Zhang <jszhang@kernel.org> <jszhang@marvell.com>
402404 Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com>
403405 Jishnu Prakash <quic_jprakash@quicinc.com> <jprakash@codeaurora.org>
406+Joe Damato <joe@dama.to> <jdamato@fastly.com>
404407 Joel Granados <joel.granados@kernel.org> <j.granados@samsung.com>
405408 Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
406409 Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
CREDITS+8−0
@@ -1242,6 +1242,10 @@ N: Veaceslav Falico · 1241 unmodified lines
12421242 E: vfalico@gmail.com
12431243 D: Co-maintainer and co-author of the network bonding driver.
12441244
1245+N: Thomas Falcon
1246+E: tlfalcon@linux.ibm.com
1247+D: Initial author of the IBM ibmvnic network driver
1248+
12451249 N: János Farkas
12461250 E: chexum@shadow.banki.hu
12471251 D: romfs, various (mostly networking) fixes
@@ -2415,6 +2419,10 @@ S: Am Muehlenweg 38 · 1167 unmodified lines
24152419 S: D53424 Remagen
24162420 S: Germany
24172421
2422+N: Jonathan Lemon
2423+E: jonathan.lemon@gmail.com
2424+D: OpenCompute PTP clock driver (ptp_ocp)
2425+
24182426 N: Colin Leroy
24192427 E: colin@colino.net
24202428 W: http://www.geekounet.org/
Documentation/ABI/testing/sysfs-driver-uniwill-laptop+5−5
@@ -1,4 +1,4 @@
1−What: /sys/bus/platform/devices/INOU0000:XX/fn_lock_toggle_enable
1+What: /sys/bus/platform/devices/INOU0000:XX/fn_lock
22 Date: November 2025
33 KernelVersion: 6.19
44 Contact: Armin Wolf <W_Armin@gmx.de>
@@ -8,15 +8,15 @@ Description: · 3 unmodified lines
88
99 Reading this file returns the current enable status of the FN lock functionality.
1010
11−What: /sys/bus/platform/devices/INOU0000:XX/super_key_toggle_enable
11+What: /sys/bus/platform/devices/INOU0000:XX/super_key_enable
1212 Date: November 2025
1313 KernelVersion: 6.19
1414 Contact: Armin Wolf <W_Armin@gmx.de>
1515 Description:
16− Allows userspace applications to enable/disable the super key functionality
17− of the integrated keyboard by writing "1"/"0" into this file.
16+ Allows userspace applications to enable/disable the super key of the integrated
17+ keyboard by writing "1"/"0" into this file.
1818
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.
2020
2121 What: /sys/bus/platform/devices/INOU0000:XX/touchpad_toggle_enable
2222 Date: November 2025
Documentation/admin-guide/kernel-parameters.txt+13−0
@@ -74,6 +74,7 @@ · 73 unmodified lines
7474 TPM TPM drivers are enabled.
7575 UMS USB Mass Storage support is enabled.
7676 USB USB support is enabled.
77+ NVME NVMe support is enabled
7778 USBHID USB Human Interface Device support is enabled.
7879 V4L Video For Linux support is enabled.
7980 VGA The VGA console has been enabled.
@@ -4787,6 +4788,18 @@ Kernel parameters · 4707 unmodified lines
47874788 This can be set from sysctl after boot.
47884789 See Documentation/admin-guide/sysctl/vm.rst for details.
47894790
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+
47904803 ohci1394_dma=early [HW,EARLY] enable debugging via the ohci1394 driver.
47914804 See Documentation/core-api/debugging-via-ohci1394.rst for more
47924805 info.
Documentation/admin-guide/laptops/uniwill-laptop.rst+1−1
@@ -24,7 +24,7 @@ Keyboard settings · 23 unmodified lines
2424
2525 The ``uniwill-laptop`` driver allows the user to enable/disable:
2626
27− - the FN and super key lock functionality of the integrated keyboard
27+ - the FN lock and super key of the integrated keyboard
2828 - the touchpad toggle functionality of the integrated touchpad
2929
3030 See 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
1616 properties:
1717 compatible:
1818 enum:
19− - kontron,sa67mcu-hwmon
2019 - kontron,sl28cpld-fan
2120
2221 reg:
Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml+1−0
@@ -87,6 +87,7 @@ required: · 86 unmodified lines
8787
8888 allOf:
8989 - $ref: can-controller.yaml#
90+ - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml
9091 - if:
9192 properties:
9293 compatible:
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml+1−0
@@ -23,6 +23,7 @@ properties: · 22 unmodified lines
2323 enum:
2424 - nvidia,tegra210-audio-graph-card
2525 - nvidia,tegra186-audio-graph-card
26+ - nvidia,tegra238-audio-graph-card
2627 - nvidia,tegra264-audio-graph-card
2728
2829 clocks:
Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml+1−0
@@ -20,6 +20,7 @@ properties: · 19 unmodified lines
2020 - renesas,r9a07g044-ssi # RZ/G2{L,LC}
2121 - renesas,r9a07g054-ssi # RZ/V2L
2222 - renesas,r9a08g045-ssi # RZ/G3S
23+ - renesas,r9a08g046-ssi # RZ/G3L
2324 - const: renesas,rz-ssi
2425
2526 reg:
Documentation/hwmon/emc1403.rst+1−1
@@ -57,7 +57,7 @@ Supported chips: · 56 unmodified lines
5757 - https://ww1.microchip.com/downloads/en/DeviceDoc/EMC1438%20DS%20Rev.%201.0%20(04-29-10).pdf
5858
5959 Author:
60− Kalhan Trisal <kalhan.trisal@intel.com
60+ Kalhan Trisal <kalhan.trisal@intel.com>
6161
6262
6363 Description
Documentation/hwmon/index.rst+0−1
@@ -220,7 +220,6 @@ Hardware Monitoring Kernel Drivers · 219 unmodified lines
220220 q54sj108a2
221221 qnap-mcu-hwmon
222222 raspberrypi-hwmon
223− sa67
224223 sbrmi
225224 sbtsi_temp
226225 sch5627
Documentation/hwmon/sa67.rst+0−41
@@ -1,41 +0,0 @@
1−.. SPDX-License-Identifier: GPL-2.0-only
2−
3−Kernel driver sa67mcu
4−=====================
5−
6−Supported chips:
7−
8− * Kontron sa67mcu
9−
10− Prefix: 'sa67mcu'
11−
12− Datasheet: not available
13−
14−Authors: Michael Walle <mwalle@kernel.org>
15−
16−Description
17−-----------
18−
19−The sa67mcu is a board management controller which also exposes a hardware
20−monitoring controller.
21−
22−The controller has two voltage and one temperature sensor. The values are
23−hold in two 8 bit registers to form one 16 bit value. Reading the lower byte
24−will also capture the high byte to make the access atomic. The unit of the
25−volatge sensors are 1mV and the unit of the temperature sensor is 0.1degC.
26−
27−Sysfs entries
28−-------------
29−
30−The following attributes are supported.
31−
32−======================= ========================================================
33−in0_label "VDDIN"
34−in0_input Measured VDDIN voltage.
35−
36−in1_label "VDD_RTC"
37−in1_input Measured VDD_RTC voltage.
38−
39−temp1_input MCU temperature. Roughly the board temperature.
40−======================= ========================================================
41−
Documentation/netlink/specs/nfsd.yaml+2−2
@@ -152,7 +152,7 @@ operations: · 151 unmodified lines
152152 - compound-ops
153153 -
154154 name: threads-set
155− doc: set the number of running threads
155+ doc: set the maximum number of running threads
156156 attribute-set: server
157157 flags: [admin-perm]
158158 do:
@@ -165,7 +165,7 @@ operations: · 6 unmodified lines
165165 - min-threads
166166 -
167167 name: threads-get
168− doc: get the number of running threads
168+ doc: get the maximum number of running threads
169169 attribute-set: server
170170 do:
171171 reply:
Documentation/sound/alsa-configuration.rst+4−0
@@ -2372,6 +2372,10 @@ quirk_flags · 2371 unmodified lines
23722372 audible volume
23732373 * bit 25: ``mixer_capture_min_mute``
23742374 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
23752379
23762380 This module supports multiple devices, autoprobe and hotplugging.
23772381
MAINTAINERS+10−27
@@ -993,10 +993,8 @@ F: Documentation/devicetree/bindings/thermal/amazon,al-thermal.yaml · 992 unmodified lines
993993 F: drivers/thermal/thermal_mmio.c
994994
995995 AMAZON ETHERNET DRIVERS
996−M: Shay Agroskin <shayagr@amazon.com>
997996 M: Arthur Kiyanovski <akiyano@amazon.com>
998−R: David Arinzon <darinzon@amazon.com>
999−R: Saeed Bishara <saeedb@amazon.com>
997+M: David Arinzon <darinzon@amazon.com>
1000998 L: netdev@vger.kernel.org
1001999 S: Maintained
10021000 F: Documentation/networking/device_drivers/ethernet/amazon/ena.rst
@@ -4617,7 +4615,6 @@ F: drivers/bluetooth/ · 3614 unmodified lines
46174615
46184616 BLUETOOTH SUBSYSTEM
46194617 M: Marcel Holtmann <marcel@holtmann.org>
4620−M: Johan Hedberg <johan.hedberg@gmail.com>
46214618 M: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
46224619 L: linux-bluetooth@vger.kernel.org
46234620 S: Supported
@@ -10187,8 +10184,8 @@ F: drivers/i2c/busses/i2c-cpm.c · 5563 unmodified lines
1018710184
1018810185 FREESCALE IMX / MXC FEC DRIVER
1018910186 M: Wei Fang <wei.fang@nxp.com>
10187+R: Frank Li <frank.li@nxp.com>
1019010188 R: Shenwei Wang <shenwei.wang@nxp.com>
10191−R: Clark Wang <xiaoning.wang@nxp.com>
1019210189 L: imx@lists.linux.dev
1019310190 L: netdev@vger.kernel.org
1019410191 S: Maintained
@@ -10500,7 +10497,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git · 305 unmodified lines
1050010497 F: Documentation/trace/ftrace*
1050110498 F: arch/*/*/*/*ftrace*
1050210499 F: arch/*/*/*ftrace*
10503−F: include/*/ftrace.h
10500+F: include/*/*ftrace*
1050410501 F: kernel/trace/fgraph.c
1050510502 F: kernel/trace/ftrace*
1050610503 F: samples/ftrace
@@ -12233,7 +12230,6 @@ IBM Power SRIOV Virtual NIC Device Driver · 1726 unmodified lines
1223312230 M: Haren Myneni <haren@linux.ibm.com>
1223412231 M: Rick Lindsley <ricklind@linux.ibm.com>
1223512232 R: Nick Child <nnac123@linux.ibm.com>
12236−R: Thomas Falcon <tlfalcon@linux.ibm.com>
1223712233 L: netdev@vger.kernel.org
1223812234 S: Maintained
1223912235 F: drivers/net/ethernet/ibm/ibmvnic.*
@@ -13958,7 +13954,7 @@ F: fs/smb/server/ · 1718 unmodified lines
1395813954
1395913955 KERNEL UNIT TESTING FRAMEWORK (KUnit)
1396013956 M: Brendan Higgins <brendan.higgins@linux.dev>
13961−M: David Gow <davidgow@google.com>
13957+M: David Gow <david@davidgow.net>
1396213958 R: Rae Moar <raemoar63@gmail.com>
1396313959 L: linux-kselftest@vger.kernel.org
1396413960 L: kunit-dev@googlegroups.com
@@ -14778,7 +14774,7 @@ F: drivers/misc/lis3lv02d/ · 813 unmodified lines
1477814774 F: drivers/platform/x86/hp/hp_accel.c
1477914775
1478014776 LIST KUNIT TEST
14781−M: David Gow <davidgow@google.com>
14777+M: David Gow <david@davidgow.net>
1478214778 L: linux-kselftest@vger.kernel.org
1478314779 L: kunit-dev@googlegroups.com
1478414780 S: Maintained
@@ -15391,10 +15387,8 @@ F: drivers/crypto/marvell/ · 606 unmodified lines
1539115387 F: include/linux/soc/marvell/octeontx2/
1539215388
1539315389 MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)
15394−M: Mirko Lindner <mlindner@marvell.com>
15395−M: Stephen Hemminger <stephen@networkplumber.org>
1539615390 L: netdev@vger.kernel.org
15397−S: Odd fixes
15391+S: Orphan
1539815392 F: drivers/net/ethernet/marvell/sk*
1539915393
1540015394 MARVELL LIBERTAS WIRELESS DRIVER
@@ -15491,7 +15485,6 @@ MARVELL OCTEONTX2 RVU ADMIN FUNCTION DRIVER · 90 unmodified lines
1549115485 M: Sunil Goutham <sgoutham@marvell.com>
1549215486 M: Linu Cherian <lcherian@marvell.com>
1549315487 M: Geetha sowjanya <gakula@marvell.com>
15494−M: Jerin Jacob <jerinj@marvell.com>
1549515488 M: hariprasad <hkelam@marvell.com>
1549615489 M: Subbaraya Sundeep <sbhatta@marvell.com>
1549715490 L: netdev@vger.kernel.org
@@ -15506,7 +15499,7 @@ S: Supported · 8 unmodified lines
1550615499 F: drivers/perf/marvell_pem_pmu.c
1550715500
1550815501 MARVELL PRESTERA ETHERNET SWITCH DRIVER
15509−M: Taras Chornyi <taras.chornyi@plvision.eu>
15502+M: Elad Nachman <enachman@marvell.com>
1551015503 S: Supported
1551115504 W: https://github.com/Marvell-switching/switchdev-prestera
1551215505 F: drivers/net/ethernet/marvell/prestera/
@@ -16180,7 +16173,6 @@ F: drivers/dma/mediatek/ · 667 unmodified lines
1618016173
1618116174 MEDIATEK ETHERNET DRIVER
1618216175 M: Felix Fietkau <nbd@nbd.name>
16183−M: Sean Wang <sean.wang@mediatek.com>
1618416176 M: Lorenzo Bianconi <lorenzo@kernel.org>
1618516177 L: netdev@vger.kernel.org
1618616178 S: Maintained
@@ -16373,8 +16365,6 @@ F: include/soc/mediatek/smi.h · 186 unmodified lines
1637316365 MEDIATEK SWITCH DRIVER
1637416366 M: Chester A. Unal <chester.a.unal@arinc9.com>
1637516367 M: Daniel Golle <daniel@makrotopia.org>
16376−M: DENG Qingfang <dqfext@gmail.com>
16377−M: Sean Wang <sean.wang@mediatek.com>
1637816368 L: netdev@vger.kernel.org
1637916369 S: Maintained
1638016370 F: drivers/net/dsa/mt7530-mdio.c
@@ -19242,8 +19232,6 @@ F: tools/objtool/ · 2861 unmodified lines
1924219232
1924319233 OCELOT ETHERNET SWITCH DRIVER
1924419234 M: Vladimir Oltean <vladimir.oltean@nxp.com>
19245−M: Claudiu Manoil <claudiu.manoil@nxp.com>
19246−M: Alexandre Belloni <alexandre.belloni@bootlin.com>
1924719235 M: UNGLinuxDriver@microchip.com
1924819236 L: netdev@vger.kernel.org
1924919237 S: Supported
@@ -19829,7 +19817,6 @@ F: arch/*/boot/dts/ · 579 unmodified lines
1982919817 F: include/dt-bindings/
1983019818
1983119819 OPENCOMPUTE PTP CLOCK DRIVER
19832−M: Jonathan Lemon <jonathan.lemon@gmail.com>
1983319820 M: Vadim Fedorenko <vadim.fedorenko@linux.dev>
1983419821 L: netdev@vger.kernel.org
1983519822 S: Maintained
@@ -20137,9 +20124,8 @@ F: Documentation/devicetree/bindings/pci/marvell,armada-3700-pcie.yaml · 301 unmodified lines
2013720124 F: drivers/pci/controller/pci-aardvark.c
2013820125
2013920126 PCI DRIVER FOR ALTERA PCIE IP
20140−M: Joyce Ooi <joyce.ooi@intel.com>
2014120127 L: linux-pci@vger.kernel.org
20142−S: Supported
20128+S: Orphan
2014320129 F: Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml
2014420130 F: drivers/pci/controller/pcie-altera.c
2014520131
@@ -20384,9 +20370,8 @@ S: Supported · 238 unmodified lines
2038420370 F: Documentation/PCI/pci-error-recovery.rst
2038520371
2038620372 PCI MSI DRIVER FOR ALTERA MSI IP
20387−M: Joyce Ooi <joyce.ooi@intel.com>
2038820373 L: linux-pci@vger.kernel.org
20389−S: Supported
20374+S: Orphan
2039020375 F: Documentation/devicetree/bindings/interrupt-controller/altr,msi-controller.yaml
2039120376 F: drivers/pci/controller/pcie-altera-msi.c
2039220377
@@ -21473,9 +21458,8 @@ S: Supported · 1080 unmodified lines
2147321458 F: drivers/scsi/qedi/
2147421459
2147521460 QLOGIC QL4xxx ETHERNET DRIVER
21476−M: Manish Chopra <manishc@marvell.com>
2147721461 L: netdev@vger.kernel.org
21478−S: Maintained
21462+S: Orphan
2147921463 F: drivers/net/ethernet/qlogic/qed/
2148021464 F: drivers/net/ethernet/qlogic/qede/
2148121465 F: include/linux/qed/
@@ -24353,7 +24337,6 @@ F: Documentation/devicetree/bindings/interrupt-controller/kontron,sl28cpld-intc. · 2871 unmodified lines
2435324337 F: Documentation/devicetree/bindings/pwm/kontron,sl28cpld-pwm.yaml
2435424338 F: Documentation/devicetree/bindings/watchdog/kontron,sl28cpld-wdt.yaml
2435524339 F: drivers/gpio/gpio-sl28cpld.c
24356−F: drivers/hwmon/sa67mcu-hwmon.c
2435724340 F: drivers/hwmon/sl28cpld-hwmon.c
2435824341 F: drivers/irqchip/irq-sl28cpld.c
2435924342 F: drivers/pwm/pwm-sl28cpld.c
Makefile+5−5
@@ -2,7 +2,7 @@ · 1 unmodified line
22 VERSION = 7
33 PATCHLEVEL = 0
44 SUBLEVEL = 0
5−EXTRAVERSION = -rc2
5+EXTRAVERSION = -rc3
66 NAME = Baby Opossum Posse
77
88 # *DOCUMENTATION*
@@ -1497,13 +1497,13 @@ ifneq ($(wildcard $(resolve_btfids_O)),) · 1488 unmodified lines
14971497 $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean
14981498 endif
14991499
1500−PHONY += objtool_clean
1500+PHONY += objtool_clean objtool_mrproper
15011501
15021502 objtool_O = $(abspath $(objtree))/tools/objtool
15031503
1504−objtool_clean:
1504+objtool_clean objtool_mrproper:
15051505 ifneq ($(wildcard $(objtool_O)),)
1506− $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean
1506+ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) $(patsubst objtool_%,%,$@)
15071507 endif
15081508
15091509 tools/: FORCE
@@ -1686,7 +1686,7 @@ PHONY += $(mrproper-dirs) mrproper · 176 unmodified lines
16861686 $(mrproper-dirs):
16871687 $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
16881688
1689−mrproper: clean $(mrproper-dirs)
1689+mrproper: clean objtool_mrproper $(mrproper-dirs)
16901690 $(call cmd,rmfiles)
16911691 @find . $(RCS_FIND_IGNORE) \
16921692 \( -name '*.rmeta' \) \
arch/alpha/kernel/vmlinux.lds.S+1−0
@@ -71,6 +71,7 @@ SECTIONS · 70 unmodified lines
7171
7272 STABS_DEBUG
7373 DWARF_DEBUG
74+ MODINFO
7475 ELF_DETAILS
7576
7677 DISCARDS
arch/arc/kernel/vmlinux.lds.S+1−0
@@ -123,6 +123,7 @@ SECTIONS · 122 unmodified lines
123123 _end = . ;
124124
125125 STABS_DEBUG
126+ MODINFO
126127 ELF_DETAILS
127128 DISCARDS
128129
arch/arm/boot/compressed/vmlinux.lds.S+1−0
@@ -21,6 +21,7 @@ SECTIONS · 20 unmodified lines
2121 COMMON_DISCARDS
2222 *(.ARM.exidx*)
2323 *(.ARM.extab*)
24+ *(.modinfo)
2425 *(.note.*)
2526 *(.rel.*)
2627 *(.printk_index)
arch/arm/kernel/vmlinux-xip.lds.S+1−0
@@ -154,6 +154,7 @@ SECTIONS · 153 unmodified lines
154154
155155 STABS_DEBUG
156156 DWARF_DEBUG
157+ MODINFO
157158 ARM_DETAILS
158159
159160 ARM_ASSERTS
arch/arm/kernel/vmlinux.lds.S+1−0
@@ -153,6 +153,7 @@ SECTIONS · 152 unmodified lines
153153
154154 STABS_DEBUG
155155 DWARF_DEBUG
156+ MODINFO
156157 ARM_DETAILS
157158
158159 ARM_ASSERTS
arch/arm64/include/asm/cmpxchg.h+7−5
@@ -91,8 +91,9 @@ __XCHG_GEN(_mb) · 90 unmodified lines
9191 #define __xchg_wrapper(sfx, ptr, x) \
9292 ({ \
9393 __typeof__(*(ptr)) __ret; \
94− __ret = (__typeof__(*(ptr))) \
95− __arch_xchg##sfx((unsigned long)(x), (ptr), sizeof(*(ptr))); \
94+ __ret = (__force __typeof__(*(ptr))) \
95+ __arch_xchg##sfx((__force unsigned long)(x), (ptr), \
96+ sizeof(*(ptr))); \
9697 __ret; \
9798 })
9899
@@ -175,9 +176,10 @@ __CMPXCHG_GEN(_mb) · 76 unmodified lines
175176 #define __cmpxchg_wrapper(sfx, ptr, o, n) \
176177 ({ \
177178 __typeof__(*(ptr)) __ret; \
178− __ret = (__typeof__(*(ptr))) \
179− __cmpxchg##sfx((ptr), (unsigned long)(o), \
180− (unsigned long)(n), sizeof(*(ptr))); \
179+ __ret = (__force __typeof__(*(ptr))) \
180+ __cmpxchg##sfx((ptr), (__force unsigned long)(o), \
181+ (__force unsigned long)(n), \
182+ sizeof(*(ptr))); \
181183 __ret; \
182184 })
183185
arch/arm64/include/asm/pgtable-prot.h+5−5
@@ -50,11 +50,11 @@ · 49 unmodified lines
5050
5151 #define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
5252
53−#define _PAGE_KERNEL (PROT_NORMAL)
54−#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
55−#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
56−#define _PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN)
57−#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
53+#define _PAGE_KERNEL (PROT_NORMAL | PTE_DIRTY)
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 | PTE_DIRTY)
56+#define _PAGE_KERNEL_EXEC ((PROT_NORMAL & ~PTE_PXN) | PTE_DIRTY)
57+#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT | PTE_DIRTY)
5858
5959 #define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
6060 #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
22 #ifndef _ASM_RUNTIME_CONST_H
33 #define _ASM_RUNTIME_CONST_H
44
5+#ifdef MODULE
6+ #error "Cannot use runtime-const infrastructure from modules"
7+#endif
8+
59 #include <asm/cacheflush.h>
610
711 /* 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
349349
350350 STABS_DEBUG
351351 DWARF_DEBUG
352+ MODINFO
352353 ELF_DETAILS
353354
354355 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
599599 }
600600 EXPORT_SYMBOL_GPL(contpte_clear_young_dirty_ptes);
601601
602+static 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+
602623 int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
603624 unsigned long addr, pte_t *ptep,
604625 pte_t entry, int dirty)
@@ -608,13 +629,37 @@ int contpte_ptep_set_access_flags(struct vm_area_struct *vma, · 3 unmodified lines
608629 int i;
609630
610631 /*
611− * Gather the access/dirty bits for the contiguous range. If nothing has
612− * changed, its a noop.
632+ * Check whether all sub-PTEs in the CONT block already match the
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.
613654 */
614− orig_pte = pte_mknoncont(ptep_get(ptep));
615− if (pte_val(orig_pte) == pte_val(entry))
655+ if (contpte_all_subptes_match_access_flags(ptep, entry))
616656 return 0;
617657
658+ /*
659+ * Use raw target pte (not gathered) for write-bit unfold decision.
660+ */
661+ orig_pte = pte_mknoncont(__ptep_get(ptep));
662+
618663 /*
619664 * We can fix up access/dirty bits without having to unfold the contig
620665 * 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
109109
110110 STABS_DEBUG
111111 DWARF_DEBUG
112+ MODINFO
112113 ELF_DETAILS
113114
114115 DISCARDS
arch/hexagon/kernel/vmlinux.lds.S+1−0
@@ -62,6 +62,7 @@ SECTIONS · 61 unmodified lines
6262
6363 STABS_DEBUG
6464 DWARF_DEBUG
65+ MODINFO
6566 ELF_DETAILS
6667 .hexagon.attributes 0 : { *(.hexagon.attributes) }
6768
arch/loongarch/kernel/vmlinux.lds.S+1−0
@@ -147,6 +147,7 @@ SECTIONS · 146 unmodified lines
147147
148148 STABS_DEBUG
149149 DWARF_DEBUG
150+ MODINFO
150151 ELF_DETAILS
151152
152153 #ifdef CONFIG_EFI_STUB
arch/m68k/kernel/vmlinux-nommu.lds+1−0
@@ -85,6 +85,7 @@ SECTIONS { · 84 unmodified lines
8585 _end = .;
8686
8787 STABS_DEBUG
88+ MODINFO
8889 ELF_DETAILS
8990
9091 /* Sections to be discarded */
arch/m68k/kernel/vmlinux-std.lds+1−0
@@ -58,6 +58,7 @@ SECTIONS · 57 unmodified lines
5858 _end = . ;
5959
6060 STABS_DEBUG
61+ MODINFO
6162 ELF_DETAILS
6263
6364 /* Sections to be discarded */
arch/m68k/kernel/vmlinux-sun3.lds+1−0
@@ -51,6 +51,7 @@ __init_begin = .; · 50 unmodified lines
5151 _end = . ;
5252
5353 STABS_DEBUG
54+ MODINFO
5455 ELF_DETAILS
5556
5657 /* Sections to be discarded */
arch/mips/kernel/vmlinux.lds.S+1−0
@@ -217,6 +217,7 @@ SECTIONS · 216 unmodified lines
217217
218218 STABS_DEBUG
219219 DWARF_DEBUG
220+ MODINFO
220221 ELF_DETAILS
221222
222223 /* These must appear regardless of . */
arch/nios2/kernel/vmlinux.lds.S+1−0
@@ -57,6 +57,7 @@ SECTIONS · 56 unmodified lines
5757
5858 STABS_DEBUG
5959 DWARF_DEBUG
60+ MODINFO
6061 ELF_DETAILS
6162
6263 DISCARDS
arch/openrisc/kernel/vmlinux.lds.S+1−0
@@ -101,6 +101,7 @@ SECTIONS · 100 unmodified lines
101101 /* Throw in the debugging sections */
102102 STABS_DEBUG
103103 DWARF_DEBUG
104+ MODINFO
104105 ELF_DETAILS
105106
106107 /* Sections to be discarded -- must be last */
arch/parisc/boot/compressed/vmlinux.lds.S+1−0
@@ -90,6 +90,7 @@ SECTIONS · 89 unmodified lines
9090 /* Sections to be discarded */
9191 DISCARDS
9292 /DISCARD/ : {
93+ *(.modinfo)
9394 #ifdef CONFIG_64BIT
9495 /* temporary hack until binutils is fixed to not emit these
9596 * 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
8585 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
8686
8787 /* This is the size of the initially mapped kernel memory */
88−#if defined(CONFIG_64BIT)
88+#if defined(CONFIG_64BIT) || defined(CONFIG_KALLSYMS)
8989 #define KERNEL_INITIAL_ORDER 26 /* 1<<26 = 64MB */
9090 #else
9191 #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
5656
5757 .import __bss_start,data
5858 .import __bss_stop,data
59+ .import __end,data
5960
6061 load32 PA(__bss_start),%r3
6162 load32 PA(__bss_stop),%r4
@@ -149,7 +150,11 @@ $cpu_ok: · 87 unmodified lines
149150 * everything ... it will get remapped correctly later */
150151 ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
151152 load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
152− load32 PA(pg0),%r1
153+ 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 */
157+1: load32 PA(pg0),%r1
153158
154159 $pgt_fill_loop:
155160 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
120120 #endif
121121 printk(KERN_CONT ".\n");
122122
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−
131123 #ifdef CONFIG_64BIT
132124 if(parisc_narrow_firmware) {
133125 printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
@@ -279,6 +271,18 @@ void __init start_parisc(void) · 145 unmodified lines
279271 int ret, cpunum;
280272 struct pdc_coproc_cfg coproc_cfg;
281273
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+
282286 /* check QEMU/SeaBIOS marker in PAGE0 */
283287 running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0);
284288
arch/parisc/kernel/vmlinux.lds.S+1−0
@@ -165,6 +165,7 @@ SECTIONS · 164 unmodified lines
165165 _end = . ;
166166
167167 STABS_DEBUG
168+ MODINFO
168169 ELF_DETAILS
169170 .note 0 : { *(.note) }
170171
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
212212 dev->error_state = pci_channel_io_normal;
213213 dev->dma_mask = 0xffffffff;
214214
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+
215222 /* Early fixups, before probing the BARs */
216223 pci_fixup_device(pci_fixup_early, dev);
217224
arch/powerpc/kernel/vmlinux.lds.S+1−0
@@ -397,6 +397,7 @@ SECTIONS · 396 unmodified lines
397397 _end = . ;
398398
399399 DWARF_DEBUG
400+ MODINFO
400401 ELF_DETAILS
401402
402403 DISCARDS
arch/riscv/kernel/vmlinux.lds.S+1−0
@@ -170,6 +170,7 @@ SECTIONS · 169 unmodified lines
170170
171171 STABS_DEBUG
172172 DWARF_DEBUG
173+ MODINFO
173174 ELF_DETAILS
174175 .riscv.attributes 0 : { *(.riscv.attributes) }
175176
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
159159 " j 4f\n"
160160 "3: mvc 8(1,%[addr]),0(%[addr])\n"
161161 "4:"
162− : [addr] "+&a" (erase_low), [count] "+&d" (count), [tmp] "=&a" (tmp)
162+ : [addr] "+&a" (erase_low), [count] "+&a" (count), [tmp] "=&a" (tmp)
163163 : [poison] "d" (poison)
164164 : "memory", "cc"
165165 );
arch/s390/kernel/vmlinux.lds.S+1−0
@@ -221,6 +221,7 @@ SECTIONS · 220 unmodified lines
221221 /* Debugging sections. */
222222 STABS_DEBUG
223223 DWARF_DEBUG
224+ MODINFO
224225 ELF_DETAILS
225226
226227 /*
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
2828 " j 3f\n"
2929 "2: xc 0(1,%1),0(%2)\n"
3030 "3:"
31− : : "d" (bytes), "a" (p1), "a" (p2)
32− : "0", "cc", "memory");
31+ : "+a" (bytes), "+a" (p1), "+a" (p2)
32+ : : "0", "cc", "memory");
3333 }
3434
3535 static 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
5454 "2: xc 0(1,%1),0(%2)\n"
5555 "3: xc 0(1,%1),0(%3)\n"
5656 "4:"
57− : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
57+ : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
5858 : : "0", "cc", "memory");
5959 }
6060
@@ -85,7 +85,7 @@ static void xor_xc_4(unsigned long bytes, unsigned long * __restrict p1, · 24 unmodified lines
8585 "3: xc 0(1,%1),0(%3)\n"
8686 "4: xc 0(1,%1),0(%4)\n"
8787 "5:"
88− : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
88+ : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
8989 : : "0", "cc", "memory");
9090 }
9191
@@ -96,7 +96,6 @@ static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1, · 4 unmodified lines
9696 const unsigned long * __restrict p5)
9797 {
9898 asm volatile(
99− " larl 1,2f\n"
10099 " aghi %0,-1\n"
101100 " jm 6f\n"
102101 " srlg 0,%0,8\n"
@@ -122,7 +121,7 @@ static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1, · 19 unmodified lines
122121 "4: xc 0(1,%1),0(%4)\n"
123122 "5: xc 0(1,%1),0(%5)\n"
124123 "6:"
125− : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
124+ : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
126125 "+a" (p5)
127126 : : "0", "cc", "memory");
128127 }
arch/sh/kernel/vmlinux.lds.S+1−0
@@ -89,6 +89,7 @@ SECTIONS · 88 unmodified lines
8989
9090 STABS_DEBUG
9191 DWARF_DEBUG
92+ MODINFO
9293 ELF_DETAILS
9394
9495 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
355355 dev->error_state = pci_channel_io_normal;
356356 dev->dma_mask = 0xffffffff;
357357
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+
358365 if (of_node_name_eq(node, "pci")) {
359366 /* a PCI-PCI bridge */
360367 dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
arch/sparc/kernel/vmlinux.lds.S+1−0
@@ -191,6 +191,7 @@ SECTIONS · 190 unmodified lines
191191
192192 STABS_DEBUG
193193 DWARF_DEBUG
194+ MODINFO
194195 ELF_DETAILS
195196
196197 DISCARDS
arch/um/kernel/dyn.lds.S+1−0
@@ -172,6 +172,7 @@ SECTIONS · 171 unmodified lines
172172
173173 STABS_DEBUG
174174 DWARF_DEBUG
175+ MODINFO
175176 ELF_DETAILS
176177
177178 DISCARDS
arch/um/kernel/uml.lds.S+1−0
@@ -113,6 +113,7 @@ SECTIONS · 112 unmodified lines
113113
114114 STABS_DEBUG
115115 DWARF_DEBUG
116+ MODINFO
116117 ELF_DETAILS
117118
118119 DISCARDS
arch/x86/boot/compressed/Makefile+1−0
@@ -113,6 +113,7 @@ vmlinux-objs-$(CONFIG_EFI_SBAT) += $(obj)/sbat.o · 112 unmodified lines
113113
114114 ifdef CONFIG_EFI_SBAT
115115 $(obj)/sbat.o: $(CONFIG_EFI_SBAT_FILE)
116+AFLAGS_sbat.o += -I $(srctree)
116117 endif
117118
118119 $(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE
arch/x86/boot/compressed/sev.c+5−4
@@ -28,17 +28,17 @@ · 27 unmodified lines
2828 #include "sev.h"
2929
3030 static struct ghcb boot_ghcb_page __aligned(PAGE_SIZE);
31−struct ghcb *boot_ghcb;
31+struct ghcb *boot_ghcb __section(".data");
3232
3333 #undef __init
3434 #define __init
3535
3636 #define __BOOT_COMPRESSED
3737
38−u8 snp_vmpl;
39−u16 ghcb_version;
38+u8 snp_vmpl __section(".data");
39+u16 ghcb_version __section(".data");
4040
41−u64 boot_svsm_caa_pa;
41+u64 boot_svsm_caa_pa __section(".data");
4242
4343 /* Include code for early handlers */
4444 #include "../../boot/startup/sev-shared.c"
@@ -188,6 +188,7 @@ bool sev_es_check_ghcb_fault(unsigned long address) · 143 unmodified lines
188188 MSR_AMD64_SNP_RESERVED_BIT13 | \
189189 MSR_AMD64_SNP_RESERVED_BIT15 | \
190190 MSR_AMD64_SNP_SECURE_AVIC | \
191+ MSR_AMD64_SNP_RESERVED_BITS19_22 | \
191192 MSR_AMD64_SNP_RESERVED_MASK)
192193
193194 #ifdef CONFIG_AMD_SECURE_AVIC
arch/x86/boot/compressed/vmlinux.lds.S+1−1
@@ -88,7 +88,7 @@ SECTIONS · 87 unmodified lines
8888 /DISCARD/ : {
8989 *(.dynamic) *(.dynsym) *(.dynstr) *(.dynbss)
9090 *(.hash) *(.gnu.hash)
91− *(.note.*)
91+ *(.note.*) *(.modinfo)
9292 }
9393
9494 .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
3131 static u32 cpuid_hyp_range_max __ro_after_init;
3232 static u32 cpuid_ext_range_max __ro_after_init;
3333
34−bool sev_snp_needs_sfw;
34+bool sev_snp_needs_sfw __section(".data");
3535
3636 void __noreturn
3737 sev_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
8989 [MSR_AMD64_SNP_VMSA_REG_PROT_BIT] = "VMSARegProt",
9090 [MSR_AMD64_SNP_SMT_PROT_BIT] = "SMTProt",
9191 [MSR_AMD64_SNP_SECURE_AVIC_BIT] = "SecureAVIC",
92+ [MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT] = "IBPBOnEntry",
9293 };
9394
9495 /*
arch/x86/entry/vdso/vdso32/sigreturn.S+30−0
@@ -35,9 +35,38 @@ · 34 unmodified lines
3535 #endif
3636 .endm
3737
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+ */
3866 .text
3967 .globl __kernel_sigreturn
4068 .type __kernel_sigreturn,@function
69+ nop /* libgcc hack: see comment above */
4170 ALIGN
4271 __kernel_sigreturn:
4372 STARTPROC_SIGNAL_FRAME IA32_SIGFRAME_sigcontext
@@ -52,6 +81,7 @@ SYM_INNER_LABEL(vdso32_sigreturn_landing_pad, SYM_L_GLOBAL) · 8 unmodified lines
5281
5382 .globl __kernel_rt_sigreturn
5483 .type __kernel_rt_sigreturn,@function
84+ nop /* libgcc hack: see comment above */
5585 ALIGN
5686 __kernel_rt_sigreturn:
5787 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
138138 extern int __init efi_reuse_config(u64 tables, int nr_tables);
139139 extern void efi_delete_dummy_variable(void);
140140 extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr);
141−extern void efi_free_boot_services(void);
141+extern void efi_unmap_boot_services(void);
142142
143143 void arch_efi_call_virt_setup(void);
144144 void arch_efi_call_virt_teardown(void);
arch/x86/include/asm/msr-index.h+4−1
@@ -740,7 +740,10 @@ · 739 unmodified lines
740740 #define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
741741 #define MSR_AMD64_SNP_SECURE_AVIC_BIT 18
742742 #define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
743−#define MSR_AMD64_SNP_RESV_BIT 19
743+#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
744747 #define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
745748 #define MSR_AMD64_SAVIC_CONTROL 0xc0010138
746749 #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
2222 */
2323 extern s16 __apicid_to_node[MAX_LOCAL_APIC];
2424 extern nodemask_t numa_nodes_parsed __initdata;
25+extern nodemask_t numa_phys_nodes_parsed __initdata;
2526
2627 static inline void set_apicid_to_node(int apicid, s16 node)
2728 {
@@ -48,6 +49,7 @@ extern void __init init_cpu_to_node(void); · 20 unmodified lines
4849 extern void numa_add_cpu(unsigned int cpu);
4950 extern void numa_remove_cpu(unsigned int cpu);
5051 extern void init_gi_nodes(void);
52+extern int num_phys_nodes(void);
5153 #else /* CONFIG_NUMA */
5254 static inline void numa_set_node(int cpu, int node) { }
5355 static inline void numa_clear_node(int cpu) { }
@@ -55,6 +57,10 @@ static inline void init_cpu_to_node(void) { } · 1 unmodified line
5557 static inline void numa_add_cpu(unsigned int cpu) { }
5658 static inline void numa_remove_cpu(unsigned int cpu) { }
5759 static inline void init_gi_nodes(void) { }
60+static inline int num_phys_nodes(void)
61+{
62+ return 1;
63+}
5864 #endif /* CONFIG_NUMA */
5965
6066 #ifdef CONFIG_DEBUG_PER_CPU_MAPS
arch/x86/include/asm/pgtable_64.h+0−2
@@ -19,10 +19,8 @@ · 18 unmodified lines
1919 extern p4d_t level4_kernel_pgt[512];
2020 extern p4d_t level4_ident_pgt[512];
2121 extern pud_t level3_kernel_pgt[512];
22−extern pud_t level3_ident_pgt[512];
2322 extern pmd_t level2_kernel_pgt[512];
2423 extern pmd_t level2_fixmap_pgt[512];
25−extern pmd_t level2_ident_pgt[512];
2624 extern pte_t level1_fixmap_pgt[512 * FIXMAP_PMD_NUM];
2725 extern pgd_t init_top_pgt[];
2826
arch/x86/include/asm/topology.h+6−0
@@ -155,6 +155,7 @@ extern unsigned int __max_logical_packages; · 154 unmodified lines
155155 extern unsigned int __max_threads_per_core;
156156 extern unsigned int __num_threads_per_package;
157157 extern unsigned int __num_cores_per_package;
158+extern unsigned int __num_nodes_per_package;
158159
159160 const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c);
160161 enum 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
179180 return __num_threads_per_package;
180181 }
181182
183+static inline unsigned int topology_num_nodes_per_package(void)
184+{
185+ return __num_nodes_per_package;
186+}
187+
182188 #ifdef CONFIG_X86_LOCAL_APIC
183189 int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level);
184190 #else
arch/x86/kernel/cpu/common.c+3−0
@@ -95,6 +95,9 @@ EXPORT_SYMBOL(__max_dies_per_package); · 94 unmodified lines
9595 unsigned int __max_logical_packages __ro_after_init = 1;
9696 EXPORT_SYMBOL(__max_logical_packages);
9797
98+unsigned int __num_nodes_per_package __ro_after_init = 1;
99+EXPORT_SYMBOL(__num_nodes_per_package);
100+
98101 unsigned int __num_cores_per_package __ro_after_init = 1;
99102 EXPORT_SYMBOL(__num_cores_per_package);
100103
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
364364 msr_clear_bit(MSR_RMID_SNC_CONFIG, 0);
365365 }
366366
367−/* CPU models that support MSR_RMID_SNC_CONFIG */
367+/* CPU models that support SNC and MSR_RMID_SNC_CONFIG */
368368 static const struct x86_cpu_id snc_cpu_ids[] __initconst = {
369369 X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
370370 X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0),
@@ -375,40 +375,14 @@ static const struct x86_cpu_id snc_cpu_ids[] __initconst = { · 4 unmodified lines
375375 {}
376376 };
377377
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− */
388378 static __init int snc_get_config(void)
389379 {
390− struct cacheinfo *ci = get_cpu_cacheinfo_level(0, RESCTRL_L3_CACHE);
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;
380+ int ret = topology_num_nodes_per_package();
397381
398− cpus_read_lock();
399− if (num_online_cpus() != num_present_cpus())
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)
382+ if (ret > 1 && !x86_match_cpu(snc_cpu_ids)) {
383+ pr_warn("CoD enabled system? Resctrl not supported\n");
409384 return 1;
410−
411− ret = cpus_per_l3 / cpus_per_node;
385+ }
412386
413387 /* sanity check: Only valid results are 1, 2, 3, 4, 6 */
414388 switch (ret) {
arch/x86/kernel/cpu/topology.c+11−2
@@ -31,6 +31,7 @@ · 30 unmodified lines
3131 #include <asm/mpspec.h>
3232 #include <asm/msr.h>
3333 #include <asm/smp.h>
34+#include <asm/numa.h>
3435
3536 #include "cpu.h"
3637
@@ -492,11 +493,19 @@ void __init topology_init_possible_cpus(void) · 455 unmodified lines
492493 set_nr_cpu_ids(allowed);
493494
494495 cnta = domain_weight(TOPO_PKG_DOMAIN);
495− cntb = domain_weight(TOPO_DIE_DOMAIN);
496496 __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);
497507 __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta));
498508
499− pr_info("Max. logical packages: %3u\n", cnta);
500509 pr_info("Max. logical dies: %3u\n", cntb);
501510 pr_info("Max. dies per package: %3u\n", __max_dies_per_package);
502511
arch/x86/kernel/head_64.S+0−28
@@ -616,38 +616,10 @@ SYM_DATA(early_recursion_flag, .long 0) · 615 unmodified lines
616616
617617 .data
618618
619−#if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH)
620−SYM_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
628−SYM_DATA_END(init_top_pgt)
629−
630−SYM_DATA_START_PAGE_ALIGNED(level3_ident_pgt)
631− .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
632− .fill 511, 8, 0
633−SYM_DATA_END(level3_ident_pgt)
634−SYM_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)
644−SYM_DATA_END(level2_ident_pgt)
645−#else
646619 SYM_DATA_START_PTI_ALIGNED(init_top_pgt)
647620 .fill 512,8,0
648621 .fill PTI_USER_PGD_FILL,8,0
649622 SYM_DATA_END(init_top_pgt)
650−#endif
651623
652624 SYM_DATA_START_PAGE_ALIGNED(level4_kernel_pgt)
653625 .fill 511,8,0
arch/x86/kernel/smpboot.c+145−56
@@ -468,13 +468,6 @@ static int x86_cluster_flags(void) · 467 unmodified lines
468468 }
469469 #endif
470470
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− */
476−static bool x86_has_numa_in_package;
477−
478471 static struct sched_domain_topology_level x86_topology[] = {
479472 SDTL_INIT(tl_smt_mask, cpu_smt_flags, SMT),
480473 #ifdef CONFIG_SCHED_CLUSTER
@@ -496,7 +489,7 @@ static void __init build_sched_topology(void) · 15 unmodified lines
496489 * PKG domain since the NUMA domains will auto-magically create the
497490 * right spanning domains based on the SLIT.
498491 */
499− if (x86_has_numa_in_package) {
492+ if (topology_num_nodes_per_package() > 1) {
500493 unsigned int pkgdom = ARRAY_SIZE(x86_topology) - 2;
501494
502495 memset(&x86_topology[pkgdom], 0, sizeof(x86_topology[pkgdom]));
@@ -513,33 +506,149 @@ static void __init build_sched_topology(void) · 10 unmodified lines
513506 }
514507
515508 #ifdef CONFIG_NUMA
516−static int sched_avg_remote_distance;
517−static int avg_remote_numa_distance(void)
509+/*
510+ * Test if the on-trace cluster at (N,N) is symmetric.
511+ * Uses upper triangle iteration to avoid obvious duplicates.
512+ */
513+static bool slit_cluster_symmetric(int N)
518514 {
519− int i, j;
520− int distance, nr_remote, total_distance;
521−
522− if (sched_avg_remote_distance > 0)
523− return sched_avg_remote_distance;
524−
525− nr_remote = 0;
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− }
515+ int u = topology_num_nodes_per_package();
516+
517+ for (int k = 0; k < u; k++) {
518+ for (int l = k; l < u; l++) {
519+ if (node_distance(N + k, N + l) !=
520+ node_distance(N + l, N + k))
521+ return false;
535522 }
536523 }
537− if (nr_remote)
538− sched_avg_remote_distance = total_distance / nr_remote;
539− else
540− sched_avg_remote_distance = REMOTE_DISTANCE;
541524
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+ */
532+static 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+ */
562+static 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+ */
614+static 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);
543652 }
544653
545654 int arch_sched_node_distance(int from, int to)
@@ -549,34 +658,14 @@ int arch_sched_node_distance(int from, int to) · 3 unmodified lines
549658 switch (boot_cpu_data.x86_vfm) {
550659 case INTEL_GRANITERAPIDS_X:
551660 case INTEL_ATOM_DARKMONT_X:
552−
553− if (!x86_has_numa_in_package || topology_max_packages() == 1 ||
554− d < REMOTE_DISTANCE)
661+ if (topology_max_packages() == 1 ||
662+ topology_num_nodes_per_package() < 3)
555663 return d;
556664
557665 /*
558− * With SNC enabled, there could be too many levels of remote
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.
666+ * Handle SNC-3 asymmetries.
573667 */
574− WARN_ONCE(topology_max_packages() > 2,
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();
668+ return slit_cluster_distance(from, to);
580669 }
581670 return d;
582671 }
@@ -606,7 +695,7 @@ void set_cpu_sibling_map(int cpu) · 23 unmodified lines
606695 o = &cpu_data(i);
607696
608697 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);
610699
611700 if ((i == cpu) || (has_smt && match_smt(c, o)))
612701 link_mask(topology_sibling_cpumask, cpu, i);
arch/x86/kernel/vmlinux.lds.S+1−0
@@ -427,6 +427,7 @@ SECTIONS · 426 unmodified lines
427427 .llvm_bb_addr_map : { *(.llvm_bb_addr_map) }
428428 #endif
429429
430+ MODINFO
430431 ELF_DETAILS
431432
432433 DISCARDS
arch/x86/mm/numa.c+8−0
@@ -48,6 +48,8 @@ s16 __apicid_to_node[MAX_LOCAL_APIC] = { · 47 unmodified lines
4848 [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
4949 };
5050
51+nodemask_t numa_phys_nodes_parsed __initdata;
52+
5153 int numa_cpu_node(int cpu)
5254 {
5355 u32 apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
@@ -57,6 +59,11 @@ int numa_cpu_node(int cpu) · 3 unmodified lines
5759 return NUMA_NO_NODE;
5860 }
5961
62+int __init num_phys_nodes(void)
63+{
64+ return bitmap_weight(numa_phys_nodes_parsed.bits, MAX_NUMNODES);
65+}
66+
6067 cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
6168 EXPORT_SYMBOL(node_to_cpumask_map);
6269
@@ -210,6 +217,7 @@ static int __init dummy_numa_init(void) · 147 unmodified lines
210217 0LLU, PFN_PHYS(max_pfn) - 1);
211218
212219 node_set(0, numa_nodes_parsed);
220+ node_set(0, numa_phys_nodes_parsed);
213221 numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
214222
215223 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
5757 }
5858 set_apicid_to_node(apic_id, node);
5959 node_set(node, numa_nodes_parsed);
60+ node_set(node, numa_phys_nodes_parsed);
6061 pr_debug("SRAT: PXM %u -> APIC 0x%04x -> Node %u\n", pxm, apic_id, node);
6162 }
6263
@@ -97,6 +98,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) · 34 unmodified lines
9798
9899 set_apicid_to_node(apic_id, node);
99100 node_set(node, numa_nodes_parsed);
101+ node_set(node, numa_phys_nodes_parsed);
100102 pr_debug("SRAT: PXM %u -> APIC 0x%02x -> Node %u\n", pxm, apic_id, node);
101103 }
102104
arch/x86/platform/efi/efi.c+1−1
@@ -836,7 +836,7 @@ static void __init __efi_enter_virtual_mode(void) · 835 unmodified lines
836836 }
837837
838838 efi_check_for_embedded_firmwares();
839− efi_free_boot_services();
839+ efi_unmap_boot_services();
840840
841841 if (!efi_is_mixed())
842842 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
341341
342342 /*
343343 * Because the following memblock_reserve() is paired
344− * with memblock_free_late() for this region in
344+ * with free_reserved_area() for this region in
345345 * efi_free_boot_services(), we must be extremely
346346 * careful not to reserve, and subsequently free,
347347 * 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
404404 pr_err("Failed to unmap VA mapping for 0x%llx\n", va);
405405 }
406406
407−void __init efi_free_boot_services(void)
407+struct efi_freeable_range {
408+ u64 start;
409+ u64 end;
410+};
411+
412+static struct efi_freeable_range *ranges_to_free;
413+
414+void __init efi_unmap_boot_services(void)
408415 {
409416 struct efi_memory_map_data data = { 0 };
410417 efi_memory_desc_t *md;
411418 int num_entries = 0;
419+ int idx = 0;
420+ size_t sz;
412421 void *new, *new_md;
413422
414423 /* Keep all regions for /sys/kernel/debug/efi */
415424 if (efi_enabled(EFI_DBG))
416425 return;
417426
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+
418434 for_each_efi_memory_desc(md) {
419435 unsigned long long start = md->phys_addr;
420436 unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
@@ -471,7 +487,15 @@ void __init efi_free_boot_services(void) · 50 unmodified lines
471487 start = SZ_1M;
472488 }
473489
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++;
475499 }
476500
477501 if (!num_entries)
@@ -512,6 +536,31 @@ void __init efi_free_boot_services(void) · 34 unmodified lines
512536 }
513537 }
514538
539+static 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+}
562+arch_initcall(efi_free_boot_services);
563+
515564 /*
516565 * A number of config table entries get remapped to virtual addresses
517566 * 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
2525
2626 const unsigned int __initconst pvh_start_info_sz = sizeof(pvh_start_info);
2727
28−static u64 __init pvh_get_root_pointer(void)
29−{
30− return pvh_start_info.rsdp_paddr;
31−}
32−
3328 /*
3429 * Xen guests are able to obtain the memory map from the hypervisor via the
3530 * HYPERVISOR_memory_op hypercall.
@@ -95,7 +90,7 @@ static void __init init_pvh_bootparams(bool xen_guest) · 59 unmodified lines
9590 pvh_bootparams.hdr.version = (2 << 8) | 12;
9691 pvh_bootparams.hdr.type_of_loader = ((xen_guest ? 0x9 : 0xb) << 4) | 0;
9792
98− x86_init.acpi.get_root_pointer = pvh_get_root_pointer;
93+ pvh_bootparams.acpi_rsdp_addr = pvh_start_info.rsdp_paddr;
9994 }
10095
10196 /*
arch/x86/xen/enlighten_pv.c+1−1
@@ -392,7 +392,7 @@ static void __init xen_init_capabilities(void) · 391 unmodified lines
392392
393393 /*
394394 * 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.
396396 */
397397 setup_clear_cpu_cap(X86_FEATURE_PCID);
398398
arch/x86/xen/mmu_pv.c+9−0
@@ -105,6 +105,9 @@ pte_t xen_make_pte_init(pteval_t pte); · 104 unmodified lines
105105 static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;
106106 #endif
107107
108+static pud_t level3_ident_pgt[PTRS_PER_PUD] __page_aligned_bss;
109+static pmd_t level2_ident_pgt[PTRS_PER_PMD] __page_aligned_bss;
110+
108111 /*
109112 * Protects atomic reservation decrease/increase against concurrent increases.
110113 * 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
17771780 /* Zap identity mapping */
17781781 init_top_pgt[0] = __pgd(0);
17791782
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+
17801789 /* Pre-constructed entries are in pfn, so convert to mfn */
17811790 /* L4[273] -> level3_ident_pgt */
17821791 /* 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
398398 if (op_is_write(op))
399399 memcpy(page_address(page), p, bytes);
400400
401− if (bio_add_page(bio, page, bytes, 0) < bytes)
402− break;
401+ __bio_add_page(bio, page, bytes, 0);
403402
404403 len -= bytes;
405404 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
47934793 }
47944794 }
47954795
4796−static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set,
4797− int new_nr_hw_queues)
4796+static struct blk_mq_tags **blk_mq_prealloc_tag_set_tags(
4797+ struct blk_mq_tag_set *set,
4798+ int new_nr_hw_queues)
47984799 {
47994800 struct blk_mq_tags **new_tags;
48004801 int i;
48014802
48024803 if (set->nr_hw_queues >= new_nr_hw_queues)
4803− goto done;
4804+ return NULL;
48044805
48054806 new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *),
48064807 GFP_KERNEL, set->numa_node);
48074808 if (!new_tags)
4808− return -ENOMEM;
4809+ return ERR_PTR(-ENOMEM);
48094810
48104811 if (set->tags)
48114812 memcpy(new_tags, set->tags, set->nr_hw_queues *
48124813 sizeof(*set->tags));
4813− kfree(set->tags);
4814− set->tags = new_tags;
48154814
48164815 for (i = set->nr_hw_queues; i < new_nr_hw_queues; i++) {
4817− if (!__blk_mq_alloc_map_and_rqs(set, i)) {
4818− while (--i >= set->nr_hw_queues)
4819− __blk_mq_free_map_and_rqs(set, i);
4820− return -ENOMEM;
4816+ if (blk_mq_is_shared_tags(set->flags)) {
4817+ new_tags[i] = set->shared_tags;
4818+ } else {
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;
48214823 }
48224824 cond_resched();
48234825 }
48244826
4825−done:
4826− set->nr_hw_queues = new_nr_hw_queues;
4827− return 0;
4827+ return new_tags;
4828+out_unwind:
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);
48284835 }
48294836
48304837 /*
@@ -5113,6 +5120,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 282 unmodified lines
51135120 unsigned int memflags;
51145121 int i;
51155122 struct xarray elv_tbl;
5123+ struct blk_mq_tags **new_tags;
51165124 bool queues_frozen = false;
51175125
51185126 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
51475155 if (blk_mq_elv_switch_none(q, &elv_tbl))
51485156 goto switch_back;
51495157
5158+ new_tags = blk_mq_prealloc_tag_set_tags(set, nr_hw_queues);
5159+ if (IS_ERR(new_tags))
5160+ goto switch_back;
5161+
51505162 list_for_each_entry(q, &set->tag_list, tag_set_list)
51515163 blk_mq_freeze_queue_nomemsave(q);
51525164 queues_frozen = true;
5153− if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0)
5154− goto switch_back;
5165+ if (new_tags) {
5166+ kfree(set->tags);
5167+ set->tags = new_tags;
5168+ }
5169+ set->nr_hw_queues = nr_hw_queues;
51555170
51565171 fallback:
51575172 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
7878 /*
7979 * Serialize updating nr_requests with concurrent queue_requests_store()
8080 * 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)
8186 */
82− down_write(&set->update_nr_hwq_lock);
87+ if (!down_write_trylock(&set->update_nr_hwq_lock))
88+ return -EBUSY;
8389
8490 if (nr == q->nr_requests)
8591 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
807807 elv_iosched_load_module(ctx.name);
808808 ctx.type = elevator_find_get(ctx.name);
809809
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+ }
811820 if (!blk_queue_no_elv_switch(q)) {
812821 ret = elevator_change(q, &ctx);
813822 if (!ret)
@@ -817,6 +826,7 @@ ssize_t elv_iosched_store(struct gendisk *disk, const char *buf, · 3 unmodified lines
817826 }
818827 up_read(&set->update_nr_hwq_lock);
819828
829+out:
820830 if (ctx.type)
821831 elevator_put(ctx.type);
822832 return ret;
crypto/Kconfig+0−9
@@ -876,8 +876,6 @@ config CRYPTO_BLAKE2B · 875 unmodified lines
876876 - blake2b-384
877877 - blake2b-512
878878
879− Used by the btrfs filesystem.
880−
881879 See https://blake2.net for further information.
882880
883881 config CRYPTO_CMAC
@@ -965,7 +963,6 @@ config CRYPTO_SHA256 · 81 unmodified lines
965963 10118-3), including HMAC support.
966964
967965 This is required for IPsec AH (XFRM_AH) and IPsec ESP (XFRM_ESP).
968− Used by the btrfs filesystem, Ceph, NFS, and SMB.
969966
970967 config CRYPTO_SHA512
971968 tristate "SHA-384 and SHA-512"
@@ -1039,8 +1036,6 @@ config CRYPTO_XXHASH · 67 unmodified lines
10391036
10401037 Extremely fast, working at speeds close to RAM limits.
10411038
1042− Used by the btrfs filesystem.
1043−
10441039 endmenu
10451040
10461041 menu "CRCs (cyclic redundancy checks)"
@@ -1058,8 +1053,6 @@ config CRYPTO_CRC32C · 11 unmodified lines
10581053 on Communications, Vol. 41, No. 6, June 1993, selected for use with
10591054 iSCSI.
10601055
1061− Used by btrfs, ext4, jbd2, NVMeoF/TCP, and iSCSI.
1062−
10631056 config CRYPTO_CRC32
10641057 tristate "CRC32"
10651058 select CRYPTO_HASH
@@ -1067,8 +1060,6 @@ config CRYPTO_CRC32 · 1 unmodified line
10671060 help
10681061 CRC32 CRC algorithm (IEEE 802.3)
10691062
1070− Used by RoCEv2 and f2fs.
1071−
10721063 endmenu
10731064
10741065 menu "Compression"
crypto/testmgr.c+2−2
@@ -4132,7 +4132,7 @@ static const struct alg_test_desc alg_test_descs[] = { · 4131 unmodified lines
41324132 .fips_allowed = 1,
41334133 }, {
41344134 .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))",
41364136 .test = alg_test_aead,
41374137 .suite = {
41384138 .aead = __VECS(hmac_sha224_aes_cbc_tv_temp)
@@ -4194,7 +4194,7 @@ static const struct alg_test_desc alg_test_descs[] = { · 55 unmodified lines
41944194 .fips_allowed = 1,
41954195 }, {
41964196 .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))",
41984198 .test = alg_test_aead,
41994199 .suite = {
42004200 .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
186186 cmd_abo = job->cmd_bo;
187187
188188 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);
190190 ret = -EINVAL;
191191 goto out;
192192 }
193193
194194 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);
196196 ret = -EINVAL;
197197 goto out;
198198 }
@@ -202,7 +202,7 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) · 3 unmodified lines
202202 if (status == AIE2_STATUS_SUCCESS)
203203 amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_COMPLETED);
204204 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);
206206
207207 out:
208208 aie2_sched_notify(job);
@@ -244,13 +244,13 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) · 35 unmodified lines
244244 cmd_abo = job->cmd_bo;
245245
246246 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);
248248 ret = -EINVAL;
249249 goto out;
250250 }
251251
252252 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);
254254 ret = -EINVAL;
255255 goto out;
256256 }
@@ -270,19 +270,12 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) · 13 unmodified lines
270270 fail_cmd_idx, fail_cmd_status);
271271
272272 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);
274274 ret = -EINVAL;
275− goto out;
275+ } else {
276+ amdxdna_cmd_set_error(cmd_abo, job, fail_cmd_idx, ERT_CMD_STATE_ERROR);
276277 }
277− amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ERROR);
278278
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− }
286279 out:
287280 aie2_sched_notify(job);
288281 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
4040 return -ENODEV;
4141
4242 ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg);
43− if (ret == -ETIME) {
44− xdna_mailbox_stop_channel(ndev->mgmt_chann);
45− xdna_mailbox_destroy_channel(ndev->mgmt_chann);
46− ndev->mgmt_chann = NULL;
47− }
43+ if (ret == -ETIME)
44+ aie2_destroy_mgmt_chann(ndev);
4845
4946 if (!ret && *hdl->status != AIE2_STATUS_SUCCESS) {
5047 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
296293 }
297294
298295 intr_reg = i2x.mb_head_ptr_reg + 4;
299− hwctx->priv->mbox_chann = xdna_mailbox_create_channel(ndev->mbox, &x2i, &i2x,
300− intr_reg, ret);
296+ hwctx->priv->mbox_chann = xdna_mailbox_alloc_channel(ndev->mbox);
301297 if (!hwctx->priv->mbox_chann) {
302298 XDNA_ERR(xdna, "Not able to create channel");
303299 ret = -EINVAL;
304300 goto del_ctx_req;
305301 }
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+ }
306310 ndev->hwctx_num++;
307311
308312 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
310314
311315 return 0;
312316
317+free_channel:
318+ xdna_mailbox_free_channel(hwctx->priv->mbox_chann);
313319 del_ctx_req:
314320 aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
315321 return ret;
@@ -325,7 +331,7 @@ int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwc · 9 unmodified lines
325331
326332 xdna_mailbox_stop_channel(hwctx->priv->mbox_chann);
327333 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);
329335 XDNA_DBG(xdna, "Destroyed fw ctx %d", hwctx->fw_ctx_id);
330336 hwctx->priv->mbox_chann = NULL;
331337 hwctx->fw_ctx_id = -1;
@@ -914,6 +920,20 @@ void aie2_msg_init(struct amdxdna_dev_hdl *ndev) · 582 unmodified lines
914920 ndev->exec_msg_ops = &legacy_exec_message_ops;
915921 }
916922
923+void 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+
917937 static inline struct amdxdna_gem_obj *
918938 aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job)
919939 {
drivers/accel/amdxdna/aie2_pci.c+37−29
@@ -331,9 +331,7 @@ static void aie2_hw_stop(struct amdxdna_dev *xdna) · 330 unmodified lines
331331
332332 aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, NULL);
333333 aie2_mgmt_fw_fini(ndev);
334− xdna_mailbox_stop_channel(ndev->mgmt_chann);
335− xdna_mailbox_destroy_channel(ndev->mgmt_chann);
336− ndev->mgmt_chann = NULL;
334+ aie2_destroy_mgmt_chann(ndev);
337335 drmm_kfree(&xdna->ddev, ndev->mbox);
338336 ndev->mbox = NULL;
339337 aie2_psp_stop(ndev->psp_hdl);
@@ -364,10 +362,29 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) · 24 unmodified lines
364362 }
365363 pci_set_master(pdev);
366364
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+
367384 ret = aie2_smu_init(ndev);
368385 if (ret) {
369386 XDNA_ERR(xdna, "failed to init smu, ret %d", ret);
370− goto disable_dev;
387+ goto free_channel;
371388 }
372389
373390 ret = aie2_psp_start(ndev->psp_hdl);
@@ -382,18 +399,6 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) · 8 unmodified lines
382399 goto stop_psp;
383400 }
384401
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−
397402 mgmt_mb_irq = pci_irq_vector(pdev, ndev->mgmt_chan_idx);
398403 if (mgmt_mb_irq < 0) {
399404 ret = mgmt_mb_irq;
@@ -402,13 +407,13 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) · 2 unmodified lines
402407 }
403408
404409 xdna_mailbox_intr_reg = ndev->mgmt_i2x.mb_head_ptr_reg + 4;
405− ndev->mgmt_chann = xdna_mailbox_create_channel(ndev->mbox,
406− &ndev->mgmt_x2i,
407− &ndev->mgmt_i2x,
408− xdna_mailbox_intr_reg,
409− mgmt_mb_irq);
410− if (!ndev->mgmt_chann) {
411− XDNA_ERR(xdna, "failed to create management mailbox channel");
410+ ret = xdna_mailbox_start_channel(ndev->mgmt_chann,
411+ &ndev->mgmt_x2i,
412+ &ndev->mgmt_i2x,
413+ xdna_mailbox_intr_reg,
414+ mgmt_mb_irq);
415+ if (ret) {
416+ XDNA_ERR(xdna, "failed to start management mailbox channel");
412417 ret = -EINVAL;
413418 goto stop_psp;
414419 }
@@ -416,38 +421,41 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) · 1 unmodified line
416421 ret = aie2_mgmt_fw_init(ndev);
417422 if (ret) {
418423 XDNA_ERR(xdna, "initial mgmt firmware failed, ret %d", ret);
419− goto destroy_mgmt_chann;
424+ goto stop_fw;
420425 }
421426
422427 ret = aie2_pm_init(ndev);
423428 if (ret) {
424429 XDNA_ERR(xdna, "failed to init pm, ret %d", ret);
425− goto destroy_mgmt_chann;
430+ goto stop_fw;
426431 }
427432
428433 ret = aie2_mgmt_fw_query(ndev);
429434 if (ret) {
430435 XDNA_ERR(xdna, "failed to query fw, ret %d", ret);
431− goto destroy_mgmt_chann;
436+ goto stop_fw;
432437 }
433438
434439 ret = aie2_error_async_events_alloc(ndev);
435440 if (ret) {
436441 XDNA_ERR(xdna, "Allocate async events failed, ret %d", ret);
437− goto destroy_mgmt_chann;
442+ goto stop_fw;
438443 }
439444
440445 ndev->dev_status = AIE2_DEV_START;
441446
442447 return 0;
443448
444−destroy_mgmt_chann:
449+stop_fw:
450+ aie2_suspend_fw(ndev);
445451 xdna_mailbox_stop_channel(ndev->mgmt_chann);
446− xdna_mailbox_destroy_channel(ndev->mgmt_chann);
447452 stop_psp:
448453 aie2_psp_stop(ndev->psp_hdl);
449454 fini_smu:
450455 aie2_smu_fini(ndev);
456+free_channel:
457+ xdna_mailbox_free_channel(ndev->mgmt_chann);
458+ ndev->mgmt_chann = NULL;
451459 disable_dev:
452460 pci_disable_device(pdev);
453461
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
331331
332332 /* aie2_message.c */
333333 void aie2_msg_init(struct amdxdna_dev_hdl *ndev);
334+void aie2_destroy_mgmt_chann(struct amdxdna_dev_hdl *ndev);
334335 int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev);
335336 int aie2_resume_fw(struct amdxdna_dev_hdl *ndev);
336337 int 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
135135 return INVALID_CU_IDX;
136136 }
137137
138+int 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+
138165 /*
139166 * This should be called in close() and remove(). DO NOT call in other syscalls.
140167 * 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
167167
168168 void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size);
169169 u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo);
170+int 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);
170173
171174 void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job);
172175 void 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
460460 return ret;
461461 }
462462
463−struct mailbox_channel *
464−xdna_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)
463+struct mailbox_channel *xdna_mailbox_alloc_channel(struct mailbox *mb)
469464 {
470465 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− }
477466
478467 mb_chann = kzalloc_obj(*mb_chann);
479468 if (!mb_chann)
480469 return NULL;
481470
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+ }
482477 mb_chann->mb = mb;
478+
479+ return mb_chann;
480+
481+free_chann:
482+ kfree(mb_chann);
483+ return NULL;
484+}
485+
486+void xdna_mailbox_free_channel(struct mailbox_channel *mb_chann)
487+{
488+ destroy_workqueue(mb_chann->work_q);
489+ kfree(mb_chann);
490+}
491+
492+int
493+xdna_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+
483506 mb_chann->msix_irq = mb_irq;
484507 mb_chann->iohub_int_addr = iohub_int_addr;
485508 memcpy(&mb_chann->res[CHAN_RES_X2I], x2i, sizeof(*x2i));
@@ -489,61 +512,37 @@ xdna_mailbox_create_channel(struct mailbox *mb, · 3 unmodified lines
489512 mb_chann->x2i_tail = mailbox_get_tailptr(mb_chann, CHAN_RES_X2I);
490513 mb_chann->i2x_head = mailbox_get_headptr(mb_chann, CHAN_RES_I2X);
491514
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−
499515 /* Everything look good. Time to enable irq handler */
500516 ret = request_irq(mb_irq, mailbox_irq_handler, 0, MAILBOX_NAME, mb_chann);
501517 if (ret) {
502518 MB_ERR(mb_chann, "Failed to request irq %d ret %d", mb_irq, ret);
503− goto destroy_wq;
519+ return ret;
504520 }
505521
506522 mb_chann->bad_state = false;
507523 mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0);
508524
509− MB_DBG(mb_chann, "Mailbox channel created (irq: %d)", mb_chann->msix_irq);
510− return mb_chann;
511−
512−destroy_wq:
513− destroy_workqueue(mb_chann->work_q);
514−free_and_out:
515− kfree(mb_chann);
516− return NULL;
525+ MB_DBG(mb_chann, "Mailbox channel started (irq: %d)", mb_chann->msix_irq);
526+ return 0;
517527 }
518528
519−int xdna_mailbox_destroy_channel(struct mailbox_channel *mb_chann)
529+void xdna_mailbox_stop_channel(struct mailbox_channel *mb_chann)
520530 {
521531 struct mailbox_msg *mb_msg;
522532 unsigned long msg_id;
523533
524− MB_DBG(mb_chann, "IRQ disabled and RX work cancelled");
534+ /* Disable an irq and wait. This might sleep. */
525535 free_irq(mb_chann->msix_irq, mb_chann);
526− destroy_workqueue(mb_chann->work_q);
527− /* We can clean up and release resources */
528536
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 */
529541 xa_for_each(&mb_chann->chan_xa, msg_id, mb_msg)
530542 mailbox_release_msg(mb_chann, mb_msg);
531−
532543 xa_destroy(&mb_chann->chan_xa);
533544
534− MB_DBG(mb_chann, "Mailbox channel destroyed, irq: %d", mb_chann->msix_irq);
535− kfree(mb_chann);
536− return 0;
537−}
538−
539−void 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");
545+ MB_DBG(mb_chann, "Mailbox channel stopped, irq: %d", mb_chann->msix_irq);
547546 }
548547
549548 struct 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
7474 const struct xdna_mailbox_res *res);
7575
7676 /*
77− * xdna_mailbox_create_channel() -- Create a mailbox channel instance
77+ * xdna_mailbox_alloc_channel() -- alloc a mailbox channel
7878 *
79− * @mailbox: the handle return from xdna_mailbox_create()
79+ * @mb: mailbox handle
80+ */
81+struct 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()
8087 * @x2i: host to firmware mailbox resources
8188 * @i2x: firmware to host mailbox resources
8289 * @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
8491 *
8592 * Return: If success, return a handle of mailbox channel. Otherwise, return NULL.
8693 */
87−struct mailbox_channel *
88−xdna_mailbox_create_channel(struct mailbox *mailbox,
89− const struct xdna_mailbox_chann_res *x2i,
90− const struct xdna_mailbox_chann_res *i2x,
91− u32 xdna_mailbox_intr_reg,
92− int mb_irq);
94+int
95+xdna_mailbox_start_channel(struct mailbox_channel *mb_chann,
96+ const struct xdna_mailbox_chann_res *x2i,
97+ const struct xdna_mailbox_chann_res *i2x,
98+ u32 xdna_mailbox_intr_reg,
99+ int mb_irq);
93100
94101 /*
95− * xdna_mailbox_destroy_channel() -- destroy mailbox channel
102+ * xdna_mailbox_free_channel() -- free mailbox channel
96103 *
97104 * @mailbox_chann: the handle return from xdna_mailbox_create_channel()
98− *
99− * Return: if success, return 0. otherwise return error code
100105 */
101−int xdna_mailbox_destroy_channel(struct mailbox_channel *mailbox_chann);
106+void xdna_mailbox_free_channel(struct mailbox_channel *mailbox_chann);
102107
103108 /*
104109 * xdna_mailbox_stop_channel() -- stop mailbox channel
105110 *
106111 * @mailbox_chann: the handle return from xdna_mailbox_create_channel()
107− *
108− * Return: if success, return 0. otherwise return error code
109112 */
110113 void xdna_mailbox_stop_channel(struct mailbox_channel *mailbox_chann);
111114
drivers/accel/amdxdna/npu1_regs.c+1−1
@@ -67,7 +67,7 @@ const struct dpm_clk_freq npu1_dpm_clk_table[] = { · 66 unmodified lines
6767
6868 static const struct aie2_fw_feature_tbl npu1_fw_feature_table[] = {
6969 { .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 },
7171 { 0 }
7272 };
7373
drivers/accel/ethosu/ethosu_gem.c+9−3
@@ -245,11 +245,14 @@ static int calc_sizes(struct drm_device *ddev, · 244 unmodified lines
245245 ((st->ifm.stride_kernel >> 1) & 0x1) + 1;
246246 u32 stride_x = ((st->ifm.stride_kernel >> 5) & 0x2) +
247247 (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 +
249249 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 +
251251 st->ifm.width - (st->ifm.pad_left + st->ifm.pad_right);
252252
253+ if (ifm_height < 0 || ifm_width < 0)
254+ return -EINVAL;
255+
253256 len = feat_matrix_length(info, &st->ifm, ifm_width,
254257 ifm_height, st->ifm.depth);
255258 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
417420 return ret;
418421 break;
419422 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) ||
421427 (param == 6) || (param == 7) || (param == 0x24));
422428 use_ifm = st.ifm.broadcast != 8;
423429 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
143143 return ret;
144144 }
145145
146+static 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+
146158 static void ethosu_job_cleanup(struct kref *ref)
147159 {
148160 struct ethosu_job *job = container_of(ref, struct ethosu_job,
149161 refcount);
150− unsigned int i;
151162
152163 pm_runtime_put_autosuspend(job->dev->base.dev);
153164
154165 dma_fence_put(job->done_fence);
155166 dma_fence_put(job->inference_done_fence);
156167
157− for (i = 0; i < job->region_cnt; i++)
158− drm_gem_object_put(job->region_bo[i]);
159−
160− drm_gem_object_put(job->cmd_bo);
161−
162− kfree(job);
168+ ethosu_job_err_cleanup(job);
163169 }
164170
165171 static 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
454460 }
455461 }
456462 ret = ethosu_job_push(ejob);
463+ if (!ret) {
464+ ethosu_job_put(ejob);
465+ return 0;
466+ }
457467
458468 out_cleanup_job:
459469 if (ret)
460470 drm_sched_job_cleanup(&ejob->base);
461471 out_put_job:
462− ethosu_job_put(ejob);
472+ ethosu_job_err_cleanup(ejob);
463473
464474 return ret;
465475 }
drivers/acpi/acpica/acpredef.h+3−2
@@ -379,8 +379,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { · 378 unmodified lines
379379
380380 {{"_CPC", METHOD_0ARGS,
381381 METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints/Bufs) */
382− PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER, 0,
383− 0, 0, 0),
382+ PACKAGE_INFO(ACPI_PTYPE1_VAR,
383+ ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER |
384+ ACPI_RTYPE_PACKAGE, 0, 0, 0, 0),
384385
385386 {{"_CR3", METHOD_0ARGS, /* ACPI 6.0 */
386387 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
14561456 if (!adev || !acpi_match_device_ids(adev, special_pm_ids))
14571457 return 0;
14581458
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−
14681459 /*
14691460 * Only attach the power domain to the first device if the
14701461 * 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
41894189 ATA_QUIRK_FIRMWARE_WARN },
41904190
41914191 /* Seagate disks with LPM issues */
4192+ { "ST1000DM010-2EP102", NULL, ATA_QUIRK_NOLPM },
41924193 { "ST2000DM008-2FR102", NULL, ATA_QUIRK_NOLPM },
41934194
41944195 /* 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
42314232 /* Devices that do not need bridging limits applied */
42324233 { "MTRON MSP-SATA*", NULL, ATA_QUIRK_BRIDGE_OK },
42334234 { "BUFFALO HD-QSU2/R5", NULL, ATA_QUIRK_BRIDGE_OK },
4235+ { "QEMU HARDDISK", "2.5+", ATA_QUIRK_BRIDGE_OK },
42344236
42354237 /* Devices which aren't very happy with higher link speeds */
42364238 { "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
647647 break;
648648 }
649649
650− if (qc == ap->deferred_qc) {
650+ if (i < ATA_MAX_QUEUE && qc == ap->deferred_qc) {
651651 /*
652652 * This is a deferred command that timed out while
653653 * 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
659659 */
660660 WARN_ON_ONCE(qc->flags & ATA_QCFLAG_ACTIVE);
661661 ap->deferred_qc = NULL;
662+ cancel_work(&ap->deferred_qc_work);
662663 set_host_byte(scmd, DID_TIME_OUT);
663664 scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
664665 } 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
16991699
17001700 scmd = qc->scsicmd;
17011701 ap->deferred_qc = NULL;
1702+ cancel_work(&ap->deferred_qc_work);
17021703 ata_qc_free(qc);
17031704 scmd->result = (DID_SOFT_ERROR << 16);
17041705 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
179179 void driver_detach(const struct device_driver *drv);
180180 void driver_deferred_probe_del(struct device *dev);
181181 void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf);
182−static 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−
190182 static inline int driver_match_device(const struct device_driver *drv,
191183 struct device *dev)
192184 {
193− guard(device)(dev);
194− return driver_match_device_locked(drv, dev);
185+ return drv->bus->match ? drv->bus->match(dev, drv) : 1;
195186 }
196187
197188 static 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
928928 bool async_allowed;
929929 int ret;
930930
931− ret = driver_match_device_locked(drv, dev);
931+ ret = driver_match_device(drv, dev);
932932 if (ret == 0) {
933933 /* no match */
934934 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
5252 rng->priv = 0;
5353 } else {
5454 work_data = kmalloc_obj(*work_data, GFP_ATOMIC);
55− if (!work_data)
55+ if (!work_data) {
56+ atomic_dec(&i2c_priv->tfm_count);
5657 return -ENOMEM;
57−
58+ }
5859 work_data->ctx = i2c_priv;
5960 work_data->client = i2c_priv->client;
6061
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
378378 return;
379379
380380 error_exit:
381− kfree(t);
382381 pr_err("Failed to enable SEV-TIO: ret=%d en=%d initdone=%d SEV=%d\n",
383382 ret, t->tio_en, t->tio_init_done, boot_cpu_has(X86_FEATURE_SEV));
383+ kfree(t);
384384 }
385385
386386 void 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
11051105 {
11061106 struct psp_device *psp_master = psp_get_master_device();
11071107 struct snp_hv_fixed_pages_entry *entry;
1108− struct sev_device *sev;
11091108 unsigned int order;
11101109 struct page *page;
11111110
1112− if (!psp_master || !psp_master->sev_data)
1111+ if (!psp_master)
11131112 return NULL;
11141113
1115− sev = psp_master->sev_data;
1116−
11171114 order = get_order(PMD_SIZE * num_2mb_pages);
11181115
11191116 /*
@@ -1126,7 +1123,8 @@ struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages) · 6 unmodified lines
11261123 * This API uses SNP_INIT_EX to transition allocated pages to HV_Fixed
11271124 * page state, fail if SNP is already initialized.
11281125 */
1129− if (sev->snp_initialized)
1126+ if (psp_master->sev_data &&
1127+ ((struct sev_device *)psp_master->sev_data)->snp_initialized)
11301128 return NULL;
11311129
11321130 /* Re-use freed pages that match the request */
@@ -1162,7 +1160,7 @@ void snp_free_hv_fixed_pages(struct page *page) · 29 unmodified lines
11621160 struct psp_device *psp_master = psp_get_master_device();
11631161 struct snp_hv_fixed_pages_entry *entry, *nentry;
11641162
1165− if (!psp_master || !psp_master->sev_data)
1163+ if (!psp_master)
11661164 return;
11671165
11681166 /*
drivers/firmware/efi/mokvar-table.c+1−1
@@ -85,7 +85,7 @@ static struct kobject *mokvar_kobj; · 84 unmodified lines
8585 * as an alternative to ordinary EFI variables, due to platform-dependent
8686 * limitations. The memory occupied by this table is marked as reserved.
8787 *
88− * This routine must be called before efi_free_boot_services() in order
88+ * This routine must be called before efi_unmap_boot_services() in order
8989 * to guarantee that it can mark the table as reserved.
9090 *
9191 * Implicit inputs:
drivers/gpu/drm/amd/amdgpu/Makefile+1−1
@@ -47,7 +47,7 @@ subdir-ccflags-$(CONFIG_DRM_AMDGPU_WERROR) += -Werror · 46 unmodified lines
4747 amdgpu-y := amdgpu_drv.o
4848
4949 # add KMS driver
50−amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
50+amdgpu-y += amdgpu_device.o amdgpu_reg_access.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
5151 amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
5252 atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
5353 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
8181 #include "amdgpu_sdma.h"
8282 #include "amdgpu_lsdma.h"
8383 #include "amdgpu_nbio.h"
84+#include "amdgpu_reg_access.h"
8485 #include "amdgpu_hdp.h"
8586 #include "amdgpu_dm.h"
8687 #include "amdgpu_virt.h"
@@ -217,9 +218,7 @@ extern struct amdgpu_watchdog_timer amdgpu_watchdog_timer; · 130 unmodified lines
217218 extern int amdgpu_async_gfx_ring;
218219 extern int amdgpu_mcbp;
219220 extern int amdgpu_discovery;
220−extern int amdgpu_mes;
221221 extern int amdgpu_mes_log_enable;
222−extern int amdgpu_mes_kiq;
223222 extern int amdgpu_uni_mes;
224223 extern int amdgpu_noretry;
225224 extern int amdgpu_force_asic_type;
@@ -680,21 +679,6 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device); · 454 unmodified lines
680679 /*
681680 * Core structure, functions and helpers.
682681 */
683−typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device*, uint32_t);
684−typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
685−
686−typedef uint32_t (*amdgpu_rreg_ext_t)(struct amdgpu_device*, uint64_t);
687−typedef void (*amdgpu_wreg_ext_t)(struct amdgpu_device*, uint64_t, uint32_t);
688−
689−typedef uint64_t (*amdgpu_rreg64_t)(struct amdgpu_device*, uint32_t);
690−typedef void (*amdgpu_wreg64_t)(struct amdgpu_device*, uint32_t, uint64_t);
691−
692−typedef uint64_t (*amdgpu_rreg64_ext_t)(struct amdgpu_device*, uint64_t);
693−typedef void (*amdgpu_wreg64_ext_t)(struct amdgpu_device*, uint64_t, uint64_t);
694−
695−typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
696−typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);
697−
698682 struct amdgpu_mmio_remap {
699683 u32 reg_offset;
700684 resource_size_t bus_addr;
@@ -791,6 +775,12 @@ struct amd_powerplay { · 90 unmodified lines
791775 (rid == 0x01) || \
792776 (rid == 0x10))))
793777
778+enum 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+
794784 struct amdgpu_mqd_prop {
795785 uint64_t mqd_gpu_addr;
796786 uint64_t hqd_base_gpu_addr;
@@ -811,6 +801,10 @@ struct amdgpu_mqd_prop { · 14 unmodified lines
811801 uint64_t fence_address;
812802 bool tmz_queue;
813803 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;
814808 };
815809
816810 struct amdgpu_mqd {
@@ -906,42 +900,8 @@ struct amdgpu_device { · 89 unmodified lines
906900 /* protects concurrent MM_INDEX/DATA based register access */
907901 spinlock_t mmio_idx_lock;
908902 struct amdgpu_mmio_remap rmmio_remap;
909− /* protects concurrent SMC based register access */
910− spinlock_t smc_idx_lock;
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;
903+ /* Indirect register access blocks */
904+ struct amdgpu_reg_access reg;
945905 struct amdgpu_doorbell doorbell;
946906
947907 /* clock/pll info */
@@ -1297,42 +1257,6 @@ size_t amdgpu_device_aper_access(struct amdgpu_device *adev, loff_t pos, · 349 unmodified lines
12971257
12981258 void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
12991259 void *buf, size_t size, bool write);
1300−uint32_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);
1303−uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
1304− uint32_t reg, uint32_t acc_flags);
1305−u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,
1306− u64 reg_addr);
1307−uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev,
1308− uint32_t reg, uint32_t acc_flags,
1309− uint32_t xcc_id);
1310−void amdgpu_device_wreg(struct amdgpu_device *adev,
1311− uint32_t reg, uint32_t v,
1312− uint32_t acc_flags);
1313−void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
1314− u64 reg_addr, u32 reg_data);
1315−void 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);
1319−void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
1320− uint32_t reg, uint32_t v, uint32_t xcc_id);
1321−void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
1322−uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
1323−
1324−u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
1325− u32 reg_addr);
1326−u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
1327− u32 reg_addr);
1328−u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev,
1329− u64 reg_addr);
1330−void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
1331− u32 reg_addr, u32 reg_data);
1332−void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
1333− u32 reg_addr, u64 reg_data);
1334−void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev,
1335− u64 reg_addr, u64 reg_data);
13361260 u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev);
13371261 bool amdgpu_device_asic_has_dc_support(struct pci_dev *pdev,
13381262 enum amd_asic_type asic_type);
@@ -1372,28 +1296,30 @@ int emu_soc_asic_init(struct amdgpu_device *adev); · 33 unmodified lines
13721296 #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
13731297 #define RREG32_XCC(reg, inst) amdgpu_device_xcc_rreg(adev, (reg), 0, inst)
13741298 #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))
1376−#define WREG32_PCIE(reg, v) adev->pcie_wreg(adev, (reg), (v))
1377−#define RREG32_PCIE_PORT(reg) adev->pciep_rreg(adev, (reg))
1378−#define WREG32_PCIE_PORT(reg, v) adev->pciep_wreg(adev, (reg), (v))
1379−#define RREG32_PCIE_EXT(reg) adev->pcie_rreg_ext(adev, (reg))
1380−#define WREG32_PCIE_EXT(reg, v) adev->pcie_wreg_ext(adev, (reg), (v))
1381−#define RREG64_PCIE(reg) adev->pcie_rreg64(adev, (reg))
1382−#define WREG64_PCIE(reg, v) adev->pcie_wreg64(adev, (reg), (v))
1383−#define RREG64_PCIE_EXT(reg) adev->pcie_rreg64_ext(adev, (reg))
1384−#define WREG64_PCIE_EXT(reg, v) adev->pcie_wreg64_ext(adev, (reg), (v))
1385−#define RREG32_SMC(reg) adev->smc_rreg(adev, (reg))
1386−#define WREG32_SMC(reg, v) adev->smc_wreg(adev, (reg), (v))
1387−#define RREG32_UVD_CTX(reg) adev->uvd_ctx_rreg(adev, (reg))
1388−#define WREG32_UVD_CTX(reg, v) adev->uvd_ctx_wreg(adev, (reg), (v))
1389−#define RREG32_DIDT(reg) adev->didt_rreg(adev, (reg))
1390−#define WREG32_DIDT(reg, v) adev->didt_wreg(adev, (reg), (v))
1391−#define RREG32_GC_CAC(reg) adev->gc_cac_rreg(adev, (reg))
1392−#define WREG32_GC_CAC(reg, v) adev->gc_cac_wreg(adev, (reg), (v))
1393−#define RREG32_SE_CAC(reg) adev->se_cac_rreg(adev, (reg))
1394−#define WREG32_SE_CAC(reg, v) adev->se_cac_wreg(adev, (reg), (v))
1395−#define RREG32_AUDIO_ENDPT(block, reg) adev->audio_endpt_rreg(adev, (block), (reg))
1396−#define WREG32_AUDIO_ENDPT(block, reg, v) adev->audio_endpt_wreg(adev, (block), (reg), (v))
1299+#define RREG32_PCIE(reg) amdgpu_reg_pcie_rd32(adev, (reg))
1300+#define WREG32_PCIE(reg, v) amdgpu_reg_pcie_wr32(adev, (reg), (v))
1301+#define RREG32_PCIE_PORT(reg) amdgpu_reg_pciep_rd32(adev, (reg))
1302+#define WREG32_PCIE_PORT(reg, v) amdgpu_reg_pciep_wr32(adev, (reg), (v))
1303+#define RREG32_PCIE_EXT(reg) amdgpu_reg_pcie_ext_rd32(adev, (reg))
1304+#define WREG32_PCIE_EXT(reg, v) amdgpu_reg_pcie_ext_wr32(adev, (reg), (v))
1305+#define RREG64_PCIE(reg) amdgpu_reg_pcie_rd64(adev, (reg))
1306+#define WREG64_PCIE(reg, v) amdgpu_reg_pcie_wr64(adev, (reg), (v))
1307+#define RREG64_PCIE_EXT(reg) amdgpu_reg_pcie_ext_rd64(adev, (reg))
1308+#define WREG64_PCIE_EXT(reg, v) amdgpu_reg_pcie_ext_wr64(adev, (reg), (v))
1309+#define RREG32_SMC(reg) amdgpu_reg_smc_rd32(adev, (reg))
1310+#define WREG32_SMC(reg, v) amdgpu_reg_smc_wr32(adev, (reg), (v))
1311+#define RREG32_UVD_CTX(reg) amdgpu_reg_uvd_ctx_rd32(adev, (reg))
1312+#define WREG32_UVD_CTX(reg, v) amdgpu_reg_uvd_ctx_wr32(adev, (reg), (v))
1313+#define RREG32_DIDT(reg) amdgpu_reg_didt_rd32(adev, (reg))
1314+#define WREG32_DIDT(reg, v) amdgpu_reg_didt_wr32(adev, (reg), (v))
1315+#define RREG32_GC_CAC(reg) amdgpu_reg_gc_cac_rd32(adev, (reg))
1316+#define WREG32_GC_CAC(reg, v) amdgpu_reg_gc_cac_wr32(adev, (reg), (v))
1317+#define RREG32_SE_CAC(reg) amdgpu_reg_se_cac_rd32(adev, (reg))
1318+#define WREG32_SE_CAC(reg, v) amdgpu_reg_se_cac_wr32(adev, (reg), (v))
1319+#define RREG32_AUDIO_ENDPT(block, reg) \
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))
13971323 #define WREG32_P(reg, val, mask) \
13981324 do { \
13991325 uint32_t tmp_ = RREG32(reg); \
@@ -1523,10 +1449,6 @@ void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev, · 123 unmodified lines
15231449 struct amdgpu_ring *ring);
15241450
15251451 void amdgpu_device_halt(struct amdgpu_device *adev);
1526−u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
1527− u32 reg);
1528−void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
1529− u32 reg, u32 v);
15301452 struct dma_fence *amdgpu_device_get_gang(struct amdgpu_device *adev);
15311453 struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
15321454 struct dma_fence *gang);
@@ -1536,6 +1458,8 @@ struct dma_fence *amdgpu_device_enforce_isolation(struct amdgpu_device *adev, · 3 unmodified lines
15361458 bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev);
15371459 ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring);
15381460 ssize_t amdgpu_show_reset_mask(char *buf, uint32_t supported_reset);
1461+void amdgpu_sdma_set_vm_pte_scheds(struct amdgpu_device *adev,
1462+ const struct amdgpu_vm_pte_funcs *vm_pte_funcs);
15391463
15401464 /* atpx handler */
15411465 #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
14391439 *process_info = info;
14401440 }
14411441
1442− vm->process_info = *process_info;
1442+ if (cmpxchg(&vm->process_info, NULL, *process_info) != NULL) {
1443+ ret = -EINVAL;
1444+ goto already_acquired;
1445+ }
14431446
14441447 /* Validate page directory and attach eviction fence */
14451448 ret = amdgpu_bo_reserve(vm->root.bo, true);
@@ -1479,6 +1482,7 @@ validate_pd_fail: · 33 unmodified lines
14791482 amdgpu_bo_unreserve(vm->root.bo);
14801483 reserve_pd_fail:
14811484 vm->process_info = NULL;
1485+already_acquired:
14821486 if (info) {
14831487 dma_fence_put(&info->eviction_fence->base);
14841488 *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
3535 struct dma_fence *fence;
3636 int i, r;
3737
38+ mutex_lock(&adev->mman.default_entity.lock);
3839 stime = ktime_get();
3940 for (i = 0; i < n; i++) {
4041 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
4950 }
5051
5152 exit_do_move:
53+ mutex_unlock(&adev->mman.default_entity.lock);
5254 etime = ktime_get();
5355 *time_ms = ktime_ms_delta(etime, stime);
5456
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
8484 if (r)
8585 return r;
8686
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−
9487 /* Check if we can add this IB to some existing job */
9588 for (i = 0; i < p->gang_size; ++i)
9689 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
231231 } else {
232232 struct amdgpu_fpriv *fpriv;
233233
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);
235236 r = amdgpu_xcp_select_scheds(adev, hw_ip, hw_prio, fpriv,
236237 &num_scheds, &scheds);
237238 if (r)
238239 goto error_free_entity;
239240 }
240241
242+ if (num_scheds == 0) {
243+ r = -EINVAL;
244+ goto error_free_entity;
245+ }
246+
241247 /* disable load balance if the hw engine retains context among dependent jobs */
242248 if (hw_ip == AMDGPU_HW_IP_VCN_ENC ||
243249 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
348354 else
349355 ctx->stable_pstate = current_stable_pstate;
350356
351− ctx->ctx_mgr = &(fpriv->ctx_mgr);
352357 return 0;
353358 }
354359
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h+6−7
@@ -44,20 +44,19 @@ struct amdgpu_ctx_entity { · 43 unmodified lines
4444
4545 struct amdgpu_ctx {
4646 struct kref refcount;
47− struct amdgpu_ctx_mgr *mgr;
47+ spinlock_t ring_lock;
4848 unsigned reset_counter;
4949 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;
5450 int32_t init_priority;
5551 int32_t override_priority;
52+ uint32_t stable_pstate;
5653 atomic_t guilty;
54+ bool preamble_presented;
55+ uint64_t generation;
5756 unsigned long ras_counter_ce;
5857 unsigned long ras_counter_ue;
59− uint32_t stable_pstate;
60− struct amdgpu_ctx_mgr *ctx_mgr;
58+ struct amdgpu_ctx_mgr *mgr;
59+ struct amdgpu_ctx_entity *entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM];
6160 };
6261
6362 struct 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
638638 if (size & 0x3 || *pos & 0x3)
639639 return -EINVAL;
640640
641− if (!adev->didt_rreg)
641+ if (!adev->reg.didt.rreg)
642642 return -EOPNOTSUPP;
643643
644644 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
696696 if (size & 0x3 || *pos & 0x3)
697697 return -EINVAL;
698698
699− if (!adev->didt_wreg)
699+ if (!adev->reg.didt.wreg)
700700 return -EOPNOTSUPP;
701701
702702 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
752752 ssize_t result = 0;
753753 int r;
754754
755− if (!adev->smc_rreg)
755+ if (!adev->reg.smc.rreg)
756756 return -EOPNOTSUPP;
757757
758758 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
810810 ssize_t result = 0;
811811 int r;
812812
813− if (!adev->smc_wreg)
813+ if (!adev->reg.smc.wreg)
814814 return -EOPNOTSUPP;
815815
816816 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
846846 return false;
847847 }
848848
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− */
858−uint32_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− */
897−uint8_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− */
918−uint32_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− */
965−void 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− */
986−void 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− */
1019−void 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− */
1049−void 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− */
1087−u32 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−
1110−u32 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− */
1170−u64 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−
1198−u64 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− */
1256−void 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−
1277−void 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− */
1325−void 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−
1352−void 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−
1401849 /**
1402850 * amdgpu_device_get_rev_id - query device rev_id
1403851 *
@@ -1410,149 +858,6 @@ u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev) · 6 unmodified lines
1410858 return adev->nbio.funcs->get_rev_id(adev);
1411859 }
1412860
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− */
1423−static 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−
1430−static 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− */
1447−static 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−
1455−static 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− */
1473−static 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−
1481−static 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− */
1498−static 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−
1506−static 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− */
1525−static 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− */
1546−static 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−
1556861 static uint32_t amdgpu_device_get_vbios_flags(struct amdgpu_device *adev)
1557862 {
1558863 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
31562461 if (r)
31572462 goto init_failed;
31582463
3159− if (adev->mman.buffer_funcs_ring &&
3160− adev->mman.buffer_funcs_ring->sched.ready)
3161− amdgpu_ttm_set_buffer_funcs_status(adev, true);
2464+ amdgpu_ttm_set_buffer_funcs_status(adev, true);
31622465
31632466 /* Don't init kfd if whole hive need to be reset during init */
31642467 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
40473350
40483351 r = amdgpu_device_ip_resume_phase2(adev);
40493352
4050− if (adev->mman.buffer_funcs_ring->sched.ready)
4051− amdgpu_ttm_set_buffer_funcs_status(adev, true);
3353+ amdgpu_ttm_set_buffer_funcs_status(adev, true);
40523354
40533355 if (r)
40543356 return r;
@@ -4108,17 +3410,6 @@ bool amdgpu_device_asic_has_dc_support(struct pci_dev *pdev, · 53 unmodified lines
41083410 case CHIP_VERDE:
41093411 case CHIP_OLAND:
41103412 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;
41223413 default:
41233414 return amdgpu_dc != 0;
41243415 #else
@@ -4396,26 +3687,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 271 unmodified lines
43963687 adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS);
43973688 bitmap_zero(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
43983689
4399− adev->smc_rreg = &amdgpu_invalid_rreg;
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;
3690+ amdgpu_reg_access_init(adev);
44193691
44203692 dev_info(
44213693 adev->dev,
@@ -4460,13 +3732,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 38 unmodified lines
44603732 return r;
44613733
44623734 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);
44703735 spin_lock_init(&adev->mm_stats.lock);
44713736 spin_lock_init(&adev->virt.rlcg_reg_lock);
44723737 spin_lock_init(&adev->wb.lock);
@@ -5195,8 +4460,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients) · 722 unmodified lines
51954460 return 0;
51964461
51974462 unwind_evict:
5198− if (adev->mman.buffer_funcs_ring->sched.ready)
5199− amdgpu_ttm_set_buffer_funcs_status(adev, true);
4463+ amdgpu_ttm_set_buffer_funcs_status(adev, true);
52004464 amdgpu_fence_driver_hw_init(adev);
52014465
52024466 unwind_userq:
@@ -5930,8 +5194,7 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context) · 727 unmodified lines
59305194 if (r)
59315195 goto out;
59325196
5933− if (tmp_adev->mman.buffer_funcs_ring->sched.ready)
5934− amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
5197+ amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
59355198
59365199 r = amdgpu_device_ip_resume_phase3(tmp_adev);
59375200 if (r)
@@ -6309,7 +5572,7 @@ static void amdgpu_device_halt_activities(struct amdgpu_device *adev, · 371 unmodified lines
63095572 if (!amdgpu_ring_sched_ready(ring))
63105573 continue;
63115574
6312− drm_sched_stop(&ring->sched, job ? &job->base : NULL);
5575+ drm_sched_wqueue_stop(&ring->sched);
63135576
63145577 if (need_emergency_restart)
63155578 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
63935656 if (!amdgpu_ring_sched_ready(ring))
63945657 continue;
63955658
6396− drm_sched_start(&ring->sched, 0);
5659+ drm_sched_wqueue_start(&ring->sched);
63975660 }
63985661
63995662 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
73766639 pci_wait_for_pending_transaction(pdev);
73776640 }
73786641
7379−u32 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−
7396−void 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−
74126642 /**
74136643 * amdgpu_device_get_gang - return a reference to the current gang
74146644 * @adev: amdgpu_device pointer
@@ -7591,36 +6821,6 @@ bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev) · 176 unmodified lines
75916821 }
75926822 }
75936823
7594−uint32_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−
76246824 ssize_t amdgpu_get_soft_full_reset_mask(struct amdgpu_ring *ring)
76256825 {
76266826 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
22982298 case IP_VERSION(3, 5, 1):
22992299 case IP_VERSION(3, 6, 0):
23002300 case IP_VERSION(4, 1, 0):
2301+ case IP_VERSION(4, 2, 0):
23012302 /* TODO: Fix IP version. DC code expects version 4.0.1 */
23022303 if (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(4, 1, 0))
23032304 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
223223 int amdgpu_async_gfx_ring = 1;
224224 int amdgpu_mcbp = -1;
225225 int amdgpu_discovery = -1;
226−int amdgpu_mes;
227226 int amdgpu_mes_log_enable = 0;
228−int amdgpu_mes_kiq;
229227 int amdgpu_uni_mes = 1;
230228 int amdgpu_noretry = -1;
231229 int amdgpu_force_asic_type = -1;
@@ -690,15 +688,6 @@ MODULE_PARM_DESC(discovery, · 458 unmodified lines
690688 "Allow driver to discover hardware IPs from IP Discovery table at the top of VRAM");
691689 module_param_named(discovery, amdgpu_discovery, int, 0444);
692690
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− */
698−MODULE_PARM_DESC(mes,
699− "Enable Micro Engine Scheduler (0 = disabled (default), 1 = enabled)");
700−module_param_named(mes, amdgpu_mes, int, 0444);
701−
702691 /**
703692 * DOC: mes_log_enable (int)
704693 * 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
708697 "Enable Micro Engine Scheduler log (0 = disabled (default), 1 = enabled)");
709698 module_param_named(mes_log_enable, amdgpu_mes_log_enable, int, 0444);
710699
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− */
716−MODULE_PARM_DESC(mes_kiq,
717− "Enable Micro Engine Scheduler KIQ (0 = disabled (default), 1 = enabled)");
718−module_param_named(mes_kiq, amdgpu_mes_kiq, int, 0444);
719−
720700 /**
721701 * DOC: uni_mes (int)
722702 * 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
8989 return seq;
9090 }
9191
92−static void amdgpu_fence_save_fence_wptr_start(struct amdgpu_fence *af)
93−{
94− af->fence_wptr_start = af->ring->wptr;
95−}
96−
97−static void amdgpu_fence_save_fence_wptr_end(struct amdgpu_fence *af)
98−{
99− af->fence_wptr_end = af->ring->wptr;
100−}
101−
10292 /**
10393 * amdgpu_fence_emit - emit a fence on the requested ring
10494 *
@@ -107,16 +97,14 @@ static void amdgpu_fence_save_fence_wptr_end(struct amdgpu_fence *af) · 2 unmodified lines
10797 * @flags: flags to pass into the subordinate .emit_fence() call
10898 *
10999 * Emits a fence command on the requested ring (all asics).
110− * Returns 0 on success, -ENOMEM on failure.
111100 */
112−int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
113− unsigned int flags)
101+void amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
102+ unsigned int flags)
114103 {
115104 struct amdgpu_device *adev = ring->adev;
116105 struct dma_fence *fence;
117106 struct dma_fence __rcu **ptr;
118107 uint32_t seq;
119− int r;
120108
121109 fence = &af->base;
122110 af->ring = ring;
@@ -126,11 +114,9 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af, · 3 unmodified lines
126114 &ring->fence_drv.lock,
127115 adev->fence_context + ring->idx, seq);
128116
129− amdgpu_fence_save_fence_wptr_start(af);
130117 amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
131118 seq, flags | AMDGPU_FENCE_FLAG_INT);
132− amdgpu_fence_save_fence_wptr_end(af);
133− amdgpu_fence_save_wptr(af);
119+
134120 pm_runtime_get_noresume(adev_to_drm(adev)->dev);
135121 ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
136122 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
141127 rcu_read_unlock();
142128
143129 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);
145136 dma_fence_put(old);
146− if (r)
147− return r;
148137 }
149138 }
150139
@@ -154,8 +143,6 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af, · 3 unmodified lines
154143 * emitting the fence would mess up the hardware ring buffer.
155144 */
156145 rcu_assign_pointer(*ptr, dma_fence_get(fence));
157−
158− return 0;
159146 }
160147
161148 /**
@@ -241,7 +228,6 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring) · 79 unmodified lines
241228
242229 do {
243230 struct dma_fence *fence, **ptr;
244− struct amdgpu_fence *am_fence;
245231
246232 ++last_seq;
247233 last_seq &= drv->num_fences_mask;
@@ -254,12 +240,6 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring) · 6 unmodified lines
254240 if (!fence)
255241 continue;
256242
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;
263243 dma_fence_signal(fence);
264244 dma_fence_put(fence);
265245 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
708688 */
709689
710690 /**
711− * amdgpu_fence_driver_update_timedout_fence_state - Update fence state and set errors
691+ * amdgpu_ring_set_fence_errors_and_reemit - Set dma_fence errors and reemit
712692 *
713− * @af: fence of the ring to update
693+ * @ring: the ring to operate on
694+ * @guilty_fence: fence of the ring to update
714695 *
715696 */
716−void amdgpu_fence_driver_update_timedout_fence_state(struct amdgpu_fence *af)
697+void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
698+ struct amdgpu_fence *guilty_fence)
717699 {
718700 struct dma_fence *unprocessed;
719701 struct dma_fence __rcu **ptr;
720702 struct amdgpu_fence *fence;
721− struct amdgpu_ring *ring = af->ring;
722703 unsigned long flags;
723704 u32 seq, last_seq;
724− bool reemitted = false;
705+ unsigned int i;
706+ bool is_guilty_fence;
707+ bool is_guilty_context;
725708
726709 last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
727710 seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
728711
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);
730714 spin_lock_irqsave(&ring->fence_drv.lock, flags);
731715 do {
732716 last_seq++;
@@ -738,39 +722,45 @@ void amdgpu_fence_driver_update_timedout_fence_state(struct amdgpu_fence *af) · 5 unmodified lines
738722
739723 if (unprocessed && !dma_fence_is_signaled_locked(unprocessed)) {
740724 fence = container_of(unprocessed, struct amdgpu_fence, base);
725+ is_guilty_fence = fence == guilty_fence;
726+ is_guilty_context = fence->context == guilty_fence->context;
741727
742− if (fence->reemitted > 1)
743− reemitted = true;
744− else if (fence == af)
728+ /* mark all fences from the guilty context with an error */
729+ if (is_guilty_fence)
745730 dma_fence_set_error(&fence->base, -ETIME);
746− else if (fence->context == af->context)
731+ else if (is_guilty_context)
747732 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+ }
748746 }
749747 rcu_read_unlock();
750748 } while (last_seq != seq);
751749 spin_unlock_irqrestore(&ring->fence_drv.lock, flags);
752−
753− if (reemitted) {
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−
760−void amdgpu_fence_save_wptr(struct amdgpu_fence *af)
761−{
762− af->wptr = af->ring->wptr;
750+ amdgpu_ring_commit(ring);
751+ ring->reemit = false;
763752 }
764753
765754 static void amdgpu_ring_backup_unprocessed_command(struct amdgpu_ring *ring,
766− u64 start_wptr, u64 end_wptr)
755+ struct amdgpu_fence *af)
767756 {
768− unsigned int first_idx = start_wptr & ring->buf_mask;
769− unsigned int last_idx = end_wptr & ring->buf_mask;
757+ unsigned int first_idx = af->ib_wptr & ring->buf_mask;
758+ unsigned int dw_size = af->ib_dw_size;
770759 unsigned int i;
771760
761+ af->backup_idx = ring->ring_backup_entries_to_copy;
772762 /* 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)
774764 ring->ring_backup[ring->ring_backup_entries_to_copy++] = ring->ring[i];
775765 }
776766
@@ -780,12 +770,10 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring, · 3 unmodified lines
780770 struct dma_fence *unprocessed;
781771 struct dma_fence __rcu **ptr;
782772 struct amdgpu_fence *fence;
783− u64 wptr;
784773 u32 seq, last_seq;
785774
786775 last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
787776 seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
788− wptr = ring->fence_drv.signalled_wptr;
789777 ring->ring_backup_entries_to_copy = 0;
790778
791779 do {
@@ -799,21 +787,7 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring, · 7 unmodified lines
799787 if (unprocessed && !dma_fence_is_signaled(unprocessed)) {
800788 fence = container_of(unprocessed, struct amdgpu_fence, base);
801789
802− /* save everything if the ring is not guilty, otherwise
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++;
790+ amdgpu_ring_backup_unprocessed_command(ring, fence);
817791 }
818792 rcu_read_unlock();
819793 } 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
503503 &ring->mqd_ptr);
504504 }
505505
506+void 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+
506555 int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id)
507556 {
508557 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
583583 int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
584584 unsigned mqd_size, int xcc_id);
585585 void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, int xcc_id);
586+void 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);
586588 int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id);
587589 int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev, int xcc_id);
588590 int 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
742742 * translation. Avoid this by doing the invalidation from the SDMA
743743 * itself at least for GART.
744744 */
745− mutex_lock(&adev->mman.gtt_window_lock);
745+ mutex_lock(&adev->mman.default_entity.lock);
746746 r = amdgpu_job_alloc_with_ib(ring->adev, &adev->mman.default_entity.base,
747747 AMDGPU_FENCE_OWNER_UNDEFINED,
748748 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
755755 job->ibs->ptr[job->ibs->length_dw++] = ring->funcs->nop;
756756 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
757757 fence = amdgpu_job_submit(job);
758− mutex_unlock(&adev->mman.gtt_window_lock);
758+ mutex_unlock(&adev->mman.default_entity.lock);
759759
760760 dma_fence_wait(fence, false);
761761 dma_fence_put(fence);
@@ -763,7 +763,7 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, · 1 unmodified line
763763 return;
764764
765765 error_alloc:
766− mutex_unlock(&adev->mman.gtt_window_lock);
766+ mutex_unlock(&adev->mman.default_entity.lock);
767767 dev_err(adev->dev, "Error flushing GPU TLB using the SDMA (%d)!\n", r);
768768 }
769769
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
324324 {
325325 struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
326326 struct ttm_resource_manager *man = &mgr->manager;
327− uint64_t start, size;
328327
329328 man->use_tt = true;
330329 man->func = &amdgpu_gtt_mgr_func;
331330
332331 ttm_resource_manager_init(man, &adev->mman.bdev, gtt_size);
333332
334− start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
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);
333+ drm_mm_init(&mgr->mm, 0, adev->gmc.gart_size >> PAGE_SHIFT);
338334 spin_lock_init(&mgr->lock);
339335
340336 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
129129 struct amdgpu_ib *ib = &ibs[0];
130130 struct dma_fence *tmp = NULL;
131131 struct amdgpu_fence *af;
132+ struct amdgpu_fence *vm_af;
132133 bool need_ctx_switch;
133134 struct amdgpu_vm *vm;
134135 uint64_t fence_ctx;
@@ -215,25 +216,28 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 80 unmodified lines
215216 dma_fence_put(tmp);
216217 }
217218
218− if ((ib->flags & AMDGPU_IB_FLAG_EMIT_MEM_SYNC) && ring->funcs->emit_mem_sync)
219− ring->funcs->emit_mem_sync(ring);
219+ if (job) {
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+ }
220227
221− if (ring->funcs->emit_wave_limit &&
222− ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
223− ring->funcs->emit_wave_limit(ring, true);
228+ /* IB sequence */
229+ af->ib_wptr = ring->wptr;
230+ amdgpu_ring_ib_begin(ring);
224231
225232 if (ring->funcs->insert_start)
226233 ring->funcs->insert_start(ring);
227234
228− if (job) {
229− r = amdgpu_vm_flush(ring, job, need_pipe_sync);
230− if (r) {
231− amdgpu_ring_undo(ring);
232− goto free_fence;
233− }
234− }
235+ if ((ib->flags & AMDGPU_IB_FLAG_EMIT_MEM_SYNC) && ring->funcs->emit_mem_sync)
236+ ring->funcs->emit_mem_sync(ring);
235237
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);
237241
238242 if (ring->funcs->emit_gfx_shadow && adev->gfx.cp_gfx_shadow)
239243 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
243247 cond_exec = amdgpu_ring_init_cond_exec(ring,
244248 ring->cond_exe_gpu_addr);
245249
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);
246253 amdgpu_device_flush_hdp(adev, ring);
247254
248255 if (need_ctx_switch)
@@ -281,6 +288,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 32 unmodified lines
281288 amdgpu_ring_emit_frame_cntl(ring, false, secure);
282289
283290 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);
284294
285295 if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE)
286296 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
297307 amdgpu_ring_init_cond_exec(ring, ring->cond_exe_gpu_addr);
298308 }
299309
300− r = 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− }
310+ amdgpu_fence_emit(ring, af, fence_flags);
308311 *f = &af->base;
309312 /* get a ref for the job */
310313 if (job)
@@ -323,15 +326,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, · 12 unmodified lines
323326 ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
324327 ring->funcs->emit_wave_limit(ring, false);
325328
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−
334329 amdgpu_ring_ib_end(ring);
330+
331+ af->ib_dw_size = amdgpu_ring_get_dw_distance(ring, af->ib_wptr, ring->wptr);
332+
335333 amdgpu_ring_commit(ring);
336334
337335 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
9292 struct drm_wedge_task_info *info = NULL;
9393 struct amdgpu_task_info *ti = NULL;
9494 struct amdgpu_device *adev = ring->adev;
95− enum drm_gpu_sched_stat status = DRM_GPU_SCHED_STAT_RESET;
9695 int idx, r;
9796
9897 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
147146 ring->sched.name);
148147 drm_dev_wedged_event(adev_to_drm(adev),
149148 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;
152149 goto exit;
153150 }
154151 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
184181 exit:
185182 amdgpu_vm_put_task_info(ti);
186183 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;
188186 }
189187
190188 int 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
2121 *
2222 *
2323 */
24+#include "amdgpu_reg_access.h"
2425 #include <linux/debugfs.h>
2526 #include <linux/list.h>
2627 #include <linux/module.h>
@@ -42,6 +43,7 @@ · 15 unmodified lines
4243 #include "amdgpu_reset.h"
4344 #include "amdgpu_psp.h"
4445 #include "amdgpu_ras_mgr.h"
46+#include "amdgpu_virt_ras_cmd.h"
4547
4648 #ifdef CONFIG_X86_MCE_AMD
4749 #include <asm/mce.h>
@@ -228,19 +230,30 @@ static int amdgpu_check_address_validity(struct amdgpu_device *adev, · 180 unmodified lines
228230 return 0;
229231
230232 if (amdgpu_sriov_vf(adev)) {
231− if (amdgpu_virt_check_vf_critical_region(adev, address, &hit))
232− return -EPERM;
233− return hit ? -EACCES : 0;
233+ if (amdgpu_uniras_enabled(adev)) {
234+ if (amdgpu_virt_ras_check_address_validity(adev, address, &hit))
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+ }
234243 }
235244
236245 if ((address >= adev->gmc.mc_vram_size) ||
237246 (address >= RAS_UMC_INJECT_ADDR_LIMIT))
238247 return -EFAULT;
239248
240− if (amdgpu_uniras_enabled(adev))
241− count = amdgpu_ras_mgr_lookup_bad_pages_in_a_row(adev, address,
242− page_pfns, ARRAY_SIZE(page_pfns));
243− else
249+ if (amdgpu_uniras_enabled(adev)) {
250+ if (amdgpu_sriov_vf(adev))
251+ count = amdgpu_virt_ras_convert_retired_address(adev, address,
252+ 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
244257 count = amdgpu_umc_lookup_bad_pages_in_a_row(adev,
245258 address, page_pfns, ARRAY_SIZE(page_pfns));
246259
@@ -3118,9 +3131,11 @@ static int __amdgpu_ras_convert_rec_array_from_rom(struct amdgpu_device *adev, · 2871 unmodified lines
31183131 enum amdgpu_memory_partition nps)
31193132 {
31203133 int i = 0;
3134+ uint64_t chan_idx_v2;
31213135 enum amdgpu_memory_partition save_nps;
31223136
31233137 save_nps = (bps[0].retired_page >> UMC_NPS_SHIFT) & UMC_NPS_MASK;
3138+ chan_idx_v2 = bps[0].retired_page & UMC_CHANNEL_IDX_V2;
31243139
31253140 /*old asics just have pa in eeprom*/
31263141 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
31323147 for (i = 0; i < adev->umc.retire_unit; i++)
31333148 bps[i].retired_page &= ~(UMC_NPS_MASK << UMC_NPS_SHIFT);
31343149
3135− if (save_nps) {
3150+ if (save_nps || chan_idx_v2) {
31363151 if (save_nps == nps) {
31373152 if (amdgpu_umc_pages_in_a_row(adev, err_data,
31383153 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
31763191 enum amdgpu_memory_partition nps)
31773192 {
31783193 int i = 0;
3194+ uint64_t chan_idx_v2;
31793195 enum amdgpu_memory_partition save_nps;
31803196
31813197 if (!amdgpu_ras_smu_eeprom_supported(adev)) {
31823198 save_nps = (bps->retired_page >> UMC_NPS_SHIFT) & UMC_NPS_MASK;
3199+ chan_idx_v2 = bps->retired_page & UMC_CHANNEL_IDX_V2;
31833200 bps->retired_page &= ~(UMC_NPS_MASK << UMC_NPS_SHIFT);
31843201 } else {
31853202 /* 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
32013218 err_data->err_addr[i].mcumc_id = bps->mcumc_id;
32023219 }
32033220 } else {
3204− if (bps->address) {
3221+ if (save_nps || chan_idx_v2) {
32053222 if (amdgpu_ras_mca2pa_by_idx(adev, bps, err_data))
32063223 return -EINVAL;
32073224 } else {
32083225 /* for specific old eeprom data, mca address is not stored,
32093226 * calc it from pa
32103227 */
3211− if (amdgpu_umc_pa2mca(adev, bps->retired_page << AMDGPU_GPU_PAGE_SHIFT,
3212− &(bps->address), AMDGPU_NPS1_PARTITION_MODE))
3213− return -EINVAL;
3228+ if (bps->address == 0)
3229+ if (amdgpu_umc_pa2mca(adev,
3230+ bps->retired_page << AMDGPU_GPU_PAGE_SHIFT,
3231+ &(bps->address),
3232+ AMDGPU_NPS1_PARTITION_MODE))
3233+ return -EINVAL;
32143234
32153235 if (amdgpu_ras_mca2pa(adev, bps, err_data))
32163236 return -EOPNOTSUPP;
@@ -5516,11 +5536,11 @@ static void amdgpu_ras_boot_time_error_reporting(struct amdgpu_device *adev, · 2299 unmodified lines
55165536 * is changed. In such case, replace the aqua_vanjaram implementation
55175537 * with more common helper */
55185538 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);
55205540 fw_status = amdgpu_device_indirect_rreg_ext(adev, reg_addr);
55215541
55225542 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);
55245544 boot_error = amdgpu_device_indirect_rreg_ext(adev, reg_addr);
55255545
55265546 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
55865606 int retry_loop;
55875607
55885608 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);
55905610
55915611 for (retry_loop = 0; retry_loop < AMDGPU_RAS_BOOT_STATUS_POLLING_LIMIT; retry_loop++) {
55925612 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
508508 control->bad_channel_bitmap = 0;
509509 amdgpu_dpm_send_hbm_bad_channel_flag(adev, control->bad_channel_bitmap);
510510 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;
511514
512515 amdgpu_ras_debugfs_set_ret_size(control);
513516
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+
36+void 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+
75+uint32_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+
84+void 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+
93+uint32_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+
103+void 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+
114+uint32_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+
123+void 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+
132+uint32_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+
141+void 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+
152+uint32_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+
161+void 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+
172+uint32_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+
183+void 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+
194+uint32_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+
203+void 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+
212+uint32_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+
221+void 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+
231+uint64_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+
240+void 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+
249+uint64_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+
258+void 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+
268+uint32_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+
277+void 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+
286+static 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+
301+uint64_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+
322+uint64_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+ */
364+uint32_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+ */
403+uint8_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+ */
423+uint32_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+ */
468+void 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+ */
489+void 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+ */
521+void 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+ */
549+void 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+ */
585+u32 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+
607+u32 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+ */
668+u64 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+
695+u64 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+ */
753+void 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+
774+void 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+ */
823+void 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+
850+void 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+
900+u32 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+
916+void 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+
931+uint32_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+
32+struct amdgpu_device;
33+
34+typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device *, uint32_t);
35+typedef void (*amdgpu_wreg_t)(struct amdgpu_device *, uint32_t, uint32_t);
36+typedef uint32_t (*amdgpu_rreg_ext_t)(struct amdgpu_device *, uint64_t);
37+typedef void (*amdgpu_wreg_ext_t)(struct amdgpu_device *, uint64_t, uint32_t);
38+typedef uint64_t (*amdgpu_rreg64_t)(struct amdgpu_device *, uint32_t);
39+typedef void (*amdgpu_wreg64_t)(struct amdgpu_device *, uint32_t, uint64_t);
40+typedef uint64_t (*amdgpu_rreg64_ext_t)(struct amdgpu_device *, uint64_t);
41+typedef void (*amdgpu_wreg64_ext_t)(struct amdgpu_device *, uint64_t, uint64_t);
42+
43+typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device *, uint32_t,
44+ uint32_t);
45+typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device *, uint32_t, uint32_t,
46+ uint32_t);
47+typedef 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+
51+struct amdgpu_reg_ind {
52+ spinlock_t lock;
53+ amdgpu_rreg_t rreg;
54+ amdgpu_wreg_t wreg;
55+};
56+
57+struct amdgpu_reg_ind_blk {
58+ spinlock_t lock;
59+ amdgpu_block_rreg_t rreg;
60+ amdgpu_block_wreg_t wreg;
61+};
62+
63+struct 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+
77+struct amdgpu_reg_smn_ext {
78+ amdgpu_reg_get_smn_base64_t get_smn_base;
79+};
80+
81+struct 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+
92+void amdgpu_reg_access_init(struct amdgpu_device *adev);
93+uint32_t amdgpu_reg_smc_rd32(struct amdgpu_device *adev, uint32_t reg);
94+void amdgpu_reg_smc_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
95+uint32_t amdgpu_reg_uvd_ctx_rd32(struct amdgpu_device *adev, uint32_t reg);
96+void amdgpu_reg_uvd_ctx_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
97+uint32_t amdgpu_reg_didt_rd32(struct amdgpu_device *adev, uint32_t reg);
98+void amdgpu_reg_didt_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
99+uint32_t amdgpu_reg_gc_cac_rd32(struct amdgpu_device *adev, uint32_t reg);
100+void amdgpu_reg_gc_cac_wr32(struct amdgpu_device *adev, uint32_t reg,
101+ uint32_t v);
102+uint32_t amdgpu_reg_se_cac_rd32(struct amdgpu_device *adev, uint32_t reg);
103+void amdgpu_reg_se_cac_wr32(struct amdgpu_device *adev, uint32_t reg,
104+ uint32_t v);
105+uint32_t amdgpu_reg_audio_endpt_rd32(struct amdgpu_device *adev, uint32_t block,
106+ uint32_t reg);
107+void amdgpu_reg_audio_endpt_wr32(struct amdgpu_device *adev, uint32_t block,
108+ uint32_t reg, uint32_t v);
109+uint32_t amdgpu_reg_pcie_rd32(struct amdgpu_device *adev, uint32_t reg);
110+void amdgpu_reg_pcie_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
111+uint32_t amdgpu_reg_pcie_ext_rd32(struct amdgpu_device *adev, uint64_t reg);
112+void amdgpu_reg_pcie_ext_wr32(struct amdgpu_device *adev, uint64_t reg,
113+ uint32_t v);
114+uint64_t amdgpu_reg_pcie_rd64(struct amdgpu_device *adev, uint32_t reg);
115+void amdgpu_reg_pcie_wr64(struct amdgpu_device *adev, uint32_t reg, uint64_t v);
116+uint64_t amdgpu_reg_pcie_ext_rd64(struct amdgpu_device *adev, uint64_t reg);
117+void amdgpu_reg_pcie_ext_wr64(struct amdgpu_device *adev, uint64_t reg,
118+ uint64_t v);
119+uint32_t amdgpu_reg_pciep_rd32(struct amdgpu_device *adev, uint32_t reg);
120+void amdgpu_reg_pciep_wr32(struct amdgpu_device *adev, uint32_t reg,
121+ uint32_t v);
122+uint64_t amdgpu_reg_get_smn_base64(struct amdgpu_device *adev,
123+ enum amd_hw_ip_block_type block,
124+ int die_inst);
125+uint64_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+
129+uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
130+ uint32_t acc_flags);
131+uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev, uint32_t reg,
132+ uint32_t acc_flags, uint32_t xcc_id);
133+void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
134+ uint32_t acc_flags);
135+void amdgpu_device_xcc_wreg(struct amdgpu_device *adev, uint32_t reg,
136+ uint32_t v, uint32_t acc_flags, uint32_t xcc_id);
137+void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg,
138+ uint32_t v, uint32_t xcc_id);
139+void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset,
140+ uint8_t value);
141+uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
142+
143+u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev, u32 reg_addr);
144+u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev, u64 reg_addr);
145+u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev, u32 reg_addr);
146+u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev, u64 reg_addr);
147+void amdgpu_device_indirect_wreg(struct amdgpu_device *adev, u32 reg_addr,
148+ u32 reg_data);
149+void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev, u64 reg_addr,
150+ u32 reg_data);
151+void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev, u32 reg_addr,
152+ u64 reg_data);
153+void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev, u64 reg_addr,
154+ u64 reg_data);
155+
156+u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev, u32 reg);
157+void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev, u32 reg, u32 v);
158+
159+uint32_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
9090 ndw = (ndw + ring->funcs->align_mask) & ~ring->funcs->align_mask;
9191
9292 /* Make sure we aren't trying to allocate more space
93− * than the maximum for one submission
93+ * than the maximum for one submission. Skip for reemit
94+ * since we may be reemitting several submissions.
9495 */
95− if (WARN_ON_ONCE(ndw > ring->max_dw))
96− return -ENOMEM;
96+ if (!ring->reemit) {
97+ if (WARN_ON_ONCE(ndw > ring->max_dw))
98+ return -ENOMEM;
99+ }
97100
98101 ring->count_dw = ndw;
99102 ring->wptr_old = ring->wptr;
@@ -104,29 +107,6 @@ int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned int ndw) · 4 unmodified lines
104107 return 0;
105108 }
106109
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− */
117−static 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−
130110 /**
131111 * amdgpu_ring_insert_nop - insert NOP packets
132112 *
@@ -875,7 +855,6 @@ void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring, · 742 unmodified lines
875855 int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,
876856 struct amdgpu_fence *guilty_fence)
877857 {
878− unsigned int i;
879858 int r;
880859
881860 /* verify that the ring is functional */
@@ -883,16 +862,9 @@ int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring, · 1 unmodified line
883862 if (r)
884863 return r;
885864
886− /* set an error on all fences from the context */
887− if (guilty_fence)
888− amdgpu_fence_driver_update_timedout_fence_state(guilty_fence);
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− }
865+ /* set an error on all fences from the context and reemit */
866+ amdgpu_ring_set_fence_errors_and_reemit(ring, guilty_fence);
867+
896868 return 0;
897869 }
898870
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+24−18
@@ -121,7 +121,6 @@ struct amdgpu_fence_driver { · 120 unmodified lines
121121 /* sync_seq is protected by ring emission lock */
122122 uint32_t sync_seq;
123123 atomic_t last_seq;
124− u64 signalled_wptr;
125124 bool initialized;
126125 struct amdgpu_irq_src *irq_src;
127126 unsigned irq_type;
@@ -146,23 +145,23 @@ struct amdgpu_fence { · 18 unmodified lines
146145 struct amdgpu_ring *ring;
147146 ktime_t start_timestamp;
148147
149− /* wptr for the total submission for resets */
150− u64 wptr;
148+ /* location and size of the IB */
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;
151153 /* fence context for resets */
152154 u64 context;
153− /* has this fence been reemitted */
154− unsigned int reemitted;
155− /* wptr for the fence for the submission */
156− u64 fence_wptr_start;
157− u64 fence_wptr_end;
155+ /* idx for ring backups */
156+ unsigned int backup_idx;
158157 };
159158
160159 extern const struct drm_sched_backend_ops amdgpu_sched_ops;
161160
162161 void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);
163162 void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
164−void amdgpu_fence_driver_update_timedout_fence_state(struct amdgpu_fence *af);
165−void amdgpu_fence_save_wptr(struct amdgpu_fence *af);
163+void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
164+ struct amdgpu_fence *guilty_fence);
166165
167166 int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
168167 int 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
172171 void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev);
173172 int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev);
174173 void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev);
175−int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
176− unsigned int flags);
174+void amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
175+ unsigned int flags);
177176 int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s,
178177 uint32_t timeout);
179178 bool amdgpu_fence_process(struct amdgpu_ring *ring);
@@ -313,6 +312,7 @@ struct amdgpu_ring { · 133 unmodified lines
313312 /* backups for resets */
314313 uint32_t *ring_backup;
315314 unsigned int ring_backup_entries_to_copy;
315+ bool reemit;
316316 unsigned rptr_offs;
317317 u64 rptr_gpu_addr;
318318 u32 *rptr_cpu_addr;
@@ -522,6 +522,17 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, · 203 unmodified lines
522522 ring->count_dw -= count_dw;
523523 }
524524
525+static 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+
525536 /**
526537 * amdgpu_ring_patch_cond_exec - patch dw count of conditional execute
527538 * @ring: amdgpu_ring structure
@@ -532,18 +543,13 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, · 4 unmodified lines
532543 static inline void amdgpu_ring_patch_cond_exec(struct amdgpu_ring *ring,
533544 unsigned int offset)
534545 {
535− unsigned cur;
536−
537546 if (!ring->funcs->init_cond_exec)
538547 return;
539548
540549 WARN_ON(offset > ring->buf_mask);
541550 WARN_ON(ring->ring[offset] != 0);
542551
543− cur = (ring->wptr - 1) & ring->buf_mask;
544− if (cur < offset)
545− cur += ring->ring_size >> 2;
546− ring->ring[offset] = cur - offset;
552+ ring->ring[offset] = amdgpu_ring_get_dw_distance(ring, offset, ring->wptr - 1);
547553 }
548554
549555 int 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
163163 }
164164
165165 static struct dma_fence *
166−amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_job *job, u32 num_dw)
166+amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entity *entity,
167+ struct amdgpu_job *job, u32 num_dw)
167168 {
168169 struct amdgpu_ring *ring;
169170
@@ -171,6 +172,8 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_job *job, u32 nu · 1 unmodified line
171172 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
172173 WARN_ON(job->ibs[0].length_dw > num_dw);
173174
175+ lockdep_assert_held(&entity->lock);
176+
174177 return amdgpu_job_submit(job);
175178 }
176179
@@ -228,9 +231,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity, · 51 unmodified lines
228231
229232 *size = min(*size, (uint64_t)num_pages * PAGE_SIZE - offset);
230233
231− *addr = adev->gmc.gart_start;
232− *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
233− AMDGPU_GPU_PAGE_SIZE;
234+ *addr = amdgpu_compute_gart_address(&adev->gmc, entity, window);
234235 *addr += offset;
235236
236237 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
248249 src_addr += job->ibs[0].gpu_addr;
249250
250251 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;
252253 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
253254 dst_addr, num_bytes, 0);
254255
@@ -269,7 +270,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity, · 14 unmodified lines
269270 amdgpu_gart_map_vram_range(adev, pa, 0, num_pages, flags, cpu_addr);
270271 }
271272
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));
273274 return 0;
274275 }
275276
@@ -313,7 +314,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, · 37 unmodified lines
313314 amdgpu_res_first(src->mem, src->offset, size, &src_mm);
314315 amdgpu_res_first(dst->mem, dst->offset, size, &dst_mm);
315316
316− mutex_lock(&adev->mman.gtt_window_lock);
317+ mutex_lock(&entity->lock);
317318 while (src_mm.remaining) {
318319 uint64_t from, to, cur_size, tiling_flags;
319320 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
368369 amdgpu_res_next(&dst_mm, cur_size);
369370 }
370371 error:
371− mutex_unlock(&adev->mman.gtt_window_lock);
372+ mutex_unlock(&entity->lock);
372373 *f = fence;
373374 return r;
374375 }
@@ -1580,7 +1581,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo, · 1205 unmodified lines
15801581 if (r)
15811582 goto out;
15821583
1583− mutex_lock(&adev->mman.gtt_window_lock);
1584+ mutex_lock(&adev->mman.default_entity.lock);
15841585 amdgpu_res_first(abo->tbo.resource, offset, len, &src_mm);
15851586 src_addr = amdgpu_ttm_domain_start(adev, bo->resource->mem_type) +
15861587 src_mm.start;
@@ -1591,8 +1592,8 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo, · 4 unmodified lines
15911592 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr,
15921593 PAGE_SIZE, 0);
15931594
1594− fence = amdgpu_ttm_job_submit(adev, job, num_dw);
1595− mutex_unlock(&adev->mman.gtt_window_lock);
1595+ fence = amdgpu_ttm_job_submit(adev, &adev->mman.default_entity, job, num_dw);
1596+ mutex_unlock(&adev->mman.default_entity.lock);
15961597
15971598 if (!dma_fence_wait_timeout(fence, false, adev->sdma_timeout))
15981599 r = -ETIMEDOUT;
@@ -1908,7 +1909,7 @@ static void amdgpu_ttm_pools_fini(struct amdgpu_device *adev) · 309 unmodified lines
19081909 }
19091910
19101911 /**
1911− * amdgpu_ttm_mmio_remap_bo_init - Allocate the singleton MMIO_REMAP BO
1912+ * amdgpu_ttm_alloc_mmio_remap_bo - Allocate the singleton MMIO_REMAP BO
19121913 * @adev: amdgpu device
19131914 *
19141915 * 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
20132014 adev->rmmio_remap.bo = NULL;
20142015 }
20152016
2017+static 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+
2054+static 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+
20162061 /*
20172062 * amdgpu_ttm_init - Init the memory management (ttm) as well as various
20182063 * gtt/vram related fields.
@@ -2027,8 +2072,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 8 unmodified lines
20272072 uint64_t gtt_size;
20282073 int r;
20292074
2030− mutex_init(&adev->mman.gtt_window_lock);
2031−
20322075 dma_set_max_seg_size(adev->dev, UINT_MAX);
20332076 /* No others user of address space so set it to 0 */
20342077 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
23132356 struct amdgpu_ring *ring;
23142357 struct drm_gpu_scheduler *sched;
23152358
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+
23162364 ring = adev->mman.buffer_funcs_ring;
23172365 sched = &ring->sched;
2318− r = drm_sched_entity_init(&adev->mman.default_entity.base,
2319− DRM_SCHED_PRIORITY_KERNEL, &sched,
2320− 1, NULL);
2321− if (r) {
2366+ r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
2367+ &adev->mman.default_entity,
2368+ DRM_SCHED_PRIORITY_KERNEL,
2369+ &sched, 1, 0);
2370+ if (r < 0) {
23222371 dev_err(adev->dev,
2323− "Failed setting up TTM BO move entity (%d)\n",
2324− r);
2372+ "Failed setting up TTM entity (%d)\n", r);
23252373 return;
23262374 }
23272375
2328− r = drm_sched_entity_init(&adev->mman.clear_entity.base,
2329− DRM_SCHED_PRIORITY_NORMAL, &sched,
2330− 1, NULL);
2331− if (r) {
2376+ r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
2377+ &adev->mman.clear_entity,
2378+ DRM_SCHED_PRIORITY_NORMAL,
2379+ &sched, 1, 1);
2380+ if (r < 0) {
23322381 dev_err(adev->dev,
2333− "Failed setting up TTM BO clear entity (%d)\n",
2334− r);
2335− goto error_free_entity;
2382+ "Failed setting up TTM BO clear entity (%d)\n", r);
2383+ goto error_free_default_entity;
23362384 }
23372385
2338− r = drm_sched_entity_init(&adev->mman.move_entity.base,
2339− DRM_SCHED_PRIORITY_NORMAL, &sched,
2340− 1, NULL);
2341− if (r) {
2386+ r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr,
2387+ &adev->mman.move_entity,
2388+ DRM_SCHED_PRIORITY_NORMAL,
2389+ &sched, 1, 2);
2390+ if (r < 0) {
23422391 dev_err(adev->dev,
2343− "Failed setting up TTM BO move entity (%d)\n",
2344− r);
2345− drm_sched_entity_destroy(&adev->mman.clear_entity.base);
2346− goto error_free_entity;
2392+ "Failed setting up TTM BO move entity (%d)\n", r);
2393+ goto error_free_clear_entity;
23472394 }
23482395 } else {
2349− drm_sched_entity_destroy(&adev->mman.default_entity.base);
2350− drm_sched_entity_destroy(&adev->mman.clear_entity.base);
2351− drm_sched_entity_destroy(&adev->mman.move_entity.base);
2396+ amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
2397+ &adev->mman.default_entity);
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);
23522402 /* Drop all the old fences since re-creating the scheduler entities
23532403 * will allocate new contexts.
23542404 */
@@ -2365,8 +2415,12 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) · 10 unmodified lines
23652415
23662416 return;
23672417
2368−error_free_entity:
2369− drm_sched_entity_destroy(&adev->mman.default_entity.base);
2418+error_free_clear_entity:
2419+ amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
2420+ &adev->mman.clear_entity);
2421+error_free_default_entity:
2422+ amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr,
2423+ &adev->mman.default_entity);
23702424 }
23712425
23722426 static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
@@ -2440,7 +2494,7 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev, · 67 unmodified lines
24402494 byte_count -= cur_size_in_bytes;
24412495 }
24422496
2443− *fence = amdgpu_ttm_job_submit(adev, job, num_dw);
2497+ *fence = amdgpu_ttm_job_submit(adev, entity, job, num_dw);
24442498
24452499 return 0;
24462500
@@ -2483,7 +2537,7 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev, · 36 unmodified lines
24832537 byte_count -= cur_size;
24842538 }
24852539
2486− *fence = amdgpu_ttm_job_submit(adev, job, num_dw);
2540+ *fence = amdgpu_ttm_job_submit(adev, entity, job, num_dw);
24872541 return 0;
24882542 }
24892543
@@ -2503,6 +2557,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, · 13 unmodified lines
25032557 struct dma_fence **fence)
25042558 {
25052559 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
2560+ struct amdgpu_ttm_buffer_entity *entity;
25062561 struct amdgpu_res_cursor cursor;
25072562 u64 addr;
25082563 int r = 0;
@@ -2513,11 +2568,12 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, · 4 unmodified lines
25132568 if (!fence)
25142569 return -EINVAL;
25152570
2571+ entity = &adev->mman.clear_entity;
25162572 *fence = dma_fence_get_stub();
25172573
25182574 amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
25192575
2520− mutex_lock(&adev->mman.gtt_window_lock);
2576+ mutex_lock(&entity->lock);
25212577 while (cursor.remaining) {
25222578 struct dma_fence *next = NULL;
25232579 u64 size;
@@ -2530,13 +2586,12 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, · 6 unmodified lines
25302586 /* Never clear more than 256MiB at once to avoid timeouts */
25312587 size = min(cursor.size, 256ULL << 20);
25322588
2533− r = amdgpu_ttm_map_buffer(&adev->mman.clear_entity,
2534− &bo->tbo, bo->tbo.resource, &cursor,
2535− 1, false, &size, &addr);
2589+ r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &cursor,
2590+ 0, false, &size, &addr);
25362591 if (r)
25372592 goto err;
25382593
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,
25402595 &next, true,
25412596 AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
25422597 if (r)
@@ -2548,7 +2603,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, · 5 unmodified lines
25482603 amdgpu_res_next(&cursor, size);
25492604 }
25502605 err:
2551− mutex_unlock(&adev->mman.gtt_window_lock);
2606+ mutex_unlock(&entity->lock);
25522607
25532608 return r;
25542609 }
@@ -2573,7 +2628,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, · 18 unmodified lines
25732628
25742629 amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &dst);
25752630
2576− mutex_lock(&adev->mman.gtt_window_lock);
2631+ mutex_lock(&entity->lock);
25772632 while (dst.remaining) {
25782633 struct dma_fence *next;
25792634 uint64_t cur_size, to;
@@ -2582,7 +2637,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, · 2 unmodified lines
25822637 cur_size = min(dst.size, 256ULL << 20);
25832638
25842639 r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &dst,
2585− 1, false, &cur_size, &to);
2640+ 0, false, &cur_size, &to);
25862641 if (r)
25872642 goto error;
25882643
@@ -2598,7 +2653,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, · 9 unmodified lines
25982653 amdgpu_res_next(&dst, cur_size);
25992654 }
26002655 error:
2601− mutex_unlock(&adev->mman.gtt_window_lock);
2656+ mutex_unlock(&entity->lock);
26022657 if (f)
26032658 *f = dma_fence_get(fence);
26042659 dma_fence_put(fence);
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h+27−4
@@ -29,6 +29,7 @@ · 28 unmodified lines
2929 #include <drm/ttm/ttm_placement.h>
3030 #include "amdgpu_vram_mgr.h"
3131 #include "amdgpu_hmm.h"
32+#include "amdgpu_gmc.h"
3233
3334 #define AMDGPU_PL_GDS (TTM_PL_PRIV + 0)
3435 #define AMDGPU_PL_GWS (TTM_PL_PRIV + 1)
@@ -38,8 +39,7 @@ · 3 unmodified lines
3839 #define AMDGPU_PL_MMIO_REMAP (TTM_PL_PRIV + 5)
3940 #define __AMDGPU_PL_NUM (TTM_PL_PRIV + 6)
4041
41−#define AMDGPU_GTT_MAX_TRANSFER_SIZE 512
42−#define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2
42+#define AMDGPU_GTT_MAX_TRANSFER_SIZE 1024
4343
4444 extern const struct attribute_group amdgpu_vram_mgr_attr_group;
4545 extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
@@ -54,6 +54,9 @@ struct amdgpu_gtt_mgr { · 8 unmodified lines
5454
5555 struct amdgpu_ttm_buffer_entity {
5656 struct drm_sched_entity base;
57+ struct mutex lock;
58+ struct drm_mm_node gart_node;
59+ u64 gart_window_offs[2];
5760 };
5861
5962 struct amdgpu_mman {
@@ -67,8 +70,7 @@ struct amdgpu_mman { · 7 unmodified lines
6770 struct amdgpu_ring *buffer_funcs_ring;
6871 bool buffer_funcs_enabled;
6972
70− struct mutex gtt_window_lock;
71−
73+ /* @default_entity: for workarounds, has no gart windows */
7274 struct amdgpu_ttm_buffer_entity default_entity;
7375 struct amdgpu_ttm_buffer_entity clear_entity;
7476 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
205207 }
206208 #endif
207209
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+ */
216+static 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+ */
226+static 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+
208231 void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct amdgpu_hmm_range *range);
209232 int amdgpu_ttm_tt_get_userptr(const struct ttm_buffer_object *tbo,
210233 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
446446 return ret;
447447 }
448448
449−static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue,
450− int queue_id)
449+static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue)
451450 {
452451 struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
453452 struct amdgpu_device *adev = uq_mgr->adev;
@@ -461,7 +460,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue, · 7 unmodified lines
461460 uq_funcs->mqd_destroy(queue);
462461 amdgpu_userq_fence_driver_free(queue);
463462 /* Use interrupt-safe locking since IRQ handlers may access these XArrays */
464− xa_erase_irq(&uq_mgr->userq_xa, (unsigned long)queue_id);
465463 xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);
466464 queue->userq_mgr = NULL;
467465 list_del(&queue->userq_va_list);
@@ -470,12 +468,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue, · 2 unmodified lines
470468 up_read(&adev->reset_domain->sem);
471469 }
472470
473−static struct amdgpu_usermode_queue *
474−amdgpu_userq_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
475−{
476− return xa_load(&uq_mgr->userq_xa, qid);
477−}
478−
479471 void
480472 amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr,
481473 struct amdgpu_eviction_fence_mgr *evf_mgr)
@@ -625,22 +617,13 @@ unref_bo: · 143 unmodified lines
625617 }
626618
627619 static int
628−amdgpu_userq_destroy(struct drm_file *filp, int queue_id)
620+amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
629621 {
630− struct amdgpu_fpriv *fpriv = filp->driver_priv;
631− struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
632622 struct amdgpu_device *adev = uq_mgr->adev;
633− struct amdgpu_usermode_queue *queue;
634623 int r = 0;
635624
636625 cancel_delayed_work_sync(&uq_mgr->resume_work);
637626 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− }
644627 amdgpu_userq_wait_for_last_fence(queue);
645628 /* Cancel any pending hang detection work and cleanup */
646629 if (queue->hang_detect_fence) {
@@ -672,7 +655,7 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id) · 25 unmodified lines
672655 drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n");
673656 queue->state = AMDGPU_USERQ_STATE_HUNG;
674657 }
675− amdgpu_userq_cleanup(queue, queue_id);
658+ amdgpu_userq_cleanup(queue);
676659 mutex_unlock(&uq_mgr->userq_mutex);
677660
678661 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
680663 return r;
681664 }
682665
666+static 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+
678+struct 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+
691+void amdgpu_userq_put(struct amdgpu_usermode_queue *queue)
692+{
693+ if (queue)
694+ kref_put(&queue->refcount, amdgpu_userq_kref_destroy);
695+}
696+
683697 static int amdgpu_userq_priority_permit(struct drm_file *filp,
684698 int priority)
685699 {
@@ -834,6 +848,9 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) · 148 unmodified lines
834848 goto unlock;
835849 }
836850
851+ /* drop this refcount during queue destroy */
852+ kref_init(&queue->refcount);
853+
837854 /* Wait for mode-1 reset to complete */
838855 down_read(&adev->reset_domain->sem);
839856 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
9851002 struct drm_file *filp)
9861003 {
9871004 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;
9891008
9901009 if (!amdgpu_userq_enabled(dev))
9911010 return -ENOTSUPP;
@@ -1000,11 +1019,16 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, · 8 unmodified lines
10001019 drm_file_err(filp, "Failed to create usermode queue\n");
10011020 break;
10021021
1003− case AMDGPU_USERQ_OP_FREE:
1004− r = amdgpu_userq_destroy(filp, args->in.queue_id);
1005− if (r)
1006− drm_file_err(filp, "Failed to destroy usermode queue\n");
1022+ case AMDGPU_USERQ_OP_FREE: {
1023+ xa_lock(&fpriv->userq_mgr.userq_xa);
1024+ queue = __xa_erase(&fpriv->userq_mgr.userq_xa, args->in.queue_id);
1025+ xa_unlock(&fpriv->userq_mgr.userq_xa);
1026+ if (!queue)
1027+ return -ENOENT;
1028+
1029+ amdgpu_userq_put(queue);
10071030 break;
1031+ }
10081032
10091033 default:
10101034 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
10231047
10241048 /* Resume all the queues for this process */
10251049 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+
10261054 if (!amdgpu_userq_buffer_vas_mapped(queue)) {
10271055 drm_file_err(uq_mgr->file,
10281056 "trying restore queue without va mapping\n");
10291057 queue->state = AMDGPU_USERQ_STATE_INVALID_VA;
1058+ amdgpu_userq_put(queue);
10301059 continue;
10311060 }
10321061
10331062 r = amdgpu_userq_restore_helper(queue);
10341063 if (r)
10351064 ret = r;
1065+
1066+ amdgpu_userq_put(queue);
10361067 }
10371068
10381069 if (ret)
@@ -1266,9 +1297,13 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr) · 227 unmodified lines
12661297 amdgpu_userq_detect_and_reset_queues(uq_mgr);
12671298 /* Try to unmap all the queues in this process ctx */
12681299 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
1300+ queue = amdgpu_userq_get(uq_mgr, queue_id);
1301+ if (!queue)
1302+ continue;
12691303 r = amdgpu_userq_preempt_helper(queue);
12701304 if (r)
12711305 ret = r;
1306+ amdgpu_userq_put(queue);
12721307 }
12731308
12741309 if (ret)
@@ -1301,16 +1336,24 @@ amdgpu_userq_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr) · 26 unmodified lines
13011336 int ret;
13021337
13031338 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+
13041343 struct dma_fence *f = queue->last_fence;
13051344
1306− if (!f || dma_fence_is_signaled(f))
1345+ if (!f || dma_fence_is_signaled(f)) {
1346+ amdgpu_userq_put(queue);
13071347 continue;
1348+ }
13081349 ret = dma_fence_wait_timeout(f, true, msecs_to_jiffies(100));
13091350 if (ret <= 0) {
13101351 drm_file_err(uq_mgr->file, "Timed out waiting for fence=%llu:%llu\n",
13111352 f->context, f->seqno);
1353+ amdgpu_userq_put(queue);
13121354 return -ETIMEDOUT;
13131355 }
1356+ amdgpu_userq_put(queue);
13141357 }
13151358
13161359 return 0;
@@ -1361,20 +1404,23 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *f · 44 unmodified lines
13611404 void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
13621405 {
13631406 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);
13651416
1366− cancel_delayed_work_sync(&userq_mgr->resume_work);
1417+ if (!queue)
1418+ break;
13671419
1368− mutex_lock(&userq_mgr->userq_mutex);
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);
1420+ amdgpu_userq_put(queue);
13741421 }
13751422
13761423 xa_destroy(&userq_mgr->userq_xa);
1377− mutex_unlock(&userq_mgr->userq_mutex);
13781424 mutex_destroy(&userq_mgr->userq_mutex);
13791425 }
13801426
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h+6−0
@@ -74,6 +74,7 @@ struct amdgpu_usermode_queue { · 73 unmodified lines
7474 struct dentry *debugfs_queue;
7575 struct delayed_work hang_detect_work;
7676 struct dma_fence *hang_detect_fence;
77+ struct kref refcount;
7778
7879 struct list_head userq_va_list;
7980 };
@@ -81,6 +82,8 @@ struct amdgpu_usermode_queue { · 1 unmodified line
8182 struct amdgpu_userq_funcs {
8283 int (*mqd_create)(struct amdgpu_usermode_queue *queue,
8384 struct drm_amdgpu_userq_in *args);
85+ int (*mqd_update)(struct amdgpu_usermode_queue *queue,
86+ struct drm_amdgpu_userq_in *args);
8487 void (*mqd_destroy)(struct amdgpu_usermode_queue *uq);
8588 int (*unmap)(struct amdgpu_usermode_queue *queue);
8689 int (*map)(struct amdgpu_usermode_queue *queue);
@@ -112,6 +115,9 @@ struct amdgpu_db_info { · 25 unmodified lines
112115 struct amdgpu_userq_obj *db_obj;
113116 };
114117
118+struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr *uq_mgr, u32 qid);
119+void amdgpu_userq_put(struct amdgpu_usermode_queue *queue);
120+
115121 int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
116122
117123 int 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
461461 struct drm_file *filp)
462462 {
463463 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;
464467 struct amdgpu_fpriv *fpriv = filp->driver_priv;
465468 struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr;
466− struct drm_amdgpu_userq_signal *args = data;
467− struct drm_gem_object **gobj_write = NULL;
468− struct drm_gem_object **gobj_read = NULL;
469− struct amdgpu_usermode_queue *queue;
469+ struct drm_gem_object **gobj_write, **gobj_read;
470+ u32 *syncobj_handles, num_syncobj_handles;
470471 struct amdgpu_userq_fence *userq_fence;
472+ struct amdgpu_usermode_queue *queue = NULL;
471473 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;
476474 struct dma_fence *fence;
477475 struct drm_exec exec;
476+ int r, i, entry;
478477 u64 wptr;
479478
480479 if (!amdgpu_userq_enabled(dev))
481480 return -ENOTSUPP;
482481
483− if (args->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES ||
484− args->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
482+ if (args->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
485483 args->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)
486484 return -EINVAL;
487485
488486 num_syncobj_handles = args->num_syncobj_handles;
489− syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles),
490− size_mul(sizeof(u32), num_syncobj_handles));
487+ syncobj_handles = memdup_array_user(u64_to_user_ptr(args->syncobj_handles),
488+ num_syncobj_handles, sizeof(u32));
491489 if (IS_ERR(syncobj_handles))
492490 return PTR_ERR(syncobj_handles);
493491
@@ -506,54 +504,22 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, · 12 unmodified lines
506504 }
507505 }
508506
509− num_read_bo_handles = args->num_bo_read_handles;
510− bo_handles_read = memdup_user(u64_to_user_ptr(args->bo_read_handles),
511− sizeof(u32) * num_read_bo_handles);
512− if (IS_ERR(bo_handles_read)) {
513− r = PTR_ERR(bo_handles_read);
507+ r = drm_gem_objects_lookup(filp,
508+ u64_to_user_ptr(args->bo_read_handles),
509+ num_read_bo_handles,
510+ &gobj_read);
511+ if (r)
514512 goto free_syncobj;
515− }
516513
517− /* Array of pointers to the GEM read objects */
518− gobj_read = kmalloc_array(num_read_bo_handles, sizeof(*gobj_read), GFP_KERNEL);
519− if (!gobj_read) {
520− r = -ENOMEM;
521− goto free_bo_handles_read;
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);
514+ r = drm_gem_objects_lookup(filp,
515+ u64_to_user_ptr(args->bo_write_handles),
516+ num_write_bo_handles,
517+ &gobj_write);
518+ if (r)
537519 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− }
554520
555521 /* 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);
557523 if (!queue) {
558524 r = -ENOENT;
559525 goto put_gobj_write;
@@ -629,17 +595,13 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, · 69 unmodified lines
629595 exec_fini:
630596 drm_exec_fini(&exec);
631597 put_gobj_write:
632− while (wentry-- > 0)
633− drm_gem_object_put(gobj_write[wentry]);
598+ for (i = 0; i < num_write_bo_handles; i++)
599+ drm_gem_object_put(gobj_write[i]);
634600 kfree(gobj_write);
635−free_bo_handles_write:
636− kfree(bo_handles_write);
637601 put_gobj_read:
638− while (rentry-- > 0)
639− drm_gem_object_put(gobj_read[rentry]);
602+ for (i = 0; i < num_read_bo_handles; i++)
603+ drm_gem_object_put(gobj_read[i]);
640604 kfree(gobj_read);
641−free_bo_handles_read:
642− kfree(bo_handles_read);
643605 free_syncobj:
644606 while (entry-- > 0)
645607 if (syncobj[entry])
@@ -648,98 +610,73 @@ free_syncobj: · 2 unmodified lines
648610 free_syncobj_handles:
649611 kfree(syncobj_handles);
650612
613+ if (queue)
614+ amdgpu_userq_put(queue);
615+
651616 return r;
652617 }
653618
654619 int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
655620 struct drm_file *filp)
656621 {
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;
660622 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;
661626 struct amdgpu_fpriv *fpriv = filp->driver_priv;
662627 struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr;
663− struct amdgpu_usermode_queue *waitq;
664− struct drm_gem_object **gobj_write;
665− struct drm_gem_object **gobj_read;
628+ struct drm_gem_object **gobj_write, **gobj_read;
629+ u32 *timeline_points, *timeline_handles;
630+ struct amdgpu_usermode_queue *waitq = NULL;
631+ u32 *syncobj_handles, num_syncobj;
666632 struct dma_fence **fences = NULL;
667633 u16 num_points, num_fences = 0;
668− int r, i, rentry, wentry, cnt;
669634 struct drm_exec exec;
635+ int r, i, cnt;
670636
671637 if (!amdgpu_userq_enabled(dev))
672638 return -ENOTSUPP;
673639
674− if (wait_info->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES ||
675− wait_info->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
640+ if (wait_info->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
676641 wait_info->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)
677642 return -EINVAL;
678643
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−
693644 num_syncobj = wait_info->num_syncobj_handles;
694− syncobj_handles = memdup_user(u64_to_user_ptr(wait_info->syncobj_handles),
695− size_mul(sizeof(u32), num_syncobj));
696− if (IS_ERR(syncobj_handles)) {
697− r = PTR_ERR(syncobj_handles);
698− goto free_bo_handles_write;
699− }
645+ syncobj_handles = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_handles),
646+ num_syncobj, sizeof(u32));
647+ if (IS_ERR(syncobj_handles))
648+ return PTR_ERR(syncobj_handles);
649+
700650
701651 num_points = wait_info->num_syncobj_timeline_handles;
702− timeline_handles = memdup_user(u64_to_user_ptr(wait_info->syncobj_timeline_handles),
703− sizeof(u32) * num_points);
652+ timeline_handles = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_timeline_handles),
653+ num_points, sizeof(u32));
704654 if (IS_ERR(timeline_handles)) {
705655 r = PTR_ERR(timeline_handles);
706656 goto free_syncobj_handles;
707657 }
708658
709− timeline_points = memdup_user(u64_to_user_ptr(wait_info->syncobj_timeline_points),
710− sizeof(u32) * num_points);
659+ timeline_points = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_timeline_points),
660+ num_points, sizeof(u32));
661+
711662 if (IS_ERR(timeline_points)) {
712663 r = PTR_ERR(timeline_points);
713664 goto free_timeline_handles;
714665 }
715666
716− gobj_read = kmalloc_array(num_read_bo_handles, sizeof(*gobj_read), GFP_KERNEL);
717− if (!gobj_read) {
718− r = -ENOMEM;
667+ r = drm_gem_objects_lookup(filp,
668+ u64_to_user_ptr(wait_info->bo_read_handles),
669+ num_read_bo_handles,
670+ &gobj_read);
671+ if (r)
719672 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− }
729673
730− gobj_write = kmalloc_array(num_write_bo_handles, sizeof(*gobj_write), GFP_KERNEL);
731− if (!gobj_write) {
732− r = -ENOMEM;
674+ r = drm_gem_objects_lookup(filp,
675+ u64_to_user_ptr(wait_info->bo_write_handles),
676+ num_write_bo_handles,
677+ &gobj_write);
678+ if (r)
733679 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− }
743680
744681 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
745682 (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
926863 */
927864 num_fences = dma_fence_dedup_array(fences, num_fences);
928865
929− waitq = xa_load(&userq_mgr->userq_xa, wait_info->waitq_id);
866+ waitq = amdgpu_userq_get(userq_mgr, wait_info->waitq_id);
930867 if (!waitq) {
931868 r = -EINVAL;
932869 goto free_fences;
@@ -983,43 +920,25 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, · 50 unmodified lines
983920 r = -EFAULT;
984921 goto free_fences;
985922 }
986−
987− kfree(fences);
988− kfree(fence_info);
989923 }
990924
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−
1008925 free_fences:
1009− while (num_fences-- > 0)
1010− dma_fence_put(fences[num_fences]);
1011− kfree(fences);
926+ if (fences) {
927+ while (num_fences-- > 0)
928+ dma_fence_put(fences[num_fences]);
929+ kfree(fences);
930+ }
1012931 free_fence_info:
1013932 kfree(fence_info);
1014933 exec_fini:
1015934 drm_exec_fini(&exec);
1016935 put_gobj_write:
1017− while (wentry-- > 0)
1018− drm_gem_object_put(gobj_write[wentry]);
936+ for (i = 0; i < num_write_bo_handles; i++)
937+ drm_gem_object_put(gobj_write[i]);
1019938 kfree(gobj_write);
1020939 put_gobj_read:
1021− while (rentry-- > 0)
1022− drm_gem_object_put(gobj_read[rentry]);
940+ for (i = 0; i < num_read_bo_handles; i++)
941+ drm_gem_object_put(gobj_read[i]);
1023942 kfree(gobj_read);
1024943 free_timeline_points:
1025944 kfree(timeline_points);
@@ -1027,10 +946,9 @@ free_timeline_handles: · 1 unmodified line
1027946 kfree(timeline_handles);
1028947 free_syncobj_handles:
1029948 kfree(syncobj_handles);
1030−free_bo_handles_write:
1031− kfree(bo_handles_write);
1032−free_bo_handles_read:
1033− kfree(bo_handles_read);
949+
950+ if (waitq)
951+ amdgpu_userq_put(waitq);
1034952
1035953 return r;
1036954 }
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
450450 }
451451 }
452452
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− */
462−u32 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−
471453 /**
472454 * amdgpu_vce_get_create_msg - generate a VCE create msg
473455 *
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h+1−1
@@ -52,6 +52,7 @@ struct amdgpu_vce { · 51 unmodified lines
5252 uint32_t srbm_soft_reset;
5353 unsigned num_rings;
5454 uint32_t keyselect;
55+ struct drm_mm_node gart_node;
5556 };
5657
5758 int 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
6162 int amdgpu_vce_suspend(struct amdgpu_device *adev);
6263 int amdgpu_vce_resume(struct amdgpu_device *adev);
6364 void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
64−u32 amdgpu_vce_required_gart_pages(struct amdgpu_device *adev);
6565 int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
6666 struct amdgpu_ib *ib);
6767 int 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
764764 * @need_pipe_sync: is pipe sync needed
765765 *
766766 * Emit a VM flush when it is necessary.
767− *
768− * Returns:
769− * 0 on success, errno otherwise.
770767 */
771−int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
772− bool need_pipe_sync)
768+void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
769+ bool need_pipe_sync)
773770 {
774771 struct amdgpu_device *adev = ring->adev;
775772 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
783780 bool cleaner_shader_needed = false;
784781 bool pasid_mapping_needed = false;
785782 struct dma_fence *fence = NULL;
786− unsigned int patch;
787− int r;
783+ unsigned int patch = 0;
788784
789785 if (amdgpu_vmid_had_gpu_reset(adev, id)) {
790786 gds_switch_needed = true;
@@ -812,9 +808,20 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, · 21 unmodified lines
812808
813809 if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync &&
814810 !cleaner_shader_needed)
815− return 0;
811+ return;
816812
817813 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+
818825 if (ring->funcs->init_cond_exec)
819826 patch = amdgpu_ring_init_cond_exec(ring,
820827 ring->cond_exe_gpu_addr);
@@ -845,9 +852,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, · 24 unmodified lines
845852 }
846853
847854 if (vm_flush_needed || pasid_mapping_needed || cleaner_shader_needed) {
848− r = amdgpu_fence_emit(ring, job->hw_vm_fence, 0);
849− if (r)
850− return r;
855+ amdgpu_fence_emit(ring, job->hw_vm_fence, 0);
851856 fence = &job->hw_vm_fence->base;
852857 /* get a ref for the job */
853858 dma_fence_get(fence);
@@ -892,7 +897,6 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, · 38 unmodified lines
892897 }
893898
894899 amdgpu_ring_ib_end(ring);
895− return 0;
896900 }
897901
898902 /**
@@ -3210,3 +3214,20 @@ void amdgpu_vm_print_task_info(struct amdgpu_device *adev, · 2311 unmodified lines
32103214 task_info->process_name, task_info->tgid,
32113215 task_info->task.comm, task_info->task.pid);
32123216 }
3217+
3218+void 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
513513 struct ww_acquire_ctx *ticket,
514514 int (*callback)(void *p, struct amdgpu_bo *bo),
515515 void *param);
516−int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
516+void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
517517 int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
518518 struct amdgpu_vm *vm, bool immediate);
519519 int 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
338338 if (!(adev->aid_mask & BIT(i)))
339339 return U32_MAX;
340340
341− addr += adev->asic_funcs->encode_ext_smn_addressing(i);
341+ addr += amdgpu_reg_get_smn_base64(adev, XGMI_HWIP, i);
342342
343343 return RREG32_PCIE_EXT(addr);
344344 }
@@ -347,6 +347,9 @@ int amdgpu_get_xgmi_link_status(struct amdgpu_device *adev, int global_link_num) · 2 unmodified lines
347347 {
348348 u32 xgmi_state_reg_val;
349349
350+ if (amdgpu_sriov_vf(adev))
351+ return AMDGPU_XGMI_LINK_NA;
352+
350353 if (adev->gmc.xgmi.num_physical_nodes <= 1)
351354 return -EINVAL;
352355
@@ -1290,7 +1293,10 @@ static void amdgpu_xgmi_legacy_reset_ras_error_count(struct amdgpu_device *adev) · 937 unmodified lines
12901293
12911294 static void __xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst, u64 mca_base)
12921295 {
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);
12941300 }
12951301
12961302 static 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
15001506 u64 mca_base, struct ras_err_data *err_data)
15011507 {
15021508 int xgmi_inst = mcm_info->die_id;
1509+ uint64_t smn_base;
15031510 u64 status = 0;
15041511
15051512 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
15161523 default:
15171524 break;
15181525 }
1519−
1520− WREG64_MCA(xgmi_inst, mca_base, ACA_REG_IDX_STATUS, 0ULL);
1526+ smn_base = amdgpu_reg_get_smn_base64(adev, XGMI_HWIP, xgmi_inst);
1527+ WREG64_MCA(smn_base, mca_base, ACA_REG_IDX_STATUS, 0ULL);
15211528 }
15221529
15231530 static 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
470470 uint32_t hit;
471471 };
472472
473+union 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)
481+struct 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+
473486 struct amdsriov_ras_telemetry {
474487 struct amd_sriov_ras_telemetry_header header;
475−
476− union {
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;
488+ union amd_sriov_ras_host_push body;
489+ struct amd_sriov_uniras_shared_mem uniras_shared_mem;
481490 };
482491
483492 /* 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
510519 _Static_assert(AMD_SRIOV_MSG_RESERVE_UCODE > AMD_SRIOV_UCODE_ID__MAX,
511520 "AMD_SRIOV_MSG_RESERVE_UCODE must be bigger than AMD_SRIOV_UCODE_ID__MAX");
512521
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+
513526 #undef _stringification
514527 #undef stringification
515528 #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
5858 adev->doorbell_index.max_assignment = AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT << 1;
5959 }
6060
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− */
66−u64 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−
8061 static enum amdgpu_gfx_partition
8162 __aqua_vanjaram_calc_xcp_mode(struct amdgpu_xcp_mgr *xcp_mgr)
8263 {
@@ -590,7 +571,7 @@ static void aqua_read_smn_ext(struct amdgpu_device *adev, · 507 unmodified lines
590571 uint64_t smn_addr, int i)
591572 {
592573 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);
594575 regdata->value = RREG32_PCIE_EXT(regdata->addr);
595576 }
596577
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
14621462
14631463 ctx->vbios_pn[count] = 0;
14641464 }
1465−
1466− drm_info(ctx->card->dev, "ATOM BIOS: %s\n", ctx->vbios_pn);
14671465 }
14681466
14691467 static 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
15201518 strscpy(ctx->build_num, str, len);
15211519 }
15221520
1521+static 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+
15231545 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
15241546 {
15251547 int base;
@@ -1582,6 +1604,8 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios) · 56 unmodified lines
15821604 atom_get_vbios_version(ctx);
15831605 atom_get_vbios_build(ctx);
15841606
1607+ atom_print_vbios_info(ctx);
1608+
15851609 return ctx;
15861610 }
15871611
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
154154 unsigned long flags;
155155 u32 r;
156156
157− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
157+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
158158 WREG32(mmPCIE_INDEX, reg);
159159 (void)RREG32(mmPCIE_INDEX);
160160 r = RREG32(mmPCIE_DATA);
161− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
161+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
162162 return r;
163163 }
164164
@@ -166,12 +166,12 @@ static void cik_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
166166 {
167167 unsigned long flags;
168168
169− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
169+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
170170 WREG32(mmPCIE_INDEX, reg);
171171 (void)RREG32(mmPCIE_INDEX);
172172 WREG32(mmPCIE_DATA, v);
173173 (void)RREG32(mmPCIE_DATA);
174− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
174+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
175175 }
176176
177177 static 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
179179 unsigned long flags;
180180 u32 r;
181181
182− spin_lock_irqsave(&adev->smc_idx_lock, flags);
182+ spin_lock_irqsave(&adev->reg.smc.lock, flags);
183183 WREG32(mmSMC_IND_INDEX_0, (reg));
184184 r = RREG32(mmSMC_IND_DATA_0);
185− spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
185+ spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
186186 return r;
187187 }
188188
@@ -190,10 +190,10 @@ static void cik_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
190190 {
191191 unsigned long flags;
192192
193− spin_lock_irqsave(&adev->smc_idx_lock, flags);
193+ spin_lock_irqsave(&adev->reg.smc.lock, flags);
194194 WREG32(mmSMC_IND_INDEX_0, (reg));
195195 WREG32(mmSMC_IND_DATA_0, (v));
196− spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
196+ spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
197197 }
198198
199199 static 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
201201 unsigned long flags;
202202 u32 r;
203203
204− spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
204+ spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
205205 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
206206 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);
208208 return r;
209209 }
210210
@@ -212,10 +212,10 @@ static void cik_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
212212 {
213213 unsigned long flags;
214214
215− spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
215+ spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
216216 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
217217 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);
219219 }
220220
221221 static 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
223223 unsigned long flags;
224224 u32 r;
225225
226− spin_lock_irqsave(&adev->didt_idx_lock, flags);
226+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
227227 WREG32(mmDIDT_IND_INDEX, (reg));
228228 r = RREG32(mmDIDT_IND_DATA);
229− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
229+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
230230 return r;
231231 }
232232
@@ -234,10 +234,10 @@ static void cik_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
234234 {
235235 unsigned long flags;
236236
237− spin_lock_irqsave(&adev->didt_idx_lock, flags);
237+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
238238 WREG32(mmDIDT_IND_INDEX, (reg));
239239 WREG32(mmDIDT_IND_DATA, (v));
240− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
240+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
241241 }
242242
243243 static const u32 bonaire_golden_spm_registers[] =
@@ -1027,7 +1027,7 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, · 783 unmodified lines
10271027 dw_ptr = (u32 *)bios;
10281028 length_dw = ALIGN(length_bytes, 4) / 4;
10291029 /* 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);
10311031 /* set rom index to 0 */
10321032 WREG32(mmSMC_IND_INDEX_0, ixROM_INDEX);
10331033 WREG32(mmSMC_IND_DATA_0, 0);
@@ -1035,7 +1035,7 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, · 1 unmodified line
10351035 WREG32(mmSMC_IND_INDEX_0, ixROM_DATA);
10361036 for (i = 0; i < length_dw; i++)
10371037 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);
10391039
10401040 return true;
10411041 }
@@ -1984,14 +1984,14 @@ static int cik_common_early_init(struct amdgpu_ip_block *ip_block) · 942 unmodified lines
19841984 {
19851985 struct amdgpu_device *adev = ip_block->adev;
19861986
1987− adev->smc_rreg = &cik_smc_rreg;
1988− adev->smc_wreg = &cik_smc_wreg;
1989− adev->pcie_rreg = &cik_pcie_rreg;
1990− adev->pcie_wreg = &cik_pcie_wreg;
1991− adev->uvd_ctx_rreg = &cik_uvd_ctx_rreg;
1992− adev->uvd_ctx_wreg = &cik_uvd_ctx_wreg;
1993− adev->didt_rreg = &cik_didt_rreg;
1994− adev->didt_wreg = &cik_didt_wreg;
1987+ adev->reg.smc.rreg = cik_smc_rreg;
1988+ adev->reg.smc.wreg = cik_smc_wreg;
1989+ adev->reg.pcie.rreg = &cik_pcie_rreg;
1990+ adev->reg.pcie.wreg = &cik_pcie_wreg;
1991+ adev->reg.uvd_ctx.rreg = &cik_uvd_ctx_rreg;
1992+ adev->reg.uvd_ctx.wreg = &cik_uvd_ctx_wreg;
1993+ adev->reg.didt.rreg = &cik_didt_rreg;
1994+ adev->reg.didt.wreg = &cik_didt_wreg;
19951995
19961996 adev->asic_funcs = &cik_asic_funcs;
19971997
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
5353 static void cik_sdma_set_ring_funcs(struct amdgpu_device *adev);
5454 static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev);
5555 static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev);
56−static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev);
5756 static int cik_sdma_soft_reset(struct amdgpu_ip_block *ip_block);
5857
5958 u32 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
919918 }
920919 }
921920
921+static 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+
922929 static int cik_sdma_early_init(struct amdgpu_ip_block *ip_block)
923930 {
924931 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
933940 cik_sdma_set_ring_funcs(adev);
934941 cik_sdma_set_irq_funcs(adev);
935942 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);
937944
938945 return 0;
939946 }
@@ -1337,26 +1344,6 @@ static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev) · 397 unmodified lines
13371344 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
13381345 }
13391346
1340−static 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−
1348−static 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−
13601347 const struct amdgpu_ip_block_version cik_sdma_ip_block =
13611348 {
13621349 .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
175175 unsigned long flags;
176176 u32 r;
177177
178− spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);
178+ spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
179179 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
180180 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);
182182
183183 return r;
184184 }
@@ -188,10 +188,10 @@ static void dce_v10_0_audio_endpt_wreg(struct amdgpu_device *adev, · 3 unmodified lines
188188 {
189189 unsigned long flags;
190190
191− spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);
191+ spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
192192 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
193193 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);
195195 }
196196
197197 static 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
27502750 {
27512751 struct amdgpu_device *adev = ip_block->adev;
27522752
2753− adev->audio_endpt_rreg = &dce_v10_0_audio_endpt_rreg;
2754− adev->audio_endpt_wreg = &dce_v10_0_audio_endpt_wreg;
2753+ adev->reg.audio_endpt.rreg = &dce_v10_0_audio_endpt_rreg;
2754+ adev->reg.audio_endpt.wreg = &dce_v10_0_audio_endpt_wreg;
27552755
27562756 dce_v10_0_set_display_funcs(adev);
27572757
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
138138 unsigned long flags;
139139 u32 r;
140140
141− spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);
141+ spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
142142 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
143143 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);
145145
146146 return r;
147147 }
@@ -151,11 +151,11 @@ static void dce_v6_0_audio_endpt_wreg(struct amdgpu_device *adev, · 3 unmodified lines
151151 {
152152 unsigned long flags;
153153
154− spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);
154+ spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
155155 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset,
156156 reg | AZALIA_F0_CODEC_ENDPOINT_INDEX__AZALIA_ENDPOINT_REG_WRITE_EN_MASK);
157157 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);
159159 }
160160
161161 static 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
26972697 {
26982698 struct amdgpu_device *adev = ip_block->adev;
26992699
2700− adev->audio_endpt_rreg = &dce_v6_0_audio_endpt_rreg;
2701− adev->audio_endpt_wreg = &dce_v6_0_audio_endpt_wreg;
2700+ adev->reg.audio_endpt.rreg = &dce_v6_0_audio_endpt_rreg;
2701+ adev->reg.audio_endpt.wreg = &dce_v6_0_audio_endpt_wreg;
27022702
27032703 dce_v6_0_set_display_funcs(adev);
27042704
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
126126 unsigned long flags;
127127 u32 r;
128128
129− spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);
129+ spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
130130 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
131131 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);
133133
134134 return r;
135135 }
@@ -139,10 +139,10 @@ static void dce_v8_0_audio_endpt_wreg(struct amdgpu_device *adev, · 3 unmodified lines
139139 {
140140 unsigned long flags;
141141
142− spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags);
142+ spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags);
143143 WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
144144 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);
146146 }
147147
148148 static 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
26552655 {
26562656 struct amdgpu_device *adev = ip_block->adev;
26572657
2658− adev->audio_endpt_rreg = &dce_v8_0_audio_endpt_rreg;
2659− adev->audio_endpt_wreg = &dce_v8_0_audio_endpt_wreg;
2658+ adev->reg.audio_endpt.rreg = &dce_v8_0_audio_endpt_rreg;
2659+ adev->reg.audio_endpt.wreg = &dce_v8_0_audio_endpt_wreg;
26602660
26612661 dce_v8_0_set_display_funcs(adev);
26622662
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
5151 address = adev->nbio.funcs->get_pcie_index_offset(adev);
5252 data = adev->nbio.funcs->get_pcie_data_offset(adev);
5353
54− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
54+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
5555 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);
5656 WREG32(data, ficaa_val);
5757
@@ -61,7 +61,7 @@ static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev, · 3 unmodified lines
6161 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);
6262 ficadh_val = RREG32(data);
6363
64− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
64+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
6565
6666 return (((ficadh_val & 0xFFFFFFFFFFFFFFFF) << 32) | ficadl_val);
6767 }
@@ -74,7 +74,7 @@ static void df_v3_6_set_fica(struct amdgpu_device *adev, uint32_t ficaa_val, · 6 unmodified lines
7474 address = adev->nbio.funcs->get_pcie_index_offset(adev);
7575 data = adev->nbio.funcs->get_pcie_data_offset(adev);
7676
77− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
77+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
7878 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);
7979 WREG32(data, ficaa_val);
8080
@@ -84,7 +84,7 @@ static void df_v3_6_set_fica(struct amdgpu_device *adev, uint32_t ficaa_val, · 3 unmodified lines
8484 WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);
8585 WREG32(data, ficadh_val);
8686
87− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
87+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
8888 }
8989
9090 /*
@@ -102,12 +102,12 @@ static void df_v3_6_perfmon_rreg(struct amdgpu_device *adev, · 11 unmodified lines
102102 address = adev->nbio.funcs->get_pcie_index_offset(adev);
103103 data = adev->nbio.funcs->get_pcie_data_offset(adev);
104104
105− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
105+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
106106 WREG32(address, lo_addr);
107107 *lo_val = RREG32(data);
108108 WREG32(address, hi_addr);
109109 *hi_val = RREG32(data);
110− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
110+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
111111 }
112112
113113 /*
@@ -124,12 +124,12 @@ static void df_v3_6_perfmon_wreg(struct amdgpu_device *adev, uint32_t lo_addr, · 10 unmodified lines
124124 address = adev->nbio.funcs->get_pcie_index_offset(adev);
125125 data = adev->nbio.funcs->get_pcie_data_offset(adev);
126126
127− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
127+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
128128 WREG32(address, lo_addr);
129129 WREG32(data, lo_val);
130130 WREG32(address, hi_addr);
131131 WREG32(data, hi_val);
132− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
132+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
133133 }
134134
135135 /* 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
143143 address = adev->nbio.funcs->get_pcie_index_offset(adev);
144144 data = adev->nbio.funcs->get_pcie_data_offset(adev);
145145
146− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
146+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
147147 WREG32(address, lo_addr);
148148 WREG32(data, lo_val);
149149 WREG32(address, hi_addr);
@@ -153,7 +153,7 @@ static int df_v3_6_perfmon_arm_with_status(struct amdgpu_device *adev, · 3 unmodified lines
153153 lo_val_rb = RREG32(data);
154154 WREG32(address, hi_addr);
155155 hi_val_rb = RREG32(data);
156− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
156+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
157157
158158 if (!(lo_val == lo_val_rb && hi_val == hi_val_rb))
159159 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
42384238 return gfx_v11_0_cp_gfx_start(adev);
42394239 }
42404240
4241+static 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+
42414272 static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
42424273 struct amdgpu_mqd_prop *prop)
42434274 {
@@ -4372,6 +4403,8 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m, · 128 unmodified lines
43724403 /* set UQ fenceaddress */
43734404 mqd->fence_address_lo = lower_32_bits(prop->fence_address);
43744405 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);
43754408
43764409 return 0;
43774410 }
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
31093109 return gfx_v12_0_cp_gfx_start(adev);
31103110 }
31113111
3112+static 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+
31123143 static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
31133144 struct amdgpu_mqd_prop *prop)
31143145 {
@@ -3242,6 +3273,8 @@ static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m, · 127 unmodified lines
32423273 /* set UQ fenceaddress */
32433274 mqd->fence_address_lo = lower_32_bits(prop->fence_address);
32443275 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);
32453278
32463279 return 0;
32473280 }
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
14051405 /*
14061406 * Configure apertures:
14071407 * LDS: 0x20000000'00000000 - 0x20000001'00000000 (4GB)
1408− * Scratch: 0x10000000'00000000 - 0x10000001'00000000 (4GB)
1408+ * Scratch: 0x10000000'00000000 - 0x11ffffff'ffffffff (128PB 57-bit)
14091409 */
14101410 sh_mem_bases = REG_SET_FIELD(0, SH_MEM_BASES, PRIVATE_BASE,
14111411 (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
654654 adev->gmc.shared_aperture_start = 0x2000000000000000ULL;
655655 adev->gmc.shared_aperture_end =
656656 adev->gmc.shared_aperture_start + (4ULL << 30) - 1;
657+
657658 adev->gmc.private_aperture_start = 0x1000000000000000ULL;
658− adev->gmc.private_aperture_end =
659− adev->gmc.private_aperture_start + (4ULL << 30) - 1;
659+ if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 1, 0))
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+
660666 adev->gmc.noretry_flags = AMDGPU_VM_NORETRY_FLAGS_TF;
661667
662668 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
345345 return;
346346 }
347347
348− mutex_lock(&adev->mman.gtt_window_lock);
349348 gmc_v12_1_flush_vm_hub(adev, vmid, vmhub, 0);
350− mutex_unlock(&adev->mman.gtt_window_lock);
351349 return;
352350 }
353351
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
283283 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
284284 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
285285
286− spin_lock_irqsave(&adev->didt_idx_lock, flags);
286+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
287287 WREG32(address, (reg));
288288 r = RREG32(data);
289− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
289+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
290290 return r;
291291 }
292292
@@ -297,10 +297,10 @@ static void nv_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 4 unmodified lines
297297 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
298298 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
299299
300− spin_lock_irqsave(&adev->didt_idx_lock, flags);
300+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
301301 WREG32(address, (reg));
302302 WREG32(data, (v));
303− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
303+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
304304 }
305305
306306 static 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
635635 struct amdgpu_device *adev = ip_block->adev;
636636
637637 adev->nbio.funcs->set_reg_remap(adev);
638− adev->smc_rreg = NULL;
639− adev->smc_wreg = NULL;
640− adev->pcie_rreg = &amdgpu_device_indirect_rreg;
641− adev->pcie_wreg = &amdgpu_device_indirect_wreg;
642− adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
643− adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
644− adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
645− adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
646−
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;
638+ adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
639+ adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
640+ adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
641+ adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
642+ adev->reg.pcie.port_rreg = &amdgpu_device_pcie_port_rreg;
643+ adev->reg.pcie.port_wreg = &amdgpu_device_pcie_port_wreg;
644+
645+ adev->reg.didt.rreg = &nv_didt_rreg;
646+ adev->reg.didt.wreg = &nv_didt_wreg;
653647
654648 adev->asic_funcs = &nv_asic_funcs;
655649
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
166166 bl_status_reg =
167167 (SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_92)
168168 << 2) +
169− adev->asic_funcs->encode_ext_smn_addressing(i);
169+ amdgpu_reg_get_smn_base64(adev, MP0_HWIP, i);
170170 at += snprintf(bl_status_msg + at,
171171 PSP13_BL_STATUS_SIZE - at,
172172 " 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
6969 0x80000000, 0x80000000, false);
7070 } else {
7171 /* Write the ring destroy command*/
72− WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64,
72+ WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64,
7373 GFX_CTRL_CMD_ID_DESTROY_RINGS);
7474 /* there might be handshake issue with hardware which needs delay */
7575 mdelay(20);
7676 /* 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),
7878 0x80000000, 0x80000000, false);
7979 }
8080
@@ -116,7 +116,7 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp, · 35 unmodified lines
116116
117117 } else {
118118 /* 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),
120120 0x80000000, 0x80000000, false);
121121 if (ret) {
122122 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
125125
126126 /* Write low address of the ring to C2PMSG_69 */
127127 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);
129129 /* Write high address of the ring to C2PMSG_70 */
130130 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);
132132 /* Write size of ring to C2PMSG_71 */
133133 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);
135135 /* Write the ring initialization command to C2PMSG_64 */
136136 psp_ring_reg = ring_type;
137137 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);
139139
140140 /* there might be handshake issue with hardware which needs delay */
141141 mdelay(20);
142142
143143 /* 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),
145145 0x80000000, 0x8000FFFF, false);
146146 }
147147
@@ -174,7 +174,7 @@ static uint32_t psp_v15_0_0_ring_get_wptr(struct psp_context *psp) · 26 unmodified lines
174174 if (amdgpu_sriov_vf(adev))
175175 data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102);
176176 else
177− data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67);
177+ data = RREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67);
178178
179179 return data;
180180 }
@@ -188,7 +188,7 @@ static void psp_v15_0_0_ring_set_wptr(struct psp_context *psp, uint32_t value) · 7 unmodified lines
188188 WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,
189189 GFX_CTRL_CMD_ID_CONSUME_CMD);
190190 } else
191− WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67, value);
191+ WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67, value);
192192 }
193193
194194 static 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
5151
5252 static void sdma_v2_4_set_ring_funcs(struct amdgpu_device *adev);
5353 static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev);
54−static void sdma_v2_4_set_vm_pte_funcs(struct amdgpu_device *adev);
5554 static void sdma_v2_4_set_irq_funcs(struct amdgpu_device *adev);
5655
5756 MODULE_FIRMWARE("amdgpu/topaz_sdma.bin");
@@ -809,6 +808,14 @@ static void sdma_v2_4_ring_emit_wreg(struct amdgpu_ring *ring, · 751 unmodified lines
809808 amdgpu_ring_write(ring, val);
810809 }
811810
811+static 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+
812819 static int sdma_v2_4_early_init(struct amdgpu_ip_block *ip_block)
813820 {
814821 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
822829
823830 sdma_v2_4_set_ring_funcs(adev);
824831 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);
826833 sdma_v2_4_set_irq_funcs(adev);
827834
828835 return 0;
@@ -1232,26 +1239,6 @@ static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev) · 403 unmodified lines
12321239 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
12331240 }
12341241
1235−static 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−
1243−static 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−
12551242 const struct amdgpu_ip_block_version sdma_v2_4_ip_block = {
12561243 .type = AMD_IP_BLOCK_TYPE_SDMA,
12571244 .major = 2,
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c+9−22
@@ -51,7 +51,6 @@ · 50 unmodified lines
5151
5252 static void sdma_v3_0_set_ring_funcs(struct amdgpu_device *adev);
5353 static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev);
54−static void sdma_v3_0_set_vm_pte_funcs(struct amdgpu_device *adev);
5554 static void sdma_v3_0_set_irq_funcs(struct amdgpu_device *adev);
5655
5756 MODULE_FIRMWARE("amdgpu/tonga_sdma.bin");
@@ -1082,6 +1081,14 @@ static void sdma_v3_0_ring_emit_wreg(struct amdgpu_ring *ring, · 1024 unmodified lines
10821081 amdgpu_ring_write(ring, val);
10831082 }
10841083
1084+static 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+
10851092 static int sdma_v3_0_early_init(struct amdgpu_ip_block *ip_block)
10861093 {
10871094 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
11021109
11031110 sdma_v3_0_set_ring_funcs(adev);
11041111 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);
11061113 sdma_v3_0_set_irq_funcs(adev);
11071114
11081115 return 0;
@@ -1674,26 +1681,6 @@ static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev) · 565 unmodified lines
16741681 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
16751682 }
16761683
1677−static 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−
1685−static 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−
16971684 const struct amdgpu_ip_block_version sdma_v3_0_ip_block =
16981685 {
16991686 .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
129129
130130 static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev);
131131 static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev);
132−static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev);
133132 static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev);
134133 static void sdma_v4_0_set_ras_funcs(struct amdgpu_device *adev);
135134
@@ -1751,6 +1750,14 @@ static bool sdma_v4_0_fw_support_paging_queue(struct amdgpu_device *adev) · 1615 unmodified lines
17511750 }
17521751 }
17531752
1753+static 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+
17541761 static int sdma_v4_0_early_init(struct amdgpu_ip_block *ip_block)
17551762 {
17561763 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
17691776
17701777 sdma_v4_0_set_ring_funcs(adev);
17711778 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);
17731780 sdma_v4_0_set_irq_funcs(adev);
17741781 sdma_v4_0_set_ras_funcs(adev);
17751782
@@ -2597,48 +2604,37 @@ static void sdma_v4_0_emit_fill_buffer(struct amdgpu_ib *ib, · 821 unmodified lines
25972604 }
25982605
25992606 static const struct amdgpu_buffer_funcs sdma_v4_0_buffer_funcs = {
2600− .copy_max_bytes = 0x400000,
2607+ .copy_max_bytes = 1 << 22,
26012608 .copy_num_dw = 7,
26022609 .emit_copy_buffer = sdma_v4_0_emit_copy_buffer,
26032610
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+
2616+static 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,
26052622 .fill_num_dw = 5,
26062623 .emit_fill_buffer = sdma_v4_0_emit_fill_buffer,
26072624 };
26082625
26092626 static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
26102627 {
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;
26122632 if (adev->sdma.has_page_queue)
26132633 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
26142634 else
26152635 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
26162636 }
26172637
2618−static 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−
2626−static 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−
26422638 static void sdma_v4_0_get_ras_error_count(uint32_t value,
26432639 uint32_t instance,
26442640 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
104104
105105 static void sdma_v4_4_2_set_ring_funcs(struct amdgpu_device *adev);
106106 static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev);
107−static void sdma_v4_4_2_set_vm_pte_funcs(struct amdgpu_device *adev);
108107 static void sdma_v4_4_2_set_irq_funcs(struct amdgpu_device *adev);
109108 static void sdma_v4_4_2_set_ras_funcs(struct amdgpu_device *adev);
110109 static 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
13471346 .soft_reset_kernel_queue = &sdma_v4_4_2_soft_reset_engine,
13481347 };
13491348
1349+static 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+
13501357 static int sdma_v4_4_2_early_init(struct amdgpu_ip_block *ip_block)
13511358 {
13521359 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
13621369
13631370 sdma_v4_4_2_set_ring_funcs(adev);
13641371 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);
13661373 sdma_v4_4_2_set_irq_funcs(adev);
13671374 sdma_v4_4_2_set_ras_funcs(adev);
13681375 return 0;
@@ -2298,11 +2305,11 @@ static void sdma_v4_4_2_emit_fill_buffer(struct amdgpu_ib *ib, · 929 unmodified lines
22982305 }
22992306
23002307 static const struct amdgpu_buffer_funcs sdma_v4_4_2_buffer_funcs = {
2301− .copy_max_bytes = 0x400000,
2308+ .copy_max_bytes = 1 << 30,
23022309 .copy_num_dw = 7,
23032310 .emit_copy_buffer = sdma_v4_4_2_emit_copy_buffer,
23042311
2305− .fill_max_bytes = 0x400000,
2312+ .fill_max_bytes = 1 << 30,
23062313 .fill_num_dw = 5,
23072314 .emit_fill_buffer = sdma_v4_4_2_emit_fill_buffer,
23082315 };
@@ -2316,30 +2323,6 @@ static void sdma_v4_4_2_set_buffer_funcs(struct amdgpu_device *adev) · 7 unmodified lines
23162323 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
23172324 }
23182325
2319−static 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−
2327−static 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−
23432326 /**
23442327 * sdma_v4_4_2_update_reset_mask - update reset mask for SDMA
23452328 * @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
110110
111111 static void sdma_v5_0_set_ring_funcs(struct amdgpu_device *adev);
112112 static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev);
113−static void sdma_v5_0_set_vm_pte_funcs(struct amdgpu_device *adev);
114113 static void sdma_v5_0_set_irq_funcs(struct amdgpu_device *adev);
115114 static int sdma_v5_0_stop_queue(struct amdgpu_ring *ring);
116115 static 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
13571356 .soft_reset_kernel_queue = &sdma_v5_0_soft_reset_engine,
13581357 };
13591358
1359+static 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+
13601366 static int sdma_v5_0_early_init(struct amdgpu_ip_block *ip_block)
13611367 {
13621368 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
13681374
13691375 sdma_v5_0_set_ring_funcs(adev);
13701376 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);
13721378 sdma_v5_0_set_irq_funcs(adev);
13731379 sdma_v5_0_set_mqd_funcs(adev);
13741380
@@ -2052,27 +2058,6 @@ static void sdma_v5_0_set_buffer_funcs(struct amdgpu_device *adev) · 677 unmodified lines
20522058 }
20532059 }
20542060
2055−static 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−
2062−static 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−
20762061 const struct amdgpu_ip_block_version sdma_v5_0_ip_block = {
20772062 .type = AMD_IP_BLOCK_TYPE_SDMA,
20782063 .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
111111
112112 static void sdma_v5_2_set_ring_funcs(struct amdgpu_device *adev);
113113 static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev);
114−static void sdma_v5_2_set_vm_pte_funcs(struct amdgpu_device *adev);
115114 static void sdma_v5_2_set_irq_funcs(struct amdgpu_device *adev);
116115 static int sdma_v5_2_stop_queue(struct amdgpu_ring *ring);
117116 static 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
12481247 amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);
12491248 }
12501249
1250+static 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+
12511257 static int sdma_v5_2_early_init(struct amdgpu_ip_block *ip_block)
12521258 {
12531259 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
12591265
12601266 sdma_v5_2_set_ring_funcs(adev);
12611267 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);
12631269 sdma_v5_2_set_irq_funcs(adev);
12641270 sdma_v5_2_set_mqd_funcs(adev);
12651271
@@ -2039,11 +2045,11 @@ static void sdma_v5_2_emit_fill_buffer(struct amdgpu_ib *ib, · 773 unmodified lines
20392045 }
20402046
20412047 static const struct amdgpu_buffer_funcs sdma_v5_2_buffer_funcs = {
2042− .copy_max_bytes = 0x400000,
2048+ .copy_max_bytes = 1 << 30,
20432049 .copy_num_dw = 7,
20442050 .emit_copy_buffer = sdma_v5_2_emit_copy_buffer,
20452051
2046− .fill_max_bytes = 0x400000,
2052+ .fill_max_bytes = 1 << 30, /* HW supports 1 << 30, but PAL uses 1 << 22 */
20472053 .fill_num_dw = 5,
20482054 .emit_fill_buffer = sdma_v5_2_emit_fill_buffer,
20492055 };
@@ -2056,27 +2062,6 @@ static void sdma_v5_2_set_buffer_funcs(struct amdgpu_device *adev) · 6 unmodified lines
20562062 }
20572063 }
20582064
2059−static 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−
2066−static 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−
20802065 const struct amdgpu_ip_block_version sdma_v5_2_ip_block = {
20812066 .type = AMD_IP_BLOCK_TYPE_SDMA,
20822067 .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
120120
121121 static void sdma_v6_0_set_ring_funcs(struct amdgpu_device *adev);
122122 static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev);
123−static void sdma_v6_0_set_vm_pte_funcs(struct amdgpu_device *adev);
124123 static void sdma_v6_0_set_irq_funcs(struct amdgpu_device *adev);
125124 static int sdma_v6_0_start(struct amdgpu_device *adev);
126125
@@ -1280,6 +1279,13 @@ static void sdma_v6_0_get_csa_info(struct amdgpu_device *adev, · 1153 unmodified lines
12801279 csa_info->alignment = SDMA6_CSA_ALIGNMENT;
12811280 }
12821281
1282+static 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+
12831289 static int sdma_v6_0_early_init(struct amdgpu_ip_block *ip_block)
12841290 {
12851291 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
13081314
13091315 sdma_v6_0_set_ring_funcs(adev);
13101316 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);
13121318 sdma_v6_0_set_irq_funcs(adev);
13131319 sdma_v6_0_set_mqd_funcs(adev);
13141320 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
18781884 }
18791885
18801886 static const struct amdgpu_buffer_funcs sdma_v6_0_buffer_funcs = {
1881− .copy_max_bytes = 0x400000,
1887+ .copy_max_bytes = 1 << 30,
18821888 .copy_num_dw = 7,
18831889 .emit_copy_buffer = sdma_v6_0_emit_copy_buffer,
18841890
1885− .fill_max_bytes = 0x400000,
1891+ .fill_max_bytes = 1 << 30,
18861892 .fill_num_dw = 5,
18871893 .emit_fill_buffer = sdma_v6_0_emit_fill_buffer,
18881894 };
@@ -1893,25 +1899,6 @@ static void sdma_v6_0_set_buffer_funcs(struct amdgpu_device *adev) · 4 unmodified lines
18931899 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
18941900 }
18951901
1896−static 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−
1903−static 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−
19151902 const struct amdgpu_ip_block_version sdma_v6_0_ip_block = {
19161903 .type = AMD_IP_BLOCK_TYPE_SDMA,
19171904 .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
119119
120120 static void sdma_v7_0_set_ring_funcs(struct amdgpu_device *adev);
121121 static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev);
122−static void sdma_v7_0_set_vm_pte_funcs(struct amdgpu_device *adev);
123122 static void sdma_v7_0_set_irq_funcs(struct amdgpu_device *adev);
124123 static int sdma_v7_0_start(struct amdgpu_device *adev);
125124
@@ -1264,6 +1263,13 @@ static void sdma_v7_0_get_csa_info(struct amdgpu_device *adev, · 1138 unmodified lines
12641263 csa_info->alignment = SDMA7_CSA_ALIGNMENT;
12651264 }
12661265
1266+static 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+
12671273 static int sdma_v7_0_early_init(struct amdgpu_ip_block *ip_block)
12681274 {
12691275 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
12941300
12951301 sdma_v7_0_set_ring_funcs(adev);
12961302 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);
12981304 sdma_v7_0_set_irq_funcs(adev);
12991305 sdma_v7_0_set_mqd_funcs(adev);
13001306 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
18291835 }
18301836
18311837 static const struct amdgpu_buffer_funcs sdma_v7_0_buffer_funcs = {
1832− .copy_max_bytes = 0x400000,
1838+ .copy_max_bytes = 1 << 30,
18331839 .copy_num_dw = 8,
18341840 .emit_copy_buffer = sdma_v7_0_emit_copy_buffer,
1835− .fill_max_bytes = 0x400000,
1841+ .fill_max_bytes = 1 << 30,
18361842 .fill_num_dw = 5,
18371843 .emit_fill_buffer = sdma_v7_0_emit_fill_buffer,
18381844 };
@@ -1843,25 +1849,6 @@ static void sdma_v7_0_set_buffer_funcs(struct amdgpu_device *adev) · 4 unmodified lines
18431849 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
18441850 }
18451851
1846−static 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−
1853−static 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−
18651852 const struct amdgpu_ip_block_version sdma_v7_0_ip_block = {
18661853 .type = AMD_IP_BLOCK_TYPE_SDMA,
18671854 .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
110110
111111 static void sdma_v7_1_set_ring_funcs(struct amdgpu_device *adev);
112112 static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev);
113−static void sdma_v7_1_set_vm_pte_funcs(struct amdgpu_device *adev);
114113 static void sdma_v7_1_set_irq_funcs(struct amdgpu_device *adev);
115114 static int sdma_v7_1_inst_start(struct amdgpu_device *adev,
116115 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
12481247 amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);
12491248 }
12501249
1250+static 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+
12511257 static int sdma_v7_1_early_init(struct amdgpu_ip_block *ip_block)
12521258 {
12531259 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
12611267
12621268 sdma_v7_1_set_ring_funcs(adev);
12631269 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);
12651271 sdma_v7_1_set_irq_funcs(adev);
12661272 sdma_v7_1_set_mqd_funcs(adev);
12671273
@@ -1739,10 +1745,10 @@ static void sdma_v7_1_emit_fill_buffer(struct amdgpu_ib *ib, · 471 unmodified lines
17391745 }
17401746
17411747 static const struct amdgpu_buffer_funcs sdma_v7_1_buffer_funcs = {
1742− .copy_max_bytes = 0x400000,
1748+ .copy_max_bytes = 1 << 30,
17431749 .copy_num_dw = 8,
17441750 .emit_copy_buffer = sdma_v7_1_emit_copy_buffer,
1745− .fill_max_bytes = 0x400000,
1751+ .fill_max_bytes = 1 << 30,
17461752 .fill_num_dw = 5,
17471753 .emit_fill_buffer = sdma_v7_1_emit_fill_buffer,
17481754 };
@@ -1753,25 +1759,6 @@ static void sdma_v7_1_set_buffer_funcs(struct amdgpu_device *adev) · 4 unmodified lines
17531759 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
17541760 }
17551761
1756−static 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−
1763−static 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−
17751762 const struct amdgpu_ip_block_version sdma_v7_1_ip_block = {
17761763 .type = AMD_IP_BLOCK_TYPE_SDMA,
17771764 .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
10271027 unsigned long flags;
10281028 u32 r;
10291029
1030− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1030+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
10311031 WREG32(AMDGPU_PCIE_INDEX, reg);
10321032 (void)RREG32(AMDGPU_PCIE_INDEX);
10331033 r = RREG32(AMDGPU_PCIE_DATA);
1034− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1034+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
10351035 return r;
10361036 }
10371037
@@ -1039,12 +1039,12 @@ static void si_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
10391039 {
10401040 unsigned long flags;
10411041
1042− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1042+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
10431043 WREG32(AMDGPU_PCIE_INDEX, reg);
10441044 (void)RREG32(AMDGPU_PCIE_INDEX);
10451045 WREG32(AMDGPU_PCIE_DATA, v);
10461046 (void)RREG32(AMDGPU_PCIE_DATA);
1047− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1047+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
10481048 }
10491049
10501050 static 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
10521052 unsigned long flags;
10531053 u32 r;
10541054
1055− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1055+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
10561056 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
10571057 (void)RREG32(PCIE_PORT_INDEX);
10581058 r = RREG32(PCIE_PORT_DATA);
1059− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1059+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
10601060 return r;
10611061 }
10621062
@@ -1064,12 +1064,12 @@ static void si_pciep_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
10641064 {
10651065 unsigned long flags;
10661066
1067− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
1067+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
10681068 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
10691069 (void)RREG32(PCIE_PORT_INDEX);
10701070 WREG32(PCIE_PORT_DATA, (v));
10711071 (void)RREG32(PCIE_PORT_DATA);
1072− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
1072+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
10731073 }
10741074
10751075 static 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
10771077 unsigned long flags;
10781078 u32 r;
10791079
1080− spin_lock_irqsave(&adev->smc_idx_lock, flags);
1080+ spin_lock_irqsave(&adev->reg.smc.lock, flags);
10811081 WREG32(mmSMC_IND_INDEX_0, (reg));
10821082 r = RREG32(mmSMC_IND_DATA_0);
1083− spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
1083+ spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
10841084 return r;
10851085 }
10861086
@@ -1088,10 +1088,10 @@ static void si_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
10881088 {
10891089 unsigned long flags;
10901090
1091− spin_lock_irqsave(&adev->smc_idx_lock, flags);
1091+ spin_lock_irqsave(&adev->reg.smc.lock, flags);
10921092 WREG32(mmSMC_IND_INDEX_0, (reg));
10931093 WREG32(mmSMC_IND_DATA_0, (v));
1094− spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
1094+ spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
10951095 }
10961096
10971097 static 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
10991099 unsigned long flags;
11001100 u32 r;
11011101
1102− spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
1102+ spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
11031103 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
11041104 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);
11061106 return r;
11071107 }
11081108
@@ -1110,10 +1110,10 @@ static void si_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
11101110 {
11111111 unsigned long flags;
11121112
1113− spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
1113+ spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
11141114 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
11151115 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);
11171117 }
11181118
11191119 static 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
20372037 {
20382038 struct amdgpu_device *adev = ip_block->adev;
20392039
2040− adev->smc_rreg = &si_smc_rreg;
2041− adev->smc_wreg = &si_smc_wreg;
2042− adev->pcie_rreg = &si_pcie_rreg;
2043− adev->pcie_wreg = &si_pcie_wreg;
2044− adev->pciep_rreg = &si_pciep_rreg;
2045− adev->pciep_wreg = &si_pciep_wreg;
2046− adev->uvd_ctx_rreg = si_uvd_ctx_rreg;
2047− adev->uvd_ctx_wreg = si_uvd_ctx_wreg;
2048− adev->didt_rreg = NULL;
2049− adev->didt_wreg = NULL;
2040+ adev->reg.smc.rreg = si_smc_rreg;
2041+ adev->reg.smc.wreg = si_smc_wreg;
2042+ adev->reg.pcie.rreg = &si_pcie_rreg;
2043+ adev->reg.pcie.wreg = &si_pcie_wreg;
2044+ adev->reg.pcie.port_rreg = &si_pciep_rreg;
2045+ adev->reg.pcie.port_wreg = &si_pciep_wreg;
2046+ adev->reg.uvd_ctx.rreg = &si_uvd_ctx_rreg;
2047+ adev->reg.uvd_ctx.wreg = &si_uvd_ctx_wreg;
20502048
20512049 adev->asic_funcs = &si_asic_funcs;
20522050
@@ -2382,10 +2380,10 @@ static inline u32 si_pif_phy0_rreg(struct amdgpu_device *adev, u32 reg) · 329 unmodified lines
23822380 unsigned long flags;
23832381 u32 r;
23842382
2385− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
2383+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
23862384 WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
23872385 r = RREG32(EVERGREEN_PIF_PHY0_DATA);
2388− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
2386+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
23892387 return r;
23902388 }
23912389
@@ -2393,10 +2391,10 @@ static inline void si_pif_phy0_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
23932391 {
23942392 unsigned long flags;
23952393
2396− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
2394+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
23972395 WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
23982396 WREG32(EVERGREEN_PIF_PHY0_DATA, (v));
2399− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
2397+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
24002398 }
24012399
24022400 static 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
24042402 unsigned long flags;
24052403 u32 r;
24062404
2407− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
2405+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
24082406 WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
24092407 r = RREG32(EVERGREEN_PIF_PHY1_DATA);
2410− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
2408+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
24112409 return r;
24122410 }
24132411
@@ -2415,10 +2413,10 @@ static inline void si_pif_phy1_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
24152413 {
24162414 unsigned long flags;
24172415
2418− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
2416+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
24192417 WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
24202418 WREG32(EVERGREEN_PIF_PHY1_DATA, (v));
2421− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
2419+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
24222420 }
24232421 static void si_program_aspm(struct amdgpu_device *adev)
24242422 {
drivers/gpu/drm/amd/amdgpu/si_dma.c+9−22
@@ -37,7 +37,6 @@ const u32 sdma_offsets[SDMA_MAX_INSTANCE] = · 36 unmodified lines
3737
3838 static void si_dma_set_ring_funcs(struct amdgpu_device *adev);
3939 static void si_dma_set_buffer_funcs(struct amdgpu_device *adev);
40−static void si_dma_set_vm_pte_funcs(struct amdgpu_device *adev);
4140 static void si_dma_set_irq_funcs(struct amdgpu_device *adev);
4241
4342 /**
@@ -473,6 +472,14 @@ static void si_dma_ring_emit_wreg(struct amdgpu_ring *ring, · 429 unmodified lines
473472 amdgpu_ring_write(ring, val);
474473 }
475474
475+static 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+
476483 static int si_dma_early_init(struct amdgpu_ip_block *ip_block)
477484 {
478485 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
481488
482489 si_dma_set_ring_funcs(adev);
483490 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);
485492 si_dma_set_irq_funcs(adev);
486493
487494 return 0;
@@ -830,26 +837,6 @@ static void si_dma_set_buffer_funcs(struct amdgpu_device *adev) · 342 unmodified lines
830837 adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
831838 }
832839
833−static 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−
841−static 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−
853840 const struct amdgpu_ip_block_version si_dma_ip_block =
854841 {
855842 .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
245245 address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX);
246246 data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA);
247247
248− spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
248+ spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
249249 WREG32(address, ((reg) & 0x1ff));
250250 r = RREG32(data);
251− spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);
251+ spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
252252 return r;
253253 }
254254
@@ -259,10 +259,10 @@ static void soc15_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 4 unmodified lines
259259 address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX);
260260 data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA);
261261
262− spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
262+ spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
263263 WREG32(address, ((reg) & 0x1ff));
264264 WREG32(data, (v));
265− spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);
265+ spin_unlock_irqrestore(&adev->reg.uvd_ctx.lock, flags);
266266 }
267267
268268 static 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
273273 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
274274 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
275275
276− spin_lock_irqsave(&adev->didt_idx_lock, flags);
276+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
277277 WREG32(address, (reg));
278278 r = RREG32(data);
279− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
279+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
280280 return r;
281281 }
282282
@@ -287,10 +287,10 @@ static void soc15_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 4 unmodified lines
287287 address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
288288 data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
289289
290− spin_lock_irqsave(&adev->didt_idx_lock, flags);
290+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
291291 WREG32(address, (reg));
292292 WREG32(data, (v));
293− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
293+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
294294 }
295295
296296 static 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
298298 unsigned long flags;
299299 u32 r;
300300
301− spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
301+ spin_lock_irqsave(&adev->reg.gc_cac.lock, flags);
302302 WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
303303 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);
305305 return r;
306306 }
307307
@@ -309,10 +309,10 @@ static void soc15_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
309309 {
310310 unsigned long flags;
311311
312− spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
312+ spin_lock_irqsave(&adev->reg.gc_cac.lock, flags);
313313 WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
314314 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);
316316 }
317317
318318 static 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
320320 unsigned long flags;
321321 u32 r;
322322
323− spin_lock_irqsave(&adev->se_cac_idx_lock, flags);
323+ spin_lock_irqsave(&adev->reg.se_cac.lock, flags);
324324 WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
325325 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);
327327 return r;
328328 }
329329
@@ -331,10 +331,10 @@ static void soc15_se_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
331331 {
332332 unsigned long flags;
333333
334− spin_lock_irqsave(&adev->se_cac_idx_lock, flags);
334+ spin_lock_irqsave(&adev->reg.se_cac.lock, flags);
335335 WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
336336 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);
338338 }
339339
340340 static 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
952952 .get_pcie_replay_count = &amdgpu_nbio_get_pcie_replay_count,
953953 .supports_baco = &soc15_supports_baco,
954954 .query_video_codecs = &soc15_query_video_codecs,
955− .encode_ext_smn_addressing = &aqua_vanjaram_encode_ext_smn_addressing,
956955 .get_reg_state = &aqua_vanjaram_get_reg_state,
957956 };
958957
@@ -961,24 +960,22 @@ static int soc15_common_early_init(struct amdgpu_ip_block *ip_block) · 2 unmodified lines
961960 struct amdgpu_device *adev = ip_block->adev;
962961
963962 adev->nbio.funcs->set_reg_remap(adev);
964− adev->smc_rreg = NULL;
965− adev->smc_wreg = NULL;
966− adev->pcie_rreg = &amdgpu_device_indirect_rreg;
967− adev->pcie_wreg = &amdgpu_device_indirect_wreg;
968− adev->pcie_rreg_ext = &amdgpu_device_indirect_rreg_ext;
969− adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext;
970− adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
971− adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
972− adev->pcie_rreg64_ext = &amdgpu_device_indirect_rreg64_ext;
973− adev->pcie_wreg64_ext = &amdgpu_device_indirect_wreg64_ext;
974− adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg;
975− adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg;
976− adev->didt_rreg = &soc15_didt_rreg;
977− adev->didt_wreg = &soc15_didt_wreg;
978− adev->gc_cac_rreg = &soc15_gc_cac_rreg;
979− adev->gc_cac_wreg = &soc15_gc_cac_wreg;
980− adev->se_cac_rreg = &soc15_se_cac_rreg;
981− adev->se_cac_wreg = &soc15_se_cac_wreg;
963+ adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
964+ adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
965+ adev->reg.pcie.rreg_ext = &amdgpu_device_indirect_rreg_ext;
966+ adev->reg.pcie.wreg_ext = &amdgpu_device_indirect_wreg_ext;
967+ adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
968+ adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
969+ adev->reg.pcie.rreg64_ext = &amdgpu_device_indirect_rreg64_ext;
970+ adev->reg.pcie.wreg64_ext = &amdgpu_device_indirect_wreg64_ext;
971+ adev->reg.uvd_ctx.rreg = &soc15_uvd_ctx_rreg;
972+ adev->reg.uvd_ctx.wreg = &soc15_uvd_ctx_wreg;
973+ adev->reg.didt.rreg = &soc15_didt_rreg;
974+ adev->reg.didt.wreg = &soc15_didt_wreg;
975+ adev->reg.gc_cac.rreg = &soc15_gc_cac_rreg;
976+ adev->reg.gc_cac.wreg = &soc15_gc_cac_wreg;
977+ adev->reg.se_cac.rreg = &soc15_se_cac_rreg;
978+ adev->reg.se_cac.wreg = &soc15_se_cac_wreg;
982979
983980 adev->rev_id = amdgpu_device_get_rev_id(adev);
984981 adev->external_rev_id = 0xFF;
@@ -1200,6 +1197,7 @@ static int soc15_common_early_init(struct amdgpu_ip_block *ip_block) · 215 unmodified lines
12001197 case IP_VERSION(9, 4, 4):
12011198 case IP_VERSION(9, 5, 0):
12021199 adev->asic_funcs = &aqua_vanjaram_asic_funcs;
1200+ adev->reg.smn.get_smn_base = &amdgpu_reg_smn_v1_0_get_base;
12031201 adev->cg_flags =
12041202 AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG |
12051203 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
118118 int vega20_reg_base_init(struct amdgpu_device *adev);
119119 int arct_reg_base_init(struct amdgpu_device *adev);
120120 int aldebaran_reg_base_init(struct amdgpu_device *adev);
121−u64 aqua_vanjaram_encode_ext_smn_addressing(int ext_id);
122121 int aqua_vanjaram_init_soc_config(struct amdgpu_device *adev);
123122 ssize_t aqua_vanjaram_get_reg_state(struct amdgpu_device *adev,
124123 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
195195 __RREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, AMDGPU_REGS_RLC, ip##_HWIP, inst)
196196
197197 /* inst equals to ext for some IPs */
198−#define RREG32_SOC15_EXT(ip, inst, reg, ext) \
199− RREG32_PCIE_EXT((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) * 4 \
200− + adev->asic_funcs->encode_ext_smn_addressing(ext)) \
201−
202−#define WREG32_SOC15_EXT(ip, inst, reg, ext, value) \
203− WREG32_PCIE_EXT((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) * 4 \
204− + adev->asic_funcs->encode_ext_smn_addressing(ext), \
205− value) \
206−
207−#define RREG64_MCA(ext, mca_base, idx) \
208− RREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8))
209−
210−#define WREG64_MCA(ext, mca_base, idx, val) \
211− WREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8), val)
198+#define RREG32_SOC15_EXT(ip, inst, reg, ext) \
199+ RREG32_PCIE_EXT((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + \
200+ reg) * 4 + \
201+ amdgpu_reg_get_smn_base64(adev, ip##_HWIP, inst))
202+
203+#define WREG32_SOC15_EXT(ip, inst, reg, ext, value) \
204+ WREG32_PCIE_EXT( \
205+ (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) * \
206+ 4 + \
207+ amdgpu_reg_get_smn_base64(adev, ip##_HWIP, inst), \
208+ value)
209+
210+#define RREG64_MCA(smn_base, mca_base, idx) \
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)
212215
213216 #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
229229 address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
230230 data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
231231
232− spin_lock_irqsave(&adev->didt_idx_lock, flags);
232+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
233233 WREG32(address, (reg));
234234 r = RREG32(data);
235− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
235+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
236236 return r;
237237 }
238238
@@ -243,10 +243,10 @@ static void soc21_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 4 unmodified lines
243243 address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
244244 data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
245245
246− spin_lock_irqsave(&adev->didt_idx_lock, flags);
246+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
247247 WREG32(address, (reg));
248248 WREG32(data, (v));
249− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
249+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
250250 }
251251
252252 static 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
589589 struct amdgpu_device *adev = ip_block->adev;
590590
591591 adev->nbio.funcs->set_reg_remap(adev);
592− adev->smc_rreg = NULL;
593− adev->smc_wreg = NULL;
594− adev->pcie_rreg = &amdgpu_device_indirect_rreg;
595− adev->pcie_wreg = &amdgpu_device_indirect_wreg;
596− adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
597− adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
598− adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
599− adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
600−
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;
592+ adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
593+ adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
594+ adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
595+ adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
596+ adev->reg.pcie.port_rreg = &amdgpu_device_pcie_port_rreg;
597+ adev->reg.pcie.port_wreg = &amdgpu_device_pcie_port_wreg;
598+
599+ adev->reg.didt.rreg = &soc21_didt_rreg;
600+ adev->reg.didt.wreg = &soc21_didt_wreg;
607601
608602 adev->asic_funcs = &soc21_asic_funcs;
609603
@@ -858,7 +852,9 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block) · 248 unmodified lines
858852 AMD_CG_SUPPORT_IH_CG |
859853 AMD_CG_SUPPORT_BIF_MGCG |
860854 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 |
862858 AMD_PG_SUPPORT_JPEG |
863859 AMD_PG_SUPPORT_GFX_PG;
864860 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
362362 struct amdgpu_device *adev = ip_block->adev;
363363
364364 adev->nbio.funcs->set_reg_remap(adev);
365− adev->smc_rreg = NULL;
366− adev->smc_wreg = NULL;
367− adev->pcie_rreg = &amdgpu_device_indirect_rreg;
368− adev->pcie_wreg = &amdgpu_device_indirect_wreg;
369− adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
370− adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
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;
365+ adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
366+ adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
367+ adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
368+ adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
369+ adev->reg.pcie.port_rreg = &amdgpu_device_pcie_port_rreg;
370+ adev->reg.pcie.port_wreg = &amdgpu_device_pcie_port_wreg;
377371
378372 adev->asic_funcs = &soc24_asic_funcs;
379373
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
250250 {
251251 struct amdgpu_device *adev = ip_block->adev;
252252
253− adev->smc_rreg = NULL;
254− adev->smc_wreg = NULL;
255− adev->pcie_rreg = &amdgpu_device_indirect_rreg;
256− adev->pcie_wreg = &amdgpu_device_indirect_wreg;
257− adev->pcie_rreg_ext = &amdgpu_device_indirect_rreg_ext;
258− adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext;
259− adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
260− adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
261− adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
262− adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
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;
253+ adev->reg.pcie.rreg = &amdgpu_device_indirect_rreg;
254+ adev->reg.pcie.wreg = &amdgpu_device_indirect_wreg;
255+ adev->reg.pcie.rreg_ext = &amdgpu_device_indirect_rreg_ext;
256+ adev->reg.pcie.wreg_ext = &amdgpu_device_indirect_wreg_ext;
257+ adev->reg.pcie.rreg64 = &amdgpu_device_indirect_rreg64;
258+ adev->reg.pcie.wreg64 = &amdgpu_device_indirect_wreg64;
259+ adev->reg.pcie.port_rreg = &amdgpu_device_pcie_port_rreg;
260+ adev->reg.pcie.port_wreg = &amdgpu_device_pcie_port_wreg;
261+ adev->reg.pcie.rreg64_ext = &amdgpu_device_indirect_rreg64_ext;
262+ adev->reg.pcie.wreg64_ext = &amdgpu_device_indirect_wreg64_ext;
269263
270264 adev->asic_funcs = &soc_v1_0_asic_funcs;
271265
drivers/gpu/drm/amd/amdgpu/vce_v1_0.c+17−16
@@ -47,11 +47,6 @@ · 46 unmodified lines
4747 #define VCE_V1_0_DATA_SIZE (7808 * (AMDGPU_MAX_VCE_HANDLES + 1))
4848 #define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02
4949
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−
5550 static void vce_v1_0_set_ring_funcs(struct amdgpu_device *adev);
5651 static void vce_v1_0_set_irq_funcs(struct amdgpu_device *adev);
5752
@@ -535,27 +530,29 @@ static int vce_v1_0_early_init(struct amdgpu_ip_block *ip_block) · 477 unmodified lines
535530 */
536531 static int vce_v1_0_ensure_vcpu_bo_32bit_addr(struct amdgpu_device *adev)
537532 {
538− u64 gpu_addr = amdgpu_bo_gpu_offset(adev->vce.vcpu_bo);
539533 u64 bo_size = amdgpu_bo_size(adev->vce.vcpu_bo);
540534 u64 max_vcpu_bo_addr = 0xffffffff - bo_size;
541535 u64 num_pages = ALIGN(bo_size, AMDGPU_GPU_PAGE_SIZE) / AMDGPU_GPU_PAGE_SIZE;
542536 u64 pa = amdgpu_gmc_vram_pa(adev, adev->vce.vcpu_bo);
543537 u64 flags = AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | AMDGPU_PTE_VALID;
538+ u64 vce_gart_start_offs;
539+ int r;
544540
545− /*
546− * Check if the VCPU BO already has a 32-bit address.
547− * Eg. if MC is configured to put VRAM in the low address range.
548− */
549− if (gpu_addr <= max_vcpu_bo_addr)
550− return 0;
541+ r = amdgpu_gtt_mgr_alloc_entries(&adev->mman.gtt_mgr,
542+ &adev->vce.gart_node, num_pages,
543+ DRM_MM_INSERT_LOW);
544+ if (r)
545+ return r;
546+
547+ vce_gart_start_offs = amdgpu_gtt_node_to_byte_offset(&adev->vce.gart_node);
551548
552549 /* 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)
554551 return -EINVAL;
555552
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,
557554 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;
559556 if (adev->vce.gpu_addr > max_vcpu_bo_addr)
560557 return -EINVAL;
561558
@@ -610,7 +607,11 @@ static int vce_v1_0_sw_fini(struct amdgpu_ip_block *ip_block) · 48 unmodified lines
610607 if (r)
611608 return r;
612609
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;
614615 }
615616
616617 /**
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
299299 unsigned long flags;
300300 u32 r;
301301
302− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
302+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
303303 WREG32_NO_KIQ(mmPCIE_INDEX, reg);
304304 (void)RREG32_NO_KIQ(mmPCIE_INDEX);
305305 r = RREG32_NO_KIQ(mmPCIE_DATA);
306− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
306+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
307307 return r;
308308 }
309309
@@ -311,12 +311,12 @@ static void vi_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
311311 {
312312 unsigned long flags;
313313
314− spin_lock_irqsave(&adev->pcie_idx_lock, flags);
314+ spin_lock_irqsave(&adev->reg.pcie.lock, flags);
315315 WREG32_NO_KIQ(mmPCIE_INDEX, reg);
316316 (void)RREG32_NO_KIQ(mmPCIE_INDEX);
317317 WREG32_NO_KIQ(mmPCIE_DATA, v);
318318 (void)RREG32_NO_KIQ(mmPCIE_DATA);
319− spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
319+ spin_unlock_irqrestore(&adev->reg.pcie.lock, flags);
320320 }
321321
322322 static 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
324324 unsigned long flags;
325325 u32 r;
326326
327− spin_lock_irqsave(&adev->smc_idx_lock, flags);
327+ spin_lock_irqsave(&adev->reg.smc.lock, flags);
328328 WREG32_NO_KIQ(mmSMC_IND_INDEX_11, (reg));
329329 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);
331331 return r;
332332 }
333333
@@ -335,10 +335,10 @@ static void vi_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
335335 {
336336 unsigned long flags;
337337
338− spin_lock_irqsave(&adev->smc_idx_lock, flags);
338+ spin_lock_irqsave(&adev->reg.smc.lock, flags);
339339 WREG32_NO_KIQ(mmSMC_IND_INDEX_11, (reg));
340340 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);
342342 }
343343
344344 /* smu_8_0_d.h */
@@ -350,10 +350,10 @@ static u32 cz_smc_rreg(struct amdgpu_device *adev, u32 reg) · 5 unmodified lines
350350 unsigned long flags;
351351 u32 r;
352352
353− spin_lock_irqsave(&adev->smc_idx_lock, flags);
353+ spin_lock_irqsave(&adev->reg.smc.lock, flags);
354354 WREG32(mmMP0PUB_IND_INDEX, (reg));
355355 r = RREG32(mmMP0PUB_IND_DATA);
356− spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
356+ spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
357357 return r;
358358 }
359359
@@ -361,10 +361,10 @@ static void cz_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
361361 {
362362 unsigned long flags;
363363
364− spin_lock_irqsave(&adev->smc_idx_lock, flags);
364+ spin_lock_irqsave(&adev->reg.smc.lock, flags);
365365 WREG32(mmMP0PUB_IND_INDEX, (reg));
366366 WREG32(mmMP0PUB_IND_DATA, (v));
367− spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
367+ spin_unlock_irqrestore(&adev->reg.smc.lock, flags);
368368 }
369369
370370 static 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
372372 unsigned long flags;
373373 u32 r;
374374
375− spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
375+ spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
376376 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
377377 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);
379379 return r;
380380 }
381381
@@ -383,10 +383,10 @@ static void vi_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
383383 {
384384 unsigned long flags;
385385
386− spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
386+ spin_lock_irqsave(&adev->reg.uvd_ctx.lock, flags);
387387 WREG32(mmUVD_CTX_INDEX, ((reg) & 0x1ff));
388388 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);
390390 }
391391
392392 static 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
394394 unsigned long flags;
395395 u32 r;
396396
397− spin_lock_irqsave(&adev->didt_idx_lock, flags);
397+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
398398 WREG32(mmDIDT_IND_INDEX, (reg));
399399 r = RREG32(mmDIDT_IND_DATA);
400− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
400+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
401401 return r;
402402 }
403403
@@ -405,10 +405,10 @@ static void vi_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
405405 {
406406 unsigned long flags;
407407
408− spin_lock_irqsave(&adev->didt_idx_lock, flags);
408+ spin_lock_irqsave(&adev->reg.didt.lock, flags);
409409 WREG32(mmDIDT_IND_INDEX, (reg));
410410 WREG32(mmDIDT_IND_DATA, (v));
411− spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
411+ spin_unlock_irqrestore(&adev->reg.didt.lock, flags);
412412 }
413413
414414 static 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
416416 unsigned long flags;
417417 u32 r;
418418
419− spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
419+ spin_lock_irqsave(&adev->reg.gc_cac.lock, flags);
420420 WREG32(mmGC_CAC_IND_INDEX, (reg));
421421 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);
423423 return r;
424424 }
425425
@@ -427,10 +427,10 @@ static void vi_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) · 1 unmodified line
427427 {
428428 unsigned long flags;
429429
430− spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
430+ spin_lock_irqsave(&adev->reg.gc_cac.lock, flags);
431431 WREG32(mmGC_CAC_IND_INDEX, (reg));
432432 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);
434434 }
435435
436436
@@ -649,7 +649,7 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, · 212 unmodified lines
649649 dw_ptr = (u32 *)bios;
650650 length_dw = ALIGN(length_bytes, 4) / 4;
651651 /* 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);
653653 /* set rom index to 0 */
654654 WREG32(mmSMC_IND_INDEX_11, ixROM_INDEX);
655655 WREG32(mmSMC_IND_DATA_11, 0);
@@ -657,7 +657,7 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, · 1 unmodified line
657657 WREG32(mmSMC_IND_INDEX_11, ixROM_DATA);
658658 for (i = 0; i < length_dw; i++)
659659 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);
661661
662662 return true;
663663 }
@@ -1454,20 +1454,20 @@ static int vi_common_early_init(struct amdgpu_ip_block *ip_block) · 790 unmodified lines
14541454 struct amdgpu_device *adev = ip_block->adev;
14551455
14561456 if (adev->flags & AMD_IS_APU) {
1457− adev->smc_rreg = &cz_smc_rreg;
1458− adev->smc_wreg = &cz_smc_wreg;
1457+ adev->reg.smc.rreg = cz_smc_rreg;
1458+ adev->reg.smc.wreg = cz_smc_wreg;
14591459 } else {
1460− adev->smc_rreg = &vi_smc_rreg;
1461− adev->smc_wreg = &vi_smc_wreg;
1460+ adev->reg.smc.rreg = vi_smc_rreg;
1461+ adev->reg.smc.wreg = vi_smc_wreg;
14621462 }
1463− adev->pcie_rreg = &vi_pcie_rreg;
1464− adev->pcie_wreg = &vi_pcie_wreg;
1465− adev->uvd_ctx_rreg = &vi_uvd_ctx_rreg;
1466− adev->uvd_ctx_wreg = &vi_uvd_ctx_wreg;
1467− adev->didt_rreg = &vi_didt_rreg;
1468− adev->didt_wreg = &vi_didt_wreg;
1469− adev->gc_cac_rreg = &vi_gc_cac_rreg;
1470− adev->gc_cac_wreg = &vi_gc_cac_wreg;
1463+ adev->reg.pcie.rreg = &vi_pcie_rreg;
1464+ adev->reg.pcie.wreg = &vi_pcie_wreg;
1465+ adev->reg.uvd_ctx.rreg = &vi_uvd_ctx_rreg;
1466+ adev->reg.uvd_ctx.wreg = &vi_uvd_ctx_wreg;
1467+ adev->reg.didt.rreg = &vi_didt_rreg;
1468+ adev->reg.didt.wreg = &vi_didt_wreg;
1469+ adev->reg.gc_cac.rreg = &vi_gc_cac_rreg;
1470+ adev->reg.gc_cac.wreg = &vi_gc_cac_wreg;
14711471
14721472 adev->asic_funcs = &vi_asic_funcs;
14731473
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
134134 var SQ_WAVE_MODE_DST_SRC0_SRC1_VGPR_MSB_SIZE = 6
135135 #endif
136136
137−var TTMP11_SCHED_MODE_SHIFT = 26
138−var TTMP11_SCHED_MODE_SIZE = 2
139−var TTMP11_SCHED_MODE_MASK = 0xC000000
140137 var TTMP11_DEBUG_TRAP_ENABLED_SHIFT = 23
141138 var TTMP11_DEBUG_TRAP_ENABLED_MASK = 0x800000
142139 var 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
342342
343343 static void kfd_init_apertures_v9(struct kfd_process_device *pdd, uint8_t id)
344344 {
345− if (KFD_GC_VERSION(pdd->dev) >= IP_VERSION(12, 1, 0))
346− pdd->lds_base = pdd->dev->adev->gmc.shared_aperture_start;
347− else
348− pdd->lds_base = MAKE_LDS_APP_BASE_V9();
345+ pdd->lds_base = MAKE_LDS_APP_BASE_V9();
349346 pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base);
350347
351348 pdd->gpuvm_base = AMDGPU_VA_RESERVED_BOTTOM;
352349 pdd->gpuvm_limit =
353350 pdd->dev->kfd->shared_resources.gpuvm_size - 1;
354351
355− if (KFD_GC_VERSION(pdd->dev) >= IP_VERSION(12, 1, 0))
356− pdd->scratch_base = pdd->dev->adev->gmc.private_aperture_start;
357− else
358− pdd->scratch_base = MAKE_SCRATCH_APP_BASE_V9();
352+ pdd->scratch_base = MAKE_SCRATCH_APP_BASE_V9();
359353 pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base);
360354
361355 /*
@@ -365,6 +359,25 @@ static void kfd_init_apertures_v9(struct kfd_process_device *pdd, uint8_t id) · 3 unmodified lines
365359 pdd->qpd.cwsr_base = AMDGPU_VA_RESERVED_TRAP_START(pdd->dev->adev);
366360 }
367361
362+static 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+
368381 int kfd_init_apertures(struct kfd_process *process)
369382 {
370383 uint8_t id = 0;
@@ -412,9 +425,11 @@ int kfd_init_apertures(struct kfd_process *process) · 41 unmodified lines
412425 kfd_init_apertures_vi(pdd, id);
413426 break;
414427 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)) {
416431 kfd_init_apertures_v9(pdd, id);
417− else {
432+ } else {
418433 WARN(1, "Unexpected ASIC family %u",
419434 dev->adev->asic_type);
420435 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
5959 void *cpu_addr;
6060 int r;
6161
62− /* use gart window 0 */
63− *gart_addr = adev->gmc.gart_start;
62+ *gart_addr = amdgpu_compute_gart_address(&adev->gmc, entity, 0);
6463
6564 num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
6665 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
7877 src_addr += job->ibs[0].gpu_addr;
7978
8079 dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
80+ dst_addr += (entity->gart_window_offs[0] >> AMDGPU_GPU_PAGE_SHIFT) * 8;
8181 amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
8282 dst_addr, num_bytes, 0);
8383
@@ -116,7 +116,7 @@ svm_migrate_gart_map(struct amdgpu_ring *ring, · 32 unmodified lines
116116 * multiple GTT_MAX_PAGES transfer, all sdma operations are serialized, wait for
117117 * the last sdma finish fence which is returned to check copy memory is done.
118118 *
119− * Context: Process context, takes and releases gtt_window_lock
119+ * Context: Process context
120120 *
121121 * Return:
122122 * 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
136136 u64 size;
137137 int r;
138138
139− entity = &adev->mman.default_entity;
139+ entity = &adev->mman.move_entity;
140140
141− mutex_lock(&adev->mman.gtt_window_lock);
141+ mutex_lock(&entity->lock);
142142
143143 while (npages) {
144144 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
175175 }
176176
177177 out_unlock:
178− mutex_unlock(&adev->mman.gtt_window_lock);
178+ mutex_unlock(&entity->lock);
179179
180180 return r;
181181 }
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
7070 static void set_priority(struct cik_mqd *m, struct queue_properties *q)
7171 {
7272 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
73− /* m->cp_hqd_queue_priority = q->priority; */
7473 }
7574
7675 static 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
7070 static void set_priority(struct v10_compute_mqd *m, struct queue_properties *q)
7171 {
7272 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
73− /* m->cp_hqd_queue_priority = q->priority; */
7473 }
7574
7675 static 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
9696 static void set_priority(struct v11_compute_mqd *m, struct queue_properties *q)
9797 {
9898 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
99− /* m->cp_hqd_queue_priority = q->priority; */
10099 }
101100
102101 static 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
7777 static void set_priority(struct v12_compute_mqd *m, struct queue_properties *q)
7878 {
7979 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
80− /* m->cp_hqd_queue_priority = q->priority; */
8180 }
8281
8382 static 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
131131 static void set_priority(struct v12_1_compute_mqd *m, struct queue_properties *q)
132132 {
133133 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
134− /* m->cp_hqd_queue_priority = q->priority; */
135134 }
136135
137136 static 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
106106 static void set_priority(struct v9_mqd *m, struct queue_properties *q)
107107 {
108108 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
109− /* m->cp_hqd_queue_priority = q->priority; */
110109 }
111110
112111 static 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
7373 static void set_priority(struct vi_mqd *m, struct queue_properties *q)
7474 {
7575 m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
76− /* m->cp_hqd_queue_priority = q->priority; */
7776 }
7877
7978 static 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 @@
11 // SPDX-License-Identifier: MIT
22 /*
3− * Copyright 2015 Advanced Micro Devices, Inc.
3+ * Copyright 2015-2026 Advanced Micro Devices, Inc.
44 *
55 * Permission is hereby granted, free of charge, to any person obtaining a
66 * copy of this software and associated documentation files (the "Software"),
@@ -153,6 +153,9 @@ MODULE_FIRMWARE(FIRMWARE_DCN_36_DMUB); · 146 unmodified lines
153153 #define FIRMWARE_DCN_401_DMUB "amdgpu/dcn_4_0_1_dmcub.bin"
154154 MODULE_FIRMWARE(FIRMWARE_DCN_401_DMUB);
155155
156+#define FIRMWARE_DCN_42_DMUB "amdgpu/dcn_4_2_dmcub.bin"
157+MODULE_FIRMWARE(FIRMWARE_DCN_42_DMUB);
158+
156159 /**
157160 * DOC: overview
158161 *
@@ -1369,6 +1372,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) · 1210 unmodified lines
13691372 case IP_VERSION(3, 5, 0):
13701373 case IP_VERSION(3, 5, 1):
13711374 case IP_VERSION(3, 6, 0):
1375+ case IP_VERSION(4, 2, 0):
13721376 hw_params.ips_sequential_ono = adev->external_rev_id > 0x10;
13731377 hw_params.lower_hbr3_phy_ssc = true;
13741378 break;
@@ -1816,6 +1820,9 @@ static void *dm_dmub_get_vbios_bounding_box(struct amdgpu_device *adev) · 441 unmodified lines
18161820 case IP_VERSION(4, 0, 1):
18171821 bb_size = sizeof(struct dml2_soc_bb);
18181822 break;
1823+ case IP_VERSION(4, 2, 0):
1824+ bb_size = sizeof(struct dml2_soc_bb);
1825+ break;
18191826 default:
18201827 return NULL;
18211828 }
@@ -1860,6 +1867,9 @@ static enum dmub_ips_disable_type dm_get_default_ips_mode( · 38 unmodified lines
18601867 case IP_VERSION(3, 5, 1):
18611868 ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
18621869 break;
1870+ case IP_VERSION(4, 2, 0):
1871+ ret = DMUB_IPS_DISABLE_ALL;
1872+ break;
18631873 default:
18641874 /* ASICs older than DCN35 do not have IPSs */
18651875 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
20032013 if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0))
20042014 init_data.num_virtual_links = 1;
20052015
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+ }
20062023 retrieve_dmi_info(&adev->dm);
20072024 if (adev->dm.edp0_on_dp1_quirk)
20082025 init_data.flags.support_edp0_on_dp1 = true;
@@ -2370,6 +2387,7 @@ static int load_dmcu_fw(struct amdgpu_device *adev) · 361 unmodified lines
23702387 case IP_VERSION(3, 5, 1):
23712388 case IP_VERSION(3, 6, 0):
23722389 case IP_VERSION(4, 0, 1):
2390+ case IP_VERSION(4, 2, 0):
23732391 return 0;
23742392 default:
23752393 break;
@@ -2503,7 +2521,9 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 127 unmodified lines
25032521 case IP_VERSION(4, 0, 1):
25042522 dmub_asic = DMUB_ASIC_DCN401;
25052523 break;
2506−
2524+ case IP_VERSION(4, 2, 0):
2525+ dmub_asic = DMUB_ASIC_DCN42;
2526+ break;
25072527 default:
25082528 /* ASIC doesn't support DMUB. */
25092529 return 0;
@@ -4390,105 +4410,6 @@ static int register_hpd_handlers(struct amdgpu_device *adev) · 1880 unmodified lines
43904410 return 0;
43914411 }
43924412
4393−#if defined(CONFIG_DRM_AMD_DC_SI)
4394−/* Register IRQ sources and initialize IRQ callbacks */
4395−static 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−
44924413 /* Register IRQ sources and initialize IRQ callbacks */
44934414 static int dce110_register_irq_handlers(struct amdgpu_device *adev)
44944415 {
@@ -4497,7 +4418,12 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) · 2 unmodified lines
44974418 struct dc_interrupt_params int_params = {0};
44984419 int r;
44994420 int i;
4421+ unsigned int src_id;
45004422 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;
45014427
45024428 if (adev->family >= AMDGPU_FAMILY_AI)
45034429 client_id = SOC15_IH_CLIENTID_DCE;
@@ -4518,8 +4444,9 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) · 14 unmodified lines
45184444 */
45194445
45204446 /* Use VBLANK interrupt */
4521− for (i = VISLANDS30_IV_SRCID_D1_VERTICAL_INTERRUPT0; i <= VISLANDS30_IV_SRCID_D6_VERTICAL_INTERRUPT0; i++) {
4522− r = amdgpu_irq_add_id(adev, client_id, i, &adev->crtc_irq);
4447+ for (i = 0; i < adev->mode_info.num_crtc; i++) {
4448+ src_id = vblank_d1 + i;
4449+ r = amdgpu_irq_add_id(adev, client_id, src_id, &adev->crtc_irq);
45234450 if (r) {
45244451 drm_err(adev_to_drm(adev), "Failed to add crtc irq id!\n");
45254452 return r;
@@ -4527,7 +4454,7 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) · 1 unmodified line
45274454
45284455 int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
45294456 int_params.irq_source =
4530− dc_interrupt_to_irq_source(dc, i, 0);
4457+ dc_interrupt_to_irq_source(dc, src_id, 0);
45314458
45324459 if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
45334460 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
45464473 return -ENOMEM;
45474474 }
45484475
4549− /* Use VUPDATE interrupt */
4550− for (i = VISLANDS30_IV_SRCID_D1_V_UPDATE_INT; i <= VISLANDS30_IV_SRCID_D6_V_UPDATE_INT; i += 2) {
4551− r = amdgpu_irq_add_id(adev, client_id, i, &adev->vupdate_irq);
4552− if (r) {
4553− drm_err(adev_to_drm(adev), "Failed to add vupdate irq id!\n");
4554− return r;
4555− }
4556−
4557− int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
4558− int_params.irq_source =
4559− dc_interrupt_to_irq_source(dc, i, 0);
4476+ if (dc_supports_vrr(adev->dm.dc->ctx->dce_version)) {
4477+ /* Use VUPDATE interrupt */
4478+ for (i = 0; i < adev->mode_info.num_crtc; i++) {
4479+ src_id = VISLANDS30_IV_SRCID_D1_V_UPDATE_INT + i * 2;
4480+ r = amdgpu_irq_add_id(adev, client_id, src_id, &adev->vupdate_irq);
4481+ if (r) {
4482+ drm_err(adev_to_drm(adev), "Failed to add vupdate irq id!\n");
4483+ return r;
4484+ }
45604485
4561− if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
4562− int_params.irq_source < DC_IRQ_SOURCE_VUPDATE1 ||
4563− int_params.irq_source > DC_IRQ_SOURCE_VUPDATE6) {
4564− drm_err(adev_to_drm(adev), "Failed to register vupdate irq!\n");
4565− return -EINVAL;
4566− }
4486+ int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
4487+ int_params.irq_source =
4488+ dc_interrupt_to_irq_source(dc, src_id, 0);
45674489
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+ }
45694496
4570− c_irq_params->adev = adev;
4571− c_irq_params->irq_src = int_params.irq_source;
4497+ c_irq_params = &adev->dm.vupdate_params[
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;
45724501
4573− if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
4574− dm_vupdate_high_irq, c_irq_params))
4575− return -ENOMEM;
4502+ if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
4503+ dm_vupdate_high_irq, c_irq_params))
4504+ return -ENOMEM;
4505+ }
45764506 }
45774507
45784508 /* Use GRPH_PFLIP interrupt */
@@ -5544,6 +5474,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 965 unmodified lines
55445474 case IP_VERSION(3, 5, 1):
55455475 case IP_VERSION(3, 6, 0):
55465476 case IP_VERSION(4, 0, 1):
5477+ case IP_VERSION(4, 2, 0):
55475478 if (register_outbox_irq_handlers(dm->adev)) {
55485479 drm_err(adev_to_drm(adev), "DM: Failed to initialize IRQ\n");
55495480 goto fail;
@@ -5568,6 +5499,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 18 unmodified lines
55685499 case IP_VERSION(3, 5, 1):
55695500 case IP_VERSION(3, 6, 0):
55705501 case IP_VERSION(4, 0, 1):
5502+ case IP_VERSION(4, 2, 0):
55715503 psr_feature_enabled = true;
55725504 break;
55735505 default:
@@ -5700,11 +5632,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 126 unmodified lines
57005632 case CHIP_PITCAIRN:
57015633 case CHIP_VERDE:
57025634 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;
57085635 #endif
57095636 case CHIP_BONAIRE:
57105637 case CHIP_HAWAII:
@@ -5750,6 +5677,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 39 unmodified lines
57505677 case IP_VERSION(3, 5, 1):
57515678 case IP_VERSION(3, 6, 0):
57525679 case IP_VERSION(4, 0, 1):
5680+ case IP_VERSION(4, 2, 0):
57535681 if (dcn10_register_irq_handlers(dm->adev)) {
57545682 drm_err(adev_to_drm(adev), "DM: Failed to initialize IRQ\n");
57555683 goto fail;
@@ -5898,6 +5826,9 @@ static int dm_init_microcode(struct amdgpu_device *adev) · 142 unmodified lines
58985826 case IP_VERSION(4, 0, 1):
58995827 fw_name_dmub = FIRMWARE_DCN_401_DMUB;
59005828 break;
5829+ case IP_VERSION(4, 2, 0):
5830+ fw_name_dmub = FIRMWARE_DCN_42_DMUB;
5831+ break;
59015832 default:
59025833 /* ASIC doesn't support DMUB. */
59035834 return 0;
@@ -6025,6 +5956,7 @@ static int dm_early_init(struct amdgpu_ip_block *ip_block) · 121 unmodified lines
60255956 case IP_VERSION(3, 5, 1):
60265957 case IP_VERSION(3, 6, 0):
60275958 case IP_VERSION(4, 0, 1):
5959+ case IP_VERSION(4, 2, 0):
60285960 adev->mode_info.num_crtc = 4;
60295961 adev->mode_info.num_hpd = 4;
60305962 adev->mode_info.num_dig = 4;
@@ -6041,8 +5973,8 @@ static int dm_early_init(struct amdgpu_ip_block *ip_block) · 10 unmodified lines
60415973 adev->mode_info.funcs = &dm_display_funcs;
60425974
60435975 /*
6044− * Note: Do NOT change adev->audio_endpt_rreg and
6045− * adev->audio_endpt_wreg because they are initialised in
5976+ * Note: Do NOT change adev->reg.audio_endpt.rreg and
5977+ * adev->reg.audio_endpt.wreg because they are initialised in
60465978 * amdgpu_device_init()
60475979 */
60485980 #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
85838515 return DRM_MODE_CONNECTOR_VGA;
85848516 case SIGNAL_TYPE_DISPLAY_PORT:
85858517 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+
85868524 return DRM_MODE_CONNECTOR_DisplayPort;
85878525 case SIGNAL_TYPE_DVI_DUAL_LINK:
85888526 case SIGNAL_TYPE_DVI_SINGLE_LINK:
@@ -9257,8 +9195,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, · 668 unmodified lines
92579195 connector_type == DRM_MODE_CONNECTOR_HDMIB)
92589196 amdgpu_dm_initialize_hdmi_connector(aconnector);
92599197
9260− if (connector_type == DRM_MODE_CONNECTOR_DisplayPort
9261− || connector_type == DRM_MODE_CONNECTOR_eDP)
9198+ if (dc_is_dp_signal(link->connector_signal))
92629199 amdgpu_dm_initialize_dp_connector(dm, aconnector, link->link_index);
92639200
92649201 out_free:
@@ -12320,10 +12257,11 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, · 3055 unmodified lines
1232012257 int i;
1232112258
1232212259 /* Overlay cursor not supported on HW before DCN
12323− * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions
12324− * as previous DCN generations, so enable native mode on DCN401
12260+ * DCN401/420 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions
12261+ * as previous DCN generations, so enable native mode on DCN401/420
1232512262 */
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)) {
1232712265 *cursor_mode = DM_CURSOR_NATIVE_MODE;
1232812266 return 0;
1232912267 }
@@ -12743,7 +12681,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 413 unmodified lines
1274312681
1274412682 /* Check if rotation or scaling is enabled on DCN401 */
1274512683 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))) {
1274712686 new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
1274812687
1274912688 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
17061706 struct dc_transfer_func *tf = &dc_plane_state->in_shaper_func;
17071707 struct drm_atomic_state *state = plane_state->state;
17081708 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;
17091710 const struct drm_device *dev = colorop->dev;
17101711 const struct drm_color_lut32 *lut3d;
17111712 uint32_t lut3d_size;
@@ -1722,7 +1723,7 @@ __set_dm_plane_colorop_3dlut(struct drm_plane_state *plane_state, · 10 unmodified lines
17221723 }
17231724
17241725 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) {
17261727 drm_dbg(dev, "3D LUT is not supported by hardware\n");
17271728 return -EINVAL;
17281729 }
@@ -1875,6 +1876,7 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state, · 146 unmodified lines
18751876 struct drm_colorop *colorop = plane_state->color_pipeline;
18761877 struct drm_device *dev = plane_state->plane->dev;
18771878 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;
18781880 int ret;
18791881
18801882 /* 1D Curve - DEGAM TF */
@@ -1907,7 +1909,7 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state, · 26 unmodified lines
19071909 if (ret)
19081910 return ret;
19091911
1910− if (adev->dm.dc->caps.color.dpp.hw_3d_lut) {
1912+ if (has_3dlut) {
19111913 /* 1D Curve & LUT - SHAPER TF & LUT */
19121914 colorop = colorop->next;
19131915 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
6464 struct drm_colorop *ops[MAX_COLOR_PIPELINE_OPS];
6565 struct drm_device *dev = plane->dev;
6666 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;
6768 int ret;
6869 int i = 0;
6970
@@ -119,7 +120,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr · 49 unmodified lines
119120
120121 i++;
121122
122− if (adev->dm.dc->caps.color.dpp.hw_3d_lut) {
123+ if (has_3dlut) {
123124 /* 1D curve - SHAPER TF */
124125 ops[i] = kzalloc_obj(*ops[0]);
125126 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
765765 dm->adev->mode_info.crtcs[crtc_index] = acrtc;
766766
767767 /* Don't enable DRM CRTC degamma property for
768− * 1. Degamma is replaced by color pipeline.
769− * 2. DCE since it doesn't support programmable degamma anywhere.
770− * 3. DCN401 since pre-blending degamma LUT doesn't apply to cursor.
768+ * 1. DCE since it doesn't support programmable degamma anywhere.
769+ * 2. 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.
771774 */
772− if (plane->color_pipeline_property)
773− has_degamma = false;
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;
775+ has_degamma = dm->adev->dm.dc->caps.color.dpp.dcn_arch &&
776+ dm->adev->dm.dc->ctx->dce_version != DCN_VERSION_4_01;
777777
778778 drm_crtc_enable_color_mgmt(&acrtc->base, has_degamma ? MAX_COLOR_LUT_ENTRIES : 0,
779779 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
10161016 else
10171017 ddc = &aconnector->i2c->base;
10181018
1019+ if (link->dc->hwss.prepare_ddc)
1020+ link->dc->hwss.prepare_ddc(link);
1021+
10191022 /* some dongles read edid incorrectly the first time,
10201023 * do check sum and retry to make sure read correct edid.
10211024 */
@@ -1162,9 +1165,9 @@ void dm_helpers_override_panel_settings( · 140 unmodified lines
11621165 link->panel_config.dsc.disable_dsc_edp = true;
11631166
11641167 if (dc_get_edp_link_panel_inst(ctx->dc, link, &panel_inst) && panel_inst == 1) {
1165− link->panel_config.psr.disable_psr = true;
1166− link->panel_config.psr.disallow_psrsu = true;;
1167− link->panel_config.psr.disallow_replay = true;
1168+ link->panel_config.psr.disable_psr = true;
1169+ link->panel_config.psr.disallow_psrsu = true;
1170+ link->panel_config.psr.disallow_replay = true;
11681171 }
11691172 }
11701173
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c+10−1
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: MIT
22 /*
3− * Copyright 2022 Advanced Micro Devices, Inc.
3+ * Copyright 2022-2026 Advanced Micro Devices, Inc.
44 *
55 * Permission is hereby granted, free of charge, to any person obtaining a
66 * 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
759759 case AMDGPU_FAMILY_GC_11_0_0:
760760 case AMDGPU_FAMILY_GC_11_0_1:
761761 case AMDGPU_FAMILY_GC_11_5_0:
762+ case AMDGPU_FAMILY_GC_11_5_4:
762763 amdgpu_dm_plane_add_gfx11_modifiers(adev, mods, &size, &capacity);
763764 break;
764765 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
12561257 if (ret)
12571258 return ret;
12581259
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+
12591268 ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info);
12601269 if (ret)
12611270 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
780780 return bp->cmd_tbl.dig_encoder_control(bp, cntl);
781781 }
782782
783+static 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+
783795 static enum bp_result bios_parser_dac_load_detection(
784796 struct dc_bios *dcb,
785797 enum engine_id engine_id,
786− enum dal_device_type device_type,
787− uint32_t enum_id)
798+ struct graphics_object_id ext_enc_id)
788799 {
789800 struct bios_parser *bp = BP_FROM_DCB(dcb);
790801 struct dc_context *ctx = dcb->ctx;
791802 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;
793805 uint32_t bios_0_scratch;
794806 uint32_t device_id_mask = 0;
795807
796− bp_params.engine_id = engine_id;
797− bp_params.device_id = get_support_mask_for_device_id(device_type, enum_id);
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;
808+ bp_params.device_id = get_support_mask_for_device_id(
809+ DEVICE_TYPE_CRT, engine_id == ENGINE_ID_DACB ? 2 : 1);
805810
806811 if (bp_params.device_id == ATOM_DEVICE_CRT1_SUPPORT)
807812 device_id_mask = ATOM_S0_CRT1_MASK;
@@ -815,7 +820,20 @@ static enum bp_result bios_parser_dac_load_detection( · 7 unmodified lines
815820 bios_0_scratch &= ~device_id_mask;
816821 dm_write_reg(ctx, bp->base.regs->BIOS_SCRATCH_0, bios_0_scratch);
817822
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+ }
819837
820838 if (bp_result != BP_RESULT_OK)
821839 return bp_result;
@@ -2912,6 +2930,8 @@ static const struct dc_vbios_funcs vbios_funcs = { · 2090 unmodified lines
29122930
29132931 .encoder_control = bios_parser_encoder_control,
29142932
2933+ .external_encoder_control = bios_parser_external_encoder_control,
2934+
29152935 .dac_load_detection = bios_parser_dac_load_detection,
29162936
29172937 .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
226226 return result;
227227 }
228228
229+static 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+
229251 static enum bp_result encoder_control_digx_v3(
230252 struct bios_parser *bp,
231253 struct bp_encoder_control *cntl)
@@ -248,23 +270,7 @@ static enum bp_result encoder_control_digx_v3( · 16 unmodified lines
248270 cntl->signal,
249271 cntl->enable_dp_audio);
250272 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
251−
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− }
273+ params.ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth);
268274
269275 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
270276 result = BP_RESULT_OK;
@@ -294,23 +300,7 @@ static enum bp_result encoder_control_digx_v4( · 23 unmodified lines
294300 cntl->signal,
295301 cntl->enable_dp_audio));
296302 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
297−
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− }
303+ params.ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth);
314304
315305 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
316306 result = BP_RESULT_OK;
@@ -334,23 +324,7 @@ static enum bp_result encoder_control_digx_v5( · 17 unmodified lines
334324 cntl->signal,
335325 cntl->enable_dp_audio));
336326 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
337−
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− }
327+ params.ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth);
354328
355329 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
356330 switch (cntl->color_depth) {
@@ -1797,30 +1771,7 @@ static enum bp_result select_crtc_source_v3( · 1440 unmodified lines
17971771 &params.ucEncodeMode))
17981772 return BP_RESULT_BADINPUT;
17991773
1800− switch (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− }
1774+ params.ucDstBpc = dc_color_depth_to_atom(bp_params->color_depth);
18241775
18251776 if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
18261777 result = BP_RESULT_OK;
@@ -2569,6 +2520,7 @@ static enum bp_result external_encoder_control_v3( · 742 unmodified lines
25692520 cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
25702521 break;
25712522 case EXTERNAL_ENCODER_CONTROL_SETUP:
2523+ case EXTERNAL_ENCODER_CONTROL_ENABLE:
25722524 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
25732525 * 10KHz
25742526 * 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
25852537 if (is_input_signal_dp) {
25862538 /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
25872539 * only valid in encoder setup with DP mode. */
2588− if (LINK_RATE_HIGH == cntl->link_rate)
2589− cntl_params->ucConfig |= 1;
2540+ if (cntl->link_rate == LINK_RATE_LOW)
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+
25902549 /* output color depth Indicate encoder data bpc format
25912550 * in DP mode, only valid in encoder setup in DP mode.
25922551 */
2593− cntl_params->ucBitPerColor =
2594− (uint8_t)(cntl->color_depth);
2552+ cntl_params->ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth);
25952553 }
25962554 /* Indicate how many lanes used by external encoder, only valid
25972555 * in encoder setup and enableoutput. */
25982556 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
25992557 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;
26082558 default:
26092559 break;
26102560 }
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
8484 case DCN_VERSION_3_51:
8585 case DCN_VERSION_3_6:
8686 case DCN_VERSION_4_01:
87+ case DCN_VERSION_4_2:
8788 *h = dal_cmd_tbl_helper_dce112_get_table2();
8889 return true;
8990
drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile+10−13
@@ -1,5 +1,5 @@
11 #
2−# Copyright 2017 Advanced Micro Devices, Inc.
2+# Copyright 2017-2026 Advanced Micro Devices, Inc.
33 #
44 # Permission is hereby granted, free of charge, to any person obtaining a
55 # 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
2929
3030 AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR)
3131
32−
33−ifdef CONFIG_DRM_AMD_DC_SI
34−###############################################################################
35−# DCE 60
36−###############################################################################
37−CLK_MGR_DCE60 = dce60_clk_mgr.o
38−
39−AMD_DAL_CLK_MGR_DCE60 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dce60/,$(CLK_MGR_DCE60))
40−
41−AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCE60)
42−endif
43−
4432 ###############################################################################
4533 # DCE 100 and DCE8x
4634 ###############################################################################
@@ -188,4 +176,13 @@ CLK_MGR_DCN401 = dcn401_clk_mgr.o dcn401_clk_mgr_smu_msg.o · 141 unmodified lines
188176 AMD_DAL_CLK_MGR_DCN401 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn401/,$(CLK_MGR_DCN401))
189177
190178 AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN401)
179+
180+###############################################################################
181+# DCN42
182+###############################################################################
183+CLK_MGR_DCN42 = dcn42_smu.o dcn42_clk_mgr.o
184+
185+AMD_DAL_CLK_MGR_DCN42 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn42/,$(CLK_MGR_DCN42))
186+
187+AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN42)
191188 endif
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c+1−13
@@ -34,7 +34,6 @@ · 33 unmodified lines
3434 #include "dce110/dce110_clk_mgr.h"
3535 #include "dce112/dce112_clk_mgr.h"
3636 #include "dce120/dce120_clk_mgr.h"
37−#include "dce60/dce60_clk_mgr.h"
3837 #include "dcn10/rv1_clk_mgr.h"
3938 #include "dcn10/rv2_clk_mgr.h"
4039 #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
149148 struct hw_asic_id asic_id = ctx->asic_id;
150149
151150 switch (asic_id.chip_family) {
152−#if defined(CONFIG_DRM_AMD_DC_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
151+ case FAMILY_SI:
164152 case FAMILY_CI:
165153 case FAMILY_KV: {
166154 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
6262 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
6363 };
6464
65+/* Max clock values for each state indexed by "enum clocks_state": */
66+static 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 } };
6577
6678 /* Max clock values for each state indexed by "enum clocks_state": */
6779 static 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
126138 return dp_ref_clk_khz;
127139 }
128140
141+static 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+
129155 int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
130156 {
131157 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
134160 int dp_ref_clk_khz;
135161 int target_div;
136162
163+ if (clk_mgr_base->ctx->dce_version <= DCE_VERSION_6_4)
164+ return dce60_get_dp_ref_freq_khz(clk_mgr_base);
165+
137166 /* ASSERT DP Reference Clock source is from DFS*/
138167 REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel);
139168 ASSERT(dprefclk_src_sel == 0);
@@ -441,27 +470,37 @@ void dce_clk_mgr_construct( · 301 unmodified lines
441470 struct clk_mgr *base = &clk_mgr->base;
442471 struct dm_pp_static_clock_info static_clk_info = {0};
443472
444− memcpy(clk_mgr->max_clks_by_state,
445− dce80_max_clks_by_state,
446− sizeof(dce80_max_clks_by_state));
473+ if (ctx->dce_version <= DCE_VERSION_6_4)
474+ memcpy(clk_mgr->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+
447482
448483 base->ctx = ctx;
449484 base->funcs = &dce_funcs;
450485
451− clk_mgr->regs = &disp_clk_regs;
452− clk_mgr->clk_mgr_shift = &disp_clk_shift;
453− clk_mgr->clk_mgr_mask = &disp_clk_mask;
454− clk_mgr->dfs_bypass_disp_clk = 0;
486+ if (ctx->dce_version >= DCE_VERSION_8_0) {
487+ clk_mgr->regs = &disp_clk_regs;
488+ clk_mgr->clk_mgr_shift = &disp_clk_shift;
489+ clk_mgr->clk_mgr_mask = &disp_clk_mask;
490+ }
455491
492+ clk_mgr->dfs_bypass_disp_clk = 0;
456493 clk_mgr->dprefclk_ss_percentage = 0;
457494 clk_mgr->dprefclk_ss_divider = 1000;
458495 clk_mgr->ss_on_dprefclk = false;
459496
460− if (dm_pp_get_static_clocks(ctx, &static_clk_info))
461− clk_mgr->max_clks_state = static_clk_info.max_clocks_state;
462− else
463− clk_mgr->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL;
464− clk_mgr->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID;
497+ if (ctx->dce_version >= DCE_VERSION_8_0) {
498+ if (dm_pp_get_static_clocks(ctx, &static_clk_info))
499+ clk_mgr->max_clks_state = static_clk_info.max_clocks_state;
500+ else
501+ clk_mgr->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL;
502+ clk_mgr->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID;
503+ }
465504
466505 base->clks.max_supported_dispclk_khz =
467506 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
469508 dce_clock_read_integrated_info(clk_mgr);
470509 dce_clock_read_ss_info(clk_mgr);
471510 }
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−
57−static const struct clk_mgr_registers disp_clk_regs = {
58− CLK_COMMON_REG_LIST_DCE60_BASE()
59−};
60−
61−static const struct clk_mgr_shift disp_clk_shift = {
62− CLK_COMMON_MASK_SH_LIST_DCE60_COMMON_BASE(__SHIFT)
63−};
64−
65−static 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": */
71−static 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−
83−static 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−
97−static 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−
109−static 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−
141−static 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−
146−void 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
204204 khz_to_mhz_ceil(requested_dispclk_khz));
205205
206206 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);
208208 }
209209
210210 int 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
221221
222222 /* TODO: add code for programing DP DTO, currently this is down by command table */
223223
224− return actual_dprefclk_set_mhz * 1000;
224+ return (int)((long long)actual_dprefclk_set_mhz * 1000);
225225 }
226226
227227 int 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
238238
239239 smu_print("requested_dcfclk_khz = %d, actual_dcfclk_set_mhz: %d\n", requested_dcfclk_khz, actual_dcfclk_set_mhz);
240240
241− return actual_dcfclk_set_mhz * 1000;
241+ return (int)((long long)actual_dcfclk_set_mhz * 1000);
242242 }
243243
244244 int 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
255255
256256 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);
257257
258− return actual_min_ds_dcfclk_mhz * 1000;
258+ return (int)((long long)actual_min_ds_dcfclk_mhz * 1000);
259259 }
260260
261261 int 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
272272
273273 smu_print("requested_dpp_khz = %d, actual_dppclk_set_mhz: %d\n", requested_dpp_khz, actual_dppclk_set_mhz);
274274
275− return actual_dppclk_set_mhz * 1000;
275+ return (int)((long long)actual_dppclk_set_mhz * 1000);
276276 }
277277
278278 void 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
424424 0);
425425
426426 smu_print("%s: SMU DPREF clk = %d mhz\n", __func__, dprefclk);
427− return dprefclk * 1000;
427+ return (int)((long long)dprefclk * 1000);
428428 }
429429
430430 int 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
439439 0);
440440
441441 smu_print("%s: get_dtbclk = %dmhz\n", __func__, dtbclk);
442− return dtbclk * 1000;
442+ return (int)((long long)dtbclk * 1000);
443443 }
444444 /* Arg = 1: Turn DTB on; 0: Turn DTB CLK OFF. when it is on, it is 600MHZ */
445445 void 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+
106+static const struct clk_mgr_registers clk_mgr_regs_dcn42 = {
107+ CLK_REG_LIST_DCN42()
108+};
109+
110+static const struct clk_mgr_shift clk_mgr_shift_dcn42 = {
111+ CLK_COMMON_MASK_SH_LIST_DCN42(__SHIFT)
112+};
113+
114+static 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+
123+int 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+
157+void 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+
164+void 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+
208+void 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+
359+void 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+
367+bool 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+
386+static 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+
419+static 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+
503+bool 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+
517+static 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+
531+static 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+
551+void 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+
569+unsigned 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+
585+void 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+
725+static 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+
734+static 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+
771+static 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+
808+struct dcn42_ss_info_table dcn42_ss_info_table = {
809+ .ss_divider = 1000,
810+ .ss_percentage = {0, 0, 375, 375, 375}
811+};
812+
813+static 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 */
830+void 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+
886+void 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+
909+void 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+
933+void dcn42_exit_low_power_state(struct clk_mgr *clk_mgr_base)
934+{
935+
936+}
937+
938+static void dcn42_init_clocks_fpga(struct clk_mgr *clk_mgr)
939+{
940+ init_clk_states(clk_mgr);
941+
942+}
943+
944+static 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+
1006+unsigned 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+
1035+static 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+}
1050+bool 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+
1056+static 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+
1071+struct 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+
1078+void 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+
1145+void 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+
31+struct dcn42_watermarks;
32+
33+struct dcn42_smu_watermark_set {
34+ struct dcn42_watermarks *wm_set;
35+ union large_integer mc_address;
36+};
37+
38+struct dcn42_ss_info_table {
39+ uint32_t ss_divider;
40+ uint32_t ss_percentage[NUM_CLOCK_SOURCES];
41+};
42+
43+struct clk_mgr_dcn42 {
44+ struct clk_mgr_internal base;
45+ struct dcn42_smu_watermark_set smu_wm_set;
46+};
47+
48+bool dcn42_are_clock_states_equal(struct dc_clocks *a,
49+ struct dc_clocks *b);
50+void dcn42_init_clocks(struct clk_mgr *clk_mgr);
51+void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
52+ struct dc_state *context,
53+ bool safe_to_lower);
54+
55+void 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+
60+void dcn42_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int);
61+
62+/* Exposed for dcn42b reuse */
63+void dcn42_init_single_clock(unsigned int *entry_0,
64+ uint32_t *smu_entry_0,
65+ uint8_t num_levels);
66+unsigned int dcn42_convert_wck_ratio(uint8_t wck_ratio);
67+extern struct dcn42_ss_info_table dcn42_ss_info_table;
68+void dcn42_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn42_watermarks *table);
69+void dcn42_enable_pme_wa(struct clk_mgr *clk_mgr_base);
70+void dcn42_notify_wm_ranges(struct clk_mgr *clk_mgr_base);
71+void dcn42_set_low_power_state(struct clk_mgr *clk_mgr_base);
72+void dcn42_exit_low_power_state(struct clk_mgr *clk_mgr_base);
73+unsigned int dcn42_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_type clk_type);
74+bool dcn42_is_smu_present(struct clk_mgr *clk_mgr_base);
75+int dcn42_get_active_display_cnt_wa(struct dc *dc, struct dc_state *context, int *all_active_disps);
76+void dcn42_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, bool safe_to_lower);
77+void dcn42_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, int ref_dtbclk_khz);
78+bool 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+
92+union 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+ */
105+static 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+
127+static 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+
172+int 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+
181+int 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+
200+int 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+
218+int 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+
236+int 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+
254+void 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+
269+void 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+
288+void 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+
300+void 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+
309+void 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+
318+void 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+
327+void 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+
336+void 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+
390+int 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+
405+int 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 */
420+void 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+
34+typedef enum {
35+ DSPCLK_DCFCLK = 0,
36+ DSPCLK_DISPCLK,
37+ DSPCLK_PIXCLK,
38+ DSPCLK_PHYCLK,
39+ DSPCLK_COUNT,
40+} DSPCLK_e;
41+
42+typedef struct {
43+ uint16_t Freq; // in MHz
44+ uint16_t Vid; // min voltage in SVI3 VID
45+} DisplayClockTable_t;
46+
47+typedef 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+
62+typedef enum {
63+ WM_SOCCLK = 0,
64+ WM_DCFCLK,
65+ WM_COUNT,
66+} WM_CLOCK_e;
67+
68+typedef 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+
84+typedef 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+
91+typedef 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
105+typedef 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+
147+struct dcn42_watermarks {
148+ // Watermarks
149+ WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES];
150+ uint32_t MmHubPadding[7]; // SMU internal use
151+};
152+
153+struct dcn42_smu_dpm_clks {
154+ DpmClocks_t_dcn42 *dpm_clks;
155+ union large_integer mc_address;
156+};
157+
158+struct 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+
165+union display_idle_optimization_u {
166+ struct display_idle_optimization idle_info;
167+ uint32_t data;
168+};
169+
170+int dcn42_smu_get_pmfw_version(struct clk_mgr_internal *clk_mgr);
171+int dcn42_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz);
172+int dcn42_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz);
173+int dcn42_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz);
174+int dcn42_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz);
175+void dcn42_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info);
176+void dcn42_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
177+void dcn42_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr);
178+void dcn42_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high);
179+void dcn42_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low);
180+void dcn42_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr);
181+void dcn42_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr);
182+
183+void dcn42_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zstate_support_state support);
184+void dcn42_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable);
185+void dcn42_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
186+
187+int dcn42_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr);
188+int 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
442442 return false;
443443 }
444444
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− */
459−bool 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−
514445 /**
515446 * dc_stream_get_last_used_drr_vtotal - Looks up the pipe context of
516447 * 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
12741205 get_fams2_visual_confirm_color(dc, context, pipe_ctx, &(pipe_ctx->visual_confirm_color));
12751206 else if (dc->debug.visual_confirm == VISUAL_CONFIRM_VABC)
12761207 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));
12771210 }
12781211 }
12791212 }
@@ -1323,6 +1256,83 @@ void dc_get_visual_confirm_for_stream( · 43 unmodified lines
13231256 }
13241257 }
13251258
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+ */
1273+bool 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+
13261336 static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
13271337 {
13281338 int i, j;
@@ -3064,7 +3074,7 @@ struct surface_update_descriptor dc_check_update_surfaces_for_stream( · 1735 unmodified lines
30643074 {
30653075 if (stream_update)
30663076 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++)
30683078 updates[i].surface->update_flags.raw = 0;
30693079
30703080 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
55405550 {
55415551 if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW &&
55425552 dc->hwss.power_down_on_boot) {
5553+ if (dc->current_state->stream_count > 0)
5554+ return;
5555+
55435556 if (dc->caps.ips_support)
55445557 dc_exit_ips_for_hw_access(dc);
55455558 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
55515564 if (!dc->current_state)
55525565 return;
55535566
5567+ dc_exit_ips_for_hw_access(dc);
5568+
55545569 switch (power_state) {
55555570 case DC_ACPI_CM_POWER_STATE_D0:
55565571 dc_state_construct(dc, dc->current_state);
55575572
5558− dc_exit_ips_for_hw_access(dc);
5559−
55605573 dc_z10_restore(dc);
55615574
55625575 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 @@
11 /*
2− * Copyright 2015 Advanced Micro Devices, Inc.
2+ * Copyright 2015-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * 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
846846 block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;
847847 (*num_steps)++;
848848 }
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+ }
849859 }
850860 if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) {
851861 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
10291039 case HUBP_PROGRAM_MCACHE_ID:
10301040 hwss_program_mcache_id_and_split_coordinate(params);
10311041 break;
1042+ case DPP_PROGRAM_CM_HIST:
1043+ hwss_program_cm_hist(params);
1044+ break;
10321045 case PROGRAM_CURSOR_UPDATE_NOW:
10331046 dc->hwss.program_cursor_offload_now(
10341047 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
20542067
20552068 }
20562069
2070+void 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+
20572080 void get_surface_tile_visual_confirm_color(
20582081 struct pipe_ctx *pipe_ctx,
20592082 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
33703393 }
33713394 }
33723395
3396+void 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+
33733410 void hwss_add_dc_ip_request_cntl(struct block_sequence_state *seq_state,
33743411 struct dc *dc,
33753412 bool enable)
@@ -4071,3 +4108,24 @@ void hwss_add_tg_get_frame_count(struct block_sequence_state *seq_state, · 695 unmodified lines
40714108 (*seq_state->num_steps)++;
40724109 }
40734110 }
4111+
4112+
4113+void 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
7878 #include "dcn351/dcn351_resource.h"
7979 #include "dcn36/dcn36_resource.h"
8080 #include "dcn401/dcn401_resource.h"
81+#include "dcn42/dcn42_resource.h"
8182 #if defined(CONFIG_DRM_AMD_DC_FP)
8283 #include "dc_spl_translate.h"
8384 #endif
@@ -252,6 +253,9 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) · 168 unmodified lines
252253 ASICREV_IS_GC_12_0_0_A0(asic_id.hw_internal_rev))
253254 dc_version = DCN_VERSION_4_01;
254255 break;
256+ case AMDGPU_FAMILY_GC_11_5_4:
257+ dc_version = DCN_VERSION_4_2;
258+ break;
255259 default:
256260 dc_version = DCE_VERSION_UNKNOWN;
257261 break;
@@ -368,6 +372,9 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, · 110 unmodified lines
368372 case DCN_VERSION_4_01:
369373 res_pool = dcn401_create_resource_pool(init_data, dc);
370374 break;
375+ case DCN_VERSION_4_2:
376+ res_pool = dcn42_create_resource_pool(init_data, dc);
377+ break;
371378 #endif /* CONFIG_DRM_AMD_DC_FP */
372379 default:
373380 break;
drivers/gpu/drm/amd/display/dc/dc.h+15−2
@@ -1,5 +1,5 @@
11 /*
2− * Copyright 2012-2023 Advanced Micro Devices, Inc.
2+ * Copyright 2012-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -63,7 +63,7 @@ struct dcn_dsc_reg_state; · 57 unmodified lines
6363 struct dcn_optc_reg_state;
6464 struct dcn_dccg_reg_state;
6565
66−#define DC_VER "3.2.369"
66+#define DC_VER "3.2.372"
6767
6868 /**
6969 * 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
581581 VISUAL_CONFIRM_HW_CURSOR = 20,
582582 VISUAL_CONFIRM_VABC = 21,
583583 VISUAL_CONFIRM_DCC = 22,
584+ VISUAL_CONFIRM_BOOSTED_REFRESH_RATE = 23,
584585 VISUAL_CONFIRM_EXPLICIT = 0x80000000,
585586 };
586587
@@ -733,6 +734,8 @@ struct dc_clocks { · 146 unmodified lines
733734 struct {
734735 uint8_t base_efficiency; //LP1
735736 uint8_t low_power_efficiency; //LP2
737+ uint8_t z8_stutter_efficiency;
738+ int z8_stutter_period;
736739 } stutter_efficiency;
737740 };
738741
@@ -1211,6 +1214,7 @@ struct dc_debug_options { · 472 unmodified lines
12111214 unsigned int num_fast_flips_to_steady_state_override;
12121215 bool enable_dmu_recovery;
12131216 unsigned int force_vmin_threshold;
1217+ bool enable_otg_frame_sync_pwa;
12141218 };
12151219
12161220
@@ -1419,6 +1423,7 @@ struct dc_plane_status { · 202 unmodified lines
14191423 struct dc_plane_address current_address;
14201424 bool is_flip_pending;
14211425 bool is_right_eye;
1426+ struct cm_hist cm_hist;
14221427 };
14231428
14241429 union surface_update_flags {
@@ -1455,6 +1460,7 @@ union surface_update_flags { · 30 unmodified lines
14551460 uint32_t mcm_transfer_function_enable_change:1; /* disable or enable MCM transfer func */
14561461 uint32_t full_update:1;
14571462 uint32_t sdr_white_level_nits:1;
1463+ uint32_t cm_hist_change:1;
14581464 } bits;
14591465
14601466 uint32_t raw;
@@ -1539,6 +1545,7 @@ struct dc_plane_state { · 78 unmodified lines
15391545 int sharpness_level;
15401546 enum linear_light_scaling linear_light_scaling;
15411547 unsigned int sdr_white_level_nits;
1548+ struct cm_hist_control cm_hist_control;
15421549 struct spl_sharpness_range sharpness_range;
15431550 enum sharpness_range_source sharpness_source;
15441551 };
@@ -1682,6 +1689,10 @@ struct dc_scratch_space { · 137 unmodified lines
16821689 struct panel_cntl *panel_cntl;
16831690 struct link_encoder *link_enc;
16841691 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+
16851696 /* Endpoint type distinguishes display endpoints which do not have entries
16861697 * in the BIOS connector table from those that do. Helps when tracking link
16871698 * encoder to display endpoint assignments.
@@ -1843,6 +1854,7 @@ struct dc_fast_update { · 155 unmodified lines
18431854 struct dc_transfer_func *out_transfer_func;
18441855 struct dc_csc_transform *output_csc_transform;
18451856 const struct dc_csc_transform *cursor_csc_color_matrix;
1857+ struct cm_hist_control *cm_hist_control;
18461858 };
18471859
18481860 struct dc_surface_update {
@@ -1875,6 +1887,7 @@ struct dc_surface_update { · 26 unmodified lines
18751887 const struct dc_csc_transform *cursor_csc_color_matrix;
18761888 unsigned int sdr_white_level_nits;
18771889 struct dc_bias_and_scale bias_and_scale;
1890+ struct cm_hist_control *cm_hist_control;
18781891 };
18791892
18801893 struct 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
9797 enum bp_result (*encoder_control)(
9898 struct dc_bios *bios,
9999 struct bp_encoder_control *cntl);
100+ enum bp_result (*external_encoder_control)(
101+ struct dc_bios *bios,
102+ struct bp_external_encoder_control *cntl);
100103 enum bp_result (*dac_load_detection)(
101104 struct dc_bios *bios,
102105 enum engine_id engine_id,
103− enum dal_device_type device_type,
104− uint32_t enum_id);
106+ struct graphics_object_id ext_enc_id);
105107 enum bp_result (*transmitter_control)(
106108 struct dc_bios *bios,
107109 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
947947 /* DPCD[0xE000E] DP_IN_ADAPTER_INFO register. */
948948 union dpia_info {
949949 struct {
950− uint8_t dpia_num :5;
951− uint8_t rsvd :3;
950+ uint8_t dpia_num :6;
951+ uint8_t rsvd :2;
952952 } bits;
953953 uint8_t raw;
954954 };
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
751751 return "DCN 3.6";
752752 case DCN_VERSION_4_01:
753753 return "DCN 4.0.1";
754+ case DCN_VERSION_4_2:
755+ return "DCN 4.2";
754756 default:
755757 return "Unknown";
756758 }
drivers/gpu/drm/amd/display/dc/dc_hw_types.h+73−0
@@ -271,6 +271,15 @@ enum tile_split_values_new { · 270 unmodified lines
271271 DC_SURF_TILE_SPLIT_1KB = 0x4,
272272 };
273273
274+enum otg_pwa_sync_mode {
275+ DC_OTG_PWA_FRAME_SYNC_MODE_VSYNC = 0x0,
276+ DC_OTG_PWA_FRAME_SYNC_MODE_VSTARTUP = 0x1,
277+};
278+struct otc_pwa_frame_sync {
279+ enum otg_pwa_sync_mode pwa_sync_mode;
280+ uint32_t pwa_frame_sync_line_offset;
281+};
282+
274283 /* TODO: These values come from hardware spec. We need to readdress this
275284 * if they ever change.
276285 */
@@ -1137,6 +1146,7 @@ struct mcif_buf_params { · 860 unmodified lines
11371146 unsigned int warmup_pitch;
11381147 unsigned int swlock;
11391148 unsigned int p_vmid;
1149+ uint8_t tmz_id;
11401150 };
11411151
11421152
@@ -1162,5 +1172,68 @@ struct phy_state { · 19 unmodified lines
11621172 enum symclk_state symclk_state;
11631173 };
11641174
1175+enum 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+
1182+enum cm_hist_src {
1183+ CM_HIST_SRC1,
1184+ CM_HIST_SRC2,
1185+ CM_HIST_SRC3,
1186+};
1187+
1188+enum 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+
1194+enum 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+
1205+enum cm_hist_src1_mode {
1206+ CM_HIST_SRC1_MODE_R_OR_CR,
1207+ CM_HIST_SRC1_MODE_MAX_RGB,
1208+};
1209+
1210+enum cm_hist_src2_mode {
1211+ CM_HIST_SRC2_MODE_G_OR_Y,
1212+ CM_HIST_SRC2_MODE_RGB_TO_Y,
1213+};
1214+
1215+enum cm_hist_src3_mode {
1216+ CM_HIST_SRC3_MODE_B_OR_CB,
1217+ CM_HIST_SRC3_MODE_MIN_RGB,
1218+};
1219+
1220+struct 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+
1233+struct cm_hist {
1234+ uint32_t ch1[256];
1235+ uint32_t ch2[256];
1236+ uint32_t ch3[256];
1237+};
11651238 #endif /* DC_HW_TYPES_H */
11661239
drivers/gpu/drm/amd/display/dc/dc_types.h+5−1
@@ -1,5 +1,5 @@
11 /*
2− * Copyright 2012-15 Advanced Micro Devices, Inc.
2+ * Copyright 2012-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -1346,6 +1346,7 @@ enum dc_cm2_gpu_mem_layout { · 1340 unmodified lines
13461346
13471347 enum dc_cm2_gpu_mem_pixel_component_order {
13481348 DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA,
1349+ DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_BGRA
13491350 };
13501351
13511352 enum dc_cm2_gpu_mem_format {
@@ -1367,6 +1368,9 @@ struct dc_cm2_gpu_mem_format_parameters { · 15 unmodified lines
13671368
13681369 enum dc_cm2_gpu_mem_size {
13691370 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,
13701374 DC_CM2_GPU_MEM_SIZE_TRANSFORMED,
13711375 };
13721376
drivers/gpu/drm/amd/display/dc/dccg/Makefile+10−1
@@ -1,5 +1,5 @@
11
2−# Copyright 2022 Advanced Micro Devices, Inc.
2+# Copyright 2022-2026 Advanced Micro Devices, Inc.
33 #
44 # Permission is hereby granted, free of charge, to any person obtaining a
55 # copy of this software and associated documentation files (the "Software"),
@@ -100,4 +100,13 @@ DCCG_DCN401 = dcn401_dccg.o · 94 unmodified lines
100100 AMD_DAL_DCCG_DCN401 = $(addprefix $(AMDDALPATH)/dc/dccg/dcn401/,$(DCCG_DCN401))
101101
102102 AMD_DISPLAY_FILES += $(AMD_DAL_DCCG_DCN401)
103+
104+###############################################################################
105+# DCN42
106+###############################################################################
107+DCCG_DCN42 = dcn42_dccg.o
108+
109+AMD_DAL_DCCG_DCN42 = $(addprefix $(AMDDALPATH)/dc/dccg/dcn42/,$(DCCG_DCN42))
110+
111+AMD_DISPLAY_FILES += $(AMD_DAL_DCCG_DCN42)
103112 endif
drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h+14−1
@@ -1,5 +1,5 @@
11 /*
2− * Copyright 2018 Advanced Micro Devices, Inc.
2+ * Copyright 2018-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -362,6 +362,16 @@ · 356 unmodified lines
362362 type SYMCLK32_LE3_EN;\
363363 type DP_DTO_ENABLE[MAX_PIPES];
364364
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+
365375 struct dccg_shift {
366376 DCCG_REG_FIELD_LIST(uint8_t)
367377 DCCG3_REG_FIELD_LIST(uint8_t)
@@ -370,6 +380,7 @@ struct dccg_shift { · 2 unmodified lines
370380 DCCG32_REG_FIELD_LIST(uint8_t)
371381 DCCG35_REG_FIELD_LIST(uint8_t)
372382 DCCG401_REG_FIELD_LIST(uint8_t)
383+ DCCG42_REG_FIELD_LIST(uint8_t)
373384 };
374385
375386 struct dccg_mask {
@@ -380,6 +391,7 @@ struct dccg_mask { · 4 unmodified lines
380391 DCCG32_REG_FIELD_LIST(uint32_t)
381392 DCCG35_REG_FIELD_LIST(uint32_t)
382393 DCCG401_REG_FIELD_LIST(uint32_t)
394+ DCCG42_REG_FIELD_LIST(uint32_t)
383395 };
384396
385397 #define DCCG_REG_VARIABLE_LIST \
@@ -493,6 +505,7 @@ struct dccg_mask { · 107 unmodified lines
493505
494506 struct dccg_registers {
495507 DCCG_REG_VARIABLE_LIST;
508+ uint32_t OTG_ADD_DROP_PIXEL_CNTL;
496509 };
497510
498511 struct 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+
25+void 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+
52+void 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+
79+void 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+
88+void 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+
183+static 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+
219+static 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+
255+struct 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+
244+void dccg42_otg_add_pixel(struct dccg *dccg,
245+ uint32_t otg_inst);
246+
247+void dccg42_otg_drop_pixel(struct dccg *dccg,
248+ uint32_t otg_inst);
249+void dccg42_enable_global_fgcg(struct dccg *dccg, bool value);
250+
251+void dccg42_set_physymclk(
252+ struct dccg *dccg,
253+ int phy_inst,
254+ enum physymclk_clock_source clk_src,
255+ bool force_enable);
256+
257+struct 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 @@
11 /*
2− * Copyright 2012-16 Advanced Micro Devices, Inc.
2+ * Copyright 2012-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -300,6 +300,64 @@ · 294 unmodified lines
300300 ABM_SF(ABM0_DC_ABM1_HG_BIN_57_64_SHIFT_INDEX, \
301301 ABM1_HG_BIN_57_64_SHIFT_INDEX, mask_sh)
302302
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+
303361 #define ABM_REG_FIELD_LIST(type) \
304362 type ABM1_HG_NUM_OF_BINS_SEL; \
305363 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
11501150 }
11511151 }
11521152
1153−#if defined(CONFIG_DRM_AMD_DC_SI)
1154−static 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−
12451153 static bool dce_aud_endpoint_valid(struct audio *audio)
12461154 {
12471155 uint32_t value;
@@ -1303,18 +1211,6 @@ static const struct audio_funcs funcs = { · 55 unmodified lines
13031211 .destroy = dce_aud_destroy,
13041212 };
13051213
1306−#if defined(CONFIG_DRM_AMD_DC_SI)
1307−static 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−
13181214 void dce_aud_destroy(struct audio **audio)
13191215 {
13201216 struct dce_audio *aud = DCE_AUD(*audio);
@@ -1347,30 +1243,3 @@ struct audio *dce_audio_create( · 26 unmodified lines
13471243 audio->masks = masks;
13481244 return &audio->base;
13491245 }
1350−
1351−#if defined(CONFIG_DRM_AMD_DC_SI)
1352−struct 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
151151 const struct dce_audio_shift *shifts,
152152 const struct dce_audio_mask *masks);
153153
154−#if defined(CONFIG_DRM_AMD_DC_SI)
155−struct 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−
163154 void dce_aud_destroy(struct audio **audio);
164155
165156 void 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": */
51−static 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−
63−static 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−
75−static 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−
87−static 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−
99−int 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− */
133−static 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−
148−static 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−
174−int 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− */
184−static 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−
213−static 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−
246−static 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−
288−int 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−
343−static 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−
401−void 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− */
468−void 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−
495−void 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−
548−static 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−
572−static 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−
598−static 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−
612−static 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−
672−static 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−
699−static 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−
726−static 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−
753−static 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−
791−static 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−
796−static 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−
801−static 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−
806−static 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−
811−static 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−
845−struct 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−
868−struct 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−
893−struct 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−
918−struct 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−
940−struct 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−
960−void 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 @@
11 #
2−# Copyright 2020 Advanced Micro Devices, Inc.
2+# Copyright 2020-2026 Advanced Micro Devices, Inc.
33 #
44 # Permission is hereby granted, free of charge, to any person obtaining a
55 # 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
123123 AMD_DAL_DIO_DCN401 = $(addprefix $(AMDDALPATH)/dc/dio/dcn401/,$(DIO_DCN401))
124124
125125 AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN401)
126+
127+###############################################################################
128+# DCN42
129+###############################################################################
130+DIO_DCN42 = dcn42_dio_link_encoder.o dcn42_dio_stream_encoder.o
131+
132+AMD_DAL_DIO_DCN42 = $(addprefix $(AMDDALPATH)/dc/dio/dcn42/,$(DIO_DCN42))
133+
134+AMD_DISPLAY_FILES += $(AMD_DAL_DIO_DCN42)
126135 endif
drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_stream_encoder.h+9−1
@@ -1,5 +1,5 @@
11 /*
2− * Copyright 2012-15 Advanced Micro Devices, Inc.
2+ * Copyright 2012-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -190,6 +190,7 @@ struct dcn10_stream_enc_registers { · 184 unmodified lines
190190 uint32_t DIG_FE_CLK_CNTL;
191191 uint32_t DIG_FE_EN_CNTL;
192192 uint32_t STREAM_MAPPER_CONTROL;
193+ uint32_t DIG_FE_AUDIO_CNTL;
193194 };
194195
195196
@@ -598,6 +599,11 @@ struct dcn10_stream_enc_registers { · 402 unmodified lines
598599 type DP_VID_N_INTERVAL;\
599600 type DIG_FIFO_OUTPUT_PIXEL_PER_CYCLE;\
600601 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+
601607 struct dcn10_stream_encoder_shift {
602608 SE_REG_FIELD_LIST_DCN1_0(uint8_t);
603609 uint8_t HDMI_ACP_SEND;
@@ -606,6 +612,7 @@ struct dcn10_stream_encoder_shift { · 2 unmodified lines
606612 SE_REG_FIELD_LIST_DCN3_1_COMMON(uint8_t);
607613 SE_REG_FIELD_LIST_DCN3_5_COMMON(uint8_t);
608614 SE_REG_FIELD_LIST_DCN4_01_COMMON(uint32_t);
615+ SE_REG_FIELD_LIST_DCN_AUDIO_COMMON(uint32_t);
609616 };
610617
611618 struct dcn10_stream_encoder_mask {
@@ -616,6 +623,7 @@ struct dcn10_stream_encoder_mask { · 4 unmodified lines
616623 SE_REG_FIELD_LIST_DCN3_1_COMMON(uint32_t);
617624 SE_REG_FIELD_LIST_DCN3_5_COMMON(uint32_t);
618625 SE_REG_FIELD_LIST_DCN4_01_COMMON(uint32_t);
626+ SE_REG_FIELD_LIST_DCN_AUDIO_COMMON(uint32_t);
619627 };
620628
621629 struct 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+
46+bool 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+
56+bool 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+
67+static 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+
103+void 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+
127+void 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+
137+bool dcn42_get_hpd_state(struct link_encoder *enc);
138+bool 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 */
35+static 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+
157+static 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+
184+static 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+
203+static 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+
260+static 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+
277+static 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+
293+static 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+
307+static 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+
329+static 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+
338+static 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+
390+static 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+
398+void 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+
408+static 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+
430+static 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+}
439+void 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+
450+static 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+
501+void 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+
189+void 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+
200+void enc42_se_enable_audio_clock(
201+ struct stream_encoder *enc,
202+ bool enable);
203+
204+void 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
734734 memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping));
735735
736736 dml_dispcfg->gpuvm_enable = dml_ctx->config.gpuvm_enable;
737− dml_dispcfg->gpuvm_max_page_table_levels = 4;
738− dml_dispcfg->hostvm_enable = false;
737+ if (dml_ctx->v21.dml_init.soc_bb.gpuvm_max_page_table_levels)
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;
739743 dml_dispcfg->minimize_det_reallocation = true;
740744 dml_dispcfg->overrides.enable_subvp_implicit_pmo = true;
741745
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
374374 dml2_map_dc_pipes(dml_ctx, context, NULL, &dml_ctx->v21.dml_to_dc_pipe_mapping, dc->current_state);
375375 }
376376
377−void dml21_build_fams2_programming(const struct dc *dc,
377+static unsigned int dml21_build_fams2_stream_programming_v2(const struct dc *dc,
378378 struct dc_state *context,
379379 struct dml2_context *dml_ctx)
380380 {
381− int i, j, k;
381+ int dc_stream_idx, dc_plane_idx, dc_pipe_idx;
382382 unsigned int num_fams2_streams = 0;
383383
384− /* reset fams2 data */
385− memset(&context->bw_ctx.bw.dcn.fams2_stream_base_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);
386− memset(&context->bw_ctx.bw.dcn.fams2_stream_sub_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);
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);
388− memset(&context->bw_ctx.bw.dcn.fams2_global_config, 0, sizeof(struct dmub_cmd_fams2_global_config));
384+ for (dc_stream_idx = 0; dc_stream_idx < context->stream_count; dc_stream_idx++) {
385+ int dml_stream_idx;
386+ struct dc_stream_state *phantom_stream;
387+ struct dc_stream_status *phantom_status;
388+ enum fams2_stream_type type = 0;
389389
390− if ((dml_ctx->v21.mode_programming.programming->fams2_required) ||
391− (dml_ctx->v21.mode_programming.programming->legacy_pstate_info_for_dmu)) {
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;
390+ union dmub_cmd_fams2_config *static_base_state = &context->bw_ctx.bw.dcn.fams2_stream_base_params[num_fams2_streams];
391+ union dmub_cmd_fams2_config *static_sub_state = &context->bw_ctx.bw.dcn.fams2_stream_sub_params[num_fams2_streams];
397392
398− union dmub_cmd_fams2_config *static_base_state = &context->bw_ctx.bw.dcn.fams2_stream_base_params[num_fams2_streams];
399− union dmub_cmd_fams2_config *static_sub_state = &context->bw_ctx.bw.dcn.fams2_stream_sub_params[num_fams2_streams];
393+ struct dc_stream_state *stream = context->streams[dc_stream_idx];
400394
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+ }
402400
403− if (context->stream_status[i].plane_count == 0 ||
404− dml_ctx->config.svp_pstate.callbacks.get_stream_subvp_type(context, stream) == SUBVP_PHANTOM) {
405− /* can ignore blanked or phantom streams */
406− continue;
407− }
401+ dml_stream_idx = dml21_helper_find_dml_pipe_idx_by_stream_id(dml_ctx, stream->stream_id);
402+ if (dml_stream_idx < 0) {
403+ ASSERT(dml_stream_idx >= 0);
404+ continue;
405+ }
408406
409− dml_stream_idx = dml21_helper_find_dml_pipe_idx_by_stream_id(dml_ctx, stream->stream_id);
410− if (dml_stream_idx < 0) {
411− ASSERT(dml_stream_idx >= 0);
412− continue;
407+ /* copy static state from PMO */
408+ memcpy(static_base_state,
409+ &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_base_params,
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+ }
413435 }
436+ }
414437
415− /* copy static state from PMO */
416− memcpy(static_base_state,
417− &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_base_params,
418− sizeof(union dmub_cmd_fams2_config));
419−
420− if (dc->debug.fams_version.major == 3) {
421− memcpy(&context->bw_ctx.bw.dcn.fams2_stream_sub_params_v2[num_fams2_streams],
422− &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_sub_params_v2,
423− sizeof(union dmub_fams2_stream_static_sub_state_v2));
424− } else {
425− memcpy(static_sub_state,
426− &dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_sub_params,
427− sizeof(union dmub_cmd_fams2_config));
428− }
438+
439+ /* get per method programming */
440+ switch (type) {
441+ case FAMS2_STREAM_TYPE_VBLANK:
442+ case FAMS2_STREAM_TYPE_VACTIVE:
443+ case FAMS2_STREAM_TYPE_DRR:
444+ break;
445+ case FAMS2_STREAM_TYPE_SUBVP:
446+ phantom_stream = dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);
447+ if (!phantom_stream)
448+ break;
449+
450+ phantom_status = dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);
451+
452+ /* phantom status should always be present */
453+ ASSERT(phantom_status);
454+ if (!phantom_status)
455+ break;
429456
430457 switch (dc->debug.fams_version.minor) {
431458 case 1:
432459 default:
433− type = static_base_state->stream_v1.base.type;
434−
435− /* get information from context */
436− static_base_state->stream_v1.base.num_planes = context->stream_status[i].plane_count;
437− static_base_state->stream_v1.base.otg_inst = context->stream_status[i].primary_otg_inst;
438−
439− /* populate pipe masks for planes */
440− for (j = 0; j < context->stream_status[i].plane_count; j++) {
441− for (k = 0; k < dc->res_pool->pipe_count; k++) {
442− if (context->res_ctx.pipe_ctx[k].stream &&
443− context->res_ctx.pipe_ctx[k].stream->stream_id == stream->stream_id &&
444− context->res_ctx.pipe_ctx[k].plane_state == context->stream_status[i].plane_states[j]) {
445− static_base_state->stream_v1.base.pipe_mask |= (1 << k);
446− static_base_state->stream_v1.base.plane_pipe_masks[j] |= (1 << k);
460+ static_sub_state->stream_v1.sub_state.subvp.phantom_otg_inst = phantom_status->primary_otg_inst;
461+
462+ /* populate pipe masks for phantom planes */
463+ for (dc_plane_idx = 0; dc_plane_idx < phantom_status->plane_count; dc_plane_idx++) {
464+ for (dc_pipe_idx = 0; dc_pipe_idx < dc->res_pool->pipe_count; dc_pipe_idx++) {
465+ if (context->res_ctx.pipe_ctx[dc_pipe_idx].stream &&
466+ context->res_ctx.pipe_ctx[dc_pipe_idx].stream->stream_id == phantom_stream->stream_id &&
467+ context->res_ctx.pipe_ctx[dc_pipe_idx].plane_state == phantom_status->plane_states[dc_plane_idx]) {
468+ switch (dc->debug.fams_version.minor) {
469+ case 1:
470+ default:
471+ static_sub_state->stream_v1.sub_state.subvp.phantom_pipe_mask |= (1 << dc_pipe_idx);
472+ static_sub_state->stream_v1.sub_state.subvp.phantom_plane_pipe_masks[dc_plane_idx] |= (1 << dc_pipe_idx);
473+ }
447474 }
448475 }
449476 }
450477 }
478+ break;
479+ default:
480+ ASSERT(false);
481+ break;
482+ }
451483
484+ num_fams2_streams++;
485+ }
452486
453− /* get per method programming */
454− switch (type) {
455− case FAMS2_STREAM_TYPE_VBLANK:
456− case FAMS2_STREAM_TYPE_VACTIVE:
457− case FAMS2_STREAM_TYPE_DRR:
458− break;
459− case FAMS2_STREAM_TYPE_SUBVP:
460− phantom_stream = dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);
461− if (!phantom_stream)
462− break;
463−
464− phantom_status = dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);
465−
466− /* phantom status should always be present */
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− }
487+ return num_fams2_streams;
488+}
489+
490+void dml21_build_fams2_programming(const struct dc *dc,
491+ struct dc_state *context,
492+ struct dml2_context *dml_ctx)
493+{
494+ unsigned int num_fams2_streams = 0;
495+
496+ /* reset fams2 data */
497+ memset(&context->bw_ctx.bw.dcn.fams2_stream_base_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);
498+ memset(&context->bw_ctx.bw.dcn.fams2_stream_sub_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);
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);
500+ memset(&context->bw_ctx.bw.dcn.fams2_global_config, 0, sizeof(struct dmub_cmd_fams2_global_config));
497501
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);
499506 }
500507 }
501508
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.h+1−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 struct dc_state;
1010 struct dc_plane_state;
1111 struct pipe_ctx;
12+struct dc_dmub_srv;
1213
1314 struct dml2_context;
1415 struct 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
160160 unsigned long return_bus_width_bytes;
161161 unsigned long hostvm_min_page_size_kbytes;
162162 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;
163165 double phy_downspread_percent;
164166 double dcn_downspread_percent;
165167 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
909909 const struct dc_plane_state *plane)
910910 {
911911 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);
914912
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+
916916 return ctx->config.callbacks.get_mpc_slice_count(dpp_pipes[0]);
917917 }
918918
drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.h+1−0
@@ -239,6 +239,7 @@ struct dml2_configuration_options { · 238 unmodified lines
239239
240240 bool use_clock_dc_limits;
241241 bool gpuvm_enable;
242+ bool hostvm_enable;
242243 bool force_tdlut_enable;
243244 void *bb_from_dmub;
244245 };
drivers/gpu/drm/amd/display/dc/dpp/Makefile+9−1
@@ -1,5 +1,5 @@
11
2−# Copyright 2022 Advanced Micro Devices, Inc.
2+# Copyright 2022-2026 Advanced Micro Devices, Inc.
33 #
44 # Permission is hereby granted, free of charge, to any person obtaining a
55 # 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
8080
8181 AMD_DISPLAY_FILES += $(AMD_DAL_DPP_DCN401)
8282
83+###############################################################################
84+# DCN42
85+###############################################################################
86+DPP_DCN42 = dcn42_dpp.o
87+
88+AMD_DAL_DPP_DCN42 = $(addprefix $(AMDDALPATH)/dc/dpp/dcn42/,$(DPP_DCN42))
89+
90+AMD_DISPLAY_FILES += $(AMD_DAL_DPP_DCN42)
8391 endif
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.
23 *
34 * Permission is hereby granted, free of charge, to any person obtaining a
45 * copy of this software and associated documentation files (the "Software"),
@@ -653,6 +654,8 @@ · 648 unmodified lines
653654
654655 struct dcn401_dpp_registers {
655656 DPP_REG_VARIABLE_LIST_DCN401;
657+ uint32_t ALPHA_2BIT_LUT01;
658+ uint32_t ALPHA_2BIT_LUT23;
656659 };
657660
658661 struct 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+
21+static 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+
38+static 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+
71+static 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+
118+static 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+
284+static 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+
308+static 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+
314+bool 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+
433+struct dcn42_dpp_registers {
434+ DPP_REG_VARIABLE_LIST_DCN42;
435+};
436+
437+struct dcn42_dpp_shift {
438+ DPP_REG_FIELD_LIST_DCN42(uint8_t);
439+};
440+
441+struct dcn42_dpp_mask {
442+ DPP_REG_FIELD_LIST_DCN42(uint32_t);
443+};
444+struct 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+
461+bool 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 @@
11 #
2−# Copyright 2017 Advanced Micro Devices, Inc.
2+# Copyright 2017-2026 Advanced Micro Devices, Inc.
33 #
44 # Permission is hereby granted, free of charge, to any person obtaining a
55 # 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
132132
133133 AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN401)
134134
135+###############################################################################
136+# DCN 4.2
137+###############################################################################
138+
139+GPIO_DCN42 = hw_translate_dcn42.o hw_factory_dcn42.o
140+
141+AMD_DAL_GPIO_DCN42 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn42/,$(GPIO_DCN42))
142+
143+AMD_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+
69+static 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+
77+static const struct hpd_sh_mask hpd_shift = {
78+ HPD_MASK_SH_LIST(__SHIFT)
79+};
80+
81+static 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+
91+static 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+
112+static 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+
133+static 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+
143+static 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+
159+static const struct generic_registers generic_regs[] = {
160+ {{ 0 }},
161+ {{ 0 }},
162+};
163+
164+static const struct generic_sh_mask generic_shift[] = {
165+ { 0 },
166+ { 0 },
167+};
168+
169+static const struct generic_sh_mask generic_mask[] = {
170+ { 0 },
171+ { 0 },
172+};
173+
174+static 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+
184+static 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+
209+static 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 */
221+static 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+ */
242+void 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 */
29+void 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+
42+static 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+
100+static 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 */
184+static 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+ */
200+void 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+
28+struct hw_translate;
29+
30+/* Initialize Hw translate function pointers */
31+void dal_hw_translate_dcn42_init(struct hw_translate *tr);
32+#ifdef DAL_EMULATION_SUPPORTED
33+void 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
5353 #include "dcn315/hw_factory_dcn315.h"
5454 #include "dcn32/hw_factory_dcn32.h"
5555 #include "dcn401/hw_factory_dcn401.h"
56+#include "dcn42/hw_factory_dcn42.h"
5657
5758 bool dal_hw_factory_init(
5859 struct hw_factory *factory,
@@ -118,6 +119,9 @@ bool dal_hw_factory_init( · 59 unmodified lines
118119 case DCN_VERSION_4_01:
119120 dal_hw_factory_dcn401_init(factory);
120121 return true;
122+ case DCN_VERSION_4_2:
123+ dal_hw_factory_dcn42_init(factory);
124+ return true;
121125 default:
122126 ASSERT_CRITICAL(false);
123127 return false;
drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c+4−0
@@ -53,6 +53,7 @@ · 52 unmodified lines
5353 #include "dcn315/hw_translate_dcn315.h"
5454 #include "dcn32/hw_translate_dcn32.h"
5555 #include "dcn401/hw_translate_dcn401.h"
56+#include "dcn42/hw_translate_dcn42.h"
5657
5758 /*
5859 * This unit
@@ -119,6 +120,9 @@ bool dal_hw_translate_init( · 60 unmodified lines
119120 case DCN_VERSION_4_01:
120121 dal_hw_translate_dcn401_init(translate);
121122 return true;
123+ case DCN_VERSION_4_2:
124+ dal_hw_translate_dcn42_init(translate);
125+ return true;
122126 default:
123127 BREAK_TO_DEBUGGER();
124128 return false;
drivers/gpu/drm/amd/display/dc/hpo/Makefile+10−1
@@ -1,5 +1,5 @@
11 #
2−# Copyright 2020 Advanced Micro Devices, Inc.
2+# Copyright 2020-2026 Advanced Micro Devices, Inc.
33 #
44 # Permission is hereby granted, free of charge, to any person obtaining a
55 # 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
4747 AMD_DAL_HPO_DCN32 = $(addprefix $(AMDDALPATH)/dc/hpo/dcn32/,$(HPO_DCN32))
4848
4949 AMD_DISPLAY_FILES += $(AMD_DAL_HPO_DCN32)
50+
51+###############################################################################
52+# DCN42
53+###############################################################################
54+HPO_DCN42 = dcn42_hpo_dp_link_encoder.o
55+
56+AMD_DAL_HPO_DCN42 = $(addprefix $(AMDDALPATH)/dc/hpo/dcn42/,$(HPO_DCN42))
57+
58+AMD_DISPLAY_FILES += $(AMD_DAL_HPO_DCN42)
5059 endif
drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.h+8−2
@@ -1,5 +1,5 @@
11 /*
2− * Copyright 2019 Advanced Micro Devices, Inc.
2+ * Copyright 2019-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -208,17 +208,24 @@ · 202 unmodified lines
208208 type CRC_CONT_MODE_ENABLE;\
209209 type HBLANK_MINIMUM_SYMBOL_WIDTH
210210
211+#define DCN4_2_HPO_DP_STREAM_ENC_REG_FIELD_LIST(type) \
212+ type DP_STREAM_ENC_APG_CLOCK_EN
211213
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)
212217 struct dcn31_hpo_dp_stream_encoder_registers {
213218 DCN3_1_HPO_DP_STREAM_ENC_REGS;
214219 };
215220
216221 struct dcn31_hpo_dp_stream_encoder_shift {
217222 DCN3_1_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint8_t);
223+ DCN4_2_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint8_t);
218224 };
219225
220226 struct dcn31_hpo_dp_stream_encoder_mask {
221227 DCN3_1_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint32_t);
228+ DCN4_2_HPO_DP_STREAM_ENC_REG_FIELD_LIST(uint32_t);
222229 };
223230
224231 struct dcn31_hpo_dp_stream_encoder {
@@ -241,5 +248,4 @@ void dcn31_hpo_dp_stream_encoder_construct( · 16 unmodified lines
241248 const struct dcn31_hpo_dp_stream_encoder_shift *hpo_se_shift,
242249 const struct dcn31_hpo_dp_stream_encoder_mask *hpo_se_mask);
243250
244−
245251 #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+
27+static 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+
63+static 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+
76+void 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+
10+void 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 @@
11
2−# Copyright 2022 Advanced Micro Devices, Inc.
2+# Copyright 2022-2026 Advanced Micro Devices, Inc.
33 #
44 # Permission is hereby granted, free of charge, to any person obtaining a
55 # 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
101101 AMD_DISPLAY_FILES += $(AMD_DAL_HUBBUB_DCN401)
102102
103103 ###############################################################################
104+# DCN42
105+###############################################################################
106+HUBBUB_DCN42 = dcn42_hubbub.o
107+
108+AMD_DAL_HUBBUB_DCN42 = $(addprefix $(AMDDALPATH)/dc/hubbub/dcn42/,$(HUBBUB_DCN42))
109+
110+AMD_DISPLAY_FILES += $(AMD_DAL_HUBBUB_DCN42)
111+
104112 endif
drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h+5−1
@@ -1,5 +1,5 @@
11 /*
2− * Copyright 2016 Advanced Micro Devices, Inc.
2+ * Copyright 2016-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -441,6 +441,8 @@ struct dcn_hubbub_registers { · 435 unmodified lines
441441 type DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_VALUE;\
442442 type DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_ENABLE
443443
444+#define HUBBUB_REG_FIELD_LIST_DCN4_2(type) \
445+ type URGENT_ZERO_SIZE_REQ_EN
444446 struct dcn_hubbub_shift {
445447 DCN_HUBBUB_REG_FIELD_LIST(uint8_t);
446448 HUBBUB_STUTTER_REG_FIELD_LIST(uint8_t);
@@ -449,6 +451,7 @@ struct dcn_hubbub_shift { · 2 unmodified lines
449451 HUBBUB_REG_FIELD_LIST_DCN32(uint8_t);
450452 HUBBUB_REG_FIELD_LIST_DCN35(uint8_t);
451453 HUBBUB_REG_FIELD_LIST_DCN4_01(uint8_t);
454+ HUBBUB_REG_FIELD_LIST_DCN4_2(uint8_t);
452455
453456 };
454457
@@ -460,6 +463,7 @@ struct dcn_hubbub_mask { · 5 unmodified lines
460463 HUBBUB_REG_FIELD_LIST_DCN32(uint32_t);
461464 HUBBUB_REG_FIELD_LIST_DCN35(uint32_t);
462465 HUBBUB_REG_FIELD_LIST_DCN4_01(uint32_t);
466+ HUBBUB_REG_FIELD_LIST_DCN4_2(uint8_t);
463467
464468 };
465469
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+
26+static 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+
158+static 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+
229+static 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+
306+static 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+
349+static 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+
420+static 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+}
442+static 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+
450+static 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+
497+static 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+
521+void 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+
260+void 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 @@
11
2−# Copyright 2022 Advanced Micro Devices, Inc.
2+# Copyright 2022-2026 Advanced Micro Devices, Inc.
33 #
44 # Permission is hereby granted, free of charge, to any person obtaining a
55 # 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
9494
9595 AMD_DISPLAY_FILES += $(AMD_DAL_HUBP_DCN401)
9696
97+###############################################################################
98+
99+HUBP_DCN42 = dcn42_hubp.o
100+
101+AMD_DAL_HUBP_DCN42 = $(addprefix $(AMDDALPATH)/dc/hubp/dcn42/,$(HUBP_DCN42))
102+
103+AMD_DISPLAY_FILES += $(AMD_DAL_HUBP_DCN42)
104+
97105 endif
drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h+7−1
@@ -1,5 +1,5 @@
11 /*
2− * Copyright 2012-17 Advanced Micro Devices, Inc.
2+ * Copyright 2012-2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -288,16 +288,22 @@ · 282 unmodified lines
288288 type MCACHEID_MALL_PREF_2H_P1;\
289289 type HUBP_FGCG_REP_DIS
290290
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
291295 struct dcn_hubp2_registers {
292296 DCN401_HUBP_REG_COMMON_VARIABLE_LIST;
293297 };
294298
295299 struct dcn_hubp2_shift {
296300 DCN401_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);
301+ DCN42_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);
297302 };
298303
299304 struct dcn_hubp2_mask {
300305 DCN401_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);
306+ DCN42_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);
301307 };
302308
303309 struct 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+
19+static 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+
26+static 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+
35+static 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+
150+void 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+
245+void 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+}
258+static 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+
277+void 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+
290+static 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+
541+struct 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+
585+bool 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+
606+void 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+
51+bool 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+
59+void 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+
65+void hubp42_read_state(struct hubp *hubp);
66+
67+void 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+
73+void 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−
2−# Copyright 2022 Advanced Micro Devices, Inc.
1+# Copyright 2022-2026 Advanced Micro Devices, Inc.
32 #
43 # Permission is hereby granted, free of charge, to any person obtaining a
54 # 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
199198 AMD_DAL_HWSS_DCN401 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn401/,$(HWSS_DCN401))
200199
201200 AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN401)
201+
202+###############################################################################
203+
204+HWSS_DCN42 = dcn42_hwseq.o dcn42_init.o
205+
206+AMD_DAL_HWSS_DCN42 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn42/,$(HWSS_DCN42))
207+
208+AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN42)
209+
202210 endif
drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h+12−1
@@ -1,5 +1,5 @@
11 /*
2− * Copyright 2016 Advanced Micro Devices, Inc.
2+ * Copyright 2016, 2026 Advanced Micro Devices, Inc.
33 *
44 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
@@ -700,6 +700,8 @@ struct dce_hwseq_registers { · 694 unmodified lines
700700 uint32_t DOMAIN23_PG_STATUS;
701701 uint32_t DOMAIN24_PG_STATUS;
702702 uint32_t DOMAIN25_PG_STATUS;
703+ uint32_t DOMAIN26_PG_CONFIG;
704+ uint32_t DOMAIN26_PG_STATUS;
703705 };
704706 /* set field name */
705707 #define HWS_SF(blk_name, reg_name, field_name, post_fix)\
@@ -1245,6 +1247,13 @@ struct dce_hwseq_registers { · 539 unmodified lines
12451247 type DOMAIN25_PGFSM_PWR_STATUS; \
12461248 type DOMAIN_DESIRED_PWR_STATE;
12471249
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+
12481257 struct dce_hwseq_shift {
12491258 HWSEQ_REG_FIELD_LIST(uint8_t)
12501259 HWSEQ_DCN_REG_FIELD_LIST(uint8_t)
@@ -1253,6 +1262,7 @@ struct dce_hwseq_shift { · 2 unmodified lines
12531262 HWSEQ_DCN31_REG_FIELD_LIST(uint8_t)
12541263 HWSEQ_DCN35_REG_FIELD_LIST(uint8_t)
12551264 HWSEQ_DCN401_REG_FIELD_LIST(uint8_t)
1265+ HWSEQ_DCN42_REG_FIELD_LIST(uint8_t)
12561266 };
12571267
12581268 struct dce_hwseq_mask {
@@ -1263,6 +1273,7 @@ struct dce_hwseq_mask { · 4 unmodified lines
12631273 HWSEQ_DCN31_REG_FIELD_LIST(uint32_t)
12641274 HWSEQ_DCN35_REG_FIELD_LIST(uint32_t)
12651275 HWSEQ_DCN401_REG_FIELD_LIST(uint32_t)
1276+ HWSEQ_DCN42_REG_FIELD_LIST(uint32_t)
12661277 };
12671278
12681279
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
660660 }
661661 }
662662
663+static void
664+dce110_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+
698+static void
699+dce110_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+
705+static bool
706+dce110_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+
663717 void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
664718 {
665719 enum dc_lane_count lane_count =
@@ -690,6 +744,8 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) · 24 unmodified lines
690744
691745 tg->funcs->set_early_control(tg, early_control);
692746
747+ if (link->ext_enc_id.id)
748+ dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_ENABLE, link, timing);
693749 }
694750
695751 static enum bp_result link_transmitter_control(
@@ -1183,6 +1239,9 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) · 487 unmodified lines
11831239 dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
11841240 link_enc->transmitter - TRANSMITTER_UNIPHY_A);
11851241 }
1242+
1243+ if (link->ext_enc_id.id)
1244+ dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_DISABLE, link, NULL);
11861245 }
11871246
11881247 void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
@@ -3317,6 +3376,11 @@ void dce110_enable_dp_link_output( · 2128 unmodified lines
33173376 }
33183377 }
33193378
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+
33203384 if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
33213385 if (dc->clk_mgr->funcs->notify_link_rate_change)
33223386 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
34093473 .enable_dp_link_output = dce110_enable_dp_link_output,
34103474 .enable_analog_link_output = dce110_enable_analog_link_output,
34113475 .disable_link_output = dce110_disable_link_output,
3476+ .dac_load_detect = dce110_dac_load_detect,
3477+ .prepare_ddc = dce110_prepare_ddc,
34123478 };
34133479
34143480 static 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
7272 * audio corruption. Read current DISPCLK from DENTIST and request the same
7373 * freq to ensure that the timing is valid and unchanged.
7474 */
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+ }
7680 }
7781 clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
7882 clocks->fclk_p_state_change_support = true;
@@ -1202,6 +1206,25 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) · 1123 unmodified lines
12021206 x_pos = pos_cpy.x - param.recout.x;
12031207 y_pos = pos_cpy.y - param.recout.y;
12041208
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+
12051228 recout_x_pos = x_pos - pos_cpy.x_hotspot;
12061229 recout_y_pos = y_pos - pos_cpy.y_hotspot;
12071230
@@ -1464,7 +1487,7 @@ void dcn401_optimize_bandwidth( · 256 unmodified lines
14641487 dc->clk_mgr,
14651488 context,
14661489 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) {
14681491 for (i = 0; i < dc->res_pool->pipe_count; ++i) {
14691492 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
14701493
@@ -1472,7 +1495,7 @@ void dcn401_optimize_bandwidth( · 1 unmodified line
14721495 && pipe_ctx->stream->adjust.v_total_min == pipe_ctx->stream->adjust.v_total_max
14731496 && pipe_ctx->stream->adjust.v_total_max > pipe_ctx->stream->timing.v_total)
14741497 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);
14761499 }
14771500 }
14781501 }
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+
55+static 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+}
62+void 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.