History

Merge tag 'drm-next-5.5-2019-10-25' of git://people.freedesktop.org/~agd5f/linux into drm-next

drm-next-5.5-2019-10-25: amdgpu: - BACO support for CI and VI asics - Quick memory training support for navi - MSI-X support - RAS fixes - Display AVI infoframe fixes - Display ref clock fixes for renoir - Fix number of audio endpoints in renoir - Fix for discovery tables - Powerplay fixes - Documentation fixes - Misc cleanups radeon: - revert a PPC fix which broke x86

Dave Airlie committed 7 years ago

Commit 60845e32 parents 3275a71 0e04ad7163 files · +5791 −1034Browse files

Unified · Split

163 files
  1. drivers/gpu/drm/amd/amdgpu/amdgpu.h +12 −2
  2. drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +5 −0
  3. drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +136 −0
  4. drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h +1 −0
  5. drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +1 −11
  6. drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +6 −1
  7. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +2 −6
  8. drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +35 −6
  9. drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +6 −14
  10. drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h +3 −1
  11. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +19 −3
  12. drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h +2 −0
  13. drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +2 −1
  14. drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +18 −0
  15. drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +55 −0
  16. drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +54 −3
  17. drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +9 −9
  18. drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +110 −9
  19. drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +24 −9
  20. drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +0 −4
  21. drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +23 −12
  22. drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +10 −9
  23. drivers/gpu/drm/amd/amdgpu/cik.c +43 −5
  24. drivers/gpu/drm/amd/amdgpu/cik.h +3 −0
  25. drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +5 −8
  26. drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +665 −331
  27. drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +44 −41
  28. drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +8 −0
  29. drivers/gpu/drm/amd/amdgpu/psp_v10_0.c +3 −0
  30. drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +174 −9
  31. drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +1 −1
  32. drivers/gpu/drm/amd/amdgpu/soc15.c +41 −19
  33. drivers/gpu/drm/amd/amdgpu/soc15.h +2 −0
  34. drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +21 −10
  35. drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +22 −11
  36. drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +7 −0
  37. drivers/gpu/drm/amd/amdgpu/vi.c +79 −5
  38. drivers/gpu/drm/amd/amdgpu/vi.h +3 −0
  39. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +15 −1
  40. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +7 −2
  41. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c +96 −13
  42. drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +2 −5
  43. drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +2 −6
  44. drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +25 −0
  45. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c +24 −0
  46. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h +1 −0
  47. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +127 −33
  48. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h +10 −1
  49. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c +18 −20
  50. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.h +2 −2
  51. drivers/gpu/drm/amd/display/dc/core/dc.c +91 −9
  52. drivers/gpu/drm/amd/display/dc/core/dc_link.c +39 −7
  53. drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +14 −0
  54. drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +27 −6
  55. drivers/gpu/drm/amd/display/dc/core/dc_stream.c +2 −2
  56. drivers/gpu/drm/amd/display/dc/dc.h +17 −2
  57. drivers/gpu/drm/amd/display/dc/dc_hw_types.h +5 −0
  58. drivers/gpu/drm/amd/display/dc/dc_link.h +15 −2
  59. drivers/gpu/drm/amd/display/dc/dc_stream.h +3 −0
  60. drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +3 −0
  61. drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +87 −6
  62. drivers/gpu/drm/amd/display/dc/dce/dce_aux.h +183 −4
  63. drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +1 −0
  64. drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +14 −1
  65. drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +5 −16
  66. drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +13 −1
  67. drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +13 −2
  68. drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +13 −2
  69. drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +13 −1
  70. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +2 −2
  71. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +5 −0
  72. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +13 −7
  73. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h +49 −1
  74. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c +3 −0
  75. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +13 −47
  76. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +2 −3
  77. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +14 −1
  78. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +62 −0
  79. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h +5 −0
  80. drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c +1 −1
  81. drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h +0 −5
  82. drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +38 −4
  83. drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h +7 −0
  84. drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c +1 −1
  85. drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +46 −7
  86. drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h +0 −3
  87. drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c +4 −0
  88. drivers/gpu/drm/amd/display/dc/dcn21/Makefile +1 −1
  89. drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c +89 −27
  90. drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.h +24 −10
  91. drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +3 −1
  92. drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c +122 −0
  93. drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h +33 −0
  94. drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c +470 −0
  95. drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.h +61 −0
  96. drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +250 −53
  97. drivers/gpu/drm/amd/display/dc/dm_pp_smu.h +3 −6
  98. drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c +10 −1
  99. drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +1 −1
  100. drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +2 −0
  101. drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +3 −0
  102. drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +5 −0
  103. drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h +3 −0
  104. drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +10 −1
  105. drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h +23 −2
  106. drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +1 −0
  107. drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +4 −0
  108. drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h +1 −0
  109. drivers/gpu/drm/amd/display/dc/inc/hw/opp.h +1 −0
  110. drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h +5 −0
  111. drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +2 −0
  112. drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +14 −2
  113. drivers/gpu/drm/amd/display/include/ddc_service_types.h +2 −0
  114. drivers/gpu/drm/amd/display/modules/freesync/freesync.c +12 −5
  115. drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h +3 −0
  116. drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +98 −0
  117. drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_d.h +1 −0
  118. drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_sh_mask.h +2 −0
  119. drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_d.h +1 −0
  120. drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_sh_mask.h +2 −0
  121. drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h +10 −0
  122. drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_0_offset.h +16 −2
  123. drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_0_sh_mask.h +16 −2
  124. drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_0_1_d.h +1 −0
  125. drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_0_1_sh_mask.h +2 −0
  126. drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_2_d.h +1 −0
  127. drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_2_sh_mask.h +2 −0
  128. drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_3_d.h +1 −0
  129. drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_3_sh_mask.h +2 −0
  130. drivers/gpu/drm/amd/include/atomfirmware.h +21 −6
  131. drivers/gpu/drm/amd/include/discovery.h +0 −1
  132. drivers/gpu/drm/amd/include/kgd_pp_interface.h +6 −0
  133. drivers/gpu/drm/amd/include/renoir_ip_offset.h +34 −0
  134. drivers/gpu/drm/amd/powerplay/amd_powerplay.c +19 −0
  135. drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +64 −44
  136. drivers/gpu/drm/amd/powerplay/arcturus_ppt.c +30 −0
  137. drivers/gpu/drm/amd/powerplay/hwmgr/Makefile +2 −1
  138. drivers/gpu/drm/amd/powerplay/hwmgr/ci_baco.c +195 −0
  139. drivers/gpu/drm/amd/powerplay/hwmgr/ci_baco.h +29 −0
  140. drivers/gpu/drm/amd/powerplay/hwmgr/common_baco.c +19 −0
  141. drivers/gpu/drm/amd/powerplay/hwmgr/common_baco.h +13 −0
  142. drivers/gpu/drm/amd/powerplay/hwmgr/fiji_baco.c +196 −0
  143. drivers/gpu/drm/amd/powerplay/hwmgr/fiji_baco.h +29 −0
  144. drivers/gpu/drm/amd/powerplay/hwmgr/polaris_baco.c +222 −0
  145. drivers/gpu/drm/amd/powerplay/hwmgr/polaris_baco.h +29 −0
  146. drivers/gpu/drm/amd/powerplay/hwmgr/smu7_baco.c +91 −0
  147. drivers/gpu/drm/amd/powerplay/hwmgr/smu7_baco.h +32 −0
  148. drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +6 −4
  149. drivers/gpu/drm/amd/powerplay/hwmgr/tonga_baco.c +231 −0
  150. drivers/gpu/drm/amd/powerplay/hwmgr/tonga_baco.h +29 −0
  151. drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +2 −4
  152. drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c +15 −8
  153. drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +24 −2
  154. drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +18 −9
  155. drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +1 −0
  156. drivers/gpu/drm/amd/powerplay/inc/smu_types.h +1 −0
  157. drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h +2 −1
  158. drivers/gpu/drm/amd/powerplay/navi10_ppt.c +85 −25
  159. drivers/gpu/drm/amd/powerplay/navi10_ppt.h +6 −0
  160. drivers/gpu/drm/amd/powerplay/renoir_ppt.c +130 −0
  161. drivers/gpu/drm/amd/powerplay/smu_v11_0.c +44 −39
  162. drivers/gpu/drm/amd/powerplay/smu_v12_0.c +0 −9
  163. drivers/gpu/drm/amd/powerplay/vega20_ppt.c +47 −1
drivers/gpu/drm/amd/amdgpu/amdgpu.h+12−2
@@ -150,6 +150,7 @@ extern uint amdgpu_sdma_phase_quantum; · 149 unmodified lines
150150 extern char *amdgpu_disable_cu;
151151 extern char *amdgpu_virtual_display;
152152 extern uint amdgpu_pp_feature_mask;
153+extern uint amdgpu_force_long_training;
153154 extern int amdgpu_job_hang_limit;
154155 extern int amdgpu_lbpw;
155156 extern int amdgpu_compute_multipipe;
@@ -288,6 +289,9 @@ struct amdgpu_ip_block_version { · 132 unmodified lines
288289 const struct amd_ip_funcs *funcs;
289290 };
290291
292+#define HW_REV(_Major, _Minor, _Rev) \
293+ ((((uint32_t) (_Major)) << 16) | ((uint32_t) (_Minor) << 8) | ((uint32_t) (_Rev)))
294+
291295 struct amdgpu_ip_block {
292296 struct amdgpu_ip_block_status status;
293297 const struct amdgpu_ip_block_version *version;
@@ -627,6 +631,11 @@ struct amdgpu_fw_vram_usage { · 333 unmodified lines
627631 u64 size;
628632 struct amdgpu_bo *reserved_bo;
629633 void *va;
634+
635+ /* Offset on the top of VRAM, used as c2p write buffer.
636+ */
637+ u64 mem_train_fb_loc;
638+ bool mem_train_support;
630639 };
631640
632641 /*
@@ -759,6 +768,7 @@ struct amdgpu_device { · 126 unmodified lines
759768 uint8_t *bios;
760769 uint32_t bios_size;
761770 struct amdgpu_bo *stolen_vga_memory;
771+ struct amdgpu_bo *discovery_memory;
762772 uint32_t bios_scratch_reg_offset;
763773 uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH];
764774
@@ -959,8 +969,6 @@ struct amdgpu_device { · 194 unmodified lines
959969 int asic_reset_res;
960970 struct work_struct xgmi_reset_work;
961971
962− bool in_baco_reset;
963−
964972 long gfx_timeout;
965973 long sdma_timeout;
966974 long video_timeout;
@@ -982,6 +990,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 15 unmodified lines
982990 void amdgpu_device_fini(struct amdgpu_device *adev);
983991 int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
984992
993+void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
994+ uint32_t *buf, size_t size, bool write);
985995 uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
986996 uint32_t acc_flags);
987997 void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c+5−0
@@ -2038,6 +2038,11 @@ int amdgpu_atombios_init(struct amdgpu_device *adev) · 2037 unmodified lines
20382038 if (adev->is_atom_fw) {
20392039 amdgpu_atomfirmware_scratch_regs_init(adev);
20402040 amdgpu_atomfirmware_allocate_fb_scratch(adev);
2041+ ret = amdgpu_atomfirmware_get_mem_train_fb_loc(adev);
2042+ if (ret) {
2043+ DRM_ERROR("Failed to get mem train fb location.\n");
2044+ return ret;
2045+ }
20412046 } else {
20422047 amdgpu_atombios_scratch_regs_init(adev);
20432048 amdgpu_atombios_allocate_fb_scratch(adev);
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c+136−0
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include "amdgpu_atomfirmware.h"
2828 #include "atom.h"
2929 #include "atombios.h"
30+#include "soc15_hw_ip.h"
3031
3132 bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev)
3233 {
@@ -462,3 +463,138 @@ int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev) · 429 unmodified lines
462463 }
463464 return -EINVAL;
464465 }
466+
467+/*
468+ * Check if VBIOS supports GDDR6 training data save/restore
469+ */
470+static bool gddr6_mem_train_vbios_support(struct amdgpu_device *adev)
471+{
472+ uint16_t data_offset;
473+ int index;
474+
475+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
476+ firmwareinfo);
477+ if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL,
478+ NULL, NULL, &data_offset)) {
479+ struct atom_firmware_info_v3_1 *firmware_info =
480+ (struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios +
481+ data_offset);
482+
483+ DRM_DEBUG("atom firmware capability:0x%08x.\n",
484+ le32_to_cpu(firmware_info->firmware_capability));
485+
486+ if (le32_to_cpu(firmware_info->firmware_capability) &
487+ ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING)
488+ return true;
489+ }
490+
491+ return false;
492+}
493+
494+static int gddr6_mem_train_support(struct amdgpu_device *adev)
495+{
496+ int ret;
497+ uint32_t major, minor, revision, hw_v;
498+
499+ if (gddr6_mem_train_vbios_support(adev)) {
500+ amdgpu_discovery_get_ip_version(adev, MP0_HWID, &major, &minor, &revision);
501+ hw_v = HW_REV(major, minor, revision);
502+ /*
503+ * treat 0 revision as a special case since register for MP0 and MMHUB is missing
504+ * for some Navi10 A0, preventing driver from discovering the hwip information since
505+ * none of the functions will be initialized, it should not cause any problems
506+ */
507+ switch (hw_v) {
508+ case HW_REV(11, 0, 0):
509+ case HW_REV(11, 0, 5):
510+ ret = 1;
511+ break;
512+ default:
513+ DRM_ERROR("memory training vbios supports but psp hw(%08x)"
514+ " doesn't support!\n", hw_v);
515+ ret = -1;
516+ break;
517+ }
518+ } else {
519+ ret = 0;
520+ hw_v = -1;
521+ }
522+
523+
524+ DRM_DEBUG("mp0 hw_v %08x, ret:%d.\n", hw_v, ret);
525+ return ret;
526+}
527+
528+int amdgpu_atomfirmware_get_mem_train_fb_loc(struct amdgpu_device *adev)
529+{
530+ struct atom_context *ctx = adev->mode_info.atom_context;
531+ unsigned char *bios = ctx->bios;
532+ struct vram_reserve_block *reserved_block;
533+ int index, block_number;
534+ uint8_t frev, crev;
535+ uint16_t data_offset, size;
536+ uint32_t start_address_in_kb;
537+ uint64_t offset;
538+ int ret;
539+
540+ adev->fw_vram_usage.mem_train_support = false;
541+
542+ if (adev->asic_type != CHIP_NAVI10 &&
543+ adev->asic_type != CHIP_NAVI14)
544+ return 0;
545+
546+ if (amdgpu_sriov_vf(adev))
547+ return 0;
548+
549+ ret = gddr6_mem_train_support(adev);
550+ if (ret == -1)
551+ return -EINVAL;
552+ else if (ret == 0)
553+ return 0;
554+
555+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
556+ vram_usagebyfirmware);
557+ ret = amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev,
558+ &data_offset);
559+ if (ret == 0) {
560+ DRM_ERROR("parse data header failed.\n");
561+ return -EINVAL;
562+ }
563+
564+ DRM_DEBUG("atom firmware common table header size:0x%04x, frev:0x%02x,"
565+ " crev:0x%02x, data_offset:0x%04x.\n", size, frev, crev, data_offset);
566+ /* only support 2.1+ */
567+ if (((uint16_t)frev << 8 | crev) < 0x0201) {
568+ DRM_ERROR("frev:0x%02x, crev:0x%02x < 2.1 !\n", frev, crev);
569+ return -EINVAL;
570+ }
571+
572+ reserved_block = (struct vram_reserve_block *)
573+ (bios + data_offset + sizeof(struct atom_common_table_header));
574+ block_number = ((unsigned int)size - sizeof(struct atom_common_table_header))
575+ / sizeof(struct vram_reserve_block);
576+ reserved_block += (block_number > 0) ? block_number-1 : 0;
577+ DRM_DEBUG("block_number:0x%04x, last block: 0x%08xkb sz, %dkb fw, %dkb drv.\n",
578+ block_number,
579+ le32_to_cpu(reserved_block->start_address_in_kb),
580+ le16_to_cpu(reserved_block->used_by_firmware_in_kb),
581+ le16_to_cpu(reserved_block->used_by_driver_in_kb));
582+ if (reserved_block->used_by_firmware_in_kb > 0) {
583+ start_address_in_kb = le32_to_cpu(reserved_block->start_address_in_kb);
584+ offset = (uint64_t)start_address_in_kb * ONE_KiB;
585+ if ((offset & (ONE_MiB - 1)) < (4 * ONE_KiB + 1) ) {
586+ offset -= ONE_MiB;
587+ }
588+
589+ offset &= ~(ONE_MiB - 1);
590+ adev->fw_vram_usage.mem_train_fb_loc = offset;
591+ adev->fw_vram_usage.mem_train_support = true;
592+ DRM_DEBUG("mem_train_fb_loc:0x%09llx.\n", offset);
593+ ret = 0;
594+ } else {
595+ DRM_ERROR("used_by_firmware_in_kb is 0!\n");
596+ ret = -EINVAL;
597+ }
598+
599+ return ret;
600+}
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h+1−0
@@ -31,6 +31,7 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev); · 30 unmodified lines
3131 int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
3232 int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
3333 int *vram_width, int *vram_type, int *vram_vendor);
34+int amdgpu_atomfirmware_get_mem_train_fb_loc(struct amdgpu_device *adev);
3435 int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
3536 int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev);
3637 bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev);
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c+1−11
@@ -613,17 +613,7 @@ static bool amdgpu_atpx_detect(void) · 612 unmodified lines
613613 bool d3_supported = false;
614614 struct pci_dev *parent_pdev;
615615
616− while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
617− vga_count++;
618−
619− has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
620−
621− parent_pdev = pci_upstream_bridge(pdev);
622− d3_supported |= parent_pdev && parent_pdev->bridge_d3;
623− amdgpu_atpx_get_quirks(pdev);
624− }
625−
626− while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
616+ while ((pdev = pci_get_class(PCI_BASE_CLASS_DISPLAY << 16, pdev)) != NULL) {
627617 vga_count++;
628618
629619 has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c+6−1
@@ -140,7 +140,12 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, · 139 unmodified lines
140140 return 0;
141141
142142 error_free:
143− while (i--) {
143+ for (i = 0; i < last_entry; ++i) {
144+ struct amdgpu_bo *bo = ttm_to_amdgpu_bo(array[i].tv.bo);
145+
146+ amdgpu_bo_unref(&bo);
147+ }
148+ for (i = first_userptr; i < num_entries; ++i) {
144149 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(array[i].tv.bo);
145150
146151 amdgpu_bo_unref(&bo);
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+2−6
@@ -474,7 +474,6 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, · 473 unmodified lines
474474
475475 list_for_each_entry(lobj, validated, tv.head) {
476476 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo);
477− bool binding_userptr = false;
478477 struct mm_struct *usermm;
479478
480479 usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
@@ -491,17 +490,14 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, · 10 unmodified lines
491490
492491 amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
493492 lobj->user_pages);
494− binding_userptr = true;
495493 }
496494
497495 r = amdgpu_cs_validate(p, bo);
498496 if (r)
499497 return r;
500498
501− if (binding_userptr) {
502− kvfree(lobj->user_pages);
503− lobj->user_pages = NULL;
504− }
499+ kvfree(lobj->user_pages);
500+ lobj->user_pages = NULL;
505501 }
506502 return 0;
507503 }
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c+35−6
@@ -153,6 +153,36 @@ bool amdgpu_device_is_px(struct drm_device *dev) · 152 unmodified lines
153153 return false;
154154 }
155155
156+/**
157+ * VRAM access helper functions.
158+ *
159+ * amdgpu_device_vram_access - read/write a buffer in vram
160+ *
161+ * @adev: amdgpu_device pointer
162+ * @pos: offset of the buffer in vram
163+ * @buf: virtual address of the buffer in system memory
164+ * @size: read/write size, sizeof(@buf) must > @size
165+ * @write: true - write to vram, otherwise - read from vram
166+ */
167+void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
168+ uint32_t *buf, size_t size, bool write)
169+{
170+ uint64_t last;
171+ unsigned long flags;
172+
173+ last = size - 4;
174+ for (last += pos; pos <= last; pos += 4) {
175+ spin_lock_irqsave(&adev->mmio_idx_lock, flags);
176+ WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x80000000);
177+ WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
178+ if (write)
179+ WREG32_NO_KIQ(mmMM_DATA, *buf++);
180+ else
181+ *buf++ = RREG32_NO_KIQ(mmMM_DATA);
182+ spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
183+ }
184+}
185+
156186 /*
157187 * MMIO register access helper functions.
158188 */
@@ -2622,8 +2652,11 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev) · 2463 unmodified lines
26222652 * There is only one value specified and
26232653 * it should apply to all non-compute jobs.
26242654 */
2625− if (index == 1)
2655+ if (index == 1) {
26262656 adev->sdma_timeout = adev->video_timeout = adev->gfx_timeout;
2657+ if (amdgpu_sriov_vf(adev) || amdgpu_passthrough(adev))
2658+ adev->compute_timeout = adev->gfx_timeout;
2659+ }
26272660 }
26282661
26292662 return ret;
@@ -3168,15 +3201,11 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) · 538 unmodified lines
31683201 */
31693202 amdgpu_bo_evict_vram(adev);
31703203
3171− pci_save_state(dev->pdev);
31723204 if (suspend) {
3205+ pci_save_state(dev->pdev);
31733206 /* Shut down the device */
31743207 pci_disable_device(dev->pdev);
31753208 pci_set_power_state(dev->pdev, PCI_D3hot);
3176− } else {
3177− r = amdgpu_asic_reset(adev);
3178− if (r)
3179− DRM_ERROR("amdgpu asic reset failed\n");
31803209 }
31813210
31823211 return 0;
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c+6−14
@@ -134,20 +134,10 @@ static int hw_id_map[MAX_HWIP] = { · 133 unmodified lines
134134
135135 static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t *binary)
136136 {
137− uint32_t *p = (uint32_t *)binary;
138137 uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
139− uint64_t pos = vram_size - BINARY_MAX_SIZE;
140− unsigned long flags;
141−
142− while (pos < vram_size) {
143− spin_lock_irqsave(&adev->mmio_idx_lock, flags);
144− WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x80000000);
145− WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
146− *p++ = RREG32_NO_KIQ(mmMM_DATA);
147− spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
148− pos += 4;
149− }
138+ uint64_t pos = vram_size - DISCOVERY_TMR_SIZE;
150139
140+ amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, DISCOVERY_TMR_SIZE, false);
151141 return 0;
152142 }
153143
@@ -179,7 +169,7 @@ int amdgpu_discovery_init(struct amdgpu_device *adev) · 25 unmodified lines
179169 uint16_t checksum;
180170 int r;
181171
182− adev->discovery = kzalloc(BINARY_MAX_SIZE, GFP_KERNEL);
172+ adev->discovery = kzalloc(DISCOVERY_TMR_SIZE, GFP_KERNEL);
183173 if (!adev->discovery)
184174 return -ENOMEM;
185175
@@ -333,7 +323,7 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) · 147 unmodified lines
333323 }
334324
335325 int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id,
336− int *major, int *minor)
326+ int *major, int *minor, int *revision)
337327 {
338328 struct binary_header *bhdr;
339329 struct ip_discovery_header *ihdr;
@@ -369,6 +359,8 @@ int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, · 29 unmodified lines
369359 *major = ip->major;
370360 if (minor)
371361 *minor = ip->minor;
362+ if (revision)
363+ *revision = ip->revision;
372364 return 0;
373365 }
374366 ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h+3−1
@@ -24,11 +24,13 @@ · 23 unmodified lines
2424 #ifndef __AMDGPU_DISCOVERY__
2525 #define __AMDGPU_DISCOVERY__
2626
27+#define DISCOVERY_TMR_SIZE (64 << 10)
28+
2729 int amdgpu_discovery_init(struct amdgpu_device *adev);
2830 void amdgpu_discovery_fini(struct amdgpu_device *adev);
2931 int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev);
3032 int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id,
31− int *major, int *minor);
33+ int *major, int *minor, int *revision);
3234 int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev);
3335
3436 #endif /* __AMDGPU_DISCOVERY__ */
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+19−3
@@ -128,6 +128,7 @@ char *amdgpu_disable_cu = NULL; · 127 unmodified lines
128128 char *amdgpu_virtual_display = NULL;
129129 /* OverDrive(bit 14) disabled by default*/
130130 uint amdgpu_pp_feature_mask = 0xffffbfff;
131+uint amdgpu_force_long_training = 0;
131132 int amdgpu_job_hang_limit = 0;
132133 int amdgpu_lbpw = -1;
133134 int amdgpu_compute_multipipe = -1;
@@ -250,9 +251,11 @@ module_param_named(msi, amdgpu_msi, int, 0444); · 116 unmodified lines
250251 * By default(with no lockup_timeout settings), the timeout for all non-compute(GFX, SDMA and Video)
251252 * jobs is 10000. And there is no timeout enforced on compute jobs.
252253 */
253−MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default: 10000 for non-compute jobs and infinity timeout for compute jobs."
254+MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default: for bare metal 10000 for non-compute jobs and infinity timeout for compute jobs; "
255+ "for passthrough or sriov, 10000 for all jobs."
254256 " 0: keep default value. negative: infinity timeout), "
255− "format is [Non-Compute] or [GFX,Compute,SDMA,Video]");
257+ "format: for bare metal [Non-Compute] or [GFX,Compute,SDMA,Video]; "
258+ "for passthrough or sriov [all jobs] or [GFX,Compute,SDMA,Video].");
256259 module_param_string(lockup_timeout, amdgpu_lockup_timeout, sizeof(amdgpu_lockup_timeout), 0444);
257260
258261 /**
@@ -390,6 +393,14 @@ module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); · 131 unmodified lines
390393 MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))");
391394 module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444);
392395
396+/**
397+ * DOC: forcelongtraining (uint)
398+ * Force long memory training in resume.
399+ * The default is zero, indicates short training in resume.
400+ */
401+MODULE_PARM_DESC(forcelongtraining, "force memory long training");
402+module_param_named(forcelongtraining, amdgpu_force_long_training, uint, 0444);
403+
393404 /**
394405 * DOC: pcie_gen_cap (uint)
395406 * Override PCIE gen speed capabilities. See the CAIL flags in drivers/gpu/drm/amd/include/amd_pcie.h.
@@ -1154,8 +1165,13 @@ static int amdgpu_pmops_resume(struct device *dev) · 758 unmodified lines
11541165 static int amdgpu_pmops_freeze(struct device *dev)
11551166 {
11561167 struct drm_device *drm_dev = dev_get_drvdata(dev);
1168+ struct amdgpu_device *adev = drm_dev->dev_private;
1169+ int r;
11571170
1158− return amdgpu_device_suspend(drm_dev, false, true);
1171+ r = amdgpu_device_suspend(drm_dev, false, true);
1172+ if (r)
1173+ return r;
1174+ return amdgpu_asic_reset(adev);
11591175 }
11601176
11611177 static int amdgpu_pmops_thaw(struct device *dev)
drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h+2−0
@@ -67,6 +67,8 @@ struct amdgpu_nbio_funcs { · 66 unmodified lines
6767 bool enable);
6868 void (*ih_doorbell_range)(struct amdgpu_device *adev,
6969 bool use_doorbell, int doorbell_index);
70+ void (*enable_doorbell_interrupt)(struct amdgpu_device *adev,
71+ bool enable);
7072 void (*update_medium_grain_clock_gating)(struct amdgpu_device *adev,
7173 bool enable);
7274 void (*update_medium_grain_light_sleep)(struct amdgpu_device *adev,
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c+2−1
@@ -517,7 +517,8 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, · 516 unmodified lines
517517 .interruptible = (bp->type != ttm_bo_type_kernel),
518518 .no_wait_gpu = bp->no_wait_gpu,
519519 .resv = bp->resv,
520− .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT
520+ .flags = bp->type != ttm_bo_type_kernel ?
521+ TTM_OPT_FLAG_ALLOW_RES_EVICT : 0
521522 };
522523 struct amdgpu_bo *bo;
523524 unsigned long page_align, size = bp->size;
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c+18−0
@@ -88,6 +88,17 @@ static int psp_sw_init(void *handle) · 87 unmodified lines
8888 return ret;
8989 }
9090
91+ ret = psp_mem_training_init(psp);
92+ if (ret) {
93+ DRM_ERROR("Failed to initliaze memory training!\n");
94+ return ret;
95+ }
96+ ret = psp_mem_training(psp, PSP_MEM_TRAIN_COLD_BOOT);
97+ if (ret) {
98+ DRM_ERROR("Failed to process memory training!\n");
99+ return ret;
100+ }
101+
91102 return 0;
92103 }
93104
@@ -95,6 +106,7 @@ static int psp_sw_fini(void *handle) · 1 unmodified line
95106 {
96107 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
97108
109+ psp_mem_training_fini(&adev->psp);
98110 release_firmware(adev->psp.sos_fw);
99111 adev->psp.sos_fw = NULL;
100112 release_firmware(adev->psp.asd_fw);
@@ -1608,6 +1620,12 @@ static int psp_resume(void *handle) · 1507 unmodified lines
16081620
16091621 DRM_INFO("PSP is resuming...\n");
16101622
1623+ ret = psp_mem_training(psp, PSP_MEM_TRAIN_RESUME);
1624+ if (ret) {
1625+ DRM_ERROR("Failed to process memory training!\n");
1626+ return ret;
1627+ }
1628+
16111629 mutex_lock(&adev->firmware.mutex);
16121630
16131631 ret = psp_hw_start(psp);
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h+55−0
@@ -49,6 +49,8 @@ enum psp_bootloader_cmd { · 48 unmodified lines
4949 PSP_BL__LOAD_SYSDRV = 0x10000,
5050 PSP_BL__LOAD_SOSDRV = 0x20000,
5151 PSP_BL__LOAD_KEY_DATABASE = 0x80000,
52+ PSP_BL__DRAM_LONG_TRAIN = 0x100000,
53+ PSP_BL__DRAM_SHORT_TRAIN = 0x200000,
5254 };
5355
5456 enum psp_ring_type
@@ -111,6 +113,9 @@ struct psp_funcs · 56 unmodified lines
111113 struct ta_ras_trigger_error_input *info);
112114 int (*ras_cure_posion)(struct psp_context *psp, uint64_t *mode_ptr);
113115 int (*rlc_autoload_start)(struct psp_context *psp);
116+ int (*mem_training_init)(struct psp_context *psp);
117+ void (*mem_training_fini)(struct psp_context *psp);
118+ int (*mem_training)(struct psp_context *psp, uint32_t ops);
114119 };
115120
116121 #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64
@@ -161,6 +166,49 @@ struct psp_dtm_context { · 44 unmodified lines
161166 void *dtm_shared_buf;
162167 };
163168
169+#define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942
170+#define GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES 0x1000
171+#define GDDR6_MEM_TRAINING_OFFSET 0x8000
172+
173+enum psp_memory_training_init_flag {
174+ PSP_MEM_TRAIN_NOT_SUPPORT = 0x0,
175+ PSP_MEM_TRAIN_SUPPORT = 0x1,
176+ PSP_MEM_TRAIN_INIT_FAILED = 0x2,
177+ PSP_MEM_TRAIN_RESERVE_SUCCESS = 0x4,
178+ PSP_MEM_TRAIN_INIT_SUCCESS = 0x8,
179+};
180+
181+enum psp_memory_training_ops {
182+ PSP_MEM_TRAIN_SEND_LONG_MSG = 0x1,
183+ PSP_MEM_TRAIN_SAVE = 0x2,
184+ PSP_MEM_TRAIN_RESTORE = 0x4,
185+ PSP_MEM_TRAIN_SEND_SHORT_MSG = 0x8,
186+ PSP_MEM_TRAIN_COLD_BOOT = PSP_MEM_TRAIN_SEND_LONG_MSG,
187+ PSP_MEM_TRAIN_RESUME = PSP_MEM_TRAIN_SEND_SHORT_MSG,
188+};
189+
190+struct psp_memory_training_context {
191+ /*training data size*/
192+ u64 train_data_size;
193+ /*
194+ * sys_cache
195+ * cpu virtual address
196+ * system memory buffer that used to store the training data.
197+ */
198+ void *sys_cache;
199+
200+ /*vram offset of the p2c training data*/
201+ u64 p2c_train_data_offset;
202+ struct amdgpu_bo *p2c_bo;
203+
204+ /*vram offset of the c2p training data*/
205+ u64 c2p_train_data_offset;
206+ struct amdgpu_bo *c2p_bo;
207+
208+ enum psp_memory_training_init_flag init;
209+ u32 training_cnt;
210+};
211+
164212 struct psp_context
165213 {
166214 struct amdgpu_device *adev;
@@ -239,6 +287,7 @@ struct psp_context · 72 unmodified lines
239287 struct psp_hdcp_context hdcp_context;
240288 struct psp_dtm_context dtm_context;
241289 struct mutex mutex;
290+ struct psp_memory_training_context mem_train_ctx;
242291 };
243292
244293 struct amdgpu_psp_funcs {
@@ -281,6 +330,12 @@ struct amdgpu_psp_funcs { · 36 unmodified lines
281330 (psp)->funcs->xgmi_set_topology_info((psp), (num_device), (topology)) : -EINVAL)
282331 #define psp_rlc_autoload(psp) \
283332 ((psp)->funcs->rlc_autoload_start ? (psp)->funcs->rlc_autoload_start((psp)) : 0)
333+#define psp_mem_training_init(psp) \
334+ ((psp)->funcs->mem_training_init ? (psp)->funcs->mem_training_init((psp)) : 0)
335+#define psp_mem_training_fini(psp) \
336+ ((psp)->funcs->mem_training_fini ? (psp)->funcs->mem_training_fini((psp)) : 0)
337+#define psp_mem_training(psp, ops) \
338+ ((psp)->funcs->mem_training ? (psp)->funcs->mem_training((psp), (ops)) : 0)
284339
285340 #define amdgpu_psp_check_fw_loading_status(adev, i) (adev)->firmware.funcs->check_fw_loading_status((adev), (i))
286341
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c+54−3
@@ -71,6 +71,9 @@ const char *ras_block_string[] = { · 70 unmodified lines
7171
7272 atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0);
7373
74+static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
75+ uint64_t addr);
76+
7477 static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf,
7578 size_t size, loff_t *pos)
7679 {
@@ -215,11 +218,12 @@ static struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev, · 138 unmodified lines
215218 * value to the address.
216219 *
217220 * Second member: struct ras_debug_if::op.
218− * It has three kinds of operations.
221+ * It has four kinds of operations.
219222 *
220223 * - 0: disable RAS on the block. Take ::head as its data.
221224 * - 1: enable RAS on the block. Take ::head as its data.
222225 * - 2: inject errors on the block. Take ::inject as its data.
226+ * - 3: reboot on unrecoverable error
223227 *
224228 * How to use the interface?
225229 * programs:
@@ -228,13 +232,13 @@ static struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev, · 2 unmodified lines
228232 *
229233 * .. code-block:: bash
230234 *
231− * echo op block [error [sub_blcok address value]] > .../ras/ras_ctrl
235+ * echo op block [error [sub_block address value]] > .../ras/ras_ctrl
232236 *
233237 * op: disable, enable, inject
234238 * disable: only block is needed
235239 * enable: block and error are needed
236240 * inject: error, address, value are needed
237− * block: umc, smda, gfx, .........
241+ * block: umc, sdma, gfx, .........
238242 * see ras_block_string[] for details
239243 * error: ue, ce
240244 * ue: multi_uncorrectable
@@ -290,6 +294,14 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user * · 49 unmodified lines
290294 break;
291295 }
292296
297+ /* umc ce/ue error injection for a bad page is not allowed */
298+ if ((data.head.block == AMDGPU_RAS_BLOCK__UMC) &&
299+ amdgpu_ras_check_bad_page(adev, data.inject.address)) {
300+ DRM_WARN("RAS WARN: 0x%llx has been marked as bad before error injection!\n",
301+ data.inject.address);
302+ break;
303+ }
304+
293305 /* data.inject.address is offset instead of absolute gpu address */
294306 ret = amdgpu_ras_error_inject(adev, &data.inject);
295307 break;
@@ -1430,6 +1442,39 @@ out: · 1134 unmodified lines
14301442 return ret;
14311443 }
14321444
1445+/*
1446+ * check if an address belongs to bad page
1447+ *
1448+ * Note: this check is only for umc block
1449+ */
1450+static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
1451+ uint64_t addr)
1452+{
1453+ struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
1454+ struct ras_err_handler_data *data;
1455+ int i;
1456+ bool ret = false;
1457+
1458+ if (!con || !con->eh_data)
1459+ return ret;
1460+
1461+ mutex_lock(&con->recovery_lock);
1462+ data = con->eh_data;
1463+ if (!data)
1464+ goto out;
1465+
1466+ addr >>= AMDGPU_GPU_PAGE_SHIFT;
1467+ for (i = 0; i < data->count; i++)
1468+ if (addr == data->bps[i].retired_page) {
1469+ ret = true;
1470+ goto out;
1471+ }
1472+
1473+out:
1474+ mutex_unlock(&con->recovery_lock);
1475+ return ret;
1476+}
1477+
14331478 /* called in gpu recovery/init */
14341479 int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev)
14351480 {
@@ -1843,6 +1888,12 @@ int amdgpu_ras_fini(struct amdgpu_device *adev) · 407 unmodified lines
18431888
18441889 void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev)
18451890 {
1891+ uint32_t hw_supported, supported;
1892+
1893+ amdgpu_ras_check_supported(adev, &hw_supported, &supported);
1894+ if (!hw_supported)
1895+ return;
1896+
18461897 if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) {
18471898 DRM_WARN("RAS event of type ERREVENT_ATHUB_INTERRUPT detected!\n");
18481899
drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h+9−9
@@ -170,7 +170,7 @@ TRACE_EVENT(amdgpu_cs_ioctl, · 169 unmodified lines
170170 __field(unsigned int, context)
171171 __field(unsigned int, seqno)
172172 __field(struct dma_fence *, fence)
173− __field(char *, ring_name)
173+ __string(ring, to_amdgpu_ring(job->base.sched)->name)
174174 __field(u32, num_ibs)
175175 ),
176176
@@ -179,12 +179,12 @@ TRACE_EVENT(amdgpu_cs_ioctl, · 2 unmodified lines
179179 __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job))
180180 __entry->context = job->base.s_fence->finished.context;
181181 __entry->seqno = job->base.s_fence->finished.seqno;
182− __entry->ring_name = to_amdgpu_ring(job->base.sched)->name;
182+ __assign_str(ring, to_amdgpu_ring(job->base.sched)->name)
183183 __entry->num_ibs = job->num_ibs;
184184 ),
185185 TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u",
186186 __entry->sched_job_id, __get_str(timeline), __entry->context,
187− __entry->seqno, __entry->ring_name, __entry->num_ibs)
187+ __entry->seqno, __get_str(ring), __entry->num_ibs)
188188 );
189189
190190 TRACE_EVENT(amdgpu_sched_run_job,
@@ -195,7 +195,7 @@ TRACE_EVENT(amdgpu_sched_run_job, · 4 unmodified lines
195195 __string(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job))
196196 __field(unsigned int, context)
197197 __field(unsigned int, seqno)
198− __field(char *, ring_name)
198+ __string(ring, to_amdgpu_ring(job->base.sched)->name)
199199 __field(u32, num_ibs)
200200 ),
201201
@@ -204,12 +204,12 @@ TRACE_EVENT(amdgpu_sched_run_job, · 2 unmodified lines
204204 __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job))
205205 __entry->context = job->base.s_fence->finished.context;
206206 __entry->seqno = job->base.s_fence->finished.seqno;
207− __entry->ring_name = to_amdgpu_ring(job->base.sched)->name;
207+ __assign_str(ring, to_amdgpu_ring(job->base.sched)->name)
208208 __entry->num_ibs = job->num_ibs;
209209 ),
210210 TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u",
211211 __entry->sched_job_id, __get_str(timeline), __entry->context,
212− __entry->seqno, __entry->ring_name, __entry->num_ibs)
212+ __entry->seqno, __get_str(ring), __entry->num_ibs)
213213 );
214214
215215
@@ -473,7 +473,7 @@ TRACE_EVENT(amdgpu_ib_pipe_sync, · 257 unmodified lines
473473 TP_PROTO(struct amdgpu_job *sched_job, struct dma_fence *fence),
474474 TP_ARGS(sched_job, fence),
475475 TP_STRUCT__entry(
476− __field(const char *,name)
476+ __string(ring, sched_job->base.sched->name);
477477 __field(uint64_t, id)
478478 __field(struct dma_fence *, fence)
479479 __field(uint64_t, ctx)
@@ -481,14 +481,14 @@ TRACE_EVENT(amdgpu_ib_pipe_sync, · 1 unmodified line
481481 ),
482482
483483 TP_fast_assign(
484− __entry->name = sched_job->base.sched->name;
484+ __assign_str(ring, sched_job->base.sched->name)
485485 __entry->id = sched_job->base.id;
486486 __entry->fence = fence;
487487 __entry->ctx = fence->context;
488488 __entry->seqno = fence->seqno;
489489 ),
490490 TP_printk("job ring=%s, id=%llu, need pipe sync to fence=%p, context=%llu, seq=%u",
491− __entry->name, __entry->id,
491+ __get_str(ring), __entry->id,
492492 __entry->fence, __entry->ctx,
493493 __entry->seqno)
494494 );
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c+110−9
@@ -1652,6 +1652,88 @@ static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev) · 1651 unmodified lines
16521652 &adev->fw_vram_usage.va);
16531653 }
16541654
1655+/*
1656+ * Memoy training reservation functions
1657+ */
1658+
1659+/**
1660+ * amdgpu_ttm_training_reserve_vram_fini - free memory training reserved vram
1661+ *
1662+ * @adev: amdgpu_device pointer
1663+ *
1664+ * free memory training reserved vram if it has been reserved.
1665+ */
1666+static int amdgpu_ttm_training_reserve_vram_fini(struct amdgpu_device *adev)
1667+{
1668+ struct psp_memory_training_context *ctx = &adev->psp.mem_train_ctx;
1669+
1670+ ctx->init = PSP_MEM_TRAIN_NOT_SUPPORT;
1671+ amdgpu_bo_free_kernel(&ctx->c2p_bo, NULL, NULL);
1672+ ctx->c2p_bo = NULL;
1673+
1674+ amdgpu_bo_free_kernel(&ctx->p2c_bo, NULL, NULL);
1675+ ctx->p2c_bo = NULL;
1676+
1677+ return 0;
1678+}
1679+
1680+/**
1681+ * amdgpu_ttm_training_reserve_vram_init - create bo vram reservation from memory training
1682+ *
1683+ * @adev: amdgpu_device pointer
1684+ *
1685+ * create bo vram reservation from memory training.
1686+ */
1687+static int amdgpu_ttm_training_reserve_vram_init(struct amdgpu_device *adev)
1688+{
1689+ int ret;
1690+ struct psp_memory_training_context *ctx = &adev->psp.mem_train_ctx;
1691+
1692+ memset(ctx, 0, sizeof(*ctx));
1693+ if (!adev->fw_vram_usage.mem_train_support) {
1694+ DRM_DEBUG("memory training does not support!\n");
1695+ return 0;
1696+ }
1697+
1698+ ctx->c2p_train_data_offset = adev->fw_vram_usage.mem_train_fb_loc;
1699+ ctx->p2c_train_data_offset = (adev->gmc.mc_vram_size - GDDR6_MEM_TRAINING_OFFSET);
1700+ ctx->train_data_size = GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES;
1701+
1702+ DRM_DEBUG("train_data_size:%llx,p2c_train_data_offset:%llx,c2p_train_data_offset:%llx.\n",
1703+ ctx->train_data_size,
1704+ ctx->p2c_train_data_offset,
1705+ ctx->c2p_train_data_offset);
1706+
1707+ ret = amdgpu_bo_create_kernel_at(adev,
1708+ ctx->p2c_train_data_offset,
1709+ ctx->train_data_size,
1710+ AMDGPU_GEM_DOMAIN_VRAM,
1711+ &ctx->p2c_bo,
1712+ NULL);
1713+ if (ret) {
1714+ DRM_ERROR("alloc p2c_bo failed(%d)!\n", ret);
1715+ goto Err_out;
1716+ }
1717+
1718+ ret = amdgpu_bo_create_kernel_at(adev,
1719+ ctx->c2p_train_data_offset,
1720+ ctx->train_data_size,
1721+ AMDGPU_GEM_DOMAIN_VRAM,
1722+ &ctx->c2p_bo,
1723+ NULL);
1724+ if (ret) {
1725+ DRM_ERROR("alloc c2p_bo failed(%d)!\n", ret);
1726+ goto Err_out;
1727+ }
1728+
1729+ ctx->init = PSP_MEM_TRAIN_RESERVE_SUCCESS;
1730+ return 0;
1731+
1732+Err_out:
1733+ amdgpu_ttm_training_reserve_vram_fini(adev);
1734+ return ret;
1735+}
1736+
16551737 /**
16561738 * amdgpu_ttm_init - Init the memory management (ttm) as well as various
16571739 * gtt/vram related fields.
@@ -1726,6 +1808,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 68 unmodified lines
17261808 return r;
17271809 }
17281810
1811+ /*
1812+ *The reserved vram for memory training must be pinned to the specified
1813+ *place on the VRAM, so reserve it early.
1814+ */
1815+ r = amdgpu_ttm_training_reserve_vram_init(adev);
1816+ if (r)
1817+ return r;
1818+
17291819 /* allocate memory as required for VGA
17301820 * This is used for VGA emulation and pre-OS scanout buffers to
17311821 * avoid display artifacts while transitioning between pre-OS
@@ -1736,6 +1826,20 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 4 unmodified lines
17361826 NULL, &stolen_vga_buf);
17371827 if (r)
17381828 return r;
1829+
1830+ /*
1831+ * reserve one TMR (64K) memory at the top of VRAM which holds
1832+ * IP Discovery data and is protected by PSP.
1833+ */
1834+ r = amdgpu_bo_create_kernel_at(adev,
1835+ adev->gmc.real_vram_size - DISCOVERY_TMR_SIZE,
1836+ DISCOVERY_TMR_SIZE,
1837+ AMDGPU_GEM_DOMAIN_VRAM,
1838+ &adev->discovery_memory,
1839+ NULL);
1840+ if (r)
1841+ return r;
1842+
17391843 DRM_INFO("amdgpu: %uM of VRAM memory ready\n",
17401844 (unsigned) (adev->gmc.real_vram_size / (1024 * 1024)));
17411845
@@ -1800,6 +1904,9 @@ void amdgpu_ttm_late_init(struct amdgpu_device *adev) · 58 unmodified lines
18001904 void *stolen_vga_buf;
18011905 /* return the VGA stolen memory (if any) back to VRAM */
18021906 amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf);
1907+
1908+ /* return the IP Discovery TMR memory back to VRAM */
1909+ amdgpu_bo_free_kernel(&adev->discovery_memory, NULL, NULL);
18031910 }
18041911
18051912 /**
@@ -1811,6 +1918,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) · 5 unmodified lines
18111918 return;
18121919
18131920 amdgpu_ttm_debugfs_fini(adev);
1921+ amdgpu_ttm_training_reserve_vram_fini(adev);
18141922 amdgpu_ttm_fw_reserve_vram_fini(adev);
18151923 if (adev->mman.aper_base_kaddr)
18161924 iounmap(adev->mman.aper_base_kaddr);
@@ -1907,10 +2015,7 @@ static int amdgpu_map_buffer(struct ttm_buffer_object *bo, · 90 unmodified lines
19072015 *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
19082016 AMDGPU_GPU_PAGE_SIZE;
19092017
1910− num_dw = adev->mman.buffer_funcs->copy_num_dw;
1911− while (num_dw & 0x7)
1912− num_dw++;
1913−
2018+ num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
19142019 num_bytes = num_pages * 8;
19152020
19162021 r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, &job);
@@ -1970,11 +2075,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, · 53 unmodified lines
19702075
19712076 max_bytes = adev->mman.buffer_funcs->copy_max_bytes;
19722077 num_loops = DIV_ROUND_UP(byte_count, max_bytes);
1973− num_dw = num_loops * adev->mman.buffer_funcs->copy_num_dw;
1974−
1975− /* for IB padding */
1976− while (num_dw & 0x7)
1977− num_dw++;
2078+ num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
19782079
19792080 r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job);
19802081 if (r)
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c+24−9
@@ -80,6 +80,11 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12); · 79 unmodified lines
8080 MODULE_FIRMWARE(FIRMWARE_VEGA20);
8181
8282 static void amdgpu_vce_idle_work_handler(struct work_struct *work);
83+static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
84+ struct amdgpu_bo *bo,
85+ struct dma_fence **fence);
86+static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
87+ bool direct, struct dma_fence **fence);
8388
8489 /**
8590 * amdgpu_vce_init - allocate memory, load vce firmware
@@ -428,14 +433,15 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) · 342 unmodified lines
428433 *
429434 * Open up a stream for HW test
430435 */
431−int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
432− struct dma_fence **fence)
436+static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
437+ struct amdgpu_bo *bo,
438+ struct dma_fence **fence)
433439 {
434440 const unsigned ib_size_dw = 1024;
435441 struct amdgpu_job *job;
436442 struct amdgpu_ib *ib;
437443 struct dma_fence *f = NULL;
438− uint64_t dummy;
444+ uint64_t addr;
439445 int i, r;
440446
441447 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
@@ -444,7 +450,7 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, · 2 unmodified lines
444450
445451 ib = &job->ibs[0];
446452
447− dummy = ib->gpu_addr + 1024;
453+ addr = amdgpu_bo_gpu_offset(bo);
448454
449455 /* stitch together an VCE create msg */
450456 ib->length_dw = 0;
@@ -476,8 +482,8 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, · 25 unmodified lines
476482
477483 ib->ptr[ib->length_dw++] = 0x00000014; /* len */
478484 ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */
479− ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
480− ib->ptr[ib->length_dw++] = dummy;
485+ ib->ptr[ib->length_dw++] = upper_32_bits(addr);
486+ ib->ptr[ib->length_dw++] = addr;
481487 ib->ptr[ib->length_dw++] = 0x00000001;
482488
483489 for (i = ib->length_dw; i < ib_size_dw; ++i)
@@ -507,8 +513,8 @@ err: · 23 unmodified lines
507513 *
508514 * Close up a stream for HW test or if userspace failed to do so
509515 */
510−int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
511− bool direct, struct dma_fence **fence)
516+static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
517+ bool direct, struct dma_fence **fence)
512518 {
513519 const unsigned ib_size_dw = 1024;
514520 struct amdgpu_job *job;
@@ -1110,13 +1116,20 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) · 595 unmodified lines
11101116 int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout)
11111117 {
11121118 struct dma_fence *fence = NULL;
1119+ struct amdgpu_bo *bo = NULL;
11131120 long r;
11141121
11151122 /* skip vce ring1/2 ib test for now, since it's not reliable */
11161123 if (ring != &ring->adev->vce.ring[0])
11171124 return 0;
11181125
1119− r = amdgpu_vce_get_create_msg(ring, 1, NULL);
1126+ r = amdgpu_bo_create_reserved(ring->adev, 512, PAGE_SIZE,
1127+ AMDGPU_GEM_DOMAIN_VRAM,
1128+ &bo, NULL, NULL);
1129+ if (r)
1130+ return r;
1131+
1132+ r = amdgpu_vce_get_create_msg(ring, 1, bo, NULL);
11201133 if (r)
11211134 goto error;
11221135
@@ -1132,5 +1145,7 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 9 unmodified lines
11321145
11331146 error:
11341147 dma_fence_put(fence);
1148+ amdgpu_bo_unreserve(bo);
1149+ amdgpu_bo_unref(&bo);
11351150 return r;
11361151 }
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h+0−4
@@ -58,10 +58,6 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev); · 57 unmodified lines
5858 int amdgpu_vce_entity_init(struct amdgpu_device *adev);
5959 int amdgpu_vce_suspend(struct amdgpu_device *adev);
6060 int amdgpu_vce_resume(struct amdgpu_device *adev);
61−int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
62− struct dma_fence **fence);
63−int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
64− bool direct, struct dma_fence **fence);
6561 void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
6662 int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx);
6763 int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx);
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c+23−12
@@ -569,13 +569,14 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) · 568 unmodified lines
569569 }
570570
571571 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
572− struct dma_fence **fence)
572+ struct amdgpu_bo *bo,
573+ struct dma_fence **fence)
573574 {
574575 const unsigned ib_size_dw = 16;
575576 struct amdgpu_job *job;
576577 struct amdgpu_ib *ib;
577578 struct dma_fence *f = NULL;
578− uint64_t dummy;
579+ uint64_t addr;
579580 int i, r;
580581
581582 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
@@ -583,14 +584,14 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand · 1 unmodified line
583584 return r;
584585
585586 ib = &job->ibs[0];
586− dummy = ib->gpu_addr + 1024;
587+ addr = amdgpu_bo_gpu_offset(bo);
587588
588589 ib->length_dw = 0;
589590 ib->ptr[ib->length_dw++] = 0x00000018;
590591 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
591592 ib->ptr[ib->length_dw++] = handle;
592− ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
593− ib->ptr[ib->length_dw++] = dummy;
593+ ib->ptr[ib->length_dw++] = upper_32_bits(addr);
594+ ib->ptr[ib->length_dw++] = addr;
594595 ib->ptr[ib->length_dw++] = 0x0000000b;
595596
596597 ib->ptr[ib->length_dw++] = 0x00000014;
@@ -621,13 +622,14 @@ err: · 24 unmodified lines
621622 }
622623
623624 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
624− struct dma_fence **fence)
625+ struct amdgpu_bo *bo,
626+ struct dma_fence **fence)
625627 {
626628 const unsigned ib_size_dw = 16;
627629 struct amdgpu_job *job;
628630 struct amdgpu_ib *ib;
629631 struct dma_fence *f = NULL;
630− uint64_t dummy;
632+ uint64_t addr;
631633 int i, r;
632634
633635 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
@@ -635,14 +637,14 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han · 1 unmodified line
635637 return r;
636638
637639 ib = &job->ibs[0];
638− dummy = ib->gpu_addr + 1024;
640+ addr = amdgpu_bo_gpu_offset(bo);
639641
640642 ib->length_dw = 0;
641643 ib->ptr[ib->length_dw++] = 0x00000018;
642644 ib->ptr[ib->length_dw++] = 0x00000001;
643645 ib->ptr[ib->length_dw++] = handle;
644− ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
645− ib->ptr[ib->length_dw++] = dummy;
646+ ib->ptr[ib->length_dw++] = upper_32_bits(addr);
647+ ib->ptr[ib->length_dw++] = addr;
646648 ib->ptr[ib->length_dw++] = 0x0000000b;
647649
648650 ib->ptr[ib->length_dw++] = 0x00000014;
@@ -675,13 +677,20 @@ err: · 26 unmodified lines
675677 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
676678 {
677679 struct dma_fence *fence = NULL;
680+ struct amdgpu_bo *bo = NULL;
678681 long r;
679682
680− r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL);
683+ r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,
684+ AMDGPU_GEM_DOMAIN_VRAM,
685+ &bo, NULL, NULL);
686+ if (r)
687+ return r;
688+
689+ r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL);
681690 if (r)
682691 goto error;
683692
684− r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence);
693+ r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence);
685694 if (r)
686695 goto error;
687696
@@ -693,6 +702,8 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 5 unmodified lines
693702
694703 error:
695704 dma_fence_put(fence);
705+ amdgpu_bo_unreserve(bo);
706+ amdgpu_bo_unref(&bo);
696707 return r;
697708 }
698709
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c+10−9
@@ -2971,6 +2971,16 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) · 2970 unmodified lines
29712971 vm->pasid = 0;
29722972 }
29732973
2974+ list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
2975+ if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) {
2976+ amdgpu_vm_prt_fini(adev, vm);
2977+ prt_fini_needed = false;
2978+ }
2979+
2980+ list_del(&mapping->list);
2981+ amdgpu_vm_free_mapping(adev, vm, mapping, NULL);
2982+ }
2983+
29742984 amdgpu_vm_free_pts(adev, vm, NULL);
29752985 amdgpu_bo_unreserve(root);
29762986 amdgpu_bo_unref(&root);
@@ -2990,15 +3000,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) · 13 unmodified lines
29903000 list_del(&mapping->list);
29913001 kfree(mapping);
29923002 }
2993− list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
2994− if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) {
2995− amdgpu_vm_prt_fini(adev, vm);
2996− prt_fini_needed = false;
2997− }
2998−
2999− list_del(&mapping->list);
3000− amdgpu_vm_free_mapping(adev, vm, mapping, NULL);
3001− }
30023003
30033004 dma_fence_put(vm->last_update);
30043005 for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
drivers/gpu/drm/amd/amdgpu/cik.c+43−5
@@ -1270,15 +1270,15 @@ static int cik_gpu_pci_config_reset(struct amdgpu_device *adev) · 1269 unmodified lines
12701270 }
12711271
12721272 /**
1273− * cik_asic_reset - soft reset GPU
1273+ * cik_asic_pci_config_reset - soft reset GPU
12741274 *
12751275 * @adev: amdgpu_device pointer
12761276 *
1277− * Look up which blocks are hung and attempt
1278− * to reset them.
1277+ * Use PCI Config method to reset the GPU.
1278+ *
12791279 * Returns 0 for success.
12801280 */
1281−static int cik_asic_reset(struct amdgpu_device *adev)
1281+static int cik_asic_pci_config_reset(struct amdgpu_device *adev)
12821282 {
12831283 int r;
12841284
@@ -1294,7 +1294,45 @@ static int cik_asic_reset(struct amdgpu_device *adev) · 9 unmodified lines
12941294 static enum amd_reset_method
12951295 cik_asic_reset_method(struct amdgpu_device *adev)
12961296 {
1297− return AMD_RESET_METHOD_LEGACY;
1297+ bool baco_reset;
1298+
1299+ switch (adev->asic_type) {
1300+ case CHIP_BONAIRE:
1301+ case CHIP_HAWAII:
1302+ /* disable baco reset until it works */
1303+ /* smu7_asic_get_baco_capability(adev, &baco_reset); */
1304+ baco_reset = false;
1305+ break;
1306+ default:
1307+ baco_reset = false;
1308+ break;
1309+ }
1310+
1311+ if (baco_reset)
1312+ return AMD_RESET_METHOD_BACO;
1313+ else
1314+ return AMD_RESET_METHOD_LEGACY;
1315+}
1316+
1317+/**
1318+ * cik_asic_reset - soft reset GPU
1319+ *
1320+ * @adev: amdgpu_device pointer
1321+ *
1322+ * Look up which blocks are hung and attempt
1323+ * to reset them.
1324+ * Returns 0 for success.
1325+ */
1326+static int cik_asic_reset(struct amdgpu_device *adev)
1327+{
1328+ int r;
1329+
1330+ if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)
1331+ r = smu7_asic_baco_reset(adev);
1332+ else
1333+ r = cik_asic_pci_config_reset(adev);
1334+
1335+ return r;
12981336 }
12991337
13001338 static u32 cik_get_config_memsize(struct amdgpu_device *adev)
drivers/gpu/drm/amd/amdgpu/cik.h+3−0
@@ -31,4 +31,7 @@ void cik_srbm_select(struct amdgpu_device *adev, · 30 unmodified lines
3131 int cik_set_ip_blocks(struct amdgpu_device *adev);
3232
3333 void legacy_doorbell_index_init(struct amdgpu_device *adev);
34+int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap);
35+int smu7_asic_baco_reset(struct amdgpu_device *adev);
36+
3437 #endif
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c+5−8
@@ -5283,15 +5283,12 @@ static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev) · 5282 unmodified lines
52835283
52845284 static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev)
52855285 {
5286− /* init asic gds info */
5287− switch (adev->asic_type) {
5288− case CHIP_NAVI10:
5289− default:
5290− adev->gds.gds_size = 0x10000;
5291− adev->gds.gds_compute_max_wave_id = 0x4ff;
5292− break;
5293− }
5286+ unsigned total_cu = adev->gfx.config.max_cu_per_sh *
5287+ adev->gfx.config.max_sh_per_se *
5288+ adev->gfx.config.max_shader_engines;
52945289
5290+ adev->gds.gds_size = 0x10000;
5291+ adev->gds.gds_compute_max_wave_id = total_cu * 32 - 1;
52955292 adev->gds.gws_size = 64;
52965293 adev->gds.oa_size = 16;
52975294 }
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c+665−331
@@ -131,6 +131,18 @@ MODULE_FIRMWARE("amdgpu/renoir_rlc.bin"); · 130 unmodified lines
131131 #define mmTCP_CHAN_STEER_5_ARCT 0x0b0c
132132 #define mmTCP_CHAN_STEER_5_ARCT_BASE_IDX 0
133133
134+struct ras_gfx_subblock_reg {
135+ const char *name;
136+ uint32_t hwip;
137+ uint32_t inst;
138+ uint32_t seg;
139+ uint32_t reg_offset;
140+ uint32_t sec_count_mask;
141+ uint32_t sec_count_shift;
142+ uint32_t ded_count_mask;
143+ uint32_t ded_count_shift;
144+};
145+
134146 enum ta_ras_gfx_subblock {
135147 /*CPC*/
136148 TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0,
@@ -3978,6 +3990,7 @@ static const struct soc15_reg_entry sec_ded_counter_registers[] = { · 3841 unmodified lines
39783990 { SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 1, 16},
39793991 { SOC15_REG_ENTRY(GC, 0, mmTCP_ATC_EDC_GATCL1_CNT), 0, 4, 16},
39803992 { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT), 0, 4, 16},
3993+ { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 0, 4, 16},
39813994 { SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 0, 4, 16},
39823995 { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 0, 4, 6},
39833996 { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 0, 4, 16},
@@ -4274,16 +4287,14 @@ static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev, · 290 unmodified lines
42744287 {
42754288 amdgpu_gfx_rlc_enter_safe_mode(adev);
42764289
4277− if (is_support_sw_smu(adev) && !enable)
4278− smu_set_gfx_cgpg(&adev->smu, enable);
4279−
42804290 if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) {
42814291 gfx_v9_0_enable_gfx_cg_power_gating(adev, true);
42824292 if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE)
42834293 gfx_v9_0_enable_gfx_pipeline_powergating(adev, true);
42844294 } else {
42854295 gfx_v9_0_enable_gfx_cg_power_gating(adev, false);
4286− gfx_v9_0_enable_gfx_pipeline_powergating(adev, false);
4296+ if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE)
4297+ gfx_v9_0_enable_gfx_pipeline_powergating(adev, false);
42874298 }
42884299
42894300 amdgpu_gfx_rlc_exit_safe_mode(adev);
@@ -4552,8 +4563,6 @@ static int gfx_v9_0_set_powergating_state(void *handle, · 262 unmodified lines
45524563 gfx_v9_0_enable_cp_power_gating(adev, false);
45534564
45544565 /* update gfx cgpg state */
4555− if (is_support_sw_smu(adev) && enable)
4556− smu_set_gfx_cgpg(&adev->smu, enable);
45574566 gfx_v9_0_update_gfx_cg_power_gating(adev, enable);
45584567
45594568 /* update mgcg state */
@@ -5437,301 +5446,446 @@ static int gfx_v9_0_priv_inst_irq(struct amdgpu_device *adev, · 877 unmodified lines
54375446 return 0;
54385447 }
54395448
5440−static const struct {
5441− const char *name;
5442− uint32_t ip;
5443− uint32_t inst;
5444− uint32_t seg;
5445− uint32_t reg_offset;
5446− uint32_t per_se_instance;
5447− int32_t num_instance;
5448− uint32_t sec_count_mask;
5449− uint32_t ded_count_mask;
5450−} gfx_ras_edc_regs[] = {
5451− { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), 0, 1,
5452− REG_FIELD_MASK(CPC_EDC_SCRATCH_CNT, SEC_COUNT),
5453− REG_FIELD_MASK(CPC_EDC_SCRATCH_CNT, DED_COUNT) },
5454− { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), 0, 1,
5455− REG_FIELD_MASK(CPC_EDC_UCODE_CNT, SEC_COUNT),
5456− REG_FIELD_MASK(CPC_EDC_UCODE_CNT, DED_COUNT) },
5457− { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1,
5458− REG_FIELD_MASK(CPF_EDC_ROQ_CNT, COUNT_ME1), 0 },
5459− { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1,
5460− REG_FIELD_MASK(CPF_EDC_ROQ_CNT, COUNT_ME2), 0 },
5461− { "CPF_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT), 0, 1,
5462− REG_FIELD_MASK(CPF_EDC_TAG_CNT, SEC_COUNT),
5463− REG_FIELD_MASK(CPF_EDC_TAG_CNT, DED_COUNT) },
5464− { "CPG_DMA_ROQ", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 0, 1,
5465− REG_FIELD_MASK(CPG_EDC_DMA_CNT, ROQ_COUNT), 0 },
5466− { "CPG_DMA_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 0, 1,
5467− REG_FIELD_MASK(CPG_EDC_DMA_CNT, TAG_SEC_COUNT),
5468− REG_FIELD_MASK(CPG_EDC_DMA_CNT, TAG_DED_COUNT) },
5469− { "CPG_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_TAG_CNT), 0, 1,
5470− REG_FIELD_MASK(CPG_EDC_TAG_CNT, SEC_COUNT),
5471− REG_FIELD_MASK(CPG_EDC_TAG_CNT, DED_COUNT) },
5472− { "DC_CSINVOC", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT), 0, 1,
5473− REG_FIELD_MASK(DC_EDC_CSINVOC_CNT, COUNT_ME1), 0 },
5474− { "DC_RESTORE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT), 0, 1,
5475− REG_FIELD_MASK(DC_EDC_RESTORE_CNT, COUNT_ME1), 0 },
5476− { "DC_STATE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT), 0, 1,
5477− REG_FIELD_MASK(DC_EDC_STATE_CNT, COUNT_ME1), 0 },
5478− { "GDS_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1,
5479− REG_FIELD_MASK(GDS_EDC_CNT, GDS_MEM_SEC),
5480− REG_FIELD_MASK(GDS_EDC_CNT, GDS_MEM_DED) },
5481− { "GDS_INPUT_QUEUE", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1,
5482− REG_FIELD_MASK(GDS_EDC_CNT, GDS_INPUT_QUEUE_SED), 0 },
5449+
5450+static const struct ras_gfx_subblock_reg ras_subblock_regs[] = {
5451+ { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT),
5452+ SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, SEC_COUNT),
5453+ SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, DED_COUNT)
5454+ },
5455+ { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT),
5456+ SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, SEC_COUNT),
5457+ SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, DED_COUNT)
5458+ },
5459+ { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT),
5460+ SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, COUNT_ME1),
5461+ 0, 0
5462+ },
5463+ { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT),
5464+ SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, COUNT_ME2),
5465+ 0, 0
5466+ },
5467+ { "CPF_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT),
5468+ SOC15_REG_FIELD(CPF_EDC_TAG_CNT, SEC_COUNT),
5469+ SOC15_REG_FIELD(CPF_EDC_TAG_CNT, DED_COUNT)
5470+ },
5471+ { "CPG_DMA_ROQ", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT),
5472+ SOC15_REG_FIELD(CPG_EDC_DMA_CNT, ROQ_COUNT),
5473+ 0, 0
5474+ },
5475+ { "CPG_DMA_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT),
5476+ SOC15_REG_FIELD(CPG_EDC_DMA_CNT, TAG_SEC_COUNT),
5477+ SOC15_REG_FIELD(CPG_EDC_DMA_CNT, TAG_DED_COUNT)
5478+ },
5479+ { "CPG_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_TAG_CNT),
5480+ SOC15_REG_FIELD(CPG_EDC_TAG_CNT, SEC_COUNT),
5481+ SOC15_REG_FIELD(CPG_EDC_TAG_CNT, DED_COUNT)
5482+ },
5483+ { "DC_CSINVOC", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT),
5484+ SOC15_REG_FIELD(DC_EDC_CSINVOC_CNT, COUNT_ME1),
5485+ 0, 0
5486+ },
5487+ { "DC_RESTORE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT),
5488+ SOC15_REG_FIELD(DC_EDC_RESTORE_CNT, COUNT_ME1),
5489+ 0, 0
5490+ },
5491+ { "DC_STATE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT),
5492+ SOC15_REG_FIELD(DC_EDC_STATE_CNT, COUNT_ME1),
5493+ 0, 0
5494+ },
5495+ { "GDS_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT),
5496+ SOC15_REG_FIELD(GDS_EDC_CNT, GDS_MEM_SEC),
5497+ SOC15_REG_FIELD(GDS_EDC_CNT, GDS_MEM_DED)
5498+ },
5499+ { "GDS_INPUT_QUEUE", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT),
5500+ SOC15_REG_FIELD(GDS_EDC_CNT, GDS_INPUT_QUEUE_SED),
5501+ 0, 0
5502+ },
54835503 { "GDS_ME0_CS_PIPE_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT),
5484− 0, 1, REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_SEC),
5485− REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED) },
5504+ SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_SEC),
5505+ SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED)
5506+ },
54865507 { "GDS_OA_PHY_PHY_CMD_RAM_MEM",
5487− SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1,
5488− REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC),
5489− REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED) },
5508+ SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT),
5509+ SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC),
5510+ SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED)
5511+ },
54905512 { "GDS_OA_PHY_PHY_DATA_RAM_MEM",
5491− SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1,
5492− REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SED), 0 },
5513+ SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT),
5514+ SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SED),
5515+ 0, 0
5516+ },
54935517 { "GDS_OA_PIPE_ME1_PIPE0_PIPE_MEM",
5494− SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1,
5495− REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC),
5496− REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED) },
5518+ SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT),
5519+ SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC),
5520+ SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED)
5521+ },
54975522 { "GDS_OA_PIPE_ME1_PIPE1_PIPE_MEM",
5498− SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1,
5499− REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC),
5500− REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED) },
5523+ SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT),
5524+ SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC),
5525+ SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED)
5526+ },
55015527 { "GDS_OA_PIPE_ME1_PIPE2_PIPE_MEM",
5502− SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1,
5503− REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC),
5504− REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED) },
5528+ SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT),
5529+ SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC),
5530+ SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED)
5531+ },
55055532 { "GDS_OA_PIPE_ME1_PIPE3_PIPE_MEM",
5506− SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1,
5507− REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC),
5508− REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED) },
5509− { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), 1, 1,
5510− REG_FIELD_MASK(SPI_EDC_CNT, SPI_SR_MEM_SED_COUNT), 0 },
5511− { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16,
5512− REG_FIELD_MASK(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT),
5513− REG_FIELD_MASK(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT) },
5514− { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16,
5515− REG_FIELD_MASK(TA_EDC_CNT, TA_FS_AFIFO_SED_COUNT), 0 },
5516− { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16,
5517− REG_FIELD_MASK(TA_EDC_CNT, TA_FL_LFIFO_SED_COUNT), 0 },
5518− { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16,
5519− REG_FIELD_MASK(TA_EDC_CNT, TA_FX_LFIFO_SED_COUNT), 0 },
5520− { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16,
5521− REG_FIELD_MASK(TA_EDC_CNT, TA_FS_CFIFO_SED_COUNT), 0 },
5522− { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 2,
5523− REG_FIELD_MASK(TCA_EDC_CNT, HOLE_FIFO_SED_COUNT), 0 },
5524− { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 2,
5525− REG_FIELD_MASK(TCA_EDC_CNT, REQ_FIFO_SED_COUNT), 0 },
5526− { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5527− REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT),
5528− REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DATA_DED_COUNT) },
5529− { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5530− REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT),
5531− REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT) },
5532− { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5533− REG_FIELD_MASK(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT),
5534− REG_FIELD_MASK(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT) },
5535− { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5536− REG_FIELD_MASK(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT),
5537− REG_FIELD_MASK(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT) },
5538− { "TCC_SRC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5539− REG_FIELD_MASK(TCC_EDC_CNT, SRC_FIFO_SEC_COUNT),
5540− REG_FIELD_MASK(TCC_EDC_CNT, SRC_FIFO_DED_COUNT) },
5541− { "TCC_IN_USE_DEC", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5542− REG_FIELD_MASK(TCC_EDC_CNT, IN_USE_DEC_SED_COUNT), 0 },
5543− { "TCC_IN_USE_TRANSFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5544− REG_FIELD_MASK(TCC_EDC_CNT, IN_USE_TRANSFER_SED_COUNT), 0 },
5545− { "TCC_LATENCY_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5546− REG_FIELD_MASK(TCC_EDC_CNT, LATENCY_FIFO_SED_COUNT), 0 },
5547− { "TCC_RETURN_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5548− REG_FIELD_MASK(TCC_EDC_CNT, RETURN_DATA_SED_COUNT), 0 },
5549− { "TCC_RETURN_CONTROL", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5550− REG_FIELD_MASK(TCC_EDC_CNT, RETURN_CONTROL_SED_COUNT), 0 },
5551− { "TCC_UC_ATOMIC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16,
5552− REG_FIELD_MASK(TCC_EDC_CNT, UC_ATOMIC_FIFO_SED_COUNT), 0 },
5553− { "TCC_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 16,
5554− REG_FIELD_MASK(TCC_EDC_CNT2, WRITE_RETURN_SED_COUNT), 0 },
5555− { "TCC_WRITE_CACHE_READ", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 16,
5556− REG_FIELD_MASK(TCC_EDC_CNT2, WRITE_CACHE_READ_SED_COUNT), 0 },
5557− { "TCC_SRC_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0,
5558− 16, REG_FIELD_MASK(TCC_EDC_CNT2, SRC_FIFO_NEXT_RAM_SED_COUNT), 0 },
5533+ SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT),
5534+ SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC),
5535+ SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED)
5536+ },
5537+ { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT),
5538+ SOC15_REG_FIELD(SPI_EDC_CNT, SPI_SR_MEM_SED_COUNT),
5539+ 0, 0
5540+ },
5541+ { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
5542+ SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT),
5543+ SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT)
5544+ },
5545+ { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
5546+ SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_AFIFO_SED_COUNT),
5547+ 0, 0
5548+ },
5549+ { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
5550+ SOC15_REG_FIELD(TA_EDC_CNT, TA_FL_LFIFO_SED_COUNT),
5551+ 0, 0
5552+ },
5553+ { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
5554+ SOC15_REG_FIELD(TA_EDC_CNT, TA_FX_LFIFO_SED_COUNT),
5555+ 0, 0
5556+ },
5557+ { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
5558+ SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_CFIFO_SED_COUNT),
5559+ 0, 0
5560+ },
5561+ { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT),
5562+ SOC15_REG_FIELD(TCA_EDC_CNT, HOLE_FIFO_SED_COUNT),
5563+ 0, 0
5564+ },
5565+ { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT),
5566+ SOC15_REG_FIELD(TCA_EDC_CNT, REQ_FIFO_SED_COUNT),
5567+ 0, 0
5568+ },
5569+ { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5570+ SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT),
5571+ SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_DED_COUNT)
5572+ },
5573+ { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5574+ SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT),
5575+ SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT)
5576+ },
5577+ { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5578+ SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT),
5579+ SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT)
5580+ },
5581+ { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5582+ SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT),
5583+ SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT)
5584+ },
5585+ { "TCC_SRC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5586+ SOC15_REG_FIELD(TCC_EDC_CNT, SRC_FIFO_SEC_COUNT),
5587+ SOC15_REG_FIELD(TCC_EDC_CNT, SRC_FIFO_DED_COUNT)
5588+ },
5589+ { "TCC_IN_USE_DEC", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5590+ SOC15_REG_FIELD(TCC_EDC_CNT, IN_USE_DEC_SED_COUNT),
5591+ 0, 0
5592+ },
5593+ { "TCC_IN_USE_TRANSFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5594+ SOC15_REG_FIELD(TCC_EDC_CNT, IN_USE_TRANSFER_SED_COUNT),
5595+ 0, 0
5596+ },
5597+ { "TCC_LATENCY_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5598+ SOC15_REG_FIELD(TCC_EDC_CNT, LATENCY_FIFO_SED_COUNT),
5599+ 0, 0
5600+ },
5601+ { "TCC_RETURN_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5602+ SOC15_REG_FIELD(TCC_EDC_CNT, RETURN_DATA_SED_COUNT),
5603+ 0, 0
5604+ },
5605+ { "TCC_RETURN_CONTROL", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5606+ SOC15_REG_FIELD(TCC_EDC_CNT, RETURN_CONTROL_SED_COUNT),
5607+ 0, 0
5608+ },
5609+ { "TCC_UC_ATOMIC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
5610+ SOC15_REG_FIELD(TCC_EDC_CNT, UC_ATOMIC_FIFO_SED_COUNT),
5611+ 0, 0
5612+ },
5613+ { "TCC_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
5614+ SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_RETURN_SED_COUNT),
5615+ 0, 0
5616+ },
5617+ { "TCC_WRITE_CACHE_READ", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
5618+ SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_CACHE_READ_SED_COUNT),
5619+ 0, 0
5620+ },
5621+ { "TCC_SRC_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
5622+ SOC15_REG_FIELD(TCC_EDC_CNT2, SRC_FIFO_NEXT_RAM_SED_COUNT),
5623+ 0, 0
5624+ },
55595625 { "TCC_LATENCY_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
5560− 0, 16, REG_FIELD_MASK(TCC_EDC_CNT2, LATENCY_FIFO_NEXT_RAM_SED_COUNT),
5561− 0 },
5562− { "TCC_CACHE_TAG_PROBE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0,
5563− 16, REG_FIELD_MASK(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_SED_COUNT), 0 },
5626+ SOC15_REG_FIELD(TCC_EDC_CNT2, LATENCY_FIFO_NEXT_RAM_SED_COUNT),
5627+ 0, 0
5628+ },
5629+ { "TCC_CACHE_TAG_PROBE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
5630+ SOC15_REG_FIELD(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_SED_COUNT),
5631+ 0, 0
5632+ },
55645633 { "TCC_WRRET_TAG_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
5565− 0, 16, REG_FIELD_MASK(TCC_EDC_CNT2, WRRET_TAG_WRITE_RETURN_SED_COUNT),
5566− 0 },
5567− { "TCC_ATOMIC_RETURN_BUFFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0,
5568− 16, REG_FIELD_MASK(TCC_EDC_CNT2, ATOMIC_RETURN_BUFFER_SED_COUNT), 0 },
5569− { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT), 0, 72,
5570− REG_FIELD_MASK(TCI_EDC_CNT, WRITE_RAM_SED_COUNT), 0 },
5571− { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16,
5572− REG_FIELD_MASK(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT),
5573− REG_FIELD_MASK(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT) },
5574− { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16,
5575− REG_FIELD_MASK(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT),
5576− REG_FIELD_MASK(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT) },
5577− { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16,
5578− REG_FIELD_MASK(TCP_EDC_CNT_NEW, CMD_FIFO_SED_COUNT), 0 },
5579− { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16,
5580− REG_FIELD_MASK(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT), 0 },
5581− { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16,
5582− REG_FIELD_MASK(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT), 0 },
5583− { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16,
5584− REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT),
5585− REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT) },
5586− { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16,
5587− REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT),
5588− REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT) },
5589− { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16,
5590− REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT),
5591− REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT) },
5592− { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16,
5593− REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT),
5594− REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT) },
5595− { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16,
5596− REG_FIELD_MASK(TD_EDC_CNT, CS_FIFO_SED_COUNT), 0 },
5597− { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16,
5598− REG_FIELD_MASK(SQ_EDC_CNT, LDS_D_SEC_COUNT),
5599− REG_FIELD_MASK(SQ_EDC_CNT, LDS_D_DED_COUNT) },
5600− { "SQ_LDS_I", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16,
5601− REG_FIELD_MASK(SQ_EDC_CNT, LDS_I_SEC_COUNT),
5602− REG_FIELD_MASK(SQ_EDC_CNT, LDS_I_DED_COUNT) },
5603− { "SQ_SGPR", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16,
5604− REG_FIELD_MASK(SQ_EDC_CNT, SGPR_SEC_COUNT),
5605− REG_FIELD_MASK(SQ_EDC_CNT, SGPR_DED_COUNT) },
5606− { "SQ_VGPR0", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16,
5607− REG_FIELD_MASK(SQ_EDC_CNT, VGPR0_SEC_COUNT),
5608− REG_FIELD_MASK(SQ_EDC_CNT, VGPR0_DED_COUNT) },
5609− { "SQ_VGPR1", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16,
5610− REG_FIELD_MASK(SQ_EDC_CNT, VGPR1_SEC_COUNT),
5611− REG_FIELD_MASK(SQ_EDC_CNT, VGPR1_DED_COUNT) },
5612− { "SQ_VGPR2", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16,
5613− REG_FIELD_MASK(SQ_EDC_CNT, VGPR2_SEC_COUNT),
5614− REG_FIELD_MASK(SQ_EDC_CNT, VGPR2_DED_COUNT) },
5615− { "SQ_VGPR3", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16,
5616− REG_FIELD_MASK(SQ_EDC_CNT, VGPR3_SEC_COUNT),
5617− REG_FIELD_MASK(SQ_EDC_CNT, VGPR3_DED_COUNT) },
5634+ SOC15_REG_FIELD(TCC_EDC_CNT2, WRRET_TAG_WRITE_RETURN_SED_COUNT),
5635+ 0, 0
5636+ },
5637+ { "TCC_ATOMIC_RETURN_BUFFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
5638+ SOC15_REG_FIELD(TCC_EDC_CNT2, ATOMIC_RETURN_BUFFER_SED_COUNT),
5639+ 0, 0
5640+ },
5641+ { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT),
5642+ SOC15_REG_FIELD(TCI_EDC_CNT, WRITE_RAM_SED_COUNT),
5643+ 0, 0
5644+ },
5645+ { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
5646+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT),
5647+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT)
5648+ },
5649+ { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
5650+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT),
5651+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT)
5652+ },
5653+ { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
5654+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CMD_FIFO_SED_COUNT),
5655+ 0, 0
5656+ },
5657+ { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
5658+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT),
5659+ 0, 0
5660+ },
5661+ { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
5662+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT),
5663+ 0, 0
5664+ },
5665+ { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
5666+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT),
5667+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT)
5668+ },
5669+ { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
5670+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT),
5671+ SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT)
5672+ },
5673+ { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT),
5674+ SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT),
5675+ SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT)
5676+ },
5677+ { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT),
5678+ SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT),
5679+ SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT)
5680+ },
5681+ { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT),
5682+ SOC15_REG_FIELD(TD_EDC_CNT, CS_FIFO_SED_COUNT),
5683+ 0, 0
5684+ },
5685+ { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
5686+ SOC15_REG_FIELD(SQ_EDC_CNT, LDS_D_SEC_COUNT),
5687+ SOC15_REG_FIELD(SQ_EDC_CNT, LDS_D_DED_COUNT)
5688+ },
5689+ { "SQ_LDS_I", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
5690+ SOC15_REG_FIELD(SQ_EDC_CNT, LDS_I_SEC_COUNT),
5691+ SOC15_REG_FIELD(SQ_EDC_CNT, LDS_I_DED_COUNT)
5692+ },
5693+ { "SQ_SGPR", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
5694+ SOC15_REG_FIELD(SQ_EDC_CNT, SGPR_SEC_COUNT),
5695+ SOC15_REG_FIELD(SQ_EDC_CNT, SGPR_DED_COUNT)
5696+ },
5697+ { "SQ_VGPR0", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
5698+ SOC15_REG_FIELD(SQ_EDC_CNT, VGPR0_SEC_COUNT),
5699+ SOC15_REG_FIELD(SQ_EDC_CNT, VGPR0_DED_COUNT)
5700+ },
5701+ { "SQ_VGPR1", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
5702+ SOC15_REG_FIELD(SQ_EDC_CNT, VGPR1_SEC_COUNT),
5703+ SOC15_REG_FIELD(SQ_EDC_CNT, VGPR1_DED_COUNT)
5704+ },
5705+ { "SQ_VGPR2", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
5706+ SOC15_REG_FIELD(SQ_EDC_CNT, VGPR2_SEC_COUNT),
5707+ SOC15_REG_FIELD(SQ_EDC_CNT, VGPR2_DED_COUNT)
5708+ },
5709+ { "SQ_VGPR3", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
5710+ SOC15_REG_FIELD(SQ_EDC_CNT, VGPR3_SEC_COUNT),
5711+ SOC15_REG_FIELD(SQ_EDC_CNT, VGPR3_DED_COUNT)
5712+ },
56185713 { "SQC_DATA_CU0_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
5619− 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_SEC_COUNT),
5620− REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_DED_COUNT) },
5621− { "SQC_DATA_CU0_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1,
5622− 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_SEC_COUNT),
5623− REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_DED_COUNT) },
5714+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_SEC_COUNT),
5715+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_DED_COUNT)
5716+ },
5717+ { "SQC_DATA_CU0_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
5718+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_SEC_COUNT),
5719+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_DED_COUNT)
5720+ },
56245721 { "SQC_DATA_CU1_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
5625− 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_SEC_COUNT),
5626− REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_DED_COUNT) },
5627− { "SQC_DATA_CU1_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1,
5628− 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_SEC_COUNT),
5629− REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_DED_COUNT) },
5722+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_SEC_COUNT),
5723+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_DED_COUNT)
5724+ },
5725+ { "SQC_DATA_CU1_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
5726+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_SEC_COUNT),
5727+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_DED_COUNT)
5728+ },
56305729 { "SQC_DATA_CU2_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
5631− 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_SEC_COUNT),
5632− REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_DED_COUNT) },
5633− { "SQC_DATA_CU2_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1,
5634− 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT),
5635− REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT) },
5636− { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1,
5637− 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT),
5638− REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT) },
5639− { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1,
5640− 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT),
5641− REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT) },
5642− { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1,
5643− 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT),
5644− REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT) },
5645− { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1,
5646− 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT),
5647− REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT) },
5648− { "SQC_INST_BANKA_UTCL1_MISS_FIFO",
5649− SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6,
5650− REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_UTCL1_MISS_FIFO_SED_COUNT),
5651− 0 },
5652− { "SQC_INST_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1,
5653− 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_MISS_FIFO_SED_COUNT), 0 },
5654− { "SQC_DATA_BANKA_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1,
5655− 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_HIT_FIFO_SED_COUNT), 0 },
5656− { "SQC_DATA_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1,
5657− 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_MISS_FIFO_SED_COUNT), 0 },
5658− { "SQC_DATA_BANKA_DIRTY_BIT_RAM",
5659− SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6,
5660− REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_DIRTY_BIT_RAM_SED_COUNT), 0 },
5661− { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6,
5662− REG_FIELD_MASK(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT),
5663− REG_FIELD_MASK(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT) },
5664− { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1,
5665− 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT),
5666− REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT) },
5667− { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1,
5668− 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT),
5669− REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT) },
5670− { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1,
5671− 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT),
5672− REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT) },
5673− { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1,
5674− 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT),
5675− REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT) },
5676− { "SQC_INST_BANKB_UTCL1_MISS_FIFO",
5677− SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 6,
5678− REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_UTCL1_MISS_FIFO_SED_COUNT),
5679− 0 },
5680− { "SQC_INST_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1,
5681− 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_MISS_FIFO_SED_COUNT), 0 },
5682− { "SQC_DATA_BANKB_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1,
5683− 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_HIT_FIFO_SED_COUNT), 0 },
5684− { "SQC_DATA_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1,
5685− 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_MISS_FIFO_SED_COUNT), 0 },
5686− { "SQC_DATA_BANKB_DIRTY_BIT_RAM",
5687− SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 6,
5688− REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_DIRTY_BIT_RAM_SED_COUNT), 0 },
5689− { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5690− REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
5691− REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT) },
5692− { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5693− REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
5694− REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT) },
5695− { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5696− REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
5697− REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT) },
5698− { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5699− REG_FIELD_MASK(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
5700− REG_FIELD_MASK(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT) },
5701− { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5702− REG_FIELD_MASK(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
5703− REG_FIELD_MASK(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT) },
5704− { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5705− REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT), 0 },
5706− { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5707− REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT), 0 },
5708− { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5709− REG_FIELD_MASK(GCEA_EDC_CNT, IORD_CMDMEM_SED_COUNT), 0 },
5710− { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5711− REG_FIELD_MASK(GCEA_EDC_CNT, IOWR_CMDMEM_SED_COUNT), 0 },
5712− { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32,
5713− REG_FIELD_MASK(GCEA_EDC_CNT, IOWR_DATAMEM_SED_COUNT), 0 },
5714− { "GMIRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5715− REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
5716− REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT) },
5717− { "GMIWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5718− REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
5719− REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT) },
5720− { "GMIWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5721− REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
5722− REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT) },
5723− { "GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5724− REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT), 0 },
5725− { "GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5726− REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT), 0 },
5727− { "MAM_D0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5728− REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D0MEM_SED_COUNT), 0 },
5729− { "MAM_D1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5730− REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D1MEM_SED_COUNT), 0 },
5731− { "MAM_D2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5732− REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D2MEM_SED_COUNT), 0 },
5733− { "MAM_D3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32,
5734− REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D3MEM_SED_COUNT), 0 },
5730+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_SEC_COUNT),
5731+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_DED_COUNT)
5732+ },
5733+ { "SQC_DATA_CU2_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
5734+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT),
5735+ SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT)
5736+ },
5737+ { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5738+ SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT),
5739+ SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT)
5740+ },
5741+ { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5742+ SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT),
5743+ SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT)
5744+ },
5745+ { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5746+ SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT),
5747+ SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT)
5748+ },
5749+ { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5750+ SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT),
5751+ SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT)
5752+ },
5753+ { "SQC_INST_BANKA_UTCL1_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5754+ SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_UTCL1_MISS_FIFO_SED_COUNT),
5755+ 0, 0
5756+ },
5757+ { "SQC_INST_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5758+ SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_MISS_FIFO_SED_COUNT),
5759+ 0, 0
5760+ },
5761+ { "SQC_DATA_BANKA_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5762+ SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_HIT_FIFO_SED_COUNT),
5763+ 0, 0
5764+ },
5765+ { "SQC_DATA_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5766+ SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_MISS_FIFO_SED_COUNT),
5767+ 0, 0
5768+ },
5769+ { "SQC_DATA_BANKA_DIRTY_BIT_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5770+ SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_DIRTY_BIT_RAM_SED_COUNT),
5771+ 0, 0
5772+ },
5773+ { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
5774+ SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT),
5775+ SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT)
5776+ },
5777+ { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5778+ SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT),
5779+ SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT)
5780+ },
5781+ { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5782+ SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT),
5783+ SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT)
5784+ },
5785+ { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5786+ SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT),
5787+ SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT)
5788+ },
5789+ { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5790+ SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT),
5791+ SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT)
5792+ },
5793+ { "SQC_INST_BANKB_UTCL1_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5794+ SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_UTCL1_MISS_FIFO_SED_COUNT),
5795+ 0, 0
5796+ },
5797+ { "SQC_INST_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5798+ SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_MISS_FIFO_SED_COUNT),
5799+ 0, 0
5800+ },
5801+ { "SQC_DATA_BANKB_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5802+ SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_HIT_FIFO_SED_COUNT),
5803+ 0, 0
5804+ },
5805+ { "SQC_DATA_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5806+ SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_MISS_FIFO_SED_COUNT),
5807+ 0, 0
5808+ },
5809+ { "SQC_DATA_BANKB_DIRTY_BIT_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
5810+ SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_DIRTY_BIT_RAM_SED_COUNT),
5811+ 0, 0
5812+ },
5813+ { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5814+ SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
5815+ SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT)
5816+ },
5817+ { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5818+ SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
5819+ SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT)
5820+ },
5821+ { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5822+ SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
5823+ SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT)
5824+ },
5825+ { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5826+ SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
5827+ SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT)
5828+ },
5829+ { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5830+ SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
5831+ SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT)
5832+ },
5833+ { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5834+ SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT),
5835+ 0, 0
5836+ },
5837+ { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5838+ SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT),
5839+ 0, 0
5840+ },
5841+ { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5842+ SOC15_REG_FIELD(GCEA_EDC_CNT, IORD_CMDMEM_SED_COUNT),
5843+ 0, 0
5844+ },
5845+ { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5846+ SOC15_REG_FIELD(GCEA_EDC_CNT, IOWR_CMDMEM_SED_COUNT),
5847+ 0, 0
5848+ },
5849+ { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
5850+ SOC15_REG_FIELD(GCEA_EDC_CNT, IOWR_DATAMEM_SED_COUNT),
5851+ 0, 0
5852+ },
5853+ { "GMIRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5854+ SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
5855+ SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT)
5856+ },
5857+ { "GMIWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5858+ SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
5859+ SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT)
5860+ },
5861+ { "GMIWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5862+ SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
5863+ SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT)
5864+ },
5865+ { "GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5866+ SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT),
5867+ 0, 0
5868+ },
5869+ { "GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5870+ SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT),
5871+ 0, 0
5872+ },
5873+ { "MAM_D0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5874+ SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D0MEM_SED_COUNT),
5875+ 0, 0
5876+ },
5877+ { "MAM_D1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5878+ SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D1MEM_SED_COUNT),
5879+ 0, 0
5880+ },
5881+ { "MAM_D2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5882+ SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D2MEM_SED_COUNT),
5883+ 0, 0
5884+ },
5885+ { "MAM_D3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
5886+ SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D3MEM_SED_COUNT),
5887+ 0, 0
5888+ }
57355889 };
57365890
57375891 static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev,
@@ -5780,14 +5934,217 @@ static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev, · 42 unmodified lines
57805934 return ret;
57815935 }
57825936
5937+static const char *vml2_mems[] = {
5938+ "UTC_VML2_BANK_CACHE_0_BIGK_MEM0",
5939+ "UTC_VML2_BANK_CACHE_0_BIGK_MEM1",
5940+ "UTC_VML2_BANK_CACHE_0_4K_MEM0",
5941+ "UTC_VML2_BANK_CACHE_0_4K_MEM1",
5942+ "UTC_VML2_BANK_CACHE_1_BIGK_MEM0",
5943+ "UTC_VML2_BANK_CACHE_1_BIGK_MEM1",
5944+ "UTC_VML2_BANK_CACHE_1_4K_MEM0",
5945+ "UTC_VML2_BANK_CACHE_1_4K_MEM1",
5946+ "UTC_VML2_BANK_CACHE_2_BIGK_MEM0",
5947+ "UTC_VML2_BANK_CACHE_2_BIGK_MEM1",
5948+ "UTC_VML2_BANK_CACHE_2_4K_MEM0",
5949+ "UTC_VML2_BANK_CACHE_2_4K_MEM1",
5950+ "UTC_VML2_BANK_CACHE_3_BIGK_MEM0",
5951+ "UTC_VML2_BANK_CACHE_3_BIGK_MEM1",
5952+ "UTC_VML2_BANK_CACHE_3_4K_MEM0",
5953+ "UTC_VML2_BANK_CACHE_3_4K_MEM1",
5954+};
5955+
5956+static const char *vml2_walker_mems[] = {
5957+ "UTC_VML2_CACHE_PDE0_MEM0",
5958+ "UTC_VML2_CACHE_PDE0_MEM1",
5959+ "UTC_VML2_CACHE_PDE1_MEM0",
5960+ "UTC_VML2_CACHE_PDE1_MEM1",
5961+ "UTC_VML2_CACHE_PDE2_MEM0",
5962+ "UTC_VML2_CACHE_PDE2_MEM1",
5963+ "UTC_VML2_RDIF_LOG_FIFO",
5964+};
5965+
5966+static const char *atc_l2_cache_2m_mems[] = {
5967+ "UTC_ATCL2_CACHE_2M_BANK0_WAY0_MEM",
5968+ "UTC_ATCL2_CACHE_2M_BANK0_WAY1_MEM",
5969+ "UTC_ATCL2_CACHE_2M_BANK1_WAY0_MEM",
5970+ "UTC_ATCL2_CACHE_2M_BANK1_WAY1_MEM",
5971+};
5972+
5973+static const char *atc_l2_cache_4k_mems[] = {
5974+ "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM0",
5975+ "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM1",
5976+ "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM2",
5977+ "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM3",
5978+ "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM4",
5979+ "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM5",
5980+ "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM6",
5981+ "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM7",
5982+ "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM0",
5983+ "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM1",
5984+ "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM2",
5985+ "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM3",
5986+ "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM4",
5987+ "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM5",
5988+ "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM6",
5989+ "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM7",
5990+ "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM0",
5991+ "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM1",
5992+ "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM2",
5993+ "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM3",
5994+ "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM4",
5995+ "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM5",
5996+ "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM6",
5997+ "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM7",
5998+ "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM0",
5999+ "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM1",
6000+ "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM2",
6001+ "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM3",
6002+ "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM4",
6003+ "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM5",
6004+ "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM6",
6005+ "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM7",
6006+};
6007+
6008+static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
6009+ struct ras_err_data *err_data)
6010+{
6011+ uint32_t i, data;
6012+ uint32_t sec_count, ded_count;
6013+
6014+ WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, 255);
6015+ WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT, 0);
6016+ WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, 255);
6017+ WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT, 0);
6018+ WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, 255);
6019+ WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT, 0);
6020+ WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255);
6021+ WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT, 0);
6022+
6023+ for (i = 0; i < 16; i++) {
6024+ WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, i);
6025+ data = RREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT);
6026+
6027+ sec_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, SEC_COUNT);
6028+ if (sec_count) {
6029+ DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
6030+ vml2_mems[i], sec_count);
6031+ err_data->ce_count += sec_count;
6032+ }
6033+
6034+ ded_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, DED_COUNT);
6035+ if (ded_count) {
6036+ DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
6037+ vml2_mems[i], ded_count);
6038+ err_data->ue_count += ded_count;
6039+ }
6040+ }
6041+
6042+ for (i = 0; i < 7; i++) {
6043+ WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, i);
6044+ data = RREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT);
6045+
6046+ sec_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT,
6047+ SEC_COUNT);
6048+ if (sec_count) {
6049+ DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
6050+ vml2_walker_mems[i], sec_count);
6051+ err_data->ce_count += sec_count;
6052+ }
6053+
6054+ ded_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT,
6055+ DED_COUNT);
6056+ if (ded_count) {
6057+ DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
6058+ vml2_walker_mems[i], ded_count);
6059+ err_data->ue_count += ded_count;
6060+ }
6061+ }
6062+
6063+ for (i = 0; i < 4; i++) {
6064+ WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, i);
6065+ data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT);
6066+
6067+ sec_count = (data & 0x00006000L) >> 0xd;
6068+ if (sec_count) {
6069+ DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
6070+ atc_l2_cache_2m_mems[i], sec_count);
6071+ err_data->ce_count += sec_count;
6072+ }
6073+ }
6074+
6075+ for (i = 0; i < 32; i++) {
6076+ WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, i);
6077+ data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT);
6078+
6079+ sec_count = (data & 0x00006000L) >> 0xd;
6080+ if (sec_count) {
6081+ DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
6082+ atc_l2_cache_4k_mems[i], sec_count);
6083+ err_data->ce_count += sec_count;
6084+ }
6085+
6086+ ded_count = (data & 0x00018000L) >> 0xf;
6087+ if (ded_count) {
6088+ DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
6089+ atc_l2_cache_4k_mems[i], ded_count);
6090+ err_data->ue_count += ded_count;
6091+ }
6092+ }
6093+
6094+ WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, 255);
6095+ WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, 255);
6096+ WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, 255);
6097+ WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255);
6098+
6099+ return 0;
6100+}
6101+
6102+static int __get_ras_error_count(const struct soc15_reg_entry *reg,
6103+ uint32_t se_id, uint32_t inst_id, uint32_t value,
6104+ uint32_t *sec_count, uint32_t *ded_count)
6105+{
6106+ uint32_t i;
6107+ uint32_t sec_cnt, ded_cnt;
6108+
6109+ for (i = 0; i < ARRAY_SIZE(ras_subblock_regs); i++) {
6110+ if(ras_subblock_regs[i].reg_offset != reg->reg_offset ||
6111+ ras_subblock_regs[i].seg != reg->seg ||
6112+ ras_subblock_regs[i].inst != reg->inst)
6113+ continue;
6114+
6115+ sec_cnt = (value &
6116+ ras_subblock_regs[i].sec_count_mask) >>
6117+ ras_subblock_regs[i].sec_count_shift;
6118+ if (sec_cnt) {
6119+ DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n",
6120+ ras_subblock_regs[i].name,
6121+ se_id, inst_id,
6122+ sec_cnt);
6123+ *sec_count += sec_cnt;
6124+ }
6125+
6126+ ded_cnt = (value &
6127+ ras_subblock_regs[i].ded_count_mask) >>
6128+ ras_subblock_regs[i].ded_count_shift;
6129+ if (ded_cnt) {
6130+ DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n",
6131+ ras_subblock_regs[i].name,
6132+ se_id, inst_id,
6133+ ded_cnt);
6134+ *ded_count += ded_cnt;
6135+ }
6136+ }
6137+
6138+ return 0;
6139+}
6140+
57836141 static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
57846142 void *ras_error_status)
57856143 {
57866144 struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
5787− uint32_t sec_count, ded_count;
5788− uint32_t i;
6145+ uint32_t sec_count = 0, ded_count = 0;
6146+ uint32_t i, j, k;
57896147 uint32_t reg_value;
5790− uint32_t se_id, instance_id;
57916148
57926149 if (adev->asic_type != CHIP_VEGA20)
57936150 return -EINVAL;
@@ -5796,52 +6153,29 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev, · 2 unmodified lines
57966153 err_data->ce_count = 0;
57976154
57986155 mutex_lock(&adev->grbm_idx_mutex);
5799− for (se_id = 0; se_id < adev->gfx.config.max_shader_engines; se_id++) {
5800− for (instance_id = 0; instance_id < 256; instance_id++) {
5801− for (i = 0;
5802− i < sizeof(gfx_ras_edc_regs) / sizeof(gfx_ras_edc_regs[0]);
5803− i++) {
5804− if (se_id != 0 &&
5805− !gfx_ras_edc_regs[i].per_se_instance)
5806− continue;
5807− if (instance_id >= gfx_ras_edc_regs[i].num_instance)
5808− continue;
5809−
5810− gfx_v9_0_select_se_sh(adev, se_id, 0,
5811− instance_id);
5812−
5813− reg_value = RREG32(
5814− adev->reg_offset[gfx_ras_edc_regs[i].ip]
5815− [gfx_ras_edc_regs[i].inst]
5816− [gfx_ras_edc_regs[i].seg] +
5817− gfx_ras_edc_regs[i].reg_offset);
5818− sec_count = reg_value &
5819− gfx_ras_edc_regs[i].sec_count_mask;
5820− ded_count = reg_value &
5821− gfx_ras_edc_regs[i].ded_count_mask;
5822− if (sec_count) {
5823− DRM_INFO(
5824− "Instance[%d][%d]: SubBlock %s, SEC %d\n",
5825− se_id, instance_id,
5826− gfx_ras_edc_regs[i].name,
5827− sec_count);
5828− err_data->ce_count++;
5829− }
58306156
5831− if (ded_count) {
5832− DRM_INFO(
5833− "Instance[%d][%d]: SubBlock %s, DED %d\n",
5834− se_id, instance_id,
5835− gfx_ras_edc_regs[i].name,
5836− ded_count);
5837− err_data->ue_count++;
5838− }
6157+ for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++) {
6158+ for (j = 0; j < sec_ded_counter_registers[i].se_num; j++) {
6159+ for (k = 0; k < sec_ded_counter_registers[i].instance; k++) {
6160+ gfx_v9_0_select_se_sh(adev, j, 0, k);
6161+ reg_value =
6162+ RREG32(SOC15_REG_ENTRY_OFFSET(sec_ded_counter_registers[i]));
6163+ if (reg_value)
6164+ __get_ras_error_count(&sec_ded_counter_registers[i],
6165+ j, k, reg_value,
6166+ &sec_count, &ded_count);
58396167 }
58406168 }
58416169 }
6170+
6171+ err_data->ce_count += sec_count;
6172+ err_data->ue_count += ded_count;
6173+
58426174 gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
58436175 mutex_unlock(&adev->grbm_idx_mutex);
58446176
6177+ gfx_v9_0_query_utc_edc_status(adev, err_data);
6178+
58456179 return 0;
58466180 }
58476181
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c+44−41
@@ -1137,13 +1137,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) · 1136 unmodified lines
11371137 */
11381138 static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
11391139 {
1140− int r, i;
1141− bool value;
1142− u32 tmp;
1143−
1144− amdgpu_device_program_register_sequence(adev,
1145− golden_settings_vega10_hdp,
1146− ARRAY_SIZE(golden_settings_vega10_hdp));
1140+ int r;
11471141
11481142 if (adev->gart.bo == NULL) {
11491143 dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
@@ -1153,15 +1147,6 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) · 3 unmodified lines
11531147 if (r)
11541148 return r;
11551149
1156− switch (adev->asic_type) {
1157− case CHIP_RAVEN:
1158− /* TODO for renoir */
1159− mmhub_v1_0_update_power_gating(adev, true);
1160− break;
1161− default:
1162− break;
1163− }
1164−
11651150 r = gfxhub_v1_0_gart_enable(adev);
11661151 if (r)
11671152 return r;
@@ -1173,6 +1158,49 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) · 5 unmodified lines
11731158 if (r)
11741159 return r;
11751160
1161+ DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1162+ (unsigned)(adev->gmc.gart_size >> 20),
1163+ (unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo));
1164+ adev->gart.ready = true;
1165+ return 0;
1166+}
1167+
1168+static int gmc_v9_0_hw_init(void *handle)
1169+{
1170+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1171+ bool value;
1172+ int r, i;
1173+ u32 tmp;
1174+
1175+ /* The sequence of these two function calls matters.*/
1176+ gmc_v9_0_init_golden_registers(adev);
1177+
1178+ if (adev->mode_info.num_crtc) {
1179+ if (adev->asic_type != CHIP_ARCTURUS) {
1180+ /* Lockout access through VGA aperture*/
1181+ WREG32_FIELD15(DCE, 0, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1);
1182+
1183+ /* disable VGA render */
1184+ WREG32_FIELD15(DCE, 0, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
1185+ }
1186+ }
1187+
1188+ amdgpu_device_program_register_sequence(adev,
1189+ golden_settings_vega10_hdp,
1190+ ARRAY_SIZE(golden_settings_vega10_hdp));
1191+
1192+ switch (adev->asic_type) {
1193+ case CHIP_RAVEN:
1194+ /* TODO for renoir */
1195+ mmhub_v1_0_update_power_gating(adev, true);
1196+ break;
1197+ case CHIP_ARCTURUS:
1198+ WREG32_FIELD15(HDP, 0, HDP_MMHUB_CNTL, HDP_MMHUB_GCC, 1);
1199+ break;
1200+ default:
1201+ break;
1202+ }
1203+
11761204 WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1);
11771205
11781206 tmp = RREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL);
@@ -1201,31 +1229,6 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) · 22 unmodified lines
12011229 if (adev->umc.funcs && adev->umc.funcs->init_registers)
12021230 adev->umc.funcs->init_registers(adev);
12031231
1204− DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1205− (unsigned)(adev->gmc.gart_size >> 20),
1206− (unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo));
1207− adev->gart.ready = true;
1208− return 0;
1209−}
1210−
1211−static int gmc_v9_0_hw_init(void *handle)
1212−{
1213− int r;
1214− struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1215−
1216− /* The sequence of these two function calls matters.*/
1217− gmc_v9_0_init_golden_registers(adev);
1218−
1219− if (adev->mode_info.num_crtc) {
1220− if (adev->asic_type != CHIP_ARCTURUS) {
1221− /* Lockout access through VGA aperture*/
1222− WREG32_FIELD15(DCE, 0, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1);
1223−
1224− /* disable VGA render */
1225− WREG32_FIELD15(DCE, 0, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
1226− }
1227− }
1228−
12291232 r = gmc_v9_0_gart_enable(adev);
12301233
12311234 return r;
drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c+8−0
@@ -502,6 +502,13 @@ static void nbio_v7_4_query_ras_error_count(struct amdgpu_device *adev, · 501 unmodified lines
502502 }
503503 }
504504
505+static void nbio_v7_4_enable_doorbell_interrupt(struct amdgpu_device *adev,
506+ bool enable)
507+{
508+ WREG32_FIELD15(NBIO, 0, BIF_DOORBELL_INT_CNTL,
509+ DOORBELL_INTERRUPT_DISABLE, enable ? 0 : 1);
510+}
511+
505512 const struct amdgpu_nbio_funcs nbio_v7_4_funcs = {
506513 .get_hdp_flush_req_offset = nbio_v7_4_get_hdp_flush_req_offset,
507514 .get_hdp_flush_done_offset = nbio_v7_4_get_hdp_flush_done_offset,
@@ -516,6 +523,7 @@ const struct amdgpu_nbio_funcs nbio_v7_4_funcs = { · 8 unmodified lines
516523 .enable_doorbell_aperture = nbio_v7_4_enable_doorbell_aperture,
517524 .enable_doorbell_selfring_aperture = nbio_v7_4_enable_doorbell_selfring_aperture,
518525 .ih_doorbell_range = nbio_v7_4_ih_doorbell_range,
526+ .enable_doorbell_interrupt = nbio_v7_4_enable_doorbell_interrupt,
519527 .update_medium_grain_clock_gating = nbio_v7_4_update_medium_grain_clock_gating,
520528 .update_medium_grain_light_sleep = nbio_v7_4_update_medium_grain_light_sleep,
521529 .get_clockgating_state = nbio_v7_4_get_clockgating_state,
drivers/gpu/drm/amd/amdgpu/psp_v10_0.c+3−0
@@ -40,6 +40,9 @@ · 39 unmodified lines
4040 MODULE_FIRMWARE("amdgpu/raven_asd.bin");
4141 MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
4242 MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
43+MODULE_FIRMWARE("amdgpu/picasso_ta.bin");
44+MODULE_FIRMWARE("amdgpu/raven2_ta.bin");
45+MODULE_FIRMWARE("amdgpu/raven_ta.bin");
4346
4447 static int psp_v10_0_init_microcode(struct psp_context *psp)
4548 {
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c+174−9
@@ -58,6 +58,8 @@ MODULE_FIRMWARE("amdgpu/arcturus_ta.bin"); · 57 unmodified lines
5858 #define mmRLC_GPM_UCODE_DATA_NV10 0x5b62
5959 #define mmSDMA0_UCODE_ADDR_NV10 0x5880
6060 #define mmSDMA0_UCODE_DATA_NV10 0x5881
61+/* memory training timeout define */
62+#define MEM_TRAIN_SEND_MSG_TIMEOUT_US 3000000
6163
6264 static int psp_v11_0_init_microcode(struct psp_context *psp)
6365 {
@@ -206,18 +208,26 @@ out: · 142 unmodified lines
206208 return err;
207209 }
208210
211+static bool psp_v11_0_is_sos_alive(struct psp_context *psp)
212+{
213+ struct amdgpu_device *adev = psp->adev;
214+ uint32_t sol_reg;
215+
216+ sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
217+
218+ return sol_reg != 0x0;
219+}
220+
209221 static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp)
210222 {
211223 int ret;
212224 uint32_t psp_gfxdrv_command_reg = 0;
213225 struct amdgpu_device *adev = psp->adev;
214− uint32_t sol_reg;
215226
216227 /* Check tOS sign of life register to confirm sys driver and sOS
217228 * are already been loaded.
218229 */
219− sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
220− if (sol_reg) {
230+ if (psp_v11_0_is_sos_alive(psp)) {
221231 psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58);
222232 dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version);
223233 return 0;
@@ -253,13 +263,11 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) · 29 unmodified lines
253263 int ret;
254264 uint32_t psp_gfxdrv_command_reg = 0;
255265 struct amdgpu_device *adev = psp->adev;
256− uint32_t sol_reg;
257266
258267 /* Check sOS sign of life register to confirm sys driver and sOS
259268 * are already been loaded.
260269 */
261− sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
262− if (sol_reg) {
270+ if (psp_v11_0_is_sos_alive(psp)) {
263271 psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58);
264272 dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version);
265273 return 0;
@@ -297,13 +305,11 @@ static int psp_v11_0_bootloader_load_sos(struct psp_context *psp) · 31 unmodified lines
297305 int ret;
298306 unsigned int psp_gfxdrv_command_reg = 0;
299307 struct amdgpu_device *adev = psp->adev;
300− uint32_t sol_reg;
301308
302309 /* Check sOS sign of life register to confirm sys driver and sOS
303310 * are already been loaded.
304311 */
305− sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
306− if (sol_reg)
312+ if (psp_v11_0_is_sos_alive(psp))
307313 return 0;
308314
309315 /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */
@@ -898,6 +904,162 @@ static int psp_v11_0_rlc_autoload_start(struct psp_context *psp) · 588 unmodified lines
898904 return psp_rlc_autoload_start(psp);
899905 }
900906
907+static int psp_v11_0_memory_training_send_msg(struct psp_context *psp, int msg)
908+{
909+ int ret;
910+ int i;
911+ uint32_t data_32;
912+ int max_wait;
913+ struct amdgpu_device *adev = psp->adev;
914+
915+ data_32 = (psp->mem_train_ctx.c2p_train_data_offset >> 20);
916+ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, data_32);
917+ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, msg);
918+
919+ max_wait = MEM_TRAIN_SEND_MSG_TIMEOUT_US / adev->usec_timeout;
920+ for (i = 0; i < max_wait; i++) {
921+ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35),
922+ 0x80000000, 0x80000000, false);
923+ if (ret == 0)
924+ break;
925+ }
926+ if (i < max_wait)
927+ ret = 0;
928+ else
929+ ret = -ETIME;
930+
931+ DRM_DEBUG("training %s %s, cost %d @ %d ms\n",
932+ (msg == PSP_BL__DRAM_SHORT_TRAIN) ? "short" : "long",
933+ (ret == 0) ? "succeed" : "failed",
934+ i, adev->usec_timeout/1000);
935+ return ret;
936+}
937+
938+static void psp_v11_0_memory_training_fini(struct psp_context *psp)
939+{
940+ struct psp_memory_training_context *ctx = &psp->mem_train_ctx;
941+
942+ ctx->init = PSP_MEM_TRAIN_NOT_SUPPORT;
943+ kfree(ctx->sys_cache);
944+ ctx->sys_cache = NULL;
945+}
946+
947+static int psp_v11_0_memory_training_init(struct psp_context *psp)
948+{
949+ int ret;
950+ struct psp_memory_training_context *ctx = &psp->mem_train_ctx;
951+
952+ if (ctx->init != PSP_MEM_TRAIN_RESERVE_SUCCESS) {
953+ DRM_DEBUG("memory training is not supported!\n");
954+ return 0;
955+ }
956+
957+ ctx->sys_cache = kzalloc(ctx->train_data_size, GFP_KERNEL);
958+ if (ctx->sys_cache == NULL) {
959+ DRM_ERROR("alloc mem_train_ctx.sys_cache failed!\n");
960+ ret = -ENOMEM;
961+ goto Err_out;
962+ }
963+
964+ DRM_DEBUG("train_data_size:%llx,p2c_train_data_offset:%llx,c2p_train_data_offset:%llx.\n",
965+ ctx->train_data_size,
966+ ctx->p2c_train_data_offset,
967+ ctx->c2p_train_data_offset);
968+ ctx->init = PSP_MEM_TRAIN_INIT_SUCCESS;
969+ return 0;
970+
971+Err_out:
972+ psp_v11_0_memory_training_fini(psp);
973+ return ret;
974+}
975+
976+/*
977+ * save and restore proces
978+ */
979+static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
980+{
981+ int ret;
982+ uint32_t p2c_header[4];
983+ struct psp_memory_training_context *ctx = &psp->mem_train_ctx;
984+ uint32_t *pcache = (uint32_t*)ctx->sys_cache;
985+
986+ if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) {
987+ DRM_DEBUG("Memory training is not supported.\n");
988+ return 0;
989+ } else if (ctx->init != PSP_MEM_TRAIN_INIT_SUCCESS) {
990+ DRM_ERROR("Memory training initialization failure.\n");
991+ return -EINVAL;
992+ }
993+
994+ if (psp_v11_0_is_sos_alive(psp)) {
995+ DRM_DEBUG("SOS is alive, skip memory training.\n");
996+ return 0;
997+ }
998+
999+ amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, p2c_header, sizeof(p2c_header), false);
1000+ DRM_DEBUG("sys_cache[%08x,%08x,%08x,%08x] p2c_header[%08x,%08x,%08x,%08x]\n",
1001+ pcache[0], pcache[1], pcache[2], pcache[3],
1002+ p2c_header[0], p2c_header[1], p2c_header[2], p2c_header[3]);
1003+
1004+ if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) {
1005+ DRM_DEBUG("Short training depends on restore.\n");
1006+ ops |= PSP_MEM_TRAIN_RESTORE;
1007+ }
1008+
1009+ if ((ops & PSP_MEM_TRAIN_RESTORE) &&
1010+ pcache[0] != MEM_TRAIN_SYSTEM_SIGNATURE) {
1011+ DRM_DEBUG("sys_cache[0] is invalid, restore depends on save.\n");
1012+ ops |= PSP_MEM_TRAIN_SAVE;
1013+ }
1014+
1015+ if (p2c_header[0] == MEM_TRAIN_SYSTEM_SIGNATURE &&
1016+ !(pcache[0] == MEM_TRAIN_SYSTEM_SIGNATURE &&
1017+ pcache[3] == p2c_header[3])) {
1018+ DRM_DEBUG("sys_cache is invalid or out-of-date, need save training data to sys_cache.\n");
1019+ ops |= PSP_MEM_TRAIN_SAVE;
1020+ }
1021+
1022+ if ((ops & PSP_MEM_TRAIN_SAVE) &&
1023+ p2c_header[0] != MEM_TRAIN_SYSTEM_SIGNATURE) {
1024+ DRM_DEBUG("p2c_header[0] is invalid, save depends on long training.\n");
1025+ ops |= PSP_MEM_TRAIN_SEND_LONG_MSG;
1026+ }
1027+
1028+ if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) {
1029+ ops &= ~PSP_MEM_TRAIN_SEND_SHORT_MSG;
1030+ ops |= PSP_MEM_TRAIN_SAVE;
1031+ }
1032+
1033+ DRM_DEBUG("Memory training ops:%x.\n", ops);
1034+
1035+ if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) {
1036+ ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN);
1037+ if (ret) {
1038+ DRM_ERROR("Send long training msg failed.\n");
1039+ return ret;
1040+ }
1041+ }
1042+
1043+ if (ops & PSP_MEM_TRAIN_SAVE) {
1044+ amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, ctx->sys_cache, ctx->train_data_size, false);
1045+ }
1046+
1047+ if (ops & PSP_MEM_TRAIN_RESTORE) {
1048+ amdgpu_device_vram_access(psp->adev, ctx->c2p_train_data_offset, ctx->sys_cache, ctx->train_data_size, true);
1049+ }
1050+
1051+ if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) {
1052+ ret = psp_v11_0_memory_training_send_msg(psp, (amdgpu_force_long_training > 0) ?
1053+ PSP_BL__DRAM_LONG_TRAIN : PSP_BL__DRAM_SHORT_TRAIN);
1054+ if (ret) {
1055+ DRM_ERROR("send training msg failed.\n");
1056+ return ret;
1057+ }
1058+ }
1059+ ctx->training_cnt++;
1060+ return 0;
1061+}
1062+
9011063 static const struct psp_funcs psp_v11_0_funcs = {
9021064 .init_microcode = psp_v11_0_init_microcode,
9031065 .bootloader_load_kdb = psp_v11_0_bootloader_load_kdb,
@@ -918,6 +1080,9 @@ static const struct psp_funcs psp_v11_0_funcs = { · 14 unmodified lines
9181080 .ras_trigger_error = psp_v11_0_ras_trigger_error,
9191081 .ras_cure_posion = psp_v11_0_ras_cure_posion,
9201082 .rlc_autoload_start = psp_v11_0_rlc_autoload_start,
1083+ .mem_training_init = psp_v11_0_memory_training_init,
1084+ .mem_training_fini = psp_v11_0_memory_training_fini,
1085+ .mem_training = psp_v11_0_memory_training,
9211086 };
9221087
9231088 void psp_v11_0_set_psp_funcs(struct psp_context *psp)
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c+1−1
@@ -1792,7 +1792,7 @@ static int sdma_v4_0_hw_init(void *handle) · 1791 unmodified lines
17921792
17931793 if ((adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs &&
17941794 adev->powerplay.pp_funcs->set_powergating_by_smu) ||
1795− adev->asic_type == CHIP_RENOIR)
1795+ (adev->asic_type == CHIP_RENOIR && !adev->in_gpu_reset))
17961796 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false);
17971797
17981798 if (!amdgpu_sriov_vf(adev))
drivers/gpu/drm/amd/amdgpu/soc15.c+41−19
@@ -478,36 +478,58 @@ static int soc15_asic_mode1_reset(struct amdgpu_device *adev) · 477 unmodified lines
478478
479479 static int soc15_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap)
480480 {
481− void *pp_handle = adev->powerplay.pp_handle;
482− const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
481+ if (is_support_sw_smu(adev)) {
482+ struct smu_context *smu = &adev->smu;
483483
484− if (!pp_funcs || !pp_funcs->get_asic_baco_capability) {
485− *cap = false;
486− return -ENOENT;
487− }
484+ *cap = smu_baco_is_support(smu);
485+ return 0;
486+ } else {
487+ void *pp_handle = adev->powerplay.pp_handle;
488+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
488489
489− return pp_funcs->get_asic_baco_capability(pp_handle, cap);
490+ if (!pp_funcs || !pp_funcs->get_asic_baco_capability) {
491+ *cap = false;
492+ return -ENOENT;
493+ }
494+
495+ return pp_funcs->get_asic_baco_capability(pp_handle, cap);
496+ }
490497 }
491498
492499 static int soc15_asic_baco_reset(struct amdgpu_device *adev)
493500 {
494− void *pp_handle = adev->powerplay.pp_handle;
495− const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
501+ struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
496502
497− if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state)
498− return -ENOENT;
503+ /* avoid NBIF got stuck when do RAS recovery in BACO reset */
504+ if (ras && ras->supported)
505+ adev->nbio.funcs->enable_doorbell_interrupt(adev, false);
499506
500− /* enter BACO state */
501− if (pp_funcs->set_asic_baco_state(pp_handle, 1))
502− return -EIO;
507+ dev_info(adev->dev, "GPU BACO reset\n");
503508
504− /* exit BACO state */
505− if (pp_funcs->set_asic_baco_state(pp_handle, 0))
506− return -EIO;
509+ if (is_support_sw_smu(adev)) {
510+ struct smu_context *smu = &adev->smu;
507511
508− dev_info(adev->dev, "GPU BACO reset\n");
512+ if (smu_baco_reset(smu))
513+ return -EIO;
514+ } else {
515+ void *pp_handle = adev->powerplay.pp_handle;
516+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
517+
518+ if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state)
519+ return -ENOENT;
520+
521+ /* enter BACO state */
522+ if (pp_funcs->set_asic_baco_state(pp_handle, 1))
523+ return -EIO;
524+
525+ /* exit BACO state */
526+ if (pp_funcs->set_asic_baco_state(pp_handle, 0))
527+ return -EIO;
528+ }
509529
510− adev->in_baco_reset = 1;
530+ /* re-enable doorbell interrupt after BACO exit */
531+ if (ras && ras->supported)
532+ adev->nbio.funcs->enable_doorbell_interrupt(adev, true);
511533
512534 return 0;
513535 }
drivers/gpu/drm/amd/amdgpu/soc15.h+2−0
@@ -67,6 +67,8 @@ struct soc15_allowed_register_entry { · 66 unmodified lines
6767 #define SOC15_REG_GOLDEN_VALUE(ip, inst, reg, and_mask, or_mask) \
6868 { ip##_HWIP, inst, reg##_BASE_IDX, reg, and_mask, or_mask }
6969
70+#define SOC15_REG_FIELD(reg, field) reg##__##field##_MASK, reg##__##field##__SHIFT
71+
7072 void soc15_grbm_select(struct amdgpu_device *adev,
7173 u32 me, u32 pipe, u32 queue, u32 vmid);
7274 int soc15_set_ip_blocks(struct amdgpu_device *adev);
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c+21−10
@@ -206,13 +206,14 @@ static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring) · 205 unmodified lines
206206 * Open up a stream for HW test
207207 */
208208 static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
209+ struct amdgpu_bo *bo,
209210 struct dma_fence **fence)
210211 {
211212 const unsigned ib_size_dw = 16;
212213 struct amdgpu_job *job;
213214 struct amdgpu_ib *ib;
214215 struct dma_fence *f = NULL;
215− uint64_t dummy;
216+ uint64_t addr;
216217 int i, r;
217218
218219 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
@@ -220,15 +221,15 @@ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle · 1 unmodified line
220221 return r;
221222
222223 ib = &job->ibs[0];
223− dummy = ib->gpu_addr + 1024;
224+ addr = amdgpu_bo_gpu_offset(bo);
224225
225226 ib->length_dw = 0;
226227 ib->ptr[ib->length_dw++] = 0x00000018;
227228 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
228229 ib->ptr[ib->length_dw++] = handle;
229230 ib->ptr[ib->length_dw++] = 0x00010000;
230− ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
231− ib->ptr[ib->length_dw++] = dummy;
231+ ib->ptr[ib->length_dw++] = upper_32_bits(addr);
232+ ib->ptr[ib->length_dw++] = addr;
232233
233234 ib->ptr[ib->length_dw++] = 0x00000014;
234235 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
@@ -268,13 +269,14 @@ err: · 33 unmodified lines
268269 */
269270 static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring,
270271 uint32_t handle,
272+ struct amdgpu_bo *bo,
271273 struct dma_fence **fence)
272274 {
273275 const unsigned ib_size_dw = 16;
274276 struct amdgpu_job *job;
275277 struct amdgpu_ib *ib;
276278 struct dma_fence *f = NULL;
277− uint64_t dummy;
279+ uint64_t addr;
278280 int i, r;
279281
280282 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
@@ -282,15 +284,15 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, · 1 unmodified line
282284 return r;
283285
284286 ib = &job->ibs[0];
285− dummy = ib->gpu_addr + 1024;
287+ addr = amdgpu_bo_gpu_offset(bo);
286288
287289 ib->length_dw = 0;
288290 ib->ptr[ib->length_dw++] = 0x00000018;
289291 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
290292 ib->ptr[ib->length_dw++] = handle;
291293 ib->ptr[ib->length_dw++] = 0x00010000;
292− ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
293− ib->ptr[ib->length_dw++] = dummy;
294+ ib->ptr[ib->length_dw++] = upper_32_bits(addr);
295+ ib->ptr[ib->length_dw++] = addr;
294296
295297 ib->ptr[ib->length_dw++] = 0x00000014;
296298 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
@@ -327,13 +329,20 @@ err: · 30 unmodified lines
327329 static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
328330 {
329331 struct dma_fence *fence = NULL;
332+ struct amdgpu_bo *bo = NULL;
330333 long r;
331334
332− r = uvd_v6_0_enc_get_create_msg(ring, 1, NULL);
335+ r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,
336+ AMDGPU_GEM_DOMAIN_VRAM,
337+ &bo, NULL, NULL);
338+ if (r)
339+ return r;
340+
341+ r = uvd_v6_0_enc_get_create_msg(ring, 1, bo, NULL);
333342 if (r)
334343 goto error;
335344
336− r = uvd_v6_0_enc_get_destroy_msg(ring, 1, &fence);
345+ r = uvd_v6_0_enc_get_destroy_msg(ring, 1, bo, &fence);
337346 if (r)
338347 goto error;
339348
@@ -345,6 +354,8 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 5 unmodified lines
345354
346355 error:
347356 dma_fence_put(fence);
357+ amdgpu_bo_unreserve(bo);
358+ amdgpu_bo_unref(&bo);
348359 return r;
349360 }
350361
drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c+22−11
@@ -214,13 +214,14 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring) · 213 unmodified lines
214214 * Open up a stream for HW test
215215 */
216216 static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
217+ struct amdgpu_bo *bo,
217218 struct dma_fence **fence)
218219 {
219220 const unsigned ib_size_dw = 16;
220221 struct amdgpu_job *job;
221222 struct amdgpu_ib *ib;
222223 struct dma_fence *f = NULL;
223− uint64_t dummy;
224+ uint64_t addr;
224225 int i, r;
225226
226227 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
@@ -228,15 +229,15 @@ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle · 1 unmodified line
228229 return r;
229230
230231 ib = &job->ibs[0];
231− dummy = ib->gpu_addr + 1024;
232+ addr = amdgpu_bo_gpu_offset(bo);
232233
233234 ib->length_dw = 0;
234235 ib->ptr[ib->length_dw++] = 0x00000018;
235236 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
236237 ib->ptr[ib->length_dw++] = handle;
237238 ib->ptr[ib->length_dw++] = 0x00000000;
238− ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
239− ib->ptr[ib->length_dw++] = dummy;
239+ ib->ptr[ib->length_dw++] = upper_32_bits(addr);
240+ ib->ptr[ib->length_dw++] = addr;
240241
241242 ib->ptr[ib->length_dw++] = 0x00000014;
242243 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
@@ -275,13 +276,14 @@ err: · 32 unmodified lines
275276 * Close up a stream for HW test or if userspace failed to do so
276277 */
277278 static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
278− struct dma_fence **fence)
279+ struct amdgpu_bo *bo,
280+ struct dma_fence **fence)
279281 {
280282 const unsigned ib_size_dw = 16;
281283 struct amdgpu_job *job;
282284 struct amdgpu_ib *ib;
283285 struct dma_fence *f = NULL;
284− uint64_t dummy;
286+ uint64_t addr;
285287 int i, r;
286288
287289 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
@@ -289,15 +291,15 @@ static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handl · 1 unmodified line
289291 return r;
290292
291293 ib = &job->ibs[0];
292− dummy = ib->gpu_addr + 1024;
294+ addr = amdgpu_bo_gpu_offset(bo);
293295
294296 ib->length_dw = 0;
295297 ib->ptr[ib->length_dw++] = 0x00000018;
296298 ib->ptr[ib->length_dw++] = 0x00000001;
297299 ib->ptr[ib->length_dw++] = handle;
298300 ib->ptr[ib->length_dw++] = 0x00000000;
299− ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
300− ib->ptr[ib->length_dw++] = dummy;
301+ ib->ptr[ib->length_dw++] = upper_32_bits(addr);
302+ ib->ptr[ib->length_dw++] = addr;
301303
302304 ib->ptr[ib->length_dw++] = 0x00000014;
303305 ib->ptr[ib->length_dw++] = 0x00000002;
@@ -334,13 +336,20 @@ err: · 30 unmodified lines
334336 static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
335337 {
336338 struct dma_fence *fence = NULL;
339+ struct amdgpu_bo *bo = NULL;
337340 long r;
338341
339− r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL);
342+ r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,
343+ AMDGPU_GEM_DOMAIN_VRAM,
344+ &bo, NULL, NULL);
345+ if (r)
346+ return r;
347+
348+ r = uvd_v7_0_enc_get_create_msg(ring, 1, bo, NULL);
340349 if (r)
341350 goto error;
342351
343− r = uvd_v7_0_enc_get_destroy_msg(ring, 1, &fence);
352+ r = uvd_v7_0_enc_get_destroy_msg(ring, 1, bo, &fence);
344353 if (r)
345354 goto error;
346355
@@ -352,6 +361,8 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 5 unmodified lines
352361
353362 error:
354363 dma_fence_put(fence);
364+ amdgpu_bo_unreserve(bo);
365+ amdgpu_bo_unref(&bo);
355366 return r;
356367 }
357368
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c+7−0
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525
2626 #include "amdgpu.h"
2727 #include "amdgpu_vcn.h"
28+#include "amdgpu_pm.h"
2829 #include "soc15.h"
2930 #include "soc15d.h"
3031 #include "vcn_v2_0.h"
@@ -709,6 +710,9 @@ static int vcn_v2_5_start(struct amdgpu_device *adev) · 678 unmodified lines
709710 uint32_t rb_bufsz, tmp;
710711 int i, j, k, r;
711712
713+ if (adev->pm.dpm_enabled)
714+ amdgpu_dpm_enable_uvd(adev, true);
715+
712716 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
713717 if (adev->vcn.harvest_config & (1 << i))
714718 continue;
@@ -939,6 +943,9 @@ static int vcn_v2_5_stop(struct amdgpu_device *adev) · 224 unmodified lines
939943 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
940944 }
941945
946+ if (adev->pm.dpm_enabled)
947+ amdgpu_dpm_enable_uvd(adev, false);
948+
942949 return 0;
943950 }
944951
drivers/gpu/drm/amd/amdgpu/vi.c+79−5
@@ -689,16 +689,50 @@ static int vi_gpu_pci_config_reset(struct amdgpu_device *adev) · 688 unmodified lines
689689 return -EINVAL;
690690 }
691691
692+int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap)
693+{
694+ void *pp_handle = adev->powerplay.pp_handle;
695+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
696+
697+ if (!pp_funcs || !pp_funcs->get_asic_baco_capability) {
698+ *cap = false;
699+ return -ENOENT;
700+ }
701+
702+ return pp_funcs->get_asic_baco_capability(pp_handle, cap);
703+}
704+
705+int smu7_asic_baco_reset(struct amdgpu_device *adev)
706+{
707+ void *pp_handle = adev->powerplay.pp_handle;
708+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
709+
710+ if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state)
711+ return -ENOENT;
712+
713+ /* enter BACO state */
714+ if (pp_funcs->set_asic_baco_state(pp_handle, 1))
715+ return -EIO;
716+
717+ /* exit BACO state */
718+ if (pp_funcs->set_asic_baco_state(pp_handle, 0))
719+ return -EIO;
720+
721+ dev_info(adev->dev, "GPU BACO reset\n");
722+
723+ return 0;
724+}
725+
692726 /**
693− * vi_asic_reset - soft reset GPU
727+ * vi_asic_pci_config_reset - soft reset GPU
694728 *
695729 * @adev: amdgpu_device pointer
696730 *
697− * Look up which blocks are hung and attempt
698− * to reset them.
731+ * Use PCI Config method to reset the GPU.
732+ *
699733 * Returns 0 for success.
700734 */
701−static int vi_asic_reset(struct amdgpu_device *adev)
735+static int vi_asic_pci_config_reset(struct amdgpu_device *adev)
702736 {
703737 int r;
704738
@@ -714,7 +748,47 @@ static int vi_asic_reset(struct amdgpu_device *adev) · 9 unmodified lines
714748 static enum amd_reset_method
715749 vi_asic_reset_method(struct amdgpu_device *adev)
716750 {
717− return AMD_RESET_METHOD_LEGACY;
751+ bool baco_reset;
752+
753+ switch (adev->asic_type) {
754+ case CHIP_FIJI:
755+ case CHIP_TONGA:
756+ case CHIP_POLARIS10:
757+ case CHIP_POLARIS11:
758+ case CHIP_POLARIS12:
759+ case CHIP_TOPAZ:
760+ smu7_asic_get_baco_capability(adev, &baco_reset);
761+ break;
762+ default:
763+ baco_reset = false;
764+ break;
765+ }
766+
767+ if (baco_reset)
768+ return AMD_RESET_METHOD_BACO;
769+ else
770+ return AMD_RESET_METHOD_LEGACY;
771+}
772+
773+/**
774+ * vi_asic_reset - soft reset GPU
775+ *
776+ * @adev: amdgpu_device pointer
777+ *
778+ * Look up which blocks are hung and attempt
779+ * to reset them.
780+ * Returns 0 for success.
781+ */
782+static int vi_asic_reset(struct amdgpu_device *adev)
783+{
784+ int r;
785+
786+ if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)
787+ r = smu7_asic_baco_reset(adev);
788+ else
789+ r = vi_asic_pci_config_reset(adev);
790+
791+ return r;
718792 }
719793
720794 static u32 vi_get_config_memsize(struct amdgpu_device *adev)
drivers/gpu/drm/amd/amdgpu/vi.h+3−0
@@ -31,4 +31,7 @@ void vi_srbm_select(struct amdgpu_device *adev, · 30 unmodified lines
3131 int vi_set_ip_blocks(struct amdgpu_device *adev);
3232
3333 void legacy_doorbell_index_init(struct amdgpu_device *adev);
34+int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap);
35+int smu7_asic_baco_reset(struct amdgpu_device *adev);
36+
3437 #endif
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c+15−1
@@ -3396,7 +3396,8 @@ static void fill_stream_properties_from_drm_display_mode( · 3395 unmodified lines
33963396 struct dc_crtc_timing *timing_out = &stream->timing;
33973397 const struct drm_display_info *info = &connector->display_info;
33983398 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
3399− memset(timing_out, 0, sizeof(struct dc_crtc_timing));
3399+ struct hdmi_vendor_infoframe hv_frame;
3400+ struct hdmi_avi_infoframe avi_frame;
34003401
34013402 timing_out->h_border_left = 0;
34023403 timing_out->h_border_right = 0;
@@ -3433,6 +3434,13 @@ static void fill_stream_properties_from_drm_display_mode( · 30 unmodified lines
34333434 timing_out->flags.VSYNC_POSITIVE_POLARITY = 1;
34343435 }
34353436
3437+ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
3438+ drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, (struct drm_connector *)connector, mode_in);
3439+ timing_out->vic = avi_frame.video_code;
3440+ drm_hdmi_vendor_infoframe_from_display_mode(&hv_frame, (struct drm_connector *)connector, mode_in);
3441+ timing_out->hdmi_vic = hv_frame.vic;
3442+ }
3443+
34363444 timing_out->h_addressable = mode_in->crtc_hdisplay;
34373445 timing_out->h_total = mode_in->crtc_htotal;
34383446 timing_out->h_sync_width =
@@ -3653,6 +3661,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 214 unmodified lines
36533661
36543662 stream->dm_stream_context = aconnector;
36553663
3664+ stream->timing.flags.LTE_340MCSC_SCRAMBLE =
3665+ drm_connector->display_info.hdmi.scdc.scrambling.low_rates;
3666+
36563667 list_for_each_entry(preferred_mode, &aconnector->base.modes, head) {
36573668 /* Search for preferred mode */
36583669 if (preferred_mode->type & DRM_MODE_TYPE_PREFERRED) {
@@ -3727,6 +3738,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 68 unmodified lines
37273738
37283739 update_stream_signal(stream, sink);
37293740
3741+ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
3742+ mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false);
3743+
37303744 finish:
37313745 dc_sink_release(sink);
37323746
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c+7−2
@@ -122,11 +122,16 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 121 unmodified lines
122122 }
123123
124124 /* Configure dithering */
125− if (!dm_need_crc_dither(source))
125+ if (!dm_need_crc_dither(source)) {
126126 dc_stream_set_dither_option(stream_state, DITHER_OPTION_TRUN8);
127− else
127+ dc_stream_set_dyn_expansion(stream_state->ctx->dc, stream_state,
128+ DYN_EXPANSION_DISABLE);
129+ } else {
128130 dc_stream_set_dither_option(stream_state,
129131 DITHER_OPTION_DEFAULT);
132+ dc_stream_set_dyn_expansion(stream_state->ctx->dc, stream_state,
133+ DYN_EXPANSION_AUTO);
134+ }
130135
131136 unlock:
132137 mutex_unlock(&adev->dm.dc_lock);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c+96−13
@@ -589,10 +589,9 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp, · 588 unmodified lines
589589 if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
590590 pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
591591 &wm_with_clock_ranges);
592− else if (adev->smu.funcs &&
593− adev->smu.funcs->set_watermarks_for_clock_ranges)
592+ else
594593 smu_set_watermarks_for_clock_ranges(&adev->smu,
595− &wm_with_clock_ranges);
594+ &wm_with_clock_ranges);
596595 }
597596
598597 void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
@@ -665,7 +664,6 @@ enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp, · 66 unmodified lines
665664 {
666665 const struct dc_context *ctx = pp->dm;
667666 struct amdgpu_device *adev = ctx->driver_context;
668− struct smu_context *smu = &adev->smu;
669667 struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges;
670668 struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks =
671669 wm_with_clock_ranges.wm_dmif_clocks_ranges;
@@ -708,15 +706,7 @@ enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp, · 36 unmodified lines
708706 ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
709707 }
710708
711− if (!smu->funcs)
712− return PP_SMU_RESULT_UNSUPPORTED;
713−
714− /* 0: successful or smu.funcs->set_watermarks_for_clock_ranges = NULL;
715− * 1: fail
716− */
717− if (smu_set_watermarks_for_clock_ranges(&adev->smu,
718− &wm_with_clock_ranges))
719− return PP_SMU_RESULT_UNSUPPORTED;
709+ smu_set_watermarks_for_clock_ranges(&adev->smu, &wm_with_clock_ranges);
720710
721711 return PP_SMU_RESULT_OK;
722712 }
@@ -901,6 +891,90 @@ enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp, · 178 unmodified lines
901891 return PP_SMU_RESULT_FAIL;
902892 }
903893
894+#ifdef CONFIG_DRM_AMD_DC_DCN2_1
895+enum pp_smu_status pp_rn_get_dpm_clock_table(
896+ struct pp_smu *pp, struct dpm_clocks *clock_table)
897+{
898+ const struct dc_context *ctx = pp->dm;
899+ struct amdgpu_device *adev = ctx->driver_context;
900+ struct smu_context *smu = &adev->smu;
901+
902+ if (!smu->ppt_funcs)
903+ return PP_SMU_RESULT_UNSUPPORTED;
904+
905+ if (!smu->ppt_funcs->get_dpm_clock_table)
906+ return PP_SMU_RESULT_UNSUPPORTED;
907+
908+ if (!smu->ppt_funcs->get_dpm_clock_table(smu, clock_table))
909+ return PP_SMU_RESULT_OK;
910+
911+ return PP_SMU_RESULT_FAIL;
912+}
913+
914+enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp,
915+ struct pp_smu_wm_range_sets *ranges)
916+{
917+ const struct dc_context *ctx = pp->dm;
918+ struct amdgpu_device *adev = ctx->driver_context;
919+ struct smu_context *smu = &adev->smu;
920+ struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges;
921+ struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks =
922+ wm_with_clock_ranges.wm_dmif_clocks_ranges;
923+ struct dm_pp_clock_range_for_mcif_wm_set_soc15 *wm_soc_clocks =
924+ wm_with_clock_ranges.wm_mcif_clocks_ranges;
925+ int32_t i;
926+
927+ if (!smu->funcs)
928+ return PP_SMU_RESULT_UNSUPPORTED;
929+
930+ wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
931+ wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets;
932+
933+ for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) {
934+ if (ranges->reader_wm_sets[i].wm_inst > 3)
935+ wm_dce_clocks[i].wm_set_id = WM_SET_A;
936+ else
937+ wm_dce_clocks[i].wm_set_id =
938+ ranges->reader_wm_sets[i].wm_inst;
939+
940+ wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz =
941+ ranges->reader_wm_sets[i].min_drain_clk_mhz;
942+
943+ wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz =
944+ ranges->reader_wm_sets[i].max_drain_clk_mhz;
945+
946+ wm_dce_clocks[i].wm_min_mem_clk_in_khz =
947+ ranges->reader_wm_sets[i].min_fill_clk_mhz;
948+
949+ wm_dce_clocks[i].wm_max_mem_clk_in_khz =
950+ ranges->reader_wm_sets[i].max_fill_clk_mhz;
951+ }
952+
953+ for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) {
954+ if (ranges->writer_wm_sets[i].wm_inst > 3)
955+ wm_soc_clocks[i].wm_set_id = WM_SET_A;
956+ else
957+ wm_soc_clocks[i].wm_set_id =
958+ ranges->writer_wm_sets[i].wm_inst;
959+ wm_soc_clocks[i].wm_min_socclk_clk_in_khz =
960+ ranges->writer_wm_sets[i].min_fill_clk_mhz;
961+
962+ wm_soc_clocks[i].wm_max_socclk_clk_in_khz =
963+ ranges->writer_wm_sets[i].max_fill_clk_mhz;
964+
965+ wm_soc_clocks[i].wm_min_mem_clk_in_khz =
966+ ranges->writer_wm_sets[i].min_drain_clk_mhz;
967+
968+ wm_soc_clocks[i].wm_max_mem_clk_in_khz =
969+ ranges->writer_wm_sets[i].max_drain_clk_mhz;
970+ }
971+
972+ smu_set_watermarks_for_clock_ranges(&adev->smu, &wm_with_clock_ranges);
973+
974+ return PP_SMU_RESULT_OK;
975+}
976+#endif
977+
904978 void dm_pp_get_funcs(
905979 struct dc_context *ctx,
906980 struct pp_smu_funcs *funcs)
@@ -945,6 +1019,15 @@ void dm_pp_get_funcs( · 38 unmodified lines
9451019 funcs->nv_funcs.set_pstate_handshake_support = pp_nv_set_pstate_handshake_support;
9461020 break;
9471021 #endif
1022+
1023+#ifdef CONFIG_DRM_AMD_DC_DCN2_1
1024+ case DCN_VERSION_2_1:
1025+ funcs->ctx.ver = PP_SMU_VER_RN;
1026+ funcs->rn_funcs.pp_smu.dm = ctx;
1027+ funcs->rn_funcs.set_wm_ranges = pp_rn_set_wm_ranges;
1028+ funcs->rn_funcs.get_dpm_clock_table = pp_rn_get_dpm_clock_table;
1029+ break;
1030+#endif
9481031 default:
9491032 DRM_ERROR("smu version is not supported !\n");
9501033 break;
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c+2−5
@@ -2543,7 +2543,6 @@ static enum bp_result construct_integrated_info( · 2542 unmodified lines
25432543
25442544 /* Sort voltage table from low to high*/
25452545 if (result == BP_RESULT_OK) {
2546− struct clock_voltage_caps temp = {0, 0};
25472546 uint32_t i;
25482547 uint32_t j;
25492548
@@ -2553,10 +2552,8 @@ static enum bp_result construct_integrated_info( · 3 unmodified lines
25532552 info->disp_clk_voltage[j].max_supported_clk <
25542553 info->disp_clk_voltage[j-1].max_supported_clk) {
25552554 /* swap j and j - 1*/
2556− temp = info->disp_clk_voltage[j-1];
2557− info->disp_clk_voltage[j-1] =
2558− info->disp_clk_voltage[j];
2559− info->disp_clk_voltage[j] = temp;
2555+ swap(info->disp_clk_voltage[j - 1],
2556+ info->disp_clk_voltage[j]);
25602557 }
25612558 }
25622559 }
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c+2−6
@@ -1613,8 +1613,6 @@ static enum bp_result construct_integrated_info( · 1612 unmodified lines
16131613
16141614 struct atom_common_table_header *header;
16151615 struct atom_data_revision revision;
1616−
1617− struct clock_voltage_caps temp = {0, 0};
16181616 uint32_t i;
16191617 uint32_t j;
16201618
@@ -1644,10 +1642,8 @@ static enum bp_result construct_integrated_info( · 23 unmodified lines
16441642 info->disp_clk_voltage[j-1].max_supported_clk
16451643 ) {
16461644 /* swap j and j - 1*/
1647− temp = info->disp_clk_voltage[j-1];
1648− info->disp_clk_voltage[j-1] =
1649− info->disp_clk_voltage[j];
1650− info->disp_clk_voltage[j] = temp;
1645+ swap(info->disp_clk_voltage[j - 1],
1646+ info->disp_clk_voltage[j]);
16511647 }
16521648 }
16531649 }
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c+25−0
@@ -65,6 +65,31 @@ int clk_mgr_helper_get_active_display_cnt( · 64 unmodified lines
6565 return display_count;
6666 }
6767
68+void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
69+{
70+ struct dc_link *edp_link = get_edp_link(dc);
71+
72+ if (dc->hwss.exit_optimized_pwr_state)
73+ dc->hwss.exit_optimized_pwr_state(dc, dc->current_state);
74+
75+ if (edp_link) {
76+ clk_mgr->psr_allow_active_cache = edp_link->psr_allow_active;
77+ dc_link_set_psr_allow_active(edp_link, false, false);
78+ }
79+
80+}
81+
82+void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
83+{
84+ struct dc_link *edp_link = get_edp_link(dc);
85+
86+ if (edp_link)
87+ dc_link_set_psr_allow_active(edp_link, clk_mgr->psr_allow_active_cache, false);
88+
89+ if (dc->hwss.optimize_pwr_state)
90+ dc->hwss.optimize_pwr_state(dc, dc->current_state);
91+
92+}
6893
6994 struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg)
7095 {
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c+24−0
@@ -349,12 +349,36 @@ void dcn2_get_clock(struct clk_mgr *clk_mgr, · 348 unmodified lines
349349 }
350350 }
351351
352+static bool dcn2_are_clock_states_equal(struct dc_clocks *a,
353+ struct dc_clocks *b)
354+{
355+ if (a->dispclk_khz != b->dispclk_khz)
356+ return false;
357+ else if (a->dppclk_khz != b->dppclk_khz)
358+ return false;
359+ else if (a->dcfclk_khz != b->dcfclk_khz)
360+ return false;
361+ else if (a->socclk_khz != b->socclk_khz)
362+ return false;
363+ else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz)
364+ return false;
365+ else if (a->phyclk_khz != b->phyclk_khz)
366+ return false;
367+ else if (a->dramclk_khz != b->dramclk_khz)
368+ return false;
369+ else if (a->p_state_change_support != b->p_state_change_support)
370+ return false;
371+
372+ return true;
373+}
374+
352375 static struct clk_mgr_funcs dcn2_funcs = {
353376 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
354377 .update_clocks = dcn2_update_clocks,
355378 .init_clocks = dcn2_init_clocks,
356379 .enable_pme_wa = dcn2_enable_pme_wa,
357380 .get_clock = dcn2_get_clock,
381+ .are_clock_states_equal = dcn2_are_clock_states_equal,
358382 };
359383
360384
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h+1−0
@@ -50,4 +50,5 @@ void dcn2_get_clock(struct clk_mgr *clk_mgr, · 49 unmodified lines
5050 enum dc_clock_type clock_type,
5151 struct dc_clock_config *clock_cfg);
5252
53+void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr);
5354 #endif //__DCN20_CLK_MGR_H__
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c+127−33
@@ -52,6 +52,45 @@ · 51 unmodified lines
5252 #define REG(reg_name) \
5353 (CLK_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
5454
55+
56+/* TODO: evaluate how to lower or disable all dcn clocks in screen off case */
57+int rn_get_active_display_cnt_wa(
58+ struct dc *dc,
59+ struct dc_state *context)
60+{
61+ int i, display_count;
62+ bool hdmi_present = false;
63+
64+ display_count = 0;
65+ for (i = 0; i < context->stream_count; i++) {
66+ const struct dc_stream_state *stream = context->streams[i];
67+
68+ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
69+ hdmi_present = true;
70+ }
71+
72+ for (i = 0; i < dc->link_count; i++) {
73+ const struct dc_link *link = dc->links[i];
74+
75+ /*
76+ * Only notify active stream or virtual stream.
77+ * Need to notify virtual stream to work around
78+ * headless case. HPD does not fire when system is in
79+ * S0i2.
80+ */
81+ /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */
82+ if (link->connector_signal == SIGNAL_TYPE_VIRTUAL ||
83+ link->link_enc->funcs->is_dig_enabled(link->link_enc))
84+ display_count++;
85+ }
86+
87+ /* WA for hang on HDMI after display off back back on*/
88+ if (display_count == 0 && hdmi_present)
89+ display_count = 1;
90+
91+ return display_count;
92+}
93+
5594 void rn_update_clocks(struct clk_mgr *clk_mgr_base,
5695 struct dc_state *context,
5796 bool safe_to_lower)
@@ -62,17 +101,36 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base, · 4 unmodified lines
62101 int display_count;
63102 bool update_dppclk = false;
64103 bool update_dispclk = false;
65− bool enter_display_off = false;
66104 bool dpp_clock_lowered = false;
67− struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
68105
69− display_count = clk_mgr_helper_get_active_display_cnt(dc, context);
106+ struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
70107
71− if (display_count == 0)
72− enter_display_off = true;
108+ if (dc->work_arounds.skip_clock_update)
109+ return;
73110
74− if (enter_display_off == safe_to_lower) {
75− rn_vbios_smu_set_display_count(clk_mgr, display_count);
111+ /*
112+ * if it is safe to lower, but we are already in the lower state, we don't have to do anything
113+ * also if safe to lower is false, we just go in the higher state
114+ */
115+ if (safe_to_lower) {
116+ /* check that we're not already in lower */
117+ if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_OPTIMIZED) {
118+
119+ display_count = rn_get_active_display_cnt_wa(dc, context);
120+ /* if we can go lower, go lower */
121+ if (display_count == 0) {
122+ rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_OPTIMIZED);
123+ /* update power state */
124+ clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_OPTIMIZED;
125+ }
126+ }
127+ } else {
128+ /* check that we're not already in the normal state */
129+ if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_NORMAL) {
130+ rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_NORMAL);
131+ /* update power state */
132+ clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_NORMAL;
133+ }
76134 }
77135
78136 if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr_base->clks.phyclk_khz)) {
@@ -319,7 +377,7 @@ void rn_get_clk_states(struct clk_mgr *clk_mgr_base, struct clk_states *s) · 240 unmodified lines
319377
320378 rn_dump_clk_registers(&sb, clk_mgr_base, &log_info);
321379
322− s->dprefclk_khz = sb.dprefclk;
380+ s->dprefclk_khz = sb.dprefclk * 1000;
323381 }
324382
325383 void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base)
@@ -329,10 +387,19 @@ void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base) · 3 unmodified lines
329387 rn_vbios_smu_enable_pme_wa(clk_mgr);
330388 }
331389
390+void rn_init_clocks(struct clk_mgr *clk_mgr)
391+{
392+ memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
393+ // Assumption is that boot state always supports pstate
394+ clk_mgr->clks.p_state_change_support = true;
395+ clk_mgr->clks.prev_p_state_change_support = true;
396+ clk_mgr->clks.pwr_state = DCN_PWR_STATE_NORMAL;
397+}
398+
332399 static struct clk_mgr_funcs dcn21_funcs = {
333400 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
334401 .update_clocks = rn_update_clocks,
335− .init_clocks = dcn2_init_clocks,
402+ .init_clocks = rn_init_clocks,
336403 .enable_pme_wa = rn_enable_pme_wa,
337404 /* .dump_clk_registers = rn_dump_clk_registers */
338405 };
@@ -405,7 +472,7 @@ struct clk_bw_params rn_bw_params = { · 66 unmodified lines
405472 }
406473 };
407474
408−void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges)
475+void rn_build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges)
409476 {
410477 int i, num_valid_sets;
411478
@@ -462,23 +529,50 @@ void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_ra · 50 unmodified lines
462529
463530 }
464531
465−void clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
532+static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
466533 {
467534 int i;
468535
536+ for (i = 0; i < PP_SMU_NUM_DCFCLK_DPM_LEVELS; i++) {
537+ if (clock_table->DcfClocks[i].Vol == voltage)
538+ return clock_table->DcfClocks[i].Freq;
539+ }
540+
541+ ASSERT(0);
542+ return 0;
543+}
544+
545+void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
546+{
547+ int i, j = 0;
548+
549+ j = -1;
550+
469551 ASSERT(PP_SMU_NUM_FCLK_DPM_LEVELS <= MAX_NUM_DPM_LVL);
470552
471− for (i = 0; i < PP_SMU_NUM_FCLK_DPM_LEVELS; i++) {
472− if (clock_table->FClocks[i].Freq == 0)
553+ /* Find lowest DPM, FCLK is filled in reverse order*/
554+
555+ for (i = PP_SMU_NUM_FCLK_DPM_LEVELS - 1; i >= 0; i--) {
556+ if (clock_table->FClocks[i].Freq != 0) {
557+ j = i;
473558 break;
559+ }
560+ }
561+
562+ if (j == -1) {
563+ /* clock table is all 0s, just use our own hardcode */
564+ ASSERT(0);
565+ return;
566+ }
567+
568+ bw_params->clk_table.num_entries = j + 1;
474569
475− bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i].Freq;
476− bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[i].Freq;
477− bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[i].Freq;
478− bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i].Freq;
479− bw_params->clk_table.entries[i].voltage = clock_table->FClocks[i].Vol;
570+ for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) {
571+ bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[j].Freq;
572+ bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[j].Freq;
573+ bw_params->clk_table.entries[i].voltage = clock_table->FClocks[j].Vol;
574+ bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->FClocks[j].Vol);
480575 }
481− bw_params->clk_table.num_entries = i;
482576
483577 bw_params->vram_type = asic_id->vram_type;
484578 bw_params->num_channels = asic_id->vram_width / DDR4_DRAM_WIDTH;
@@ -486,7 +580,7 @@ void clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct d · 1 unmodified line
486580 for (i = 0; i < WM_SET_COUNT; i++) {
487581 bw_params->wm_table.entries[i].wm_inst = i;
488582
489− if (clock_table->FClocks[i].Freq == 0) {
583+ if (i >= bw_params->clk_table.num_entries) {
490584 bw_params->wm_table.entries[i].valid = false;
491585 continue;
492586 }
@@ -547,25 +641,24 @@ void rn_clk_mgr_construct( · 54 unmodified lines
547641 clk_mgr->dentist_vco_freq_khz = 3600000;
548642
549643 rn_dump_clk_registers(&s, &clk_mgr->base, &log_info);
550− clk_mgr->base.dprefclk_khz = s.dprefclk;
551−
552− if (clk_mgr->base.dprefclk_khz != 600000) {
553− clk_mgr->base.dprefclk_khz = 600000;
554− ASSERT(1); //TODO: Renoir follow up.
555− }
644+ /* Convert dprefclk units from MHz to KHz */
645+ /* Value already divided by 10, some resolution lost */
646+ clk_mgr->base.dprefclk_khz = s.dprefclk * 1000;
556647
557648 /* in case we don't get a value from the register, use default */
558− if (clk_mgr->base.dprefclk_khz == 0)
649+ if (clk_mgr->base.dprefclk_khz == 0) {
650+ ASSERT(clk_mgr->base.dprefclk_khz == 600000);
559651 clk_mgr->base.dprefclk_khz = 600000;
652+ }
560653 }
561654
562655 dce_clock_read_ss_info(clk_mgr);
563656
564657 clk_mgr->base.bw_params = &rn_bw_params;
565658
566− if (pp_smu) {
659+ if (pp_smu && pp_smu->rn_funcs.get_dpm_clock_table) {
567660 pp_smu->rn_funcs.get_dpm_clock_table(&pp_smu->rn_funcs.pp_smu, &clock_table);
568− clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id);
661+ rn_clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id);
569662 }
570663
571664 /*
@@ -576,15 +669,16 @@ void rn_clk_mgr_construct( · 4 unmodified lines
576669 if (!debug->disable_pplib_wm_range) {
577670 struct pp_smu_wm_range_sets ranges = {0};
578671
579− build_watermark_ranges(clk_mgr->base.bw_params, &ranges);
672+ rn_build_watermark_ranges(clk_mgr->base.bw_params, &ranges);
580673
581674 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
582675 if (pp_smu && pp_smu->rn_funcs.set_wm_ranges)
583676 pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges);
584677 }
585678
586− /* enable powerfeatures when displaycount goes to 0 */
587− if (!debug->disable_48mhz_pwrdwn)
588− rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr);
679+ if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver >= 0x00371500) {
680+ /* enable powerfeatures when displaycount goes to 0 */
681+ rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn);
682+ }
589683 }
590684
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h+10−1
@@ -26,11 +26,20 @@ · 25 unmodified lines
2626 #ifndef __RN_CLK_MGR_H__
2727 #define __RN_CLK_MGR_H__
2828
29+#include "clk_mgr.h"
30+#include "dm_pp_smu.h"
31+
2932 struct rn_clk_registers {
3033 uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */
3134 };
3235
33−
36+void rn_build_watermark_ranges(
37+ struct clk_bw_params *bw_params,
38+ struct pp_smu_wm_range_sets *ranges);
39+void rn_clk_mgr_helper_populate_bw_params(
40+ struct clk_bw_params *bw_params,
41+ struct dpm_clocks *clock_table,
42+ struct hw_asic_id *asic_id);
3443 void rn_clk_mgr_construct(struct dc_context *ctx,
3544 struct clk_mgr_internal *clk_mgr,
3645 struct pp_smu_funcs *pp_smu,
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c+18−20
@@ -33,7 +33,7 @@ · 32 unmodified lines
3333 #include "mp/mp_12_0_0_sh_mask.h"
3434
3535 #define REG(reg_name) \
36− (MP1_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
36+ (MP0_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
3737
3838 #define FN(reg_name, field) \
3939 FD(reg_name##__##field)
@@ -84,16 +84,12 @@ int rn_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dis · 44 unmodified lines
8484 int actual_dispclk_set_mhz = -1;
8585 struct dc *core_dc = clk_mgr->base.ctx->dc;
8686 struct dmcu *dmcu = core_dc->res_pool->dmcu;
87− uint32_t clk = requested_dispclk_khz / 1000;
88−
89− if (clk <= 100)
90− clk = 101;
9187
9288 /* Unit of SMU msg parameter is Mhz */
9389 actual_dispclk_set_mhz = rn_vbios_smu_send_msg_with_param(
9490 clk_mgr,
9591 VBIOSSMC_MSG_SetDispclkFreq,
96− clk);
92+ requested_dispclk_khz / 1000);
9793
9894 if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
9995 if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
@@ -124,7 +120,7 @@ int rn_vbios_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int reque · 24 unmodified lines
124120 {
125121 int actual_dcfclk_set_mhz = -1;
126122
127− if (clk_mgr->smu_ver < 0xFFFFFFFF)
123+ if (clk_mgr->smu_ver < 0x370c00)
128124 return actual_dcfclk_set_mhz;
129125
130126 actual_dcfclk_set_mhz = rn_vbios_smu_send_msg_with_param(
@@ -139,7 +135,7 @@ int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int · 8 unmodified lines
139135 {
140136 int actual_min_ds_dcfclk_mhz = -1;
141137
142− if (clk_mgr->smu_ver < 0xFFFFFFFF)
138+ if (clk_mgr->smu_ver < 0x370c00)
143139 return actual_min_ds_dcfclk_mhz;
144140
145141 actual_min_ds_dcfclk_mhz = rn_vbios_smu_send_msg_with_param(
@@ -162,33 +158,35 @@ int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_ · 16 unmodified lines
162158 {
163159 int actual_dppclk_set_mhz = -1;
164160
165− uint32_t clk = requested_dpp_khz / 1000;
166−
167− if (clk <= 100)
168− clk = 101;
169−
170161 actual_dppclk_set_mhz = rn_vbios_smu_send_msg_with_param(
171162 clk_mgr,
172163 VBIOSSMC_MSG_SetDppclkFreq,
173− clk);
164+ requested_dpp_khz / 1000);
174165
175166 return actual_dppclk_set_mhz * 1000;
176167 }
177168
178−void rn_vbios_smu_set_display_count(struct clk_mgr_internal *clk_mgr, int display_count)
169+void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, enum dcn_pwr_state state)
179170 {
171+ int disp_count;
172+
173+ if (state == DCN_PWR_STATE_OPTIMIZED)
174+ disp_count = 0;
175+ else
176+ disp_count = 1;
177+
180178 rn_vbios_smu_send_msg_with_param(
181− clk_mgr,
182− VBIOSSMC_MSG_SetDisplayCount,
183− display_count);
179+ clk_mgr,
180+ VBIOSSMC_MSG_SetDisplayCount,
181+ disp_count);
184182 }
185183
186−void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr)
184+void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable)
187185 {
188186 rn_vbios_smu_send_msg_with_param(
189187 clk_mgr,
190188 VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown,
191− 0);
189+ enable);
192190 }
193191
194192 void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.h+2−2
@@ -33,8 +33,8 @@ int rn_vbios_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int reque · 32 unmodified lines
3333 int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz);
3434 void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz);
3535 int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz);
36−void rn_vbios_smu_set_display_count(struct clk_mgr_internal *clk_mgr, int display_count);
37−void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr);
36+void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, int display_count);
37+void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
3838 void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr);
3939
4040 #endif /* DAL_DC_DCN10_RV1_CLK_MGR_VBIOS_SMU_H_ */
drivers/gpu/drm/amd/display/dc/core/dc.c+91−9
@@ -411,6 +411,27 @@ bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, · 410 unmodified lines
411411 return false;
412412 }
413413
414+void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
415+ enum dc_dynamic_expansion option)
416+{
417+ /* OPP FMT dyn expansion updates*/
418+ int i = 0;
419+ struct pipe_ctx *pipe_ctx;
420+
421+ for (i = 0; i < MAX_PIPES; i++) {
422+ if (dc->current_state->res_ctx.pipe_ctx[i].stream
423+ == stream) {
424+ pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
425+ pipe_ctx->stream_res.opp->dyn_expansion = option;
426+ pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
427+ pipe_ctx->stream_res.opp,
428+ COLOR_SPACE_YCBCR601,
429+ stream->timing.display_color_depth,
430+ stream->signal);
431+ }
432+ }
433+}
434+
414435 void dc_stream_set_dither_option(struct dc_stream_state *stream,
415436 enum dc_dither_option option)
416437 {
@@ -918,15 +939,11 @@ static void program_timing_sync( · 501 unmodified lines
918939
919940 /* set first pipe with plane as master */
920941 for (j = 0; j < group_size; j++) {
921− struct pipe_ctx *temp;
922−
923942 if (pipe_set[j]->plane_state) {
924943 if (j == 0)
925944 break;
926945
927− temp = pipe_set[0];
928− pipe_set[0] = pipe_set[j];
929− pipe_set[j] = temp;
946+ swap(pipe_set[0], pipe_set[j]);
930947 break;
931948 }
932949 }
@@ -983,6 +1000,10 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 50 unmodified lines
9831000 struct dc_crtc_timing *crtc_timing)
9841001 {
9851002 struct timing_generator *tg;
1003+ struct stream_encoder *se = NULL;
1004+
1005+ struct dc_crtc_timing hw_crtc_timing = {0};
1006+
9861007 struct dc_link *link = sink->link;
9871008 unsigned int i, enc_inst, tg_inst = 0;
9881009
@@ -1002,6 +1023,9 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 13 unmodified lines
10021023
10031024 for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
10041025 if (dc->res_pool->stream_enc[i]->id == enc_inst) {
1026+
1027+ se = dc->res_pool->stream_enc[i];
1028+
10051029 tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg(
10061030 dc->res_pool->stream_enc[i]);
10071031 break;
@@ -1017,10 +1041,46 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 9 unmodified lines
10171041
10181042 tg = dc->res_pool->timing_generators[tg_inst];
10191043
1020− if (!tg->funcs->is_matching_timing)
1044+ if (!tg->funcs->get_hw_timing)
1045+ return false;
1046+
1047+ if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing))
1048+ return false;
1049+
1050+ if (crtc_timing->h_total != hw_crtc_timing.h_total)
1051+ return false;
1052+
1053+ if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left)
1054+ return false;
1055+
1056+ if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable)
1057+ return false;
1058+
1059+ if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right)
10211060 return false;
10221061
1023− if (!tg->funcs->is_matching_timing(tg, crtc_timing))
1062+ if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch)
1063+ return false;
1064+
1065+ if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width)
1066+ return false;
1067+
1068+ if (crtc_timing->v_total != hw_crtc_timing.v_total)
1069+ return false;
1070+
1071+ if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top)
1072+ return false;
1073+
1074+ if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable)
1075+ return false;
1076+
1077+ if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom)
1078+ return false;
1079+
1080+ if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch)
1081+ return false;
1082+
1083+ if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width)
10241084 return false;
10251085
10261086 if (dc_is_dp_signal(link->connector_signal)) {
@@ -1033,6 +1093,20 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 6 unmodified lines
10331093 if (crtc_timing->pix_clk_100hz != pix_clk_100hz)
10341094 return false;
10351095
1096+ if (!se->funcs->dp_get_pixel_format)
1097+ return false;
1098+
1099+ if (!se->funcs->dp_get_pixel_format(
1100+ se,
1101+ &hw_crtc_timing.pixel_encoding,
1102+ &hw_crtc_timing.display_color_depth))
1103+ return false;
1104+
1105+ if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth)
1106+ return false;
1107+
1108+ if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding)
1109+ return false;
10361110 }
10371111
10381112 return true;
@@ -1660,8 +1734,16 @@ enum surface_update_type dc_check_update_surfaces_for_stream( · 621 unmodified lines
16601734 updates[i].surface->update_flags.raw = 0xFFFFFFFF;
16611735 }
16621736
1663− if (type == UPDATE_TYPE_FAST && memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0)
1664− dc->optimized_required = true;
1737+ if (type == UPDATE_TYPE_FAST) {
1738+ // If there's an available clock comparator, we use that.
1739+ if (dc->clk_mgr->funcs->are_clock_states_equal) {
1740+ if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk))
1741+ dc->optimized_required = true;
1742+ // Else we fallback to mem compare.
1743+ } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) {
1744+ dc->optimized_required = true;
1745+ }
1746+ }
16651747
16661748 return type;
16671749 }
drivers/gpu/drm/amd/display/dc/core/dc_link.c+39−7
@@ -743,7 +743,8 @@ static bool wait_for_alt_mode(struct dc_link *link) · 742 unmodified lines
743743 * This does not create remote sinks but will trigger DM
744744 * to start MST detection if a branch is detected.
745745 */
746−bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
746+static bool dc_link_detect_helper(struct dc_link *link,
747+ enum dc_detect_reason reason)
747748 {
748749 struct dc_sink_init_data sink_init_data = { 0 };
749750 struct display_sink_capability sink_caps = { 0 };
@@ -759,6 +760,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) · 9 unmodified lines
759760 bool same_dpcd = true;
760761 enum dc_connection_type new_connection_type = dc_connection_none;
761762 bool perform_dp_seamless_boot = false;
763+
762764 DC_LOGGER_INIT(link->ctx->logger);
763765
764766 if (dc_is_virtual_signal(link->connector_signal))
@@ -871,7 +873,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) · 106 unmodified lines
871873 * empty which leads to allocate_mst_payload() has "0"
872874 * pbn_per_slot value leading to exception on dc_fixpt_div()
873875 */
874− link->verified_link_cap = link->reported_link_cap;
876+ dp_verify_mst_link_cap(link);
877+
875878 if (prev_sink != NULL)
876879 dc_sink_release(prev_sink);
877880 return false;
@@ -1065,6 +1068,23 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) · 187 unmodified lines
10651068 dc_sink_release(prev_sink);
10661069
10671070 return true;
1071+
1072+}
1073+
1074+bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
1075+{
1076+ const struct dc *dc = link->dc;
1077+ bool ret;
1078+
1079+ /* get out of low power state */
1080+ clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
1081+
1082+ ret = dc_link_detect_helper(link, reason);
1083+
1084+ /* Go back to power optimized state */
1085+ clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
1086+
1087+ return ret;
10681088 }
10691089
10701090 bool dc_link_get_hpd_state(struct dc_link *dc_link)
@@ -1510,7 +1530,7 @@ static enum dc_status enable_link_dp( · 439 unmodified lines
15101530
15111531 pipe_ctx->stream_res.pix_clk_params.requested_sym_clk =
15121532 link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
1513− if (!apply_seamless_boot_optimization)
1533+ if (state->clk_mgr && !apply_seamless_boot_optimization)
15141534 state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false);
15151535
15161536 dp_enable_link_phy(
@@ -2237,7 +2257,7 @@ static bool dp_active_dongle_validate_timing( · 720 unmodified lines
22372257 break;
22382258 }
22392259
2240− if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER ||
2260+ if (dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER ||
22412261 dongle_caps->extendedCapValid == false)
22422262 return true;
22432263
@@ -2401,13 +2421,17 @@ bool dc_link_set_abm_disable(const struct dc_link *link) · 157 unmodified lines
24012421 return true;
24022422 }
24032423
2404−bool dc_link_set_psr_enable(const struct dc_link *link, bool enable, bool wait)
2424+bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
24052425 {
24062426 struct dc *core_dc = link->ctx->dc;
24072427 struct dmcu *dmcu = core_dc->res_pool->dmcu;
24082428
2409− if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_enabled)
2410− dmcu->funcs->set_psr_enable(dmcu, enable, wait);
2429+
2430+
2431+ if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_feature_enabled)
2432+ dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
2433+
2434+ link->psr_allow_active = allow_active;
24112435
24122436 return true;
24132437 }
@@ -2718,6 +2742,10 @@ void core_link_enable_stream( · 304 unmodified lines
27182742 enum dc_status status;
27192743 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
27202744
2745+ if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment) &&
2746+ dc_is_virtual_signal(pipe_ctx->stream->signal))
2747+ return;
2748+
27212749 if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) {
27222750 stream->link->link_enc->funcs->setup(
27232751 stream->link->link_enc,
@@ -2860,6 +2888,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) · 136 unmodified lines
28602888 struct dc_stream_state *stream = pipe_ctx->stream;
28612889 struct dc_link *link = stream->sink->link;
28622890
2891+ if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment) &&
2892+ dc_is_virtual_signal(pipe_ctx->stream->signal))
2893+ return;
2894+
28632895 #if defined(CONFIG_DRM_AMD_DC_HDCP)
28642896 update_psp_stream_config(pipe_ctx, true);
28652897 #endif
drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c+14−0
@@ -634,6 +634,20 @@ bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, · 633 unmodified lines
634634 return dce_aux_transfer_with_retries(ddc, payload);
635635 }
636636
637+
638+enum dc_status dc_link_aux_configure_timeout(struct ddc_service *ddc,
639+ uint32_t timeout)
640+{
641+ enum dc_status status = DC_OK;
642+ struct ddc *ddc_pin = ddc->ddc_pin;
643+
644+ if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout == NULL)
645+ return DC_ERROR_UNEXPECTED;
646+ if (!ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout))
647+ status = DC_ERROR_UNEXPECTED;
648+ return status;
649+}
650+
637651 /*test only function*/
638652 void dal_ddc_service_set_ddc_pin(
639653 struct ddc_service *ddc_service,
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c+27−6
@@ -1409,6 +1409,9 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link) · 1408 unmodified lines
14091409 if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
14101410 max_link_cap.link_rate = LINK_RATE_HIGH3;
14111411
1412+ if (link->link_enc->funcs->get_max_link_cap)
1413+ link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
1414+
14121415 /* Lower link settings based on sink's link cap */
14131416 if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
14141417 max_link_cap.lane_count =
@@ -1653,11 +1656,14 @@ bool dp_verify_link_cap_with_retries( · 238 unmodified lines
16531656
16541657 for (i = 0; i < attempts; i++) {
16551658 int fail_count = 0;
1656− enum dc_connection_type type;
1659+ enum dc_connection_type type = dc_connection_none;
16571660
16581661 memset(&link->verified_link_cap, 0,
16591662 sizeof(struct dc_link_settings));
1660− if (!dc_link_detect_sink(link, &type)) {
1663+ if (!dc_link_detect_sink(link, &type) || type == dc_connection_none) {
1664+ link->verified_link_cap.lane_count = LANE_COUNT_ONE;
1665+ link->verified_link_cap.link_rate = LINK_RATE_LOW;
1666+ link->verified_link_cap.link_spread = LINK_SPREAD_DISABLED;
16611667 break;
16621668 } else if (dp_verify_link_cap(link,
16631669 &link->reported_link_cap,
@@ -1670,6 +1676,19 @@ bool dp_verify_link_cap_with_retries( · 6 unmodified lines
16701676 return success;
16711677 }
16721678
1679+bool dp_verify_mst_link_cap(
1680+ struct dc_link *link)
1681+{
1682+ struct dc_link_settings max_link_cap = {0};
1683+
1684+ max_link_cap = get_max_link_cap(link);
1685+ link->verified_link_cap = get_common_supported_link_settings(
1686+ link->reported_link_cap,
1687+ max_link_cap);
1688+
1689+ return true;
1690+}
1691+
16731692 static struct dc_link_settings get_common_supported_link_settings(
16741693 struct dc_link_settings link_setting_a,
16751694 struct dc_link_settings link_setting_b)
@@ -2057,11 +2076,11 @@ static bool allow_hpd_rx_irq(const struct dc_link *link) · 381 unmodified lines
20572076 return false;
20582077 }
20592078
2060−static bool handle_hpd_irq_psr_sink(const struct dc_link *link)
2079+static bool handle_hpd_irq_psr_sink(struct dc_link *link)
20612080 {
20622081 union dpcd_psr_configuration psr_configuration;
20632082
2064− if (!link->psr_enabled)
2083+ if (!link->psr_feature_enabled)
20652084 return false;
20662085
20672086 dm_helpers_dp_read_dpcd(
@@ -2100,8 +2119,8 @@ static bool handle_hpd_irq_psr_sink(const struct dc_link *link) · 32 unmodified lines
21002119 sizeof(psr_error_status.raw));
21012120
21022121 /* PSR error, disable and re-enable PSR */
2103− dc_link_set_psr_enable(link, false, true);
2104− dc_link_set_psr_enable(link, true, true);
2122+ dc_link_set_psr_allow_active(link, false, true);
2123+ dc_link_set_psr_allow_active(link, true, true);
21052124
21062125 return true;
21072126 } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
@@ -2556,6 +2575,7 @@ static void get_active_converter_info( · 448 unmodified lines
25562575 uint8_t data, struct dc_link *link)
25572576 {
25582577 union dp_downstream_port_present ds_port = { .byte = data };
2578+ memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps));
25592579
25602580 /* decode converter info*/
25612581 if (!ds_port.fields.PORT_PRESENT) {
@@ -2702,6 +2722,7 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data, · 140 unmodified lines
27022722 * keep receiver powered all the time.*/
27032723 case DP_BRANCH_DEVICE_ID_0010FA:
27042724 case DP_BRANCH_DEVICE_ID_0080E1:
2725+ case DP_BRANCH_DEVICE_ID_00E04C:
27052726 link->wa_flags.dp_keep_receiver_powered = true;
27062727 break;
27072728
drivers/gpu/drm/amd/display/dc/core/dc_stream.c+2−2
@@ -423,10 +423,10 @@ bool dc_stream_add_writeback(struct dc *dc, · 422 unmodified lines
423423
424424 if (dwb->funcs->is_enabled(dwb)) {
425425 /* writeback pipe already enabled, only need to update */
426− dc->hwss.update_writeback(dc, stream_status, wb_info);
426+ dc->hwss.update_writeback(dc, stream_status, wb_info, dc->current_state);
427427 } else {
428428 /* Enable writeback pipe from scratch*/
429− dc->hwss.enable_writeback(dc, stream_status, wb_info);
429+ dc->hwss.enable_writeback(dc, stream_status, wb_info, dc->current_state);
430430 }
431431 }
432432
drivers/gpu/drm/amd/display/dc/dc.h+17−2
@@ -39,7 +39,7 @@ · 38 unmodified lines
3939 #include "inc/hw/dmcu.h"
4040 #include "dml/display_mode_lib.h"
4141
42−#define DC_VER "3.2.51.1"
42+#define DC_VER "3.2.54"
4343
4444 #define MAX_SURFACES 3
4545 #define MAX_PLANES 6
@@ -111,6 +111,7 @@ struct dc_caps { · 65 unmodified lines
111111 bool force_dp_tps4_for_cp2520;
112112 bool disable_dp_clk_share;
113113 bool psp_setup_panel_mode;
114+ bool extended_aux_timeout_support;
114115 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
115116 bool hw_3d_lut;
116117 #endif
@@ -220,6 +221,7 @@ struct dc_config { · 103 unmodified lines
220221 bool power_down_display_on_boot;
221222 bool edp_not_connected;
222223 bool forced_clocks;
224+ bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well
223225 bool multi_mon_pp_mclk_switch;
224226 };
225227
@@ -245,6 +247,18 @@ enum wm_report_mode { · 19 unmodified lines
245247 WM_REPORT_DEFAULT = 0,
246248 WM_REPORT_OVERRIDE = 1,
247249 };
250+enum dtm_pstate{
251+ dtm_level_p0 = 0,/*highest voltage*/
252+ dtm_level_p1,
253+ dtm_level_p2,
254+ dtm_level_p3,
255+ dtm_level_p4,/*when active_display_count = 0*/
256+};
257+
258+enum dcn_pwr_state {
259+ DCN_PWR_STATE_OPTIMIZED = 0,
260+ DCN_PWR_STATE_NORMAL = 1
261+};
248262
249263 /*
250264 * For any clocks that may differ per pipe
@@ -260,12 +274,13 @@ struct dc_clocks { · 9 unmodified lines
260274 int phyclk_khz;
261275 int dramclk_khz;
262276 bool p_state_change_support;
263−
277+ enum dcn_pwr_state pwr_state;
264278 /*
265279 * Elements below are not compared for the purposes of
266280 * optimization required
267281 */
268282 bool prev_p_state_change_support;
283+ enum dtm_pstate dtm_level;
269284 int max_supported_dppclk_khz;
270285 int max_supported_dispclk_khz;
271286 int bw_dppclk_khz; /*a copy of dppclk_khz*/
drivers/gpu/drm/amd/display/dc/dc_hw_types.h+5−0
@@ -578,6 +578,11 @@ enum dc_quantization_range { · 577 unmodified lines
578578 QUANTIZATION_RANGE_LIMITED
579579 };
580580
581+enum dc_dynamic_expansion {
582+ DYN_EXPANSION_AUTO,
583+ DYN_EXPANSION_DISABLE
584+};
585+
581586 /* XFM */
582587
583588 /* used in struct dc_plane_state */
drivers/gpu/drm/amd/display/dc/dc_link.h+15−2
@@ -126,7 +126,8 @@ struct dc_link { · 125 unmodified lines
126126 unsigned short chip_caps;
127127 unsigned int dpcd_sink_count;
128128 enum edp_revision edp_revision;
129− bool psr_enabled;
129+ bool psr_feature_enabled;
130+ bool psr_allow_active;
130131
131132 /* MST record stream using this link */
132133 struct link_flags {
@@ -158,6 +159,18 @@ static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_ · 25 unmodified lines
158159 return dc->links[link_index];
159160 }
160161
162+static inline struct dc_link *get_edp_link(const struct dc *dc)
163+{
164+ int i;
165+
166+ // report any eDP links, even unconnected DDI's
167+ for (i = 0; i < dc->link_count; i++) {
168+ if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP)
169+ return dc->links[i];
170+ }
171+ return NULL;
172+}
173+
161174 /* Set backlight level of an embedded panel (eDP, LVDS).
162175 * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer
163176 * and 16 bit fractional, where 1.0 is max backlight value.
@@ -170,7 +183,7 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link); · 6 unmodified lines
170183
171184 bool dc_link_set_abm_disable(const struct dc_link *dc_link);
172185
173−bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable, bool wait);
186+bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, bool wait);
174187
175188 bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
176189
drivers/gpu/drm/amd/display/dc/dc_stream.h+3−0
@@ -451,6 +451,9 @@ void dc_stream_set_static_screen_events(struct dc *dc, · 450 unmodified lines
451451 int num_streams,
452452 const struct dc_static_screen_events *events);
453453
454+void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
455+ enum dc_dynamic_expansion option);
456+
454457 void dc_stream_set_dither_option(struct dc_stream_state *stream,
455458 enum dc_dither_option option);
456459
drivers/gpu/drm/amd/display/dc/dce/dce_abm.c+3−0
@@ -77,6 +77,9 @@ static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id) · 76 unmodified lines
7777 /* notifyDMCUMsg */
7878 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
7979
80+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
81+ 1, 80000);
82+
8083 return true;
8184 }
8285
drivers/gpu/drm/amd/display/dc/dce/dce_aux.c+87−6
@@ -42,6 +42,10 @@ · 41 unmodified lines
4242
4343 #include "reg_helper.h"
4444
45+#undef FN
46+#define FN(reg_name, field_name) \
47+ aux110->shift->field_name, aux110->mask->field_name
48+
4549 #define FROM_AUX_ENGINE(ptr) \
4650 container_of((ptr), struct aux_engine_dce110, base)
4751
@@ -55,6 +59,14 @@ enum { · 7 unmodified lines
5559 AUX_TIMED_OUT_RETRY_COUNTER = 2,
5660 AUX_DEFER_RETRY_COUNTER = 6
5761 };
62+
63+#define TIME_OUT_INCREMENT 1016
64+#define TIME_OUT_MULTIPLIER_8 8
65+#define TIME_OUT_MULTIPLIER_16 16
66+#define TIME_OUT_MULTIPLIER_32 32
67+#define TIME_OUT_MULTIPLIER_64 64
68+#define MAX_TIMEOUT_LENGTH 127
69+
5870 static void release_engine(
5971 struct dce_aux *engine)
6072 {
@@ -198,7 +210,7 @@ static void submit_channel_request( · 137 unmodified lines
198210 REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1);
199211
200212 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0,
201− 10, aux110->timeout_period/10);
213+ 10, aux110->polling_timeout_period/10);
202214
203215 /* set the delay and the number of bytes to write */
204216
@@ -327,7 +339,7 @@ static enum aux_channel_operation_result get_channel_status( · 122 unmodified lines
327339
328340 /* poll to make sure that SW_DONE is asserted */
329341 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1,
330− 10, aux110->timeout_period/10);
342+ 10, aux110->polling_timeout_period/10);
331343
332344 value = REG_READ(AUX_SW_STATUS);
333345 /* in case HPD is LOW, exit AUX transaction */
@@ -414,20 +426,82 @@ void dce110_engine_destroy(struct dce_aux **engine) · 80 unmodified lines
414426 *engine = NULL;
415427
416428 }
429+
430+static bool dce_aux_configure_timeout(struct ddc_service *ddc,
431+ uint32_t timeout_in_us)
432+{
433+ uint32_t multiplier = 0;
434+ uint32_t length = 0;
435+ uint32_t timeout = 0;
436+ struct ddc *ddc_pin = ddc->ddc_pin;
437+ struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
438+ struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
439+
440+ /* 1-Update polling timeout period */
441+ aux110->polling_timeout_period = timeout_in_us * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER;
442+
443+ /* 2-Update aux timeout period length and multiplier */
444+ if (timeout_in_us <= TIME_OUT_INCREMENT) {
445+ multiplier = 0;
446+ length = timeout_in_us/TIME_OUT_MULTIPLIER_8;
447+ if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0)
448+ length++;
449+ timeout = length * TIME_OUT_MULTIPLIER_8;
450+ } else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) {
451+ multiplier = 1;
452+ length = timeout_in_us/TIME_OUT_MULTIPLIER_16;
453+ if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0)
454+ length++;
455+ timeout = length * TIME_OUT_MULTIPLIER_16;
456+ } else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) {
457+ multiplier = 2;
458+ length = timeout_in_us/TIME_OUT_MULTIPLIER_32;
459+ if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0)
460+ length++;
461+ timeout = length * TIME_OUT_MULTIPLIER_32;
462+ } else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) {
463+ multiplier = 3;
464+ length = timeout_in_us/TIME_OUT_MULTIPLIER_64;
465+ if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0)
466+ length++;
467+ timeout = length * TIME_OUT_MULTIPLIER_64;
468+ }
469+
470+ length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH;
471+
472+ REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, length, AUX_RX_TIMEOUT_LEN_MUL, multiplier);
473+
474+ return true;
475+}
476+
477+static struct dce_aux_funcs aux_functions = {
478+ .configure_timeout = NULL,
479+ .destroy = NULL,
480+};
481+
417482 struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110,
418483 struct dc_context *ctx,
419484 uint32_t inst,
420485 uint32_t timeout_period,
421− const struct dce110_aux_registers *regs)
486+ const struct dce110_aux_registers *regs,
487+ const struct dce110_aux_registers_mask *mask,
488+ const struct dce110_aux_registers_shift *shift,
489+ bool is_ext_aux_timeout_configurable)
422490 {
423491 aux_engine110->base.ddc = NULL;
424492 aux_engine110->base.ctx = ctx;
425493 aux_engine110->base.delay = 0;
426494 aux_engine110->base.max_defer_write_retry = 0;
427495 aux_engine110->base.inst = inst;
428− aux_engine110->timeout_period = timeout_period;
496+ aux_engine110->polling_timeout_period = timeout_period;
429497 aux_engine110->regs = regs;
430498
499+ aux_engine110->mask = mask;
500+ aux_engine110->shift = shift;
501+ aux_engine110->base.funcs = &aux_functions;
502+ if (is_ext_aux_timeout_configurable)
503+ aux_engine110->base.funcs->configure_timeout = &dce_aux_configure_timeout;
504+
431505 return &aux_engine110->base;
432506 }
433507
@@ -475,7 +549,7 @@ int dce_aux_transfer_raw(struct ddc_service *ddc, · 41 unmodified lines
475549 aux_req.action = i2caux_action_from_payload(payload);
476550
477551 aux_req.address = payload->address;
478− aux_req.delay = payload->defer_delay * 10;
552+ aux_req.delay = 0;
479553 aux_req.length = payload->length;
480554 aux_req.data = payload->data;
481555
@@ -544,8 +618,15 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, · 62 unmodified lines
544618 case AUX_TRANSACTION_REPLY_AUX_DEFER:
545619 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
546620 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
547− if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES)
621+ if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) {
548622 goto fail;
623+ } else {
624+ if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) ||
625+ (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) {
626+ if (payload->defer_delay > 0)
627+ msleep(payload->defer_delay);
628+ }
629+ }
549630 break;
550631
551632 case AUX_TRANSACTION_REPLY_I2C_DEFER:
drivers/gpu/drm/amd/display/dc/dce/dce_aux.h+183−4
@@ -29,6 +29,7 @@ · 28 unmodified lines
2929 #include "i2caux_interface.h"
3030 #include "inc/hw/aux_engine.h"
3131
32+
3233 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
3334 #define AUX_COMMON_REG_LIST0(id)\
3435 SRI(AUX_CONTROL, DP_AUX, id), \
@@ -36,6 +37,7 @@ · 1 unmodified line
3637 SRI(AUX_SW_DATA, DP_AUX, id), \
3738 SRI(AUX_SW_CONTROL, DP_AUX, id), \
3839 SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \
40+ SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id), \
3941 SRI(AUX_SW_STATUS, DP_AUX, id)
4042 #endif
4143
@@ -55,6 +57,7 @@ struct dce110_aux_registers { · 13 unmodified lines
5557 uint32_t AUX_SW_DATA;
5658 uint32_t AUX_SW_CONTROL;
5759 uint32_t AUX_INTERRUPT_CONTROL;
60+ uint32_t AUX_DPHY_RX_CONTROL1;
5861 uint32_t AUX_SW_STATUS;
5962 uint32_t AUXN_IMPCAL;
6063 uint32_t AUXP_IMPCAL;
@@ -62,6 +65,156 @@ struct dce110_aux_registers { · 1 unmodified line
6265 uint32_t AUX_RESET_MASK;
6366 };
6467
68+#define DCE_AUX_REG_FIELD_LIST(type)\
69+ type AUX_EN;\
70+ type AUX_RESET;\
71+ type AUX_RESET_DONE;\
72+ type AUX_REG_RW_CNTL_STATUS;\
73+ type AUX_SW_USE_AUX_REG_REQ;\
74+ type AUX_SW_DONE_USING_AUX_REG;\
75+ type AUX_SW_AUTOINCREMENT_DISABLE;\
76+ type AUX_SW_DATA_RW;\
77+ type AUX_SW_INDEX;\
78+ type AUX_SW_GO;\
79+ type AUX_SW_DATA;\
80+ type AUX_SW_REPLY_BYTE_COUNT;\
81+ type AUX_SW_DONE;\
82+ type AUX_SW_DONE_ACK;\
83+ type AUXN_IMPCAL_ENABLE;\
84+ type AUXP_IMPCAL_ENABLE;\
85+ type AUXN_IMPCAL_OVERRIDE_ENABLE;\
86+ type AUXP_IMPCAL_OVERRIDE_ENABLE;\
87+ type AUX_RX_TIMEOUT_LEN;\
88+ type AUX_RX_TIMEOUT_LEN_MUL;\
89+ type AUXN_CALOUT_ERROR_AK;\
90+ type AUXP_CALOUT_ERROR_AK;\
91+ type AUX_SW_START_DELAY;\
92+ type AUX_SW_WR_BYTES
93+
94+#define DCE10_AUX_MASK_SH_LIST(mask_sh)\
95+ AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\
96+ AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
97+ AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
98+ AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
99+ AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
100+ AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
101+ AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
102+ AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
103+ AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
104+ AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
105+ AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
106+ AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
107+ AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
108+ AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
109+ AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
110+ AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
111+ AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
112+ AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
113+ AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
114+ AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
115+ AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
116+
117+#define DCE_AUX_MASK_SH_LIST(mask_sh)\
118+ AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\
119+ AUX_SF(AUX_CONTROL, AUX_RESET, mask_sh),\
120+ AUX_SF(AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
121+ AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
122+ AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
123+ AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
124+ AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
125+ AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
126+ AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
127+ AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
128+ AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
129+ AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
130+ AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
131+ AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
132+ AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
133+ AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
134+ AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
135+ AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
136+ AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
137+ AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
138+ AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
139+ AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
140+ AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
141+
142+#define DCE12_AUX_MASK_SH_LIST(mask_sh)\
143+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
144+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
145+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
146+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
147+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
148+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
149+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
150+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
151+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
152+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
153+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
154+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
155+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
156+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
157+ AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
158+ AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
159+ AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
160+ AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
161+ AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
162+ AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
163+ AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
164+ AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
165+ AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
166+
167+/* DCN10 MASK */
168+#define DCN10_AUX_MASK_SH_LIST(mask_sh)\
169+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
170+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
171+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
172+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
173+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
174+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
175+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
176+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
177+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
178+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
179+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
180+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
181+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
182+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
183+ AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
184+ AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
185+ AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
186+ AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
187+ AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
188+ AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
189+ AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
190+ AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
191+ AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
192+
193+/* for all other DCN */
194+#define DCN_AUX_MASK_SH_LIST(mask_sh)\
195+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
196+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
197+ AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
198+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
199+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
200+ AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
201+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
202+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
203+ AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
204+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
205+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
206+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
207+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
208+ AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
209+ AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
210+ AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
211+ AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
212+ AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, mask_sh),\
213+ AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN_MUL, mask_sh)
214+
215+#define AUX_SF(reg_name, field_name, post_fix)\
216+ .field_name = reg_name ## __ ## field_name ## post_fix
217+
65218 enum { /* This is the timeout as defined in DP 1.2a,
66219 * 2.3.4 "Detailed uPacket TX AUX CH State Description".
67220 */
@@ -97,20 +250,34 @@ struct dce_aux { · 29 unmodified lines
97250 uint32_t max_defer_write_retry;
98251
99252 bool acquire_reset;
253+ struct dce_aux_funcs *funcs;
254+};
255+
256+struct dce110_aux_registers_mask {
257+ DCE_AUX_REG_FIELD_LIST(uint32_t);
258+};
259+
260+struct dce110_aux_registers_shift {
261+ DCE_AUX_REG_FIELD_LIST(uint8_t);
100262 };
101263
264+
102265 struct aux_engine_dce110 {
103266 struct dce_aux base;
104267 const struct dce110_aux_registers *regs;
268+ const struct dce110_aux_registers_mask *mask;
269+ const struct dce110_aux_registers_shift *shift;
105270 struct {
106271 uint32_t aux_control;
107272 uint32_t aux_arb_control;
108273 uint32_t aux_sw_data;
109274 uint32_t aux_sw_control;
110275 uint32_t aux_interrupt_control;
276+ uint32_t aux_dphy_rx_control1;
277+ uint32_t aux_dphy_rx_control0;
111278 uint32_t aux_sw_status;
112279 } addr;
113− uint32_t timeout_period;
280+ uint32_t polling_timeout_period;
114281 };
115282
116283 struct aux_engine_dce110_init_data {
@@ -120,12 +287,15 @@ struct aux_engine_dce110_init_data { · 3 unmodified lines
120287 const struct dce110_aux_registers *regs;
121288 };
122289
123−struct dce_aux *dce110_aux_engine_construct(
124− struct aux_engine_dce110 *aux_engine110,
290+struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110,
125291 struct dc_context *ctx,
126292 uint32_t inst,
127293 uint32_t timeout_period,
128− const struct dce110_aux_registers *regs);
294+ const struct dce110_aux_registers *regs,
295+
296+ const struct dce110_aux_registers_mask *mask,
297+ const struct dce110_aux_registers_shift *shift,
298+ bool is_ext_aux_timeout_configurable);
129299
130300 void dce110_engine_destroy(struct dce_aux **engine);
131301
@@ -139,4 +309,13 @@ int dce_aux_transfer_raw(struct ddc_service *ddc, · 7 unmodified lines
139309
140310 bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
141311 struct aux_payload *cmd);
312+
313+struct dce_aux_funcs {
314+ bool (*configure_timeout)
315+ (struct ddc_service *ddc,
316+ uint32_t timeout);
317+ void (*destroy)
318+ (struct aux_engine **ptr);
319+};
320+
142321 #endif
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h+1−0
@@ -679,6 +679,7 @@ struct dce_hwseq_registers { · 678 unmodified lines
679679 HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
680680 HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
681681 HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
682+ HWSEQ_LVTMA_MASK_SH_LIST(mask_sh), \
682683 HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
683684 HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
684685 #endif
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c+14−1
@@ -506,6 +506,14 @@ static const struct dce_mem_input_mask mi_masks = { · 505 unmodified lines
506506 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
507507 };
508508
509+static const struct dce110_aux_registers_shift aux_shift = {
510+ DCE10_AUX_MASK_SH_LIST(__SHIFT)
511+};
512+
513+static const struct dce110_aux_registers_mask aux_mask = {
514+ DCE10_AUX_MASK_SH_LIST(_MASK)
515+};
516+
509517 static struct mem_input *dce100_mem_input_create(
510518 struct dc_context *ctx,
511519 uint32_t inst)
@@ -611,7 +619,10 @@ struct dce_aux *dce100_aux_engine_create( · 99 unmodified lines
611619
612620 dce110_aux_engine_construct(aux_engine, ctx, inst,
613621 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
614− &aux_engine_regs[inst]);
622+ &aux_engine_regs[inst],
623+ &aux_mask,
624+ &aux_shift,
625+ ctx->dc->caps.extended_aux_timeout_support);
615626
616627 return &aux_engine->base;
617628 }
@@ -997,6 +1008,8 @@ static bool construct( · 379 unmodified lines
9971008 dc->caps.max_cursor_size = 128;
9981009 dc->caps.dual_link_dvi = true;
9991010 dc->caps.disable_dp_clk_share = true;
1011+ dc->caps.extended_aux_timeout_support = false;
1012+
10001013 for (i = 0; i < pool->base.pipe_count; i++) {
10011014 pool->base.timing_generators[i] =
10021015 dce100_timing_generator_create(
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c+5−16
@@ -1161,8 +1161,9 @@ static void build_audio_output( · 1160 unmodified lines
11611161 }
11621162 }
11631163
1164− if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
1165− pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
1164+ if (state->clk_mgr &&
1165+ (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
1166+ pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) {
11661167 audio_output->pll_info.dp_dto_source_clock_in_khz =
11671168 state->clk_mgr->funcs->get_dp_ref_clk_frequency(
11681169 state->clk_mgr);
@@ -1410,7 +1411,7 @@ static enum dc_status apply_single_controller_ctx_to_hw( · 241 unmodified lines
14101411
14111412 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
14121413
1413− pipe_ctx->stream->link->psr_enabled = false;
1414+ pipe_ctx->stream->link->psr_feature_enabled = false;
14141415
14151416 return DC_OK;
14161417 }
@@ -1521,18 +1522,6 @@ static struct dc_stream_state *get_edp_stream(struct dc_state *context) · 104 unmodified lines
15211522 return NULL;
15221523 }
15231524
1524−static struct dc_link *get_edp_link(struct dc *dc)
1525−{
1526− int i;
1527−
1528− // report any eDP links, even unconnected DDI's
1529− for (i = 0; i < dc->link_count; i++) {
1530− if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP)
1531− return dc->links[i];
1532− }
1533− return NULL;
1534−}
1535−
15361525 static struct dc_link *get_edp_link_with_sink(
15371526 struct dc *dc,
15381527 struct dc_state *context)
@@ -1826,7 +1815,7 @@ static bool should_enable_fbc(struct dc *dc, · 287 unmodified lines
18261815 return false;
18271816
18281817 /* PSR should not be enabled */
1829− if (pipe_ctx->stream->link->psr_enabled)
1818+ if (pipe_ctx->stream->link->psr_feature_enabled)
18301819 return false;
18311820
18321821 /* Nothing to compress */
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c+13−1
@@ -275,6 +275,14 @@ static const struct dce_stream_encoder_mask se_mask = { · 274 unmodified lines
275275 SE_COMMON_MASK_SH_LIST_DCE110(_MASK)
276276 };
277277
278+static const struct dce110_aux_registers_shift aux_shift = {
279+ DCE_AUX_MASK_SH_LIST(__SHIFT)
280+};
281+
282+static const struct dce110_aux_registers_mask aux_mask = {
283+ DCE_AUX_MASK_SH_LIST(_MASK)
284+};
285+
278286 #define opp_regs(id)\
279287 [id] = {\
280288 OPP_DCE_110_REG_LIST(id),\
@@ -657,7 +665,10 @@ struct dce_aux *dce110_aux_engine_create( · 376 unmodified lines
657665
658666 dce110_aux_engine_construct(aux_engine, ctx, inst,
659667 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
660− &aux_engine_regs[inst]);
668+ &aux_engine_regs[inst],
669+ &aux_mask,
670+ &aux_shift,
671+ ctx->dc->caps.extended_aux_timeout_support);
661672
662673 return &aux_engine->base;
663674 }
@@ -1293,6 +1304,7 @@ static bool construct( · 629 unmodified lines
12931304 dc->caps.i2c_speed_in_khz = 100;
12941305 dc->caps.max_cursor_size = 128;
12951306 dc->caps.is_apu = true;
1307+ dc->caps.extended_aux_timeout_support = false;
12961308
12971309 /*************************************************
12981310 * Create resources *
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c+13−2
@@ -172,6 +172,14 @@ static const struct dce_abm_mask abm_mask = { · 171 unmodified lines
172172 ABM_MASK_SH_LIST_DCE110(_MASK)
173173 };
174174
175+static const struct dce110_aux_registers_shift aux_shift = {
176+ DCE_AUX_MASK_SH_LIST(__SHIFT)
177+};
178+
179+static const struct dce110_aux_registers_mask aux_mask = {
180+ DCE_AUX_MASK_SH_LIST(_MASK)
181+};
182+
175183 #define ipp_regs(id)\
176184 [id] = {\
177185 IPP_DCE110_REG_LIST_DCE_BASE(id)\
@@ -630,7 +638,10 @@ struct dce_aux *dce112_aux_engine_create( · 452 unmodified lines
630638
631639 dce110_aux_engine_construct(aux_engine, ctx, inst,
632640 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
633− &aux_engine_regs[inst]);
641+ &aux_engine_regs[inst],
642+ &aux_mask,
643+ &aux_shift,
644+ ctx->dc->caps.extended_aux_timeout_support);
634645
635646 return &aux_engine->base;
636647 }
@@ -1163,7 +1174,7 @@ static bool construct( · 526 unmodified lines
11631174 dc->caps.i2c_speed_in_khz = 100;
11641175 dc->caps.max_cursor_size = 128;
11651176 dc->caps.dual_link_dvi = true;
1166−
1177+ dc->caps.extended_aux_timeout_support = false;
11671178
11681179 /*************************************************
11691180 * Create resources *
drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c+13−2
@@ -293,6 +293,14 @@ static const struct dce_stream_encoder_mask se_mask = { · 292 unmodified lines
293293 SE_COMMON_MASK_SH_LIST_DCE120(_MASK)
294294 };
295295
296+static const struct dce110_aux_registers_shift aux_shift = {
297+ DCE12_AUX_MASK_SH_LIST(__SHIFT)
298+};
299+
300+static const struct dce110_aux_registers_mask aux_mask = {
301+ DCE12_AUX_MASK_SH_LIST(_MASK)
302+};
303+
296304 #define opp_regs(id)\
297305 [id] = {\
298306 OPP_DCE_120_REG_LIST(id),\
@@ -404,7 +412,10 @@ struct dce_aux *dce120_aux_engine_create( · 105 unmodified lines
404412
405413 dce110_aux_engine_construct(aux_engine, ctx, inst,
406414 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
407− &aux_engine_regs[inst]);
415+ &aux_engine_regs[inst],
416+ &aux_mask,
417+ &aux_shift,
418+ ctx->dc->caps.extended_aux_timeout_support);
408419
409420 return &aux_engine->base;
410421 }
@@ -1006,7 +1017,7 @@ static bool construct( · 595 unmodified lines
10061017 dc->caps.max_cursor_size = 128;
10071018 dc->caps.dual_link_dvi = true;
10081019 dc->caps.psp_setup_panel_mode = true;
1009−
1020+ dc->caps.extended_aux_timeout_support = false;
10101021 dc->debug = debug_defaults;
10111022
10121023 /*************************************************
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c+13−1
@@ -288,6 +288,14 @@ static const struct dce_opp_mask opp_mask = { · 287 unmodified lines
288288 OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK)
289289 };
290290
291+static const struct dce110_aux_registers_shift aux_shift = {
292+ DCE10_AUX_MASK_SH_LIST(__SHIFT)
293+};
294+
295+static const struct dce110_aux_registers_mask aux_mask = {
296+ DCE10_AUX_MASK_SH_LIST(_MASK)
297+};
298+
291299 #define aux_engine_regs(id)\
292300 [id] = {\
293301 AUX_COMMON_REG_LIST(id), \
@@ -491,7 +499,10 @@ struct dce_aux *dce80_aux_engine_create( · 197 unmodified lines
491499
492500 dce110_aux_engine_construct(aux_engine, ctx, inst,
493501 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
494− &aux_engine_regs[inst]);
502+ &aux_engine_regs[inst],
503+ &aux_mask,
504+ &aux_shift,
505+ ctx->dc->caps.extended_aux_timeout_support);
495506
496507 return &aux_engine->base;
497508 }
@@ -895,6 +906,7 @@ static bool dce80_construct( · 397 unmodified lines
895906 dc->caps.i2c_speed_in_khz = 40;
896907 dc->caps.max_cursor_size = 128;
897908 dc->caps.dual_link_dvi = true;
909+ dc->caps.extended_aux_timeout_support = false;
898910
899911 /*************************************************
900912 * Create resources *
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c+2−2
@@ -129,7 +129,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp) · 128 unmodified lines
129129
130130 #define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19))
131131
132−static bool dpp_get_optimal_number_of_taps(
132+bool dpp1_get_optimal_number_of_taps(
133133 struct dpp *dpp,
134134 struct scaler_data *scl_data,
135135 const struct scaling_taps *in_taps)
@@ -521,7 +521,7 @@ static const struct dpp_funcs dcn10_dpp_funcs = { · 385 unmodified lines
521521 .dpp_read_state = dpp_read_state,
522522 .dpp_reset = dpp_reset,
523523 .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
524− .dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
524+ .dpp_get_optimal_number_of_taps = dpp1_get_optimal_number_of_taps,
525525 .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap,
526526 .dpp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment,
527527 .dpp_set_csc_default = dpp1_cm_set_output_csc_default,
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h+5−0
@@ -1504,6 +1504,11 @@ void dpp1_set_hdr_multiplier( · 1503 unmodified lines
15041504 struct dpp *dpp_base,
15051505 uint32_t multiplier);
15061506
1507+bool dpp1_get_optimal_number_of_taps(
1508+ struct dpp *dpp,
1509+ struct scaler_data *scl_data,
1510+ const struct scaling_taps *in_taps);
1511+
15071512 void dpp1_construct(struct dcn10_dpp *dpp1,
15081513 struct dc_context *ctx,
15091514 uint32_t inst,
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c+13−7
@@ -670,6 +670,10 @@ static void dcn10_bios_golden_init(struct dc *dc) · 669 unmodified lines
670670 int i;
671671 bool allow_self_fresh_force_enable = true;
672672
673+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
674+ if (dc->hwss.s0i3_golden_init_wa && dc->hwss.s0i3_golden_init_wa(dc))
675+ return;
676+#endif
673677 if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled)
674678 allow_self_fresh_force_enable =
675679 dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub);
@@ -1452,15 +1456,15 @@ static void log_tf(struct dc_context *ctx, · 776 unmodified lines
14521456 DC_LOG_ALL_TF_CHANNELS("Logging all channels...");
14531457
14541458 for (i = 0; i < hw_points_num; i++) {
1455− DC_LOG_GAMMA("R\t%d\t%llu\n", i, tf->tf_pts.red[i].value);
1456− DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", i, tf->tf_pts.green[i].value);
1457− DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu\n", i, tf->tf_pts.blue[i].value);
1459+ DC_LOG_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value);
1460+ DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value);
1461+ DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value);
14581462 }
14591463
14601464 for (i = hw_points_num; i < MAX_NUM_HW_POINTS; i++) {
1461− DC_LOG_ALL_GAMMA("R\t%d\t%llu\n", i, tf->tf_pts.red[i].value);
1462− DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", i, tf->tf_pts.green[i].value);
1463− DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu\n", i, tf->tf_pts.blue[i].value);
1465+ DC_LOG_ALL_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value);
1466+ DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value);
1467+ DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value);
14641468 }
14651469 }
14661470
@@ -2511,8 +2515,10 @@ static void program_all_pipe_in_tree( · 1044 unmodified lines
25112515 pipe_ctx->stream_res.tg->funcs->set_vtg_params(
25122516 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
25132517
2514− dc->hwss.blank_pixel_data(dc, pipe_ctx, blank);
2518+ if (dc->hwss.setup_vupdate_interrupt)
2519+ dc->hwss.setup_vupdate_interrupt(pipe_ctx);
25152520
2521+ dc->hwss.blank_pixel_data(dc, pipe_ctx, blank);
25162522 }
25172523
25182524 if (pipe_ctx->plane_state != NULL)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h+49−1
@@ -113,6 +113,20 @@ struct dcn10_link_enc_registers { · 112 unmodified lines
113113 uint32_t DIG_LANE_ENABLE;
114114 /* UNIPHY */
115115 uint32_t CHANNEL_XBAR_CNTL;
116+ /* DPCS */
117+ uint32_t RDPCSTX_PHY_CNTL3;
118+ uint32_t RDPCSTX_PHY_CNTL4;
119+ uint32_t RDPCSTX_PHY_CNTL5;
120+ uint32_t RDPCSTX_PHY_CNTL6;
121+ uint32_t RDPCSTX_PHY_CNTL7;
122+ uint32_t RDPCSTX_PHY_CNTL8;
123+ uint32_t RDPCSTX_PHY_CNTL9;
124+ uint32_t RDPCSTX_PHY_CNTL10;
125+ uint32_t RDPCSTX_PHY_CNTL11;
126+ uint32_t RDPCSTX_PHY_CNTL12;
127+ uint32_t RDPCSTX_PHY_CNTL13;
128+ uint32_t RDPCSTX_PHY_CNTL14;
129+ uint32_t RDPCSTX_PHY_CNTL15;
116130 /* indirect registers */
117131 uint32_t RAWLANE0_DIG_PCS_XF_RX_OVRD_IN_2;
118132 uint32_t RAWLANE0_DIG_PCS_XF_RX_OVRD_IN_3;
@@ -250,6 +264,10 @@ struct dcn10_link_enc_registers { · 131 unmodified lines
250264 type RDPCS_EXT_REFCLK_EN;\
251265 type RDPCS_TX_FIFO_EN;\
252266 type UNIPHY_LINK_ENABLE;\
267+ type UNIPHY_CHANNEL0_XBAR_SOURCE;\
268+ type UNIPHY_CHANNEL1_XBAR_SOURCE;\
269+ type UNIPHY_CHANNEL2_XBAR_SOURCE;\
270+ type UNIPHY_CHANNEL3_XBAR_SOURCE;\
253271 type UNIPHY_CHANNEL0_INVERT;\
254272 type UNIPHY_CHANNEL1_INVERT;\
255273 type UNIPHY_CHANNEL2_INVERT;\
@@ -337,16 +355,46 @@ struct dcn10_link_enc_registers { · 81 unmodified lines
337355 type RDPCS_TX_FIFO_ERROR_MASK;\
338356 type RDPCS_DPALT_DISABLE_TOGGLE_MASK;\
339357 type RDPCS_DPALT_4LANE_TOGGLE_MASK;\
358+ type RDPCS_PHY_DPALT_DP4;\
340359 type RDPCS_PHY_DPALT_DISABLE;\
341360 type RDPCS_PHY_DPALT_DISABLE_ACK;\
342361 type RDPCS_PHY_DP_MPLLB_V2I;\
343362 type RDPCS_PHY_DP_MPLLB_FREQ_VCO;\
363+ type RDPCS_PHY_DP_MPLLB_CP_INT_GS;\
364+ type RDPCS_PHY_RX_VREF_CTRL;\
344365 type RDPCS_PHY_DP_MPLLB_CP_INT;\
345366 type RDPCS_PHY_DP_MPLLB_CP_PROP;\
346367 type RDPCS_PHY_RX_REF_LD_VAL;\
347368 type RDPCS_PHY_RX_VCO_LD_VAL;\
348369 type DPCSTX_DEBUG_CONFIG; \
349− type RDPCSTX_DEBUG_CONFIG
370+ type RDPCSTX_DEBUG_CONFIG; \
371+ type RDPCS_PHY_DP_TX0_EQ_MAIN;\
372+ type RDPCS_PHY_DP_TX0_EQ_PRE;\
373+ type RDPCS_PHY_DP_TX0_EQ_POST;\
374+ type RDPCS_PHY_DP_TX1_EQ_MAIN;\
375+ type RDPCS_PHY_DP_TX1_EQ_PRE;\
376+ type RDPCS_PHY_DP_TX1_EQ_POST;\
377+ type RDPCS_PHY_DP_TX2_EQ_MAIN;\
378+ type RDPCS_PHY_DP_MPLLB_CP_PROP_GS;\
379+ type RDPCS_PHY_DP_TX2_EQ_PRE;\
380+ type RDPCS_PHY_DP_TX2_EQ_POST;\
381+ type RDPCS_PHY_DP_TX3_EQ_MAIN;\
382+ type RDPCS_PHY_DCO_RANGE;\
383+ type RDPCS_PHY_DCO_FINETUNE;\
384+ type RDPCS_PHY_DP_TX3_EQ_PRE;\
385+ type RDPCS_PHY_DP_TX3_EQ_POST;\
386+ type RDPCS_PHY_SUP_PRE_HP;\
387+ type RDPCS_PHY_DP_TX0_VREGDRV_BYP;\
388+ type RDPCS_PHY_DP_TX1_VREGDRV_BYP;\
389+ type RDPCS_PHY_DP_TX2_VREGDRV_BYP;\
390+ type RDPCS_PHY_DP_TX3_VREGDRV_BYP;\
391+ type RDPCS_DMCU_DPALT_DIS_BLOCK_REG;\
392+ type UNIPHYA_SOFT_RESET;\
393+ type UNIPHYB_SOFT_RESET;\
394+ type UNIPHYC_SOFT_RESET;\
395+ type UNIPHYD_SOFT_RESET;\
396+ type UNIPHYE_SOFT_RESET;\
397+ type UNIPHYF_SOFT_RESET
350398
351399 #define DCN20_LINK_ENCODER_REG_FIELD_LIST(type) \
352400 type DIG_LANE0EN;\
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c+3−0
@@ -240,6 +240,9 @@ void opp1_set_dyn_expansion( · 239 unmodified lines
240240 FMT_DYNAMIC_EXP_EN, 0,
241241 FMT_DYNAMIC_EXP_MODE, 0);
242242
243+ if (opp->dyn_expansion == DYN_EXPANSION_DISABLE)
244+ return;
245+
243246 /*00 - 10-bit -> 12-bit dynamic expansion*/
244247 /*01 - 8-bit -> 12-bit dynamic expansion*/
245248 if (signal == SIGNAL_TYPE_HDMI_TYPE_A ||
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c+13−47
@@ -1230,59 +1230,25 @@ bool optc1_is_stereo_left_eye(struct timing_generator *optc) · 1229 unmodified lines
12301230 return ret;
12311231 }
12321232
1233−bool optc1_is_matching_timing(struct timing_generator *tg,
1234− const struct dc_crtc_timing *otg_timing)
1233+bool optc1_get_hw_timing(struct timing_generator *tg,
1234+ struct dc_crtc_timing *hw_crtc_timing)
12351235 {
1236− struct dc_crtc_timing hw_crtc_timing = {0};
12371236 struct dcn_otg_state s = {0};
12381237
1239− if (tg == NULL || otg_timing == NULL)
1238+ if (tg == NULL || hw_crtc_timing == NULL)
12401239 return false;
12411240
12421241 optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
12431242
1244− hw_crtc_timing.h_total = s.h_total + 1;
1245− hw_crtc_timing.h_addressable = s.h_total - ((s.h_total - s.h_blank_start) + s.h_blank_end);
1246− hw_crtc_timing.h_front_porch = s.h_total + 1 - s.h_blank_start;
1247− hw_crtc_timing.h_sync_width = s.h_sync_a_end - s.h_sync_a_start;
1243+ hw_crtc_timing->h_total = s.h_total + 1;
1244+ hw_crtc_timing->h_addressable = s.h_total - ((s.h_total - s.h_blank_start) + s.h_blank_end);
1245+ hw_crtc_timing->h_front_porch = s.h_total + 1 - s.h_blank_start;
1246+ hw_crtc_timing->h_sync_width = s.h_sync_a_end - s.h_sync_a_start;
12481247
1249− hw_crtc_timing.v_total = s.v_total + 1;
1250− hw_crtc_timing.v_addressable = s.v_total - ((s.v_total - s.v_blank_start) + s.v_blank_end);
1251− hw_crtc_timing.v_front_porch = s.v_total + 1 - s.v_blank_start;
1252− hw_crtc_timing.v_sync_width = s.v_sync_a_end - s.v_sync_a_start;
1253−
1254− if (otg_timing->h_total != hw_crtc_timing.h_total)
1255− return false;
1256−
1257− if (otg_timing->h_border_left != hw_crtc_timing.h_border_left)
1258− return false;
1259−
1260− if (otg_timing->h_addressable != hw_crtc_timing.h_addressable)
1261− return false;
1262−
1263− if (otg_timing->h_border_right != hw_crtc_timing.h_border_right)
1264− return false;
1265−
1266− if (otg_timing->h_front_porch != hw_crtc_timing.h_front_porch)
1267− return false;
1268−
1269− if (otg_timing->h_sync_width != hw_crtc_timing.h_sync_width)
1270− return false;
1271−
1272− if (otg_timing->v_total != hw_crtc_timing.v_total)
1273− return false;
1274−
1275− if (otg_timing->v_border_top != hw_crtc_timing.v_border_top)
1276− return false;
1277−
1278− if (otg_timing->v_addressable != hw_crtc_timing.v_addressable)
1279− return false;
1280−
1281− if (otg_timing->v_border_bottom != hw_crtc_timing.v_border_bottom)
1282− return false;
1283−
1284− if (otg_timing->v_sync_width != hw_crtc_timing.v_sync_width)
1285− return false;
1248+ hw_crtc_timing->v_total = s.v_total + 1;
1249+ hw_crtc_timing->v_addressable = s.v_total - ((s.v_total - s.v_blank_start) + s.v_blank_end);
1250+ hw_crtc_timing->v_front_porch = s.v_total + 1 - s.v_blank_start;
1251+ hw_crtc_timing->v_sync_width = s.v_sync_a_end - s.v_sync_a_start;
12861252
12871253 return true;
12881254 }
@@ -1486,7 +1452,6 @@ static const struct timing_generator_funcs dcn10_tg_funcs = { · 197 unmodified lines
14861452 .get_frame_count = optc1_get_vblank_counter,
14871453 .get_scanoutpos = optc1_get_crtc_scanoutpos,
14881454 .get_otg_active_size = optc1_get_otg_active_size,
1489− .is_matching_timing = optc1_is_matching_timing,
14901455 .set_early_control = optc1_set_early_control,
14911456 /* used by enable_timing_synchronization. Not need for FPGA */
14921457 .wait_for_state = optc1_wait_for_state,
@@ -1514,7 +1479,8 @@ static const struct timing_generator_funcs dcn10_tg_funcs = { · 21 unmodified lines
15141479 .configure_crc = optc1_configure_crc,
15151480 .set_vtg_params = optc1_set_vtg_params,
15161481 .program_manual_trigger = optc1_program_manual_trigger,
1517− .setup_manual_trigger = optc1_setup_manual_trigger
1482+ .setup_manual_trigger = optc1_setup_manual_trigger,
1483+ .get_hw_timing = optc1_get_hw_timing,
15181484 };
15191485
15201486 void dcn10_timing_generator_init(struct optc *optc1)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h+2−3
@@ -547,9 +547,8 @@ struct dcn_otg_state { · 546 unmodified lines
547547 void optc1_read_otg_state(struct optc *optc1,
548548 struct dcn_otg_state *s);
549549
550−bool optc1_is_matching_timing(
551− struct timing_generator *tg,
552− const struct dc_crtc_timing *otg_timing);
550+bool optc1_get_hw_timing(struct timing_generator *tg,
551+ struct dc_crtc_timing *hw_crtc_timing);
553552
554553 bool optc1_validate_timing(
555554 struct timing_generator *optc,
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c+14−1
@@ -319,6 +319,14 @@ static const struct dcn10_link_enc_mask le_mask = { · 318 unmodified lines
319319 LINK_ENCODER_MASK_SH_LIST_DCN10(_MASK)
320320 };
321321
322+static const struct dce110_aux_registers_shift aux_shift = {
323+ DCN10_AUX_MASK_SH_LIST(__SHIFT)
324+};
325+
326+static const struct dce110_aux_registers_mask aux_mask = {
327+ DCN10_AUX_MASK_SH_LIST(_MASK)
328+};
329+
322330 #define ipp_regs(id)\
323331 [id] = {\
324332 IPP_REG_LIST_DCN10(id),\
@@ -642,7 +650,10 @@ struct dce_aux *dcn10_aux_engine_create( · 317 unmodified lines
642650
643651 dce110_aux_engine_construct(aux_engine, ctx, inst,
644652 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
645− &aux_engine_regs[inst]);
653+ &aux_engine_regs[inst],
654+ &aux_mask,
655+ &aux_shift,
656+ ctx->dc->caps.extended_aux_timeout_support);
646657
647658 return &aux_engine->base;
648659 }
@@ -1308,6 +1319,8 @@ static bool construct( · 659 unmodified lines
13081319 dc->caps.max_slave_planes = 1;
13091320 dc->caps.is_apu = true;
13101321 dc->caps.post_blend_color_processing = false;
1322+ dc->caps.extended_aux_timeout_support = false;
1323+
13111324 /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
13121325 dc->caps.force_dp_tps4_for_cp2520 = true;
13131326
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c+62−0
@@ -1553,6 +1553,66 @@ unsigned int enc1_dig_source_otg( · 1552 unmodified lines
15531553 return tg_inst;
15541554 }
15551555
1556+bool enc1_stream_encoder_dp_get_pixel_format(
1557+ struct stream_encoder *enc,
1558+ enum dc_pixel_encoding *encoding,
1559+ enum dc_color_depth *depth)
1560+{
1561+ uint32_t hw_encoding = 0;
1562+ uint32_t hw_depth = 0;
1563+ struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1564+
1565+ if (enc == NULL ||
1566+ encoding == NULL ||
1567+ depth == NULL)
1568+ return false;
1569+
1570+ REG_GET_2(DP_PIXEL_FORMAT,
1571+ DP_PIXEL_ENCODING, &hw_encoding,
1572+ DP_COMPONENT_DEPTH, &hw_depth);
1573+
1574+ switch (hw_depth) {
1575+ case DP_COMPONENT_PIXEL_DEPTH_6BPC:
1576+ *depth = COLOR_DEPTH_666;
1577+ break;
1578+ case DP_COMPONENT_PIXEL_DEPTH_8BPC:
1579+ *depth = COLOR_DEPTH_888;
1580+ break;
1581+ case DP_COMPONENT_PIXEL_DEPTH_10BPC:
1582+ *depth = COLOR_DEPTH_101010;
1583+ break;
1584+ case DP_COMPONENT_PIXEL_DEPTH_12BPC:
1585+ *depth = COLOR_DEPTH_121212;
1586+ break;
1587+ case DP_COMPONENT_PIXEL_DEPTH_16BPC:
1588+ *depth = COLOR_DEPTH_161616;
1589+ break;
1590+ default:
1591+ *depth = COLOR_DEPTH_UNDEFINED;
1592+ break;
1593+ }
1594+
1595+ switch (hw_encoding) {
1596+ case DP_PIXEL_ENCODING_TYPE_RGB444:
1597+ *encoding = PIXEL_ENCODING_RGB;
1598+ break;
1599+ case DP_PIXEL_ENCODING_TYPE_YCBCR422:
1600+ *encoding = PIXEL_ENCODING_YCBCR422;
1601+ break;
1602+ case DP_PIXEL_ENCODING_TYPE_YCBCR444:
1603+ case DP_PIXEL_ENCODING_TYPE_Y_ONLY:
1604+ *encoding = PIXEL_ENCODING_YCBCR444;
1605+ break;
1606+ case DP_PIXEL_ENCODING_TYPE_YCBCR420:
1607+ *encoding = PIXEL_ENCODING_YCBCR420;
1608+ break;
1609+ default:
1610+ *encoding = PIXEL_ENCODING_UNDEFINED;
1611+ break;
1612+ }
1613+ return true;
1614+}
1615+
15561616 static const struct stream_encoder_funcs dcn10_str_enc_funcs = {
15571617 .dp_set_stream_attribute =
15581618 enc1_stream_encoder_dp_set_stream_attribute,
@@ -1589,6 +1649,8 @@ static const struct stream_encoder_funcs dcn10_str_enc_funcs = { · 30 unmodified lines
15891649 .dig_connect_to_otg = enc1_dig_connect_to_otg,
15901650 .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
15911651 .dig_source_otg = enc1_dig_source_otg,
1652+
1653+ .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format,
15921654 };
15931655
15941656 void dcn10_stream_encoder_construct(
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h+5−0
@@ -621,4 +621,9 @@ void get_audio_clock_info( · 620 unmodified lines
621621 void enc1_reset_hdmi_stream_attribute(
622622 struct stream_encoder *enc);
623623
624+bool enc1_stream_encoder_dp_get_pixel_format(
625+ struct stream_encoder *enc,
626+ enum dc_pixel_encoding *encoding,
627+ enum dc_color_depth *depth);
628+
624629 #endif /* __DC_STREAM_ENCODER_DCN10_H__ */
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c+1−1
@@ -457,7 +457,7 @@ static struct dpp_funcs dcn20_dpp_funcs = { · 456 unmodified lines
457457 .dpp_read_state = dpp20_read_state,
458458 .dpp_reset = dpp_reset,
459459 .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
460− .dpp_get_optimal_number_of_taps = dpp2_get_optimal_number_of_taps,
460+ .dpp_get_optimal_number_of_taps = dpp1_get_optimal_number_of_taps,
461461 .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap,
462462 .dpp_set_csc_adjustment = NULL,
463463 .dpp_set_csc_default = NULL,
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h+0−5
@@ -705,11 +705,6 @@ void dpp2_set_hdr_multiplier( · 704 unmodified lines
705705 struct dpp *dpp_base,
706706 uint32_t multiplier);
707707
708−bool dpp2_get_optimal_number_of_taps(
709− struct dpp *dpp,
710− struct scaler_data *scl_data,
711− const struct scaling_taps *in_taps);
712−
713708 bool dpp2_construct(struct dcn20_dpp *dpp2,
714709 struct dc_context *ctx,
715710 uint32_t inst,
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c+38−4
@@ -1370,6 +1370,9 @@ static void dcn20_program_pipe( · 1369 unmodified lines
13701370
13711371 pipe_ctx->stream_res.tg->funcs->set_vtg_params(
13721372 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
1373+
1374+ if (dc->hwss.setup_vupdate_interrupt)
1375+ dc->hwss.setup_vupdate_interrupt(pipe_ctx);
13731376 }
13741377
13751378 if (pipe_ctx->update_flags.bits.odm)
@@ -1396,6 +1399,26 @@ static void dcn20_program_pipe( · 20 unmodified lines
13961399 */
13971400 if (pipe_ctx->update_flags.bits.enable || pipe_ctx->stream->update_flags.bits.out_tf)
13981401 dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream);
1402+
1403+ /* If the pipe has been enabled or has a different opp, we
1404+ * should reprogram the fmt. This deals with cases where
1405+ * interation between mpc and odm combine on different streams
1406+ * causes a different pipe to be chosen to odm combine with.
1407+ */
1408+ if (pipe_ctx->update_flags.bits.enable
1409+ || pipe_ctx->update_flags.bits.opp_changed) {
1410+
1411+ pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
1412+ pipe_ctx->stream_res.opp,
1413+ COLOR_SPACE_YCBCR601,
1414+ pipe_ctx->stream->timing.display_color_depth,
1415+ pipe_ctx->stream->signal);
1416+
1417+ pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
1418+ pipe_ctx->stream_res.opp,
1419+ &pipe_ctx->stream->bit_depth_params,
1420+ &pipe_ctx->stream->clamping);
1421+ }
13991422 }
14001423
14011424 static bool does_pipe_need_lock(struct pipe_ctx *pipe)
@@ -1510,6 +1533,10 @@ static void dcn20_program_front_end_for_ctx( · 108 unmodified lines
15101533 msleep(1);
15111534 }
15121535 }
1536+
1537+ /* WA to apply WM setting*/
1538+ if (dc->hwseq->wa.DEGVIDCN21)
1539+ dc->res_pool->hubbub->funcs->apply_DEDCN21_147_wa(dc->res_pool->hubbub);
15131540 }
15141541
15151542
@@ -1581,8 +1608,12 @@ bool dcn20_update_bandwidth( · 65 unmodified lines
15811608
15821609 pipe_ctx->stream_res.tg->funcs->set_vtg_params(
15831610 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
1611+
15841612 if (pipe_ctx->prev_odm_pipe == NULL)
15851613 dc->hwss.blank_pixel_data(dc, pipe_ctx, blank);
1614+
1615+ if (dc->hwss.setup_vupdate_interrupt)
1616+ dc->hwss.setup_vupdate_interrupt(pipe_ctx);
15861617 }
15871618
15881619 pipe_ctx->plane_res.hubp->funcs->hubp_setup(
@@ -1599,7 +1630,8 @@ bool dcn20_update_bandwidth( · 10 unmodified lines
15991630 static void dcn20_enable_writeback(
16001631 struct dc *dc,
16011632 const struct dc_stream_status *stream_status,
1602− struct dc_writeback_info *wb_info)
1633+ struct dc_writeback_info *wb_info,
1634+ struct dc_state *context)
16031635 {
16041636 struct dwbc *dwb;
16051637 struct mcif_wb *mcif_wb;
@@ -1616,7 +1648,7 @@ static void dcn20_enable_writeback( · 10 unmodified lines
16161648 optc->funcs->set_dwb_source(optc, wb_info->dwb_pipe_inst);
16171649 /* set MCIF_WB buffer and arbitration configuration */
16181650 mcif_wb->funcs->config_mcif_buf(mcif_wb, &wb_info->mcif_buf_params, wb_info->dwb_params.dest_height);
1619− mcif_wb->funcs->config_mcif_arb(mcif_wb, &dc->current_state->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]);
1651+ mcif_wb->funcs->config_mcif_arb(mcif_wb, &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]);
16201652 /* Enable MCIF_WB */
16211653 mcif_wb->funcs->enable_mcif(mcif_wb);
16221654 /* Enable DWB */
@@ -2181,8 +2213,10 @@ static void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 558 unmodified lines
21812213 link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
21822214 pipe_ctx->stream_res.stream_enc->id, true);
21832215
2184− if (link->dc->hwss.program_dmdata_engine)
2185− link->dc->hwss.program_dmdata_engine(pipe_ctx);
2216+ if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
2217+ if (link->dc->hwss.program_dmdata_engine)
2218+ link->dc->hwss.program_dmdata_engine(pipe_ctx);
2219+ }
21862220
21872221 link->dc->hwss.update_info_frame(pipe_ctx);
21882222
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h+7−0
@@ -91,6 +91,13 @@ struct mpll_cfg { · 90 unmodified lines
9191 uint32_t ref_range;
9292 uint32_t ref_clk;
9393 bool hdmimode_enable;
94+ bool sup_pre_hp;
95+ bool dp_tx0_vergdrv_byp;
96+ bool dp_tx1_vergdrv_byp;
97+ bool dp_tx2_vergdrv_byp;
98+ bool dp_tx3_vergdrv_byp;
99+
100+
94101 };
95102
96103 struct dpcssys_phy_seq_cfg {
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c+1−1
@@ -460,7 +460,7 @@ static struct timing_generator_funcs dcn20_tg_funcs = { · 459 unmodified lines
460460 .set_vtg_params = optc1_set_vtg_params,
461461 .program_manual_trigger = optc2_program_manual_trigger,
462462 .setup_manual_trigger = optc2_setup_manual_trigger,
463− .is_matching_timing = optc1_is_matching_timing
463+ .get_hw_timing = optc1_get_hw_timing,
464464 };
465465
466466 void dcn20_timing_generator_init(struct optc *optc1)
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c+46−7
@@ -581,11 +581,13 @@ static const struct dcn2_dpp_registers tf_regs[] = { · 580 unmodified lines
581581 };
582582
583583 static const struct dcn2_dpp_shift tf_shift = {
584− TF_REG_LIST_SH_MASK_DCN20(__SHIFT)
584+ TF_REG_LIST_SH_MASK_DCN20(__SHIFT),
585+ TF_DEBUG_REG_LIST_SH_DCN10
585586 };
586587
587588 static const struct dcn2_dpp_mask tf_mask = {
588− TF_REG_LIST_SH_MASK_DCN20(_MASK)
589+ TF_REG_LIST_SH_MASK_DCN20(_MASK),
590+ TF_DEBUG_REG_LIST_MASK_DCN10
589591 };
590592
591593 #define dwbc_regs_dcn2(id)\
@@ -732,6 +734,15 @@ static const struct dcn20_vmid_mask vmid_masks = { · 140 unmodified lines
732734 DCN20_VMID_MASK_SH_LIST(_MASK)
733735 };
734736
737+static const struct dce110_aux_registers_shift aux_shift = {
738+ DCN_AUX_MASK_SH_LIST(__SHIFT)
739+};
740+
741+static const struct dce110_aux_registers_mask aux_mask = {
742+ DCN_AUX_MASK_SH_LIST(_MASK)
743+};
744+
745+
735746 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
736747 #define dsc_regsDCN20(id)\
737748 [id] = {\
@@ -922,7 +933,10 @@ struct dce_aux *dcn20_aux_engine_create( · 184 unmodified lines
922933
923934 dce110_aux_engine_construct(aux_engine, ctx, inst,
924935 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
925− &aux_engine_regs[inst]);
936+ &aux_engine_regs[inst],
937+ &aux_mask,
938+ &aux_shift,
939+ ctx->dc->caps.extended_aux_timeout_support);
926940
927941 return &aux_engine->base;
928942 }
@@ -1154,6 +1168,8 @@ static const struct resource_create_funcs res_create_maximus_funcs = { · 225 unmodified lines
11541168 .create_hwseq = dcn20_hwseq_create,
11551169 };
11561170
1171+static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
1172+
11571173 void dcn20_clock_source_destroy(struct clock_source **clk_src)
11581174 {
11591175 kfree(TO_DCE110_CLK_SRC(*clk_src));
@@ -1892,7 +1908,7 @@ int dcn20_populate_dml_pipes_from_context( · 732 unmodified lines
18921908 break;
18931909 case PIXEL_ENCODING_YCBCR420:
18941910 pipes[pipe_cnt].dout.output_format = dm_420;
1895− pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3) / 2;
1911+ pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2;
18961912 break;
18971913 case PIXEL_ENCODING_YCBCR422:
18981914 if (true) /* todo */
@@ -1906,6 +1922,11 @@ int dcn20_populate_dml_pipes_from_context( · 7 unmodified lines
19061922 pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
19071923 }
19081924
1925+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1926+ if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC)
1927+ pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0;
1928+#endif
1929+
19091930 /* todo: default max for now, until there is logic reflecting this in dc*/
19101931 pipes[pipe_cnt].dout.output_bpc = 12;
19111932 /*
@@ -2202,7 +2223,8 @@ static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, · 290 unmodified lines
22022223 */
22032224 if (secondary_pipe == NULL) {
22042225 for (j = dc->res_pool->pipe_count - 1; j >= 0; j--) {
2205− if (dc->current_state->res_ctx.pipe_ctx[j].top_pipe == NULL) {
2226+ if (dc->current_state->res_ctx.pipe_ctx[j].top_pipe == NULL
2227+ && dc->current_state->res_ctx.pipe_ctx[j].prev_odm_pipe == NULL) {
22062228 preferred_pipe_idx = j;
22072229
22082230 if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
@@ -2555,6 +2577,10 @@ void dcn20_calculate_wm( · 346 unmodified lines
25552577 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
25562578 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
25572579 context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2580+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
2581+ context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2582+ context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2583+#endif
25582584
25592585 if (vlevel < 2) {
25602586 pipes[0].clks_cfg.voltage = 2;
@@ -2566,6 +2592,10 @@ void dcn20_calculate_wm( · 5 unmodified lines
25662592 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
25672593 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
25682594 context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2595+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
2596+ context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2597+ context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2598+#endif
25692599
25702600 if (vlevel < 3) {
25712601 pipes[0].clks_cfg.voltage = 3;
@@ -2577,6 +2607,10 @@ void dcn20_calculate_wm( · 5 unmodified lines
25772607 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
25782608 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
25792609 context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2610+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
2611+ context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2612+ context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2613+#endif
25802614
25812615 pipes[0].clks_cfg.voltage = vlevel;
25822616 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
@@ -2586,6 +2620,10 @@ void dcn20_calculate_wm( · 3 unmodified lines
25862620 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
25872621 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
25882622 context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2623+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
2624+ context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2625+ context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
2626+#endif
25892627 }
25902628
25912629 void dcn20_calculate_dlg_params(
@@ -2922,7 +2960,7 @@ bool dcn20_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) · 330 unmodified lines
29222960 return true;
29232961 }
29242962
2925−struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx)
2963+static struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx)
29262964 {
29272965 struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
29282966
@@ -2937,7 +2975,7 @@ struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) · 8 unmodified lines
29372975 return pp_smu;
29382976 }
29392977
2940−void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
2978+static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
29412979 {
29422980 if (pp_smu && *pp_smu) {
29432981 kfree(*pp_smu);
@@ -3322,6 +3360,7 @@ static bool construct( · 378 unmodified lines
33223360 dc->caps.post_blend_color_processing = true;
33233361 dc->caps.force_dp_tps4_for_cp2520 = true;
33243362 dc->caps.hw_3d_lut = true;
3363+ dc->caps.extended_aux_timeout_support = true;
33253364
33263365 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) {
33273366 dc->debug = debug_defaults_drv;
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h+0−3
@@ -95,9 +95,6 @@ struct display_stream_compressor *dcn20_dsc_create( · 94 unmodified lines
9595 struct dc_context *ctx, uint32_t inst);
9696 void dcn20_dsc_destroy(struct display_stream_compressor **dsc);
9797
98−struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx);
99−void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
100−
10198 struct hubp *dcn20_hubp_create(
10299 struct dc_context *ctx,
103100 uint32_t inst);
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c+4−0
@@ -578,6 +578,10 @@ static const struct stream_encoder_funcs dcn20_str_enc_funcs = { · 577 unmodified lines
578578 .set_avmute = enc1_stream_encoder_set_avmute,
579579 .dig_connect_to_otg = enc1_dig_connect_to_otg,
580580 .dig_source_otg = enc1_dig_source_otg,
581+
582+ .dp_get_pixel_format =
583+ enc1_stream_encoder_dp_get_pixel_format,
584+
581585 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
582586 .enc_read_state = enc2_read_state,
583587 .dp_set_dsc_config = enc2_dp_set_dsc_config,
drivers/gpu/drm/amd/display/dc/dcn21/Makefile+1−1
@@ -1,7 +1,7 @@
11 #
22 # Makefile for DCN21.
33
4−DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o
4+DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o dcn21_hwseq.o dcn21_link_encoder.o
55
66 ifneq ($(call cc-option, -mpreferred-stack-boundary=4),)
77 cc_stack_align := -mpreferred-stack-boundary=4
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c+89−27
@@ -22,6 +22,7 @@ · 21 unmodified lines
2222 * Authors: AMD
2323 *
2424 */
25+#include <linux/delay.h>
2526 #include "dm_services.h"
2627 #include "dcn20/dcn20_hubbub.h"
2728 #include "dcn21_hubbub.h"
@@ -51,7 +52,7 @@ · 23 unmodified lines
5152 #ifdef NUM_VMID
5253 #undef NUM_VMID
5354 #endif
54−#define NUM_VMID 1
55+#define NUM_VMID 16
5556
5657 static uint32_t convert_and_clamp(
5758 uint32_t wm_ns,
@@ -71,56 +72,76 @@ static uint32_t convert_and_clamp( · 13 unmodified lines
7172 void dcn21_dchvm_init(struct hubbub *hubbub)
7273 {
7374 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
75+ uint32_t riommu_active;
76+ int i;
7477
7578 //Init DCHVM block
7679 REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1);
7780
7881 //Poll until RIOMMU_ACTIVE = 1
79− //TODO: Figure out interval us and retry count
80− REG_WAIT(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, 1, 5, 100);
82+ for (i = 0; i < 100; i++) {
83+ REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active);
8184
82− //Reflect the power status of DCHUBBUB
83− REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1);
85+ if (riommu_active)
86+ break;
87+ else
88+ udelay(5);
89+ }
90+
91+ if (riommu_active) {
92+ //Reflect the power status of DCHUBBUB
93+ REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1);
8494
85− //Start rIOMMU prefetching
86− REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1);
95+ //Start rIOMMU prefetching
96+ REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1);
8797
88− // Enable dynamic clock gating
89− REG_UPDATE_4(DCHVM_CLK_CTRL,
90− HVM_DISPCLK_R_GATE_DIS, 0,
91− HVM_DISPCLK_G_GATE_DIS, 0,
92− HVM_DCFCLK_R_GATE_DIS, 0,
93− HVM_DCFCLK_G_GATE_DIS, 0);
98+ // Enable dynamic clock gating
99+ REG_UPDATE_4(DCHVM_CLK_CTRL,
100+ HVM_DISPCLK_R_GATE_DIS, 0,
101+ HVM_DISPCLK_G_GATE_DIS, 0,
102+ HVM_DCFCLK_R_GATE_DIS, 0,
103+ HVM_DCFCLK_G_GATE_DIS, 0);
94104
95− //Poll until HOSTVM_PREFETCH_DONE = 1
96− //TODO: Figure out interval us and retry count
97− REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100);
105+ //Poll until HOSTVM_PREFETCH_DONE = 1
106+ REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100);
107+ }
98108 }
99109
100−static int hubbub21_init_dchub(struct hubbub *hubbub,
110+int hubbub21_init_dchub(struct hubbub *hubbub,
101111 struct dcn_hubbub_phys_addr_config *pa_config)
102112 {
103113 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
114+ struct dcn_vmid_page_table_config phys_config;
104115
105116 REG_SET(DCN_VM_FB_LOCATION_BASE, 0,
106− FB_BASE, pa_config->system_aperture.fb_base);
117+ FB_BASE, pa_config->system_aperture.fb_base >> 24);
107118 REG_SET(DCN_VM_FB_LOCATION_TOP, 0,
108− FB_TOP, pa_config->system_aperture.fb_top);
119+ FB_TOP, pa_config->system_aperture.fb_top >> 24);
109120 REG_SET(DCN_VM_FB_OFFSET, 0,
110− FB_OFFSET, pa_config->system_aperture.fb_offset);
121+ FB_OFFSET, pa_config->system_aperture.fb_offset >> 24);
111122 REG_SET(DCN_VM_AGP_BOT, 0,
112− AGP_BOT, pa_config->system_aperture.agp_bot);
123+ AGP_BOT, pa_config->system_aperture.agp_bot >> 24);
113124 REG_SET(DCN_VM_AGP_TOP, 0,
114− AGP_TOP, pa_config->system_aperture.agp_top);
125+ AGP_TOP, pa_config->system_aperture.agp_top >> 24);
115126 REG_SET(DCN_VM_AGP_BASE, 0,
116− AGP_BASE, pa_config->system_aperture.agp_base);
127+ AGP_BASE, pa_config->system_aperture.agp_base >> 24);
128+
129+ if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) {
130+ phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12;
131+ phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12;
132+ phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr | 1; //Note: hack
133+ phys_config.depth = 0;
134+ phys_config.block_size = 0;
135+ // Init VMID 0 based on PA config
136+ dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config);
137+ }
117138
118139 dcn21_dchvm_init(hubbub);
119140
120141 return NUM_VMID;
121142 }
122143
123−static void hubbub21_program_urgent_watermarks(
144+void hubbub21_program_urgent_watermarks(
124145 struct hubbub *hubbub,
125146 struct dcn_watermark_set *watermarks,
126147 unsigned int refclk_mhz,
@@ -160,6 +181,13 @@ static void hubbub21_program_urgent_watermarks( · 33 unmodified lines
160181 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0,
161182 DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom);
162183 }
184+ if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub1->watermarks.a.urgent_latency_ns) {
185+ hubbub1->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns;
186+ prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns,
187+ refclk_mhz, 0x1fffff);
188+ REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0,
189+ DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value);
190+ }
163191
164192 /* clock state B */
165193 if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) {
@@ -192,6 +220,14 @@ static void hubbub21_program_urgent_watermarks( · 26 unmodified lines
192220 DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom);
193221 }
194222
223+ if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub1->watermarks.b.urgent_latency_ns) {
224+ hubbub1->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns;
225+ prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns,
226+ refclk_mhz, 0x1fffff);
227+ REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0,
228+ DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value);
229+ }
230+
195231 /* clock state C */
196232 if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) {
197233 hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
@@ -223,6 +259,14 @@ static void hubbub21_program_urgent_watermarks( · 25 unmodified lines
223259 DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom);
224260 }
225261
262+ if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub1->watermarks.c.urgent_latency_ns) {
263+ hubbub1->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns;
264+ prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns,
265+ refclk_mhz, 0x1fffff);
266+ REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0,
267+ DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value);
268+ }
269+
226270 /* clock state D */
227271 if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) {
228272 hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
@@ -253,9 +297,17 @@ static void hubbub21_program_urgent_watermarks( · 24 unmodified lines
253297 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0,
254298 DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom);
255299 }
300+
301+ if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub1->watermarks.d.urgent_latency_ns) {
302+ hubbub1->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns;
303+ prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns,
304+ refclk_mhz, 0x1fffff);
305+ REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0,
306+ DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value);
307+ }
256308 }
257309
258−static void hubbub21_program_stutter_watermarks(
310+void hubbub21_program_stutter_watermarks(
259311 struct hubbub *hubbub,
260312 struct dcn_watermark_set *watermarks,
261313 unsigned int refclk_mhz,
@@ -389,7 +441,7 @@ static void hubbub21_program_stutter_watermarks( · 127 unmodified lines
389441 }
390442 }
391443
392−static void hubbub21_program_pstate_watermarks(
444+void hubbub21_program_pstate_watermarks(
393445 struct hubbub *hubbub,
394446 struct dcn_watermark_set *watermarks,
395447 unsigned int refclk_mhz,
@@ -564,17 +616,26 @@ void hubbub21_wm_read_state(struct hubbub *hubbub, · 168 unmodified lines
564616 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage);
565617 }
566618
619+void hubbub21_apply_DEDCN21_147_wa(struct hubbub *hubbub)
620+{
621+ struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
622+ uint32_t prog_wm_value;
623+
624+ prog_wm_value = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);
625+ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
626+}
567627
568628 static const struct hubbub_funcs hubbub21_funcs = {
569629 .update_dchub = hubbub2_update_dchub,
570630 .init_dchub_sys_ctx = hubbub21_init_dchub,
571− .init_vm_ctx = NULL,
631+ .init_vm_ctx = hubbub2_init_vm_ctx,
572632 .dcc_support_swizzle = hubbub2_dcc_support_swizzle,
573633 .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format,
574634 .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap,
575635 .wm_read_state = hubbub21_wm_read_state,
576636 .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq,
577637 .program_watermarks = hubbub21_program_watermarks,
638+ .apply_DEDCN21_147_wa = hubbub21_apply_DEDCN21_147_wa,
578639 };
579640
580641 void hubbub21_construct(struct dcn20_hubbub *hubbub,
@@ -592,4 +653,5 @@ void hubbub21_construct(struct dcn20_hubbub *hubbub, · 11 unmodified lines
592653 hubbub->masks = hubbub_mask;
593654
594655 hubbub->debug_test_index_pstate = 0xB;
656+ hubbub->detile_buf_size = 164 * 1024; /* 164KB for DCN2.0 */
595657 }
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.h+24−10
@@ -36,6 +36,10 @@ · 35 unmodified lines
3636 SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B),\
3737 SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C),\
3838 SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D),\
39+ SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A),\
40+ SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B),\
41+ SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C),\
42+ SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D),\
3943 SR(DCHUBBUB_ARB_HOSTVM_CNTL), \
4044 SR(DCHVM_CTRL0), \
4145 SR(DCHVM_MEM_CTRL), \
@@ -44,16 +48,9 @@ · 2 unmodified lines
4448 SR(DCHVM_RIOMMU_STAT0)
4549
4650 #define HUBBUB_REG_LIST_DCN21()\
47− HUBBUB_REG_LIST_DCN_COMMON(), \
51+ HUBBUB_REG_LIST_DCN20_COMMON(), \
4852 HUBBUB_SR_WATERMARK_REG_LIST(), \
49− HUBBUB_HVM_REG_LIST(), \
50− SR(DCHUBBUB_CRC_CTRL), \
51− SR(DCN_VM_FB_LOCATION_BASE),\
52− SR(DCN_VM_FB_LOCATION_TOP),\
53− SR(DCN_VM_FB_OFFSET),\
54− SR(DCN_VM_AGP_BOT),\
55− SR(DCN_VM_AGP_TOP),\
56− SR(DCN_VM_AGP_BASE)
53+ HUBBUB_HVM_REG_LIST()
5754
5855 #define HUBBUB_MASK_SH_LIST_HVM(mask_sh) \
5956 HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, mask_sh), \
@@ -102,7 +99,7 @@ · 42 unmodified lines
10299 HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, mask_sh)
103100
104101 #define HUBBUB_MASK_SH_LIST_DCN21(mask_sh)\
105− HUBBUB_MASK_SH_LIST_HVM(mask_sh),\
102+ HUBBUB_MASK_SH_LIST_HVM(mask_sh), \
106103 HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh), \
107104 HUBBUB_MASK_SH_LIST_STUTTER(mask_sh), \
108105 HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
@@ -114,11 +111,28 @@ · 5 unmodified lines
114111 HUBBUB_SF(DCN_VM_AGP_BASE, AGP_BASE, mask_sh)
115112
116113 void dcn21_dchvm_init(struct hubbub *hubbub);
114+int hubbub21_init_dchub(struct hubbub *hubbub,
115+ struct dcn_hubbub_phys_addr_config *pa_config);
117116 void hubbub21_program_watermarks(
118117 struct hubbub *hubbub,
119118 struct dcn_watermark_set *watermarks,
120119 unsigned int refclk_mhz,
121120 bool safe_to_lower);
121+void hubbub21_program_urgent_watermarks(
122+ struct hubbub *hubbub,
123+ struct dcn_watermark_set *watermarks,
124+ unsigned int refclk_mhz,
125+ bool safe_to_lower);
126+void hubbub21_program_stutter_watermarks(
127+ struct hubbub *hubbub,
128+ struct dcn_watermark_set *watermarks,
129+ unsigned int refclk_mhz,
130+ bool safe_to_lower);
131+void hubbub21_program_pstate_watermarks(
132+ struct hubbub *hubbub,
133+ struct dcn_watermark_set *watermarks,
134+ unsigned int refclk_mhz,
135+ bool safe_to_lower);
122136
123137 void hubbub21_wm_read_state(struct hubbub *hubbub,
124138 struct dcn_hubbub_wm *wm);
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c+3−1
@@ -22,6 +22,8 @@ · 21 unmodified lines
2222 * Authors: AMD
2323 *
2424 */
25+
26+#include "dcn10/dcn10_hubp.h"
2527 #include "dcn21_hubp.h"
2628
2729 #include "dm_services.h"
@@ -202,7 +204,7 @@ static struct hubp_funcs dcn21_hubp_funcs = { · 174 unmodified lines
202204 .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
203205 .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
204206 .hubp_program_surface_flip_and_addr = hubp2_program_surface_flip_and_addr,
205− .hubp_program_surface_config = hubp2_program_surface_config,
207+ .hubp_program_surface_config = hubp1_program_surface_config,
206208 .hubp_is_flip_pending = hubp1_is_flip_pending,
207209 .hubp_setup = hubp21_setup,
208210 .hubp_setup_interdependent = hubp2_setup_interdependent,
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c+122−0
@@ -0,0 +1,122 @@
1+/*
2+ * Copyright 2016 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 "dm_services.h"
27+#include "dm_helpers.h"
28+#include "core_types.h"
29+#include "resource.h"
30+#include "dce/dce_hwseq.h"
31+#include "dcn20/dcn20_hwseq.h"
32+#include "vmid.h"
33+#include "reg_helper.h"
34+#include "hw/clk_mgr.h"
35+
36+
37+#define DC_LOGGER_INIT(logger)
38+
39+#define CTX \
40+ hws->ctx
41+#define REG(reg)\
42+ hws->regs->reg
43+
44+#undef FN
45+#define FN(reg_name, field_name) \
46+ hws->shifts->field_name, hws->masks->field_name
47+
48+/* Temporary read settings, future will get values from kmd directly */
49+static void mmhub_update_page_table_config(struct dcn_hubbub_phys_addr_config *config,
50+ struct dce_hwseq *hws)
51+{
52+ uint32_t page_table_base_hi;
53+ uint32_t page_table_base_lo;
54+
55+ REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
56+ PAGE_DIRECTORY_ENTRY_HI32, &page_table_base_hi);
57+ REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
58+ PAGE_DIRECTORY_ENTRY_LO32, &page_table_base_lo);
59+
60+ config->gart_config.page_table_base_addr = ((uint64_t)page_table_base_hi << 32) | page_table_base_lo;
61+
62+}
63+
64+static int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
65+{
66+ struct dcn_hubbub_phys_addr_config config;
67+
68+ config.system_aperture.fb_top = pa_config->system_aperture.fb_top;
69+ config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;
70+ config.system_aperture.fb_base = pa_config->system_aperture.fb_base;
71+ config.system_aperture.agp_top = pa_config->system_aperture.agp_top;
72+ config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;
73+ config.system_aperture.agp_base = pa_config->system_aperture.agp_base;
74+ config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;
75+ config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;
76+ config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
77+
78+ mmhub_update_page_table_config(&config, hws);
79+
80+ return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);
81+}
82+
83+// work around for Renoir s0i3, if register is programmed, bypass golden init.
84+
85+static bool dcn21_s0i3_golden_init_wa(struct dc *dc)
86+{
87+ struct dce_hwseq *hws = dc->hwseq;
88+ uint32_t value = 0;
89+
90+ value = REG_READ(MICROSECOND_TIME_BASE_DIV);
91+
92+ return value != 0x00120464;
93+}
94+
95+void dcn21_exit_optimized_pwr_state(
96+ const struct dc *dc,
97+ struct dc_state *context)
98+{
99+ dc->clk_mgr->funcs->update_clocks(
100+ dc->clk_mgr,
101+ context,
102+ false);
103+}
104+
105+void dcn21_optimize_pwr_state(
106+ const struct dc *dc,
107+ struct dc_state *context)
108+{
109+ dc->clk_mgr->funcs->update_clocks(
110+ dc->clk_mgr,
111+ context,
112+ true);
113+}
114+
115+void dcn21_hw_sequencer_construct(struct dc *dc)
116+{
117+ dcn20_hw_sequencer_construct(dc);
118+ dc->hwss.init_sys_ctx = dcn21_init_sys_ctx;
119+ dc->hwss.s0i3_golden_init_wa = dcn21_s0i3_golden_init_wa;
120+ dc->hwss.optimize_pwr_state = dcn21_optimize_pwr_state;
121+ dc->hwss.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state;
122+}
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h+33−0
@@ -0,0 +1,33 @@
1+/*
2+* Copyright 2016 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+#ifndef __DC_HWSS_DCN21_H__
27+#define __DC_HWSS_DCN21_H__
28+
29+struct dc;
30+
31+void dcn21_hw_sequencer_construct(struct dc *dc);
32+
33+#endif /* __DC_HWSS_DCN21_H__ */
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c+470−0
@@ -0,0 +1,470 @@
1+/*
2+ * Copyright 2012-15 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 "reg_helper.h"
27+
28+#include <linux/delay.h>
29+#include "core_types.h"
30+#include "link_encoder.h"
31+#include "dcn21_link_encoder.h"
32+#include "stream_encoder.h"
33+
34+#include "i2caux_interface.h"
35+#include "dc_bios_types.h"
36+
37+#include "gpio_service_interface.h"
38+
39+#define CTX \
40+ enc10->base.ctx
41+#define DC_LOGGER \
42+ enc10->base.ctx->logger
43+
44+#define REG(reg)\
45+ (enc10->link_regs->reg)
46+
47+#undef FN
48+#define FN(reg_name, field_name) \
49+ enc10->link_shift->field_name, enc10->link_mask->field_name
50+
51+#define IND_REG(index) \
52+ (enc10->link_regs->index)
53+
54+static struct mpll_cfg dcn21_mpll_cfg_ref[] = {
55+ // RBR
56+ {
57+ .hdmimode_enable = 0,
58+ .ref_range = 1,
59+ .ref_clk_mpllb_div = 1,
60+ .mpllb_ssc_en = 1,
61+ .mpllb_div5_clk_en = 1,
62+ .mpllb_multiplier = 238,
63+ .mpllb_fracn_en = 0,
64+ .mpllb_fracn_quot = 0,
65+ .mpllb_fracn_rem = 0,
66+ .mpllb_fracn_den = 1,
67+ .mpllb_ssc_up_spread = 0,
68+ .mpllb_ssc_peak = 44237,
69+ .mpllb_ssc_stepsize = 59454,
70+ .mpllb_div_clk_en = 0,
71+ .mpllb_div_multiplier = 0,
72+ .mpllb_hdmi_div = 0,
73+ .mpllb_tx_clk_div = 2,
74+ .tx_vboost_lvl = 5,
75+ .mpllb_pmix_en = 1,
76+ .mpllb_word_div2_en = 0,
77+ .mpllb_ana_v2i = 2,
78+ .mpllb_ana_freq_vco = 2,
79+ .mpllb_ana_cp_int = 9,
80+ .mpllb_ana_cp_prop = 15,
81+ .hdmi_pixel_clk_div = 0,
82+ },
83+ // HBR
84+ {
85+ .hdmimode_enable = 0,
86+ .ref_range = 1,
87+ .ref_clk_mpllb_div = 1,
88+ .mpllb_ssc_en = 1,
89+ .mpllb_div5_clk_en = 1,
90+ .mpllb_multiplier = 192,
91+ .mpllb_fracn_en = 1,
92+ .mpllb_fracn_quot = 32768,
93+ .mpllb_fracn_rem = 0,
94+ .mpllb_fracn_den = 1,
95+ .mpllb_ssc_up_spread = 0,
96+ .mpllb_ssc_peak = 36864,
97+ .mpllb_ssc_stepsize = 49545,
98+ .mpllb_div_clk_en = 0,
99+ .mpllb_div_multiplier = 0,
100+ .mpllb_hdmi_div = 0,
101+ .mpllb_tx_clk_div = 1,
102+ .tx_vboost_lvl = 5,
103+ .mpllb_pmix_en = 1,
104+ .mpllb_word_div2_en = 0,
105+ .mpllb_ana_v2i = 2,
106+ .mpllb_ana_freq_vco = 3,
107+ .mpllb_ana_cp_int = 9,
108+ .mpllb_ana_cp_prop = 15,
109+ .hdmi_pixel_clk_div = 0,
110+ },
111+ //HBR2
112+ {
113+ .hdmimode_enable = 0,
114+ .ref_range = 1,
115+ .ref_clk_mpllb_div = 1,
116+ .mpllb_ssc_en = 1,
117+ .mpllb_div5_clk_en = 1,
118+ .mpllb_multiplier = 192,
119+ .mpllb_fracn_en = 1,
120+ .mpllb_fracn_quot = 32768,
121+ .mpllb_fracn_rem = 0,
122+ .mpllb_fracn_den = 1,
123+ .mpllb_ssc_up_spread = 0,
124+ .mpllb_ssc_peak = 36864,
125+ .mpllb_ssc_stepsize = 49545,
126+ .mpllb_div_clk_en = 0,
127+ .mpllb_div_multiplier = 0,
128+ .mpllb_hdmi_div = 0,
129+ .mpllb_tx_clk_div = 0,
130+ .tx_vboost_lvl = 5,
131+ .mpllb_pmix_en = 1,
132+ .mpllb_word_div2_en = 0,
133+ .mpllb_ana_v2i = 2,
134+ .mpllb_ana_freq_vco = 3,
135+ .mpllb_ana_cp_int = 9,
136+ .mpllb_ana_cp_prop = 15,
137+ .hdmi_pixel_clk_div = 0,
138+ },
139+ //HBR3
140+ {
141+ .hdmimode_enable = 0,
142+ .ref_range = 1,
143+ .ref_clk_mpllb_div = 1,
144+ .mpllb_ssc_en = 1,
145+ .mpllb_div5_clk_en = 1,
146+ .mpllb_multiplier = 304,
147+ .mpllb_fracn_en = 1,
148+ .mpllb_fracn_quot = 49152,
149+ .mpllb_fracn_rem = 0,
150+ .mpllb_fracn_den = 1,
151+ .mpllb_ssc_up_spread = 0,
152+ .mpllb_ssc_peak = 55296,
153+ .mpllb_ssc_stepsize = 74318,
154+ .mpllb_div_clk_en = 0,
155+ .mpllb_div_multiplier = 0,
156+ .mpllb_hdmi_div = 0,
157+ .mpllb_tx_clk_div = 0,
158+ .tx_vboost_lvl = 5,
159+ .mpllb_pmix_en = 1,
160+ .mpllb_word_div2_en = 0,
161+ .mpllb_ana_v2i = 2,
162+ .mpllb_ana_freq_vco = 1,
163+ .mpllb_ana_cp_int = 7,
164+ .mpllb_ana_cp_prop = 16,
165+ .hdmi_pixel_clk_div = 0,
166+ },
167+};
168+
169+
170+static bool update_cfg_data(
171+ struct dcn10_link_encoder *enc10,
172+ const struct dc_link_settings *link_settings,
173+ struct dpcssys_phy_seq_cfg *cfg)
174+{
175+ int i;
176+
177+ cfg->load_sram_fw = false;
178+ cfg->use_calibration_setting = true;
179+
180+ //TODO: need to implement a proper lane mapping for Renoir.
181+ for (i = 0; i < 4; i++)
182+ cfg->lane_en[i] = true;
183+
184+ switch (link_settings->link_rate) {
185+ case LINK_RATE_LOW:
186+ cfg->mpll_cfg = dcn21_mpll_cfg_ref[0];
187+ break;
188+ case LINK_RATE_HIGH:
189+ cfg->mpll_cfg = dcn21_mpll_cfg_ref[1];
190+ break;
191+ case LINK_RATE_HIGH2:
192+ cfg->mpll_cfg = dcn21_mpll_cfg_ref[2];
193+ break;
194+ case LINK_RATE_HIGH3:
195+ cfg->mpll_cfg = dcn21_mpll_cfg_ref[3];
196+ break;
197+ default:
198+ DC_LOG_ERROR("%s: No supported link rate found %X!\n",
199+ __func__, link_settings->link_rate);
200+ return false;
201+ }
202+
203+ return true;
204+}
205+
206+void dcn21_link_encoder_get_max_link_cap(struct link_encoder *enc,
207+ struct dc_link_settings *link_settings)
208+{
209+ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
210+ uint32_t value;
211+
212+ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &value);
213+
214+ if (!value && link_settings->lane_count > LANE_COUNT_TWO)
215+ link_settings->lane_count = LANE_COUNT_TWO;
216+}
217+
218+bool dcn21_link_encoder_is_in_alt_mode(struct link_encoder *enc)
219+{
220+ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
221+ uint32_t value;
222+
223+ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &value);
224+
225+ // if value == 1 alt mode is disabled, otherwise it is enabled
226+ return !value;
227+}
228+
229+bool dcn21_link_encoder_acquire_phy(struct link_encoder *enc)
230+{
231+ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
232+ int value;
233+
234+ if (enc->features.flags.bits.DP_IS_USB_C) {
235+ REG_GET(RDPCSTX_PHY_CNTL6,
236+ RDPCS_PHY_DPALT_DISABLE, &value);
237+
238+ if (value == 1) {
239+ ASSERT(0);
240+ return false;
241+ }
242+ REG_UPDATE(RDPCSTX_PHY_CNTL6,
243+ RDPCS_PHY_DPALT_DISABLE_ACK, 0);
244+
245+ udelay(40);
246+
247+ REG_GET(RDPCSTX_PHY_CNTL6,
248+ RDPCS_PHY_DPALT_DISABLE, &value);
249+ if (value == 1) {
250+ ASSERT(0);
251+ REG_UPDATE(RDPCSTX_PHY_CNTL6,
252+ RDPCS_PHY_DPALT_DISABLE_ACK, 1);
253+ return false;
254+ }
255+ }
256+
257+ REG_UPDATE(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_REF_CLK_EN, 1);
258+
259+ return true;
260+}
261+
262+
263+
264+static void dcn21_link_encoder_release_phy(struct link_encoder *enc)
265+{
266+ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
267+
268+ if (enc->features.flags.bits.DP_IS_USB_C) {
269+ REG_UPDATE(RDPCSTX_PHY_CNTL6,
270+ RDPCS_PHY_DPALT_DISABLE_ACK, 1);
271+ }
272+
273+ REG_UPDATE(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_REF_CLK_EN, 0);
274+
275+}
276+
277+void dcn21_link_encoder_enable_dp_output(
278+ struct link_encoder *enc,
279+ const struct dc_link_settings *link_settings,
280+ enum clock_source_id clock_source)
281+{
282+ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
283+ struct dcn21_link_encoder *enc21 = (struct dcn21_link_encoder *) enc10;
284+ struct dpcssys_phy_seq_cfg *cfg = &enc21->phy_seq_cfg;
285+
286+ if (!dcn21_link_encoder_acquire_phy(enc))
287+ return;
288+
289+ if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
290+ dcn10_link_encoder_enable_dp_output(enc, link_settings, clock_source);
291+ return;
292+ }
293+
294+ if (!update_cfg_data(enc10, link_settings, cfg))
295+ return;
296+
297+ enc1_configure_encoder(enc10, link_settings);
298+
299+ dcn10_link_encoder_setup(enc, SIGNAL_TYPE_DISPLAY_PORT);
300+
301+}
302+
303+void dcn21_link_encoder_enable_dp_mst_output(
304+ struct link_encoder *enc,
305+ const struct dc_link_settings *link_settings,
306+ enum clock_source_id clock_source)
307+{
308+ if (!dcn21_link_encoder_acquire_phy(enc))
309+ return;
310+
311+ dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source);
312+}
313+
314+void dcn21_link_encoder_disable_output(
315+ struct link_encoder *enc,
316+ enum signal_type signal)
317+{
318+ dcn10_link_encoder_disable_output(enc, signal);
319+
320+ if (dc_is_dp_signal(signal))
321+ dcn21_link_encoder_release_phy(enc);
322+}
323+
324+
325+static const struct link_encoder_funcs dcn21_link_enc_funcs = {
326+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
327+ .read_state = link_enc2_read_state,
328+#endif
329+ .validate_output_with_stream =
330+ dcn10_link_encoder_validate_output_with_stream,
331+ .hw_init = enc2_hw_init,
332+ .setup = dcn10_link_encoder_setup,
333+ .enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
334+ .enable_dp_output = dcn21_link_encoder_enable_dp_output,
335+ .enable_dp_mst_output = dcn21_link_encoder_enable_dp_mst_output,
336+ .disable_output = dcn21_link_encoder_disable_output,
337+ .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
338+ .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
339+ .update_mst_stream_allocation_table =
340+ dcn10_link_encoder_update_mst_stream_allocation_table,
341+ .psr_program_dp_dphy_fast_training =
342+ dcn10_psr_program_dp_dphy_fast_training,
343+ .psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
344+ .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
345+ .enable_hpd = dcn10_link_encoder_enable_hpd,
346+ .disable_hpd = dcn10_link_encoder_disable_hpd,
347+ .is_dig_enabled = dcn10_is_dig_enabled,
348+ .destroy = dcn10_link_encoder_destroy,
349+ .fec_set_enable = enc2_fec_set_enable,
350+ .fec_set_ready = enc2_fec_set_ready,
351+ .fec_is_active = enc2_fec_is_active,
352+ .get_dig_frontend = dcn10_get_dig_frontend,
353+ .is_in_alt_mode = dcn21_link_encoder_is_in_alt_mode,
354+ .get_max_link_cap = dcn21_link_encoder_get_max_link_cap,
355+};
356+
357+void dcn21_link_encoder_construct(
358+ struct dcn21_link_encoder *enc21,
359+ const struct encoder_init_data *init_data,
360+ const struct encoder_feature_support *enc_features,
361+ const struct dcn10_link_enc_registers *link_regs,
362+ const struct dcn10_link_enc_aux_registers *aux_regs,
363+ const struct dcn10_link_enc_hpd_registers *hpd_regs,
364+ const struct dcn10_link_enc_shift *link_shift,
365+ const struct dcn10_link_enc_mask *link_mask)
366+{
367+ struct bp_encoder_cap_info bp_cap_info = {0};
368+ const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
369+ enum bp_result result = BP_RESULT_OK;
370+ struct dcn10_link_encoder *enc10 = &enc21->enc10;
371+
372+ enc10->base.funcs = &dcn21_link_enc_funcs;
373+ enc10->base.ctx = init_data->ctx;
374+ enc10->base.id = init_data->encoder;
375+
376+ enc10->base.hpd_source = init_data->hpd_source;
377+ enc10->base.connector = init_data->connector;
378+
379+ enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
380+
381+ enc10->base.features = *enc_features;
382+
383+ enc10->base.transmitter = init_data->transmitter;
384+
385+ /* set the flag to indicate whether driver poll the I2C data pin
386+ * while doing the DP sink detect
387+ */
388+
389+/* if (dal_adapter_service_is_feature_supported(as,
390+ FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
391+ enc10->base.features.flags.bits.
392+ DP_SINK_DETECT_POLL_DATA_PIN = true;*/
393+
394+ enc10->base.output_signals =
395+ SIGNAL_TYPE_DVI_SINGLE_LINK |
396+ SIGNAL_TYPE_DVI_DUAL_LINK |
397+ SIGNAL_TYPE_LVDS |
398+ SIGNAL_TYPE_DISPLAY_PORT |
399+ SIGNAL_TYPE_DISPLAY_PORT_MST |
400+ SIGNAL_TYPE_EDP |
401+ SIGNAL_TYPE_HDMI_TYPE_A;
402+
403+ /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
404+ * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
405+ * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
406+ * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS.
407+ * Prefer DIG assignment is decided by board design.
408+ * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design
409+ * and VBIOS will filter out 7 UNIPHY for DCE 8.0.
410+ * By this, adding DIGG should not hurt DCE 8.0.
411+ * This will let DCE 8.1 share DCE 8.0 as much as possible
412+ */
413+
414+ enc10->link_regs = link_regs;
415+ enc10->aux_regs = aux_regs;
416+ enc10->hpd_regs = hpd_regs;
417+ enc10->link_shift = link_shift;
418+ enc10->link_mask = link_mask;
419+
420+ switch (enc10->base.transmitter) {
421+ case TRANSMITTER_UNIPHY_A:
422+ enc10->base.preferred_engine = ENGINE_ID_DIGA;
423+ break;
424+ case TRANSMITTER_UNIPHY_B:
425+ enc10->base.preferred_engine = ENGINE_ID_DIGB;
426+ break;
427+ case TRANSMITTER_UNIPHY_C:
428+ enc10->base.preferred_engine = ENGINE_ID_DIGC;
429+ break;
430+ case TRANSMITTER_UNIPHY_D:
431+ enc10->base.preferred_engine = ENGINE_ID_DIGD;
432+ break;
433+ case TRANSMITTER_UNIPHY_E:
434+ enc10->base.preferred_engine = ENGINE_ID_DIGE;
435+ break;
436+ case TRANSMITTER_UNIPHY_F:
437+ enc10->base.preferred_engine = ENGINE_ID_DIGF;
438+ break;
439+ case TRANSMITTER_UNIPHY_G:
440+ enc10->base.preferred_engine = ENGINE_ID_DIGG;
441+ break;
442+ default:
443+ ASSERT_CRITICAL(false);
444+ enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
445+ }
446+
447+ /* default to one to mirror Windows behavior */
448+ enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
449+
450+ result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios,
451+ enc10->base.id, &bp_cap_info);
452+
453+ /* Override features with DCE-specific values */
454+ if (result == BP_RESULT_OK) {
455+ enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
456+ bp_cap_info.DP_HBR2_EN;
457+ enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
458+ bp_cap_info.DP_HBR3_EN;
459+ enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
460+ enc10->base.features.flags.bits.DP_IS_USB_C =
461+ bp_cap_info.DP_IS_USB_C;
462+ } else {
463+ DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
464+ __func__,
465+ result);
466+ }
467+ if (enc10->base.ctx->dc->debug.hdmi20_disable) {
468+ enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
469+ }
470+}
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.h+61−0
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright 2012-15 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+#ifndef __DC_LINK_ENCODER__DCN21_H__
27+#define __DC_LINK_ENCODER__DCN21_H__
28+
29+#include "dcn20/dcn20_link_encoder.h"
30+
31+struct dcn21_link_encoder {
32+ struct dcn10_link_encoder enc10;
33+ struct dpcssys_phy_seq_cfg phy_seq_cfg;
34+};
35+
36+#define LINK_ENCODER_MASK_SH_LIST_DCN21(mask_sh)\
37+ LINK_ENCODER_MASK_SH_LIST_DCN20(mask_sh),\
38+ LE_SF(UNIPHYA_CHANNEL_XBAR_CNTL, UNIPHY_CHANNEL0_XBAR_SOURCE, mask_sh),\
39+ LE_SF(UNIPHYA_CHANNEL_XBAR_CNTL, UNIPHY_CHANNEL1_XBAR_SOURCE, mask_sh),\
40+ LE_SF(UNIPHYA_CHANNEL_XBAR_CNTL, UNIPHY_CHANNEL2_XBAR_SOURCE, mask_sh),\
41+ LE_SF(UNIPHYA_CHANNEL_XBAR_CNTL, UNIPHY_CHANNEL3_XBAR_SOURCE, mask_sh), \
42+ SRI(RDPCSTX_PHY_FUSE2, RDPCSTX, id), \
43+ SRI(RDPCSTX_PHY_FUSE3, RDPCSTX, id), \
44+ SR(RDPCSTX0_RDPCSTX_SCRATCH)
45+
46+void dcn21_link_encoder_enable_dp_output(
47+ struct link_encoder *enc,
48+ const struct dc_link_settings *link_settings,
49+ enum clock_source_id clock_source);
50+
51+void dcn21_link_encoder_construct(
52+ struct dcn21_link_encoder *enc21,
53+ const struct encoder_init_data *init_data,
54+ const struct encoder_feature_support *enc_features,
55+ const struct dcn10_link_enc_registers *link_regs,
56+ const struct dcn10_link_enc_aux_registers *aux_regs,
57+ const struct dcn10_link_enc_hpd_registers *hpd_regs,
58+ const struct dcn10_link_enc_shift *link_shift,
59+ const struct dcn10_link_enc_mask *link_mask);
60+
61+#endif
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c+250−53
@@ -23,8 +23,6 @@ · 22 unmodified lines
2323 *
2424 */
2525
26−#include <linux/slab.h>
27−
2826 #include "dm_services.h"
2927 #include "dc.h"
3028
@@ -42,11 +40,11 @@ · 11 unmodified lines
4240 #include "irq/dcn21/irq_service_dcn21.h"
4341 #include "dcn20/dcn20_dpp.h"
4442 #include "dcn20/dcn20_optc.h"
45−#include "dcn20/dcn20_hwseq.h"
43+#include "dcn21/dcn21_hwseq.h"
4644 #include "dce110/dce110_hw_sequencer.h"
4745 #include "dcn20/dcn20_opp.h"
4846 #include "dcn20/dcn20_dsc.h"
49−#include "dcn20/dcn20_link_encoder.h"
47+#include "dcn21/dcn21_link_encoder.h"
5048 #include "dcn20/dcn20_stream_encoder.h"
5149 #include "dce/dce_clock_source.h"
5250 #include "dce/dce_audio.h"
@@ -84,6 +82,7 @@ · 31 unmodified lines
8482
8583
8684 struct _vcs_dpi_ip_params_st dcn2_1_ip = {
85+ .odm_capable = 1,
8786 .gpuvm_enable = 0,
8887 .hostvm_enable = 0,
8988 .gpuvm_max_page_table_levels = 1,
@@ -205,11 +204,11 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 115 unmodified lines
205204 .state = 4,
206205 .dcfclk_mhz = 810.0,
207206 .fabricclk_mhz = 1600.0,
208− .dispclk_mhz = 1015.0,
209− .dppclk_mhz = 1015.0,
210− .phyclk_mhz = 810.0,
207+ .dispclk_mhz = 1395.0,
208+ .dppclk_mhz = 1285.0,
209+ .phyclk_mhz = 1325.0,
211210 .socclk_mhz = 953.0,
212− .dscclk_mhz = 318.334,
211+ .dscclk_mhz = 489.0,
213212 .dram_speed_mts = 4266.0,
214213 },
215214 /*Extra state, no dispclk ramping*/
@@ -217,18 +216,18 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 1 unmodified line
217216 .state = 5,
218217 .dcfclk_mhz = 810.0,
219218 .fabricclk_mhz = 1600.0,
220− .dispclk_mhz = 1015.0,
221− .dppclk_mhz = 1015.0,
222− .phyclk_mhz = 810.0,
219+ .dispclk_mhz = 1395.0,
220+ .dppclk_mhz = 1285.0,
221+ .phyclk_mhz = 1325.0,
223222 .socclk_mhz = 953.0,
224− .dscclk_mhz = 318.334,
223+ .dscclk_mhz = 489.0,
225224 .dram_speed_mts = 4266.0,
226225 },
227226
228227 },
229228
230− .sr_exit_time_us = 9.0,
231− .sr_enter_plus_exit_time_us = 11.0,
229+ .sr_exit_time_us = 12.5,
230+ .sr_enter_plus_exit_time_us = 17.0,
232231 .urgent_latency_us = 4.0,
233232 .urgent_latency_pixel_data_only_us = 4.0,
234233 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
@@ -350,6 +349,30 @@ static const struct bios_registers bios_regs = { · 115 unmodified lines
350349 NBIO_SR(BIOS_SCRATCH_6)
351350 };
352351
352+static const struct dce_dmcu_registers dmcu_regs = {
353+ DMCU_DCN10_REG_LIST()
354+};
355+
356+static const struct dce_dmcu_shift dmcu_shift = {
357+ DMCU_MASK_SH_LIST_DCN10(__SHIFT)
358+};
359+
360+static const struct dce_dmcu_mask dmcu_mask = {
361+ DMCU_MASK_SH_LIST_DCN10(_MASK)
362+};
363+
364+static const struct dce_abm_registers abm_regs = {
365+ ABM_DCN20_REG_LIST()
366+};
367+
368+static const struct dce_abm_shift abm_shift = {
369+ ABM_MASK_SH_LIST_DCN20(__SHIFT)
370+};
371+
372+static const struct dce_abm_mask abm_mask = {
373+ ABM_MASK_SH_LIST_DCN20(_MASK)
374+};
375+
353376 #ifdef CONFIG_DRM_AMD_DC_DMUB
354377 static const struct dcn21_dmcub_registers dmcub_regs = {
355378 DMCUB_REG_LIST_DCN()
@@ -628,6 +651,14 @@ static const struct dcn10_stream_enc_registers stream_enc_regs[] = { · 272 unmodified lines
628651 stream_enc_regs(4),
629652 };
630653
654+static const struct dce110_aux_registers_shift aux_shift = {
655+ DCN_AUX_MASK_SH_LIST(__SHIFT)
656+};
657+
658+static const struct dce110_aux_registers_mask aux_mask = {
659+ DCN_AUX_MASK_SH_LIST(_MASK)
660+};
661+
631662 static const struct dcn10_stream_encoder_shift se_shift = {
632663 SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT)
633664 };
@@ -636,6 +667,8 @@ static const struct dcn10_stream_encoder_mask se_mask = { · 2 unmodified lines
636667 SE_COMMON_MASK_SH_LIST_DCN20(_MASK)
637668 };
638669
670+static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
671+
639672 static struct input_pixel_processor *dcn21_ipp_create(
640673 struct dc_context *ctx, uint32_t inst)
641674 {
@@ -683,7 +716,10 @@ static struct dce_aux *dcn21_aux_engine_create( · 41 unmodified lines
683716
684717 dce110_aux_engine_construct(aux_engine, ctx, inst,
685718 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
686− &aux_engine_regs[inst]);
719+ &aux_engine_regs[inst],
720+ &aux_mask,
721+ &aux_shift,
722+ ctx->dc->caps.extended_aux_timeout_support);
687723
688724 return &aux_engine->base;
689725 }
@@ -726,11 +762,12 @@ static const struct resource_caps res_cap_rn = { · 36 unmodified lines
726762 .num_timing_generator = 4,
727763 .num_opp = 4,
728764 .num_video_plane = 4,
729− .num_audio = 6, // 6 audio endpoints. 4 audio streams
765+ .num_audio = 4, // 4 audio endpoints. 4 audio streams
730766 .num_stream_encoder = 5,
731767 .num_pll = 5, // maybe 3 because the last two used for USB-c
732768 .num_dwb = 1,
733769 .num_ddc = 5,
770+ .num_vmid = 1,
734771 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
735772 .num_dsc = 3,
736773 #endif
@@ -800,11 +837,11 @@ static const struct dc_debug_options debug_defaults_drv = { · 63 unmodified lines
800837 .disable_dcc = DCC_ENABLE,
801838 .vsr_support = true,
802839 .performance_trace = false,
803− .max_downscale_src_width = 5120,/*upto 5K*/
840+ .max_downscale_src_width = 3840,
804841 .disable_pplib_wm_range = false,
805842 .scl_reset_length10 = true,
806843 .sanity_checks = true,
807− .disable_48mhz_pwrdwn = true,
844+ .disable_48mhz_pwrdwn = false,
808845 };
809846
810847 static const struct dc_debug_options debug_defaults_diags = {
@@ -939,7 +976,7 @@ static void destruct(struct dcn21_resource_pool *pool) · 128 unmodified lines
939976 dcn_dccg_destroy(&pool->base.dccg);
940977
941978 if (pool->base.pp_smu != NULL)
942− dcn20_pp_smu_destroy(&pool->base.pp_smu);
979+ dcn21_pp_smu_destroy(&pool->base.pp_smu);
943980 }
944981
945982
@@ -974,6 +1011,29 @@ static void calculate_wm_set_for_vlevel( · 28 unmodified lines
9741011
9751012 }
9761013
1014+static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
1015+{
1016+ kernel_fpu_begin();
1017+ if (dc->bb_overrides.sr_exit_time_ns) {
1018+ bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
1019+ }
1020+
1021+ if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {
1022+ bb->sr_enter_plus_exit_time_us =
1023+ dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
1024+ }
1025+
1026+ if (dc->bb_overrides.urgent_latency_ns) {
1027+ bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
1028+ }
1029+
1030+ if (dc->bb_overrides.dram_clock_change_latency_ns) {
1031+ bb->dram_clock_change_latency_us =
1032+ dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
1033+ }
1034+ kernel_fpu_end();
1035+}
1036+
9771037 void dcn21_calculate_wm(
9781038 struct dc *dc, struct dc_state *context,
9791039 display_e2e_pipe_params_st *pipes,
@@ -988,6 +1048,8 @@ void dcn21_calculate_wm( · 8 unmodified lines
9881048
9891049 ASSERT(bw_params);
9901050
1051+ patch_bounding_box(dc, &context->bw_ctx.dml.soc);
1052+
9911053 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
9921054 if (!context->res_ctx.pipe_ctx[i].stream)
9931055 continue;
@@ -1278,7 +1340,6 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 284 unmodified lines
12781340 dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
12791341 dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
12801342 dcn2_1_soc.num_chans = bw_params->num_channels;
1281− dcn2_1_soc.num_states = 0;
12821343
12831344 for (i = 0; i < clk_table->num_entries; i++) {
12841345
@@ -1288,8 +1349,9 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 3 unmodified lines
12881349 dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
12891350 /* This is probably wrong, TODO: find correct calculation */
12901351 dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000;
1291− dcn2_1_soc.num_states++;
12921352 }
1353+ dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i];
1354+ dcn2_1_soc.num_states = i;
12931355 }
12941356
12951357 /* Temporary Place holder until we can get them from fuse */
@@ -1317,32 +1379,42 @@ static struct dpm_clocks dummy_clocks = { · 21 unmodified lines
13171379
13181380 };
13191381
1320−enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp,
1382+static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp,
13211383 struct pp_smu_wm_range_sets *ranges)
13221384 {
13231385 return PP_SMU_RESULT_OK;
13241386 }
13251387
1326−enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp,
1388+static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp,
13271389 struct dpm_clocks *clock_table)
13281390 {
13291391 *clock_table = dummy_clocks;
13301392 return PP_SMU_RESULT_OK;
13311393 }
13321394
1333−struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx)
1395+static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx)
13341396 {
13351397 struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
13361398
1337− pp_smu->ctx.ver = PP_SMU_VER_RN;
1399+ if (!pp_smu)
1400+ return pp_smu;
1401+
1402+ if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) {
1403+ pp_smu->ctx.ver = PP_SMU_VER_RN;
1404+ pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table;
1405+ pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges;
1406+ } else {
13381407
1339− pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table;
1340− pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges;
1408+ dm_pp_get_funcs(ctx, pp_smu);
1409+
1410+ if (pp_smu->ctx.ver != PP_SMU_VER_RN)
1411+ pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs));
1412+ }
13411413
13421414 return pp_smu;
13431415 }
13441416
1345−void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
1417+static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
13461418 {
13471419 if (pp_smu && *pp_smu) {
13481420 kfree(*pp_smu);
@@ -1400,6 +1472,7 @@ static struct dce_hwseq *dcn21_hwseq_create( · 51 unmodified lines
14001472 hws->regs = &hwseq_reg;
14011473 hws->shifts = &hwseq_shift;
14021474 hws->masks = &hwseq_mask;
1475+ hws->wa.DEGVIDCN21 = true;
14031476 }
14041477 return hws;
14051478 }
@@ -1418,9 +1491,103 @@ static const struct resource_create_funcs res_create_maximus_funcs = { · 12 unmodified lines
14181491 .create_hwseq = dcn21_hwseq_create,
14191492 };
14201493
1494+static const struct encoder_feature_support link_enc_feature = {
1495+ .max_hdmi_deep_color = COLOR_DEPTH_121212,
1496+ .max_hdmi_pixel_clock = 600000,
1497+ .hdmi_ycbcr420_supported = true,
1498+ .dp_ycbcr420_supported = true,
1499+ .flags.bits.IS_HBR2_CAPABLE = true,
1500+ .flags.bits.IS_HBR3_CAPABLE = true,
1501+ .flags.bits.IS_TPS3_CAPABLE = true,
1502+ .flags.bits.IS_TPS4_CAPABLE = true
1503+};
1504+
1505+
1506+#define link_regs(id, phyid)\
1507+[id] = {\
1508+ LE_DCN10_REG_LIST(id), \
1509+ UNIPHY_DCN2_REG_LIST(phyid), \
1510+ SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
1511+}
1512+
1513+static const struct dcn10_link_enc_registers link_enc_regs[] = {
1514+ link_regs(0, A),
1515+ link_regs(1, B),
1516+ link_regs(2, C),
1517+ link_regs(3, D),
1518+ link_regs(4, E),
1519+};
1520+
1521+#define aux_regs(id)\
1522+[id] = {\
1523+ DCN2_AUX_REG_LIST(id)\
1524+}
1525+
1526+static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
1527+ aux_regs(0),
1528+ aux_regs(1),
1529+ aux_regs(2),
1530+ aux_regs(3),
1531+ aux_regs(4)
1532+};
1533+
1534+#define hpd_regs(id)\
1535+[id] = {\
1536+ HPD_REG_LIST(id)\
1537+}
1538+
1539+static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
1540+ hpd_regs(0),
1541+ hpd_regs(1),
1542+ hpd_regs(2),
1543+ hpd_regs(3),
1544+ hpd_regs(4)
1545+};
1546+
1547+static const struct dcn10_link_enc_shift le_shift = {
1548+ LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT)
1549+};
1550+
1551+static const struct dcn10_link_enc_mask le_mask = {
1552+ LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK)
1553+};
1554+
1555+static struct link_encoder *dcn21_link_encoder_create(
1556+ const struct encoder_init_data *enc_init_data)
1557+{
1558+ struct dcn21_link_encoder *enc21 =
1559+ kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL);
1560+
1561+ if (!enc21)
1562+ return NULL;
1563+
1564+ dcn21_link_encoder_construct(enc21,
1565+ enc_init_data,
1566+ &link_enc_feature,
1567+ &link_enc_regs[enc_init_data->transmitter],
1568+ &link_enc_aux_regs[enc_init_data->channel - 1],
1569+ &link_enc_hpd_regs[enc_init_data->hpd_source],
1570+ &le_shift,
1571+ &le_mask);
1572+
1573+ return &enc21->enc10.base;
1574+}
1575+#define CTX ctx
1576+
1577+#define REG(reg_name) \
1578+ (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
1579+
1580+static uint32_t read_pipe_fuses(struct dc_context *ctx)
1581+{
1582+ uint32_t value = REG_READ(CC_DC_PIPE_DIS);
1583+ /* RV1 support max 4 pipes */
1584+ value = value & 0xf;
1585+ return value;
1586+}
1587+
14211588 static struct resource_funcs dcn21_res_pool_funcs = {
14221589 .destroy = dcn21_destroy_resource_pool,
1423− .link_enc_create = dcn20_link_encoder_create,
1590+ .link_enc_create = dcn21_link_encoder_create,
14241591 .validate_bandwidth = dcn21_validate_bandwidth,
14251592 .add_stream_to_ctx = dcn20_add_stream_to_ctx,
14261593 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
@@ -1437,9 +1604,10 @@ static bool construct( · 10 unmodified lines
14371604 struct dc *dc,
14381605 struct dcn21_resource_pool *pool)
14391606 {
1440− int i;
1607+ int i, j;
14411608 struct dc_context *ctx = dc->ctx;
14421609 struct irq_service_init_data init_data;
1610+ uint32_t pipe_fuses = read_pipe_fuses(ctx);
14431611
14441612 ctx->dc_bios->regs = &bios_regs;
14451613
@@ -1457,7 +1625,9 @@ static bool construct( · 11 unmodified lines
14571625 *************************************************/
14581626 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
14591627
1460− pool->base.pipe_count = 4;
1628+ /* max pipe num for ASIC before check pipe fuses */
1629+ pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1630+
14611631 dc->caps.max_downscale_ratio = 200;
14621632 dc->caps.i2c_speed_in_khz = 100;
14631633 dc->caps.max_cursor_size = 256;
@@ -1467,6 +1637,7 @@ static bool construct( · 3 unmodified lines
14671637 dc->caps.max_slave_planes = 1;
14681638 dc->caps.post_blend_color_processing = true;
14691639 dc->caps.force_dp_tps4_for_cp2520 = true;
1640+ dc->caps.extended_aux_timeout_support = true;
14701641
14711642 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
14721643 dc->debug = debug_defaults_drv;
@@ -1516,6 +1687,26 @@ static bool construct( · 43 unmodified lines
15161687 goto create_fail;
15171688 }
15181689
1690+ pool->base.dmcu = dcn20_dmcu_create(ctx,
1691+ &dmcu_regs,
1692+ &dmcu_shift,
1693+ &dmcu_mask);
1694+ if (pool->base.dmcu == NULL) {
1695+ dm_error("DC: failed to create dmcu!\n");
1696+ BREAK_TO_DEBUGGER();
1697+ goto create_fail;
1698+ }
1699+
1700+ pool->base.abm = dce_abm_create(ctx,
1701+ &abm_regs,
1702+ &abm_shift,
1703+ &abm_mask);
1704+ if (pool->base.abm == NULL) {
1705+ dm_error("DC: failed to create abm!\n");
1706+ BREAK_TO_DEBUGGER();
1707+ goto create_fail;
1708+ }
1709+
15191710 #ifdef CONFIG_DRM_AMD_DC_DMUB
15201711 pool->base.dmcub = dcn21_dmcub_create(ctx,
15211712 &dmcub_regs,
@@ -1537,8 +1728,15 @@ static bool construct( · 15 unmodified lines
15371728 if (!pool->base.irqs)
15381729 goto create_fail;
15391730
1731+ j = 0;
15401732 /* mem input -> ipp -> dpp -> opp -> TG */
15411733 for (i = 0; i < pool->base.pipe_count; i++) {
1734+ /* if pipe is disabled, skip instance of HW pipe,
1735+ * i.e, skip ASIC register instance
1736+ */
1737+ if ((pipe_fuses & (1 << i)) != 0)
1738+ continue;
1739+
15421740 pool->base.hubps[i] = dcn21_hubp_create(ctx, i);
15431741 if (pool->base.hubps[i] == NULL) {
15441742 BREAK_TO_DEBUGGER();
@@ -1562,6 +1760,23 @@ static bool construct( · 17 unmodified lines
15621760 "DC: failed to create dpps!\n");
15631761 goto create_fail;
15641762 }
1763+
1764+ pool->base.opps[i] = dcn21_opp_create(ctx, i);
1765+ if (pool->base.opps[i] == NULL) {
1766+ BREAK_TO_DEBUGGER();
1767+ dm_error(
1768+ "DC: failed to create output pixel processor!\n");
1769+ goto create_fail;
1770+ }
1771+
1772+ pool->base.timing_generators[i] = dcn21_timing_generator_create(
1773+ ctx, i);
1774+ if (pool->base.timing_generators[i] == NULL) {
1775+ BREAK_TO_DEBUGGER();
1776+ dm_error("DC: failed to create tg!\n");
1777+ goto create_fail;
1778+ }
1779+ j++;
15651780 }
15661781
15671782 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
@@ -1582,27 +1797,9 @@ static bool construct( · 14 unmodified lines
15821797 pool->base.sw_i2cs[i] = NULL;
15831798 }
15841799
1585− for (i = 0; i < pool->base.res_cap->num_opp; i++) {
1586− pool->base.opps[i] = dcn21_opp_create(ctx, i);
1587− if (pool->base.opps[i] == NULL) {
1588− BREAK_TO_DEBUGGER();
1589− dm_error(
1590− "DC: failed to create output pixel processor!\n");
1591− goto create_fail;
1592− }
1593− }
1594−
1595− for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1596− pool->base.timing_generators[i] = dcn21_timing_generator_create(
1597− ctx, i);
1598− if (pool->base.timing_generators[i] == NULL) {
1599− BREAK_TO_DEBUGGER();
1600− dm_error("DC: failed to create tg!\n");
1601− goto create_fail;
1602− }
1603− }
1604−
1605− pool->base.timing_generator_count = i;
1800+ pool->base.timing_generator_count = j;
1801+ pool->base.pipe_count = j;
1802+ pool->base.mpcc_count = j;
16061803
16071804 pool->base.mpc = dcn21_mpc_create(ctx);
16081805 if (pool->base.mpc == NULL) {
@@ -1645,7 +1842,7 @@ static bool construct( · 36 unmodified lines
16451842 &res_create_funcs : &res_create_maximus_funcs)))
16461843 goto create_fail;
16471844
1648− dcn20_hw_sequencer_construct(dc);
1845+ dcn21_hw_sequencer_construct(dc);
16491846
16501847 dc->caps.max_planes = pool->base.pipe_count;
16511848
drivers/gpu/drm/amd/display/dc/dm_pp_smu.h+3−6
@@ -249,12 +249,10 @@ struct pp_smu_funcs_nv { · 248 unmodified lines
249249 };
250250 #endif
251251
252−#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
253−
254252 #define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8
255−#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 4
256−#define PP_SMU_NUM_FCLK_DPM_LEVELS 4
257−#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 4
253+#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 8
254+#define PP_SMU_NUM_FCLK_DPM_LEVELS 8
255+#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 8
258256
259257 struct dpm_clock {
260258 uint32_t Freq; // In MHz
@@ -288,7 +286,6 @@ struct pp_smu_funcs_rn { · 27 unmodified lines
288286 enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp,
289287 struct dpm_clocks *clock_table);
290288 };
291−#endif
292289
293290 struct pp_smu_funcs {
294291 struct pp_smu ctx;
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c+10−1
@@ -65,6 +65,7 @@ typedef struct { · 64 unmodified lines
6565
6666 #define BPP_INVALID 0
6767 #define BPP_BLENDED_PIPE 0xffffffff
68+#define DCN21_MAX_DSC_IMAGE_WIDTH 5184
6869
6970 static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
7071 static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
@@ -3379,6 +3380,8 @@ static unsigned int TruncToValidBPP( · 3308 unmodified lines
33793380 return 30;
33803381 else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24))
33813382 return 24;
3383+ else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18))
3384+ return 18;
33823385 else
33833386 return BPP_INVALID;
33843387 }
@@ -3936,6 +3939,10 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 551 unmodified lines
39363939 mode_lib->vba.MaximumSwathWidthInLineBuffer);
39373940 }
39383941 for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
3942+ double MaxMaxDispclkRoundedDown = RoundToDFSGranularityDown(
3943+ mode_lib->vba.MaxDispclk[mode_lib->vba.soc.num_states],
3944+ mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
3945+
39393946 for (j = 0; j < 2; j++) {
39403947 mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
39413948 mode_lib->vba.MaxDispclk[i],
@@ -3965,7 +3972,9 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 23 unmodified lines
39653972 && i == mode_lib->vba.soc.num_states)
39663973 mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
39673974 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
3968− if (mode_lib->vba.ODMCapability == false || mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine <= mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
3975+ if (mode_lib->vba.ODMCapability == false ||
3976+ (locals->PlaneRequiredDISPCLKWithoutODMCombine <= MaxMaxDispclkRoundedDown
3977+ && (!locals->DSCEnabled[k] || locals->HActive[k] <= DCN21_MAX_DSC_IMAGE_WIDTH))) {
39693978 locals->ODMCombineEnablePerState[i][k] = false;
39703979 mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
39713980 } else {
drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h+1−1
@@ -269,7 +269,7 @@ struct writeback_st { · 268 unmodified lines
269269
270270 struct _vcs_dpi_display_output_params_st {
271271 int dp_lanes;
272− int output_bpp;
272+ double output_bpp;
273273 int dsc_enable;
274274 int wb_enable;
275275 int num_active_wb;
drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c+2−0
@@ -434,6 +434,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) · 433 unmodified lines
434434 dst->odm_combine;
435435 mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
436436 (enum output_format_class) (dout->output_format);
437+ mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
438+ dout->output_bpp;
437439 mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
438440 (enum output_encoder_class) (dout->output_type);
439441
drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h+3−0
@@ -105,6 +105,9 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc, · 104 unmodified lines
105105 bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
106106 struct aux_payload *payload);
107107
108+enum dc_status dc_link_aux_configure_timeout(struct ddc_service *ddc,
109+ uint32_t timeout);
110+
108111 void dal_ddc_service_write_scdc_data(
109112 struct ddc_service *ddc_service,
110113 uint32_t pix_clk,
drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h+5−0
@@ -28,6 +28,8 @@ · 27 unmodified lines
2828
2929 #define LINK_TRAINING_ATTEMPTS 4
3030 #define LINK_TRAINING_RETRY_DELAY 50 /* ms */
31+#define LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD 32000 /*us*/
32+#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 400 /*us*/
3133
3234 struct dc_link;
3335 struct dc_stream_state;
@@ -43,6 +45,9 @@ bool dp_verify_link_cap_with_retries( · 9 unmodified lines
4345 struct dc_link_settings *known_limit_link_setting,
4446 int attempts);
4547
48+bool dp_verify_mst_link_cap(
49+ struct dc_link *link);
50+
4651 bool dp_validate_mode_timing(
4752 struct dc_link *link,
4853 const struct dc_crtc_timing *timing);
drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h+3−0
@@ -140,6 +140,9 @@ struct write_command_context { · 139 unmodified lines
140140
141141
142142 struct aux_engine_funcs {
143+ bool (*configure_timeout)(
144+ struct ddc_service *ddc,
145+ uint32_t timeout);
143146 void (*destroy)(
144147 struct aux_engine **ptr);
145148 bool (*acquire_engine)(
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h+10−1
@@ -47,7 +47,7 @@ · 46 unmodified lines
4747 #ifdef CONFIG_DRM_AMD_DC_DCN2_1
4848 /* Will these bw structures be ASIC specific? */
4949
50−#define MAX_NUM_DPM_LVL 4
50+#define MAX_NUM_DPM_LVL 8
5151 #define WM_SET_COUNT 4
5252
5353
@@ -149,6 +149,7 @@ struct wm_table { · 95 unmodified lines
149149 struct clk_bw_params {
150150 unsigned int vram_type;
151151 unsigned int num_channels;
152+ unsigned int dispclk_vco_khz;
152153 struct clk_limit_table clk_table;
153154 struct wm_table wm_table;
154155 };
@@ -180,12 +181,16 @@ struct clk_mgr_funcs { · 25 unmodified lines
180181 struct dc_state *context,
181182 enum dc_clock_type clock_type,
182183 struct dc_clock_config *clock_cfg);
184+
185+ bool (*are_clock_states_equal) (struct dc_clocks *a,
186+ struct dc_clocks *b);
183187 };
184188
185189 struct clk_mgr {
186190 struct dc_context *ctx;
187191 struct clk_mgr_funcs *funcs;
188192 struct dc_clocks clks;
193+ bool psr_allow_active_cache;
189194 int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
190195 #ifdef CONFIG_DRM_AMD_DC_DCN2_1
191196 struct clk_bw_params *bw_params;
@@ -199,4 +204,8 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p · 7 unmodified lines
199204
200205 void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr);
201206
207+void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr);
208+
209+void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr);
210+
202211 #endif /* __DAL_CLK_MGR_H__ */
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h+23−2
@@ -184,6 +184,21 @@ struct clk_mgr_registers { · 183 unmodified lines
184184 uint32_t MP1_SMN_C2PMSG_91;
185185 };
186186
187+enum clock_type {
188+ clock_type_dispclk = 1,
189+ clock_type_dcfclk,
190+ clock_type_socclk,
191+ clock_type_pixelclk,
192+ clock_type_phyclk,
193+ clock_type_dppclk,
194+ clock_type_fclk,
195+ clock_type_dcfdsclk,
196+ clock_type_dscclk,
197+ clock_type_uclk,
198+ clock_type_dramclk,
199+};
200+
201+
187202 struct state_dependent_clocks {
188203 int display_clk_khz;
189204 int pixel_clk_khz;
@@ -281,8 +296,14 @@ static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_cl · 91 unmodified lines
281296
282297 static inline bool should_update_pstate_support(bool safe_to_lower, bool calc_support, bool cur_support)
283298 {
284− // Whenever we are transitioning pstate support, we always want to notify prior to committing state
285− return (calc_support != cur_support) ? !safe_to_lower : false;
299+ if (cur_support != calc_support) {
300+ if (calc_support == true && safe_to_lower)
301+ return true;
302+ else if (calc_support == false && !safe_to_lower)
303+ return true;
304+ }
305+
306+ return false;
286307 }
287308
288309 int clk_mgr_helper_get_active_display_cnt(
drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h+1−0
@@ -147,6 +147,7 @@ struct hubbub_funcs { · 146 unmodified lines
147147 bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub);
148148 void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow);
149149
150+ void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub);
150151 };
151152
152153 struct hubbub {
drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h+4−0
@@ -184,6 +184,10 @@ struct link_encoder_funcs { · 183 unmodified lines
184184 bool (*fec_is_active)(struct link_encoder *enc);
185185 #endif
186186 bool (*is_in_alt_mode) (struct link_encoder *enc);
187+
188+ void (*get_max_link_cap)(struct link_encoder *enc,
189+ struct dc_link_settings *link_settings);
190+
187191 enum signal_type (*get_dig_mode)(
188192 struct link_encoder *enc);
189193 };
drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h+1−0
@@ -43,6 +43,7 @@ struct dcn_watermarks { · 42 unmodified lines
4343 #if defined(CONFIG_DRM_AMD_DC_DCN2_1)
4444 uint32_t frac_urg_bw_nom;
4545 uint32_t frac_urg_bw_flip;
46+ int32_t urgent_latency_ns;
4647 #endif
4748 struct cstate_pstate_watermarks_st cstate_pstate;
4849 };
drivers/gpu/drm/amd/display/dc/inc/hw/opp.h+1−0
@@ -208,6 +208,7 @@ struct output_pixel_processor { · 207 unmodified lines
208208 struct mpc_tree mpc_tree_params;
209209 bool mpcc_disconnect_pending[MAX_PIPES];
210210 const struct opp_funcs *funcs;
211+ uint32_t dyn_expansion;
211212 };
212213
213214 enum fmt_stereo_action {
drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h+5−0
@@ -214,6 +214,11 @@ struct stream_encoder_funcs { · 213 unmodified lines
214214 unsigned int (*dig_source_otg)(
215215 struct stream_encoder *enc);
216216
217+ bool (*dp_get_pixel_format)(
218+ struct stream_encoder *enc,
219+ enum dc_pixel_encoding *encoding,
220+ enum dc_color_depth *depth);
221+
217222 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
218223 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
219224 void (*enc_read_state)(struct stream_encoder *enc, struct enc_state *s);
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h+2−0
@@ -261,6 +261,8 @@ struct timing_generator_funcs { · 260 unmodified lines
261261
262262 void (*program_manual_trigger)(struct timing_generator *optc);
263263 void (*setup_manual_trigger)(struct timing_generator *optc);
264+ bool (*get_hw_timing)(struct timing_generator *optc,
265+ struct dc_crtc_timing *hw_crtc_timing);
264266
265267 void (*set_vtg_params)(struct timing_generator *optc,
266268 const struct dc_crtc_timing *dc_crtc_timing);
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h+14−2
@@ -232,6 +232,13 @@ struct hw_sequencer_funcs { · 231 unmodified lines
232232 struct dc *dc,
233233 struct dc_state *context);
234234
235+ void (*exit_optimized_pwr_state)(
236+ const struct dc *dc,
237+ struct dc_state *context);
238+ void (*optimize_pwr_state)(
239+ const struct dc *dc,
240+ struct dc_state *context);
241+
235242 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
236243 bool (*update_bandwidth)(
237244 struct dc *dc,
@@ -324,10 +331,12 @@ struct hw_sequencer_funcs { · 86 unmodified lines
324331 struct dc_state *context);
325332 void (*update_writeback)(struct dc *dc,
326333 const struct dc_stream_status *stream_status,
327− struct dc_writeback_info *wb_info);
334+ struct dc_writeback_info *wb_info,
335+ struct dc_state *context);
328336 void (*enable_writeback)(struct dc *dc,
329337 const struct dc_stream_status *stream_status,
330− struct dc_writeback_info *wb_info);
338+ struct dc_writeback_info *wb_info,
339+ struct dc_state *context);
331340 void (*disable_writeback)(struct dc *dc,
332341 unsigned int dwb_pipe_inst);
333342 #endif
@@ -340,6 +349,9 @@ struct hw_sequencer_funcs { · 6 unmodified lines
340349 enum dc_clock_type clock_type,
341350 struct dc_clock_config *clock_cfg);
342351
352+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
353+ bool (*s0i3_golden_init_wa)(struct dc *dc);
354+#endif
343355 };
344356
345357 void color_space_to_black_color(
drivers/gpu/drm/amd/display/include/ddc_service_types.h+2−0
@@ -31,6 +31,8 @@ · 30 unmodified lines
3131 #define DP_BRANCH_DEVICE_ID_0022B9 0x0022B9
3232 #define DP_BRANCH_DEVICE_ID_00001A 0x00001A
3333 #define DP_BRANCH_DEVICE_ID_0080E1 0x0080e1
34+#define DP_BRANCH_DEVICE_ID_90CC24 0x90CC24
35+#define DP_BRANCH_DEVICE_ID_00E04C 0x00E04C
3436
3537 enum ddc_result {
3638 DDC_RESULT_UNKNOWN = 0,
drivers/gpu/drm/amd/display/modules/freesync/freesync.c+12−5
@@ -234,6 +234,10 @@ static void update_v_total_for_static_ramp( · 233 unmodified lines
234234 current_duration_in_us) * (stream->timing.pix_clk_100hz / 10)),
235235 stream->timing.h_total), 1000);
236236
237+ /* v_total cannot be less than nominal */
238+ if (v_total < stream->timing.v_total)
239+ v_total = stream->timing.v_total;
240+
237241 in_out_vrr->adjust.v_total_min = v_total;
238242 in_out_vrr->adjust.v_total_max = v_total;
239243 }
@@ -743,6 +747,10 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, · 503 unmodified lines
743747 nominal_field_rate_in_uhz =
744748 mod_freesync_calc_nominal_field_rate(stream);
745749
750+ /* Rounded to the nearest Hz */
751+ nominal_field_rate_in_uhz = 1000000ULL *
752+ div_u64(nominal_field_rate_in_uhz + 500000, 1000000);
753+
746754 min_refresh_in_uhz = in_config->min_refresh_in_uhz;
747755 max_refresh_in_uhz = in_config->max_refresh_in_uhz;
748756
@@ -998,14 +1006,13 @@ unsigned long long mod_freesync_calc_nominal_field_rate( · 249 unmodified lines
9981006 const struct dc_stream_state *stream)
9991007 {
10001008 unsigned long long nominal_field_rate_in_uhz = 0;
1009+ unsigned int total = stream->timing.h_total * stream->timing.v_total;
10011010
1002− /* Calculate nominal field rate for stream */
1011+ /* Calculate nominal field rate for stream, rounded up to nearest integer */
10031012 nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz / 10;
10041013 nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL;
1005− nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz,
1006− stream->timing.h_total);
1007− nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz,
1008− stream->timing.v_total);
1014+
1015+ nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, total);
10091016
10101017 return nominal_field_rate_in_uhz;
10111018 }
drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h+3−0
@@ -35,4 +35,7 @@ struct mod_vrr_params; · 34 unmodified lines
3535 void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
3636 struct dc_info_packet *info_packet);
3737
38+void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
39+ struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue);
40+
3841 #endif
drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c+98−0
@@ -31,6 +31,7 @@ · 30 unmodified lines
3131 #include "dc.h"
3232
3333 #define HDMI_INFOFRAME_TYPE_VENDOR 0x81
34+#define HF_VSIF_VERSION 1
3435
3536 // VTEM Byte Offset
3637 #define VTEM_PB0 0
@@ -395,3 +396,100 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream, · 358 unmodified lines
395396
396397 }
397398
399+/**
400+ *****************************************************************************
401+ * Function: mod_build_hf_vsif_infopacket
402+ *
403+ * @brief
404+ * Prepare HDMI Vendor Specific info frame.
405+ * Follows HDMI Spec to build up Vendor Specific info frame
406+ *
407+ * @param [in] stream: contains data we may need to construct VSIF (i.e. timing_3d_format, etc.)
408+ * @param [out] info_packet: output structure where to store VSIF
409+ *****************************************************************************
410+ */
411+void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
412+ struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue)
413+{
414+ unsigned int length = 5;
415+ bool hdmi_vic_mode = false;
416+ uint8_t checksum = 0;
417+ uint32_t i = 0;
418+ enum dc_timing_3d_format format;
419+ bool bALLM = (bool)ALLMEnabled;
420+ bool bALLMVal = (bool)ALLMValue;
421+
422+ info_packet->valid = false;
423+ format = stream->timing.timing_3d_format;
424+ if (stream->view_format == VIEW_3D_FORMAT_NONE)
425+ format = TIMING_3D_FORMAT_NONE;
426+
427+ if (stream->timing.hdmi_vic != 0
428+ && stream->timing.h_total >= 3840
429+ && stream->timing.v_total >= 2160
430+ && format == TIMING_3D_FORMAT_NONE)
431+ hdmi_vic_mode = true;
432+
433+ if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode && !bALLM)
434+ return;
435+
436+ info_packet->sb[1] = 0x03;
437+ info_packet->sb[2] = 0x0C;
438+ info_packet->sb[3] = 0x00;
439+
440+ if (bALLM) {
441+ info_packet->sb[1] = 0xD8;
442+ info_packet->sb[2] = 0x5D;
443+ info_packet->sb[3] = 0xC4;
444+ info_packet->sb[4] = HF_VSIF_VERSION;
445+ }
446+
447+ if (format != TIMING_3D_FORMAT_NONE)
448+ info_packet->sb[4] = (2 << 5);
449+
450+ else if (hdmi_vic_mode)
451+ info_packet->sb[4] = (1 << 5);
452+
453+ switch (format) {
454+ case TIMING_3D_FORMAT_HW_FRAME_PACKING:
455+ case TIMING_3D_FORMAT_SW_FRAME_PACKING:
456+ info_packet->sb[5] = (0x0 << 4);
457+ break;
458+
459+ case TIMING_3D_FORMAT_SIDE_BY_SIDE:
460+ case TIMING_3D_FORMAT_SBS_SW_PACKED:
461+ info_packet->sb[5] = (0x8 << 4);
462+ length = 6;
463+ break;
464+
465+ case TIMING_3D_FORMAT_TOP_AND_BOTTOM:
466+ case TIMING_3D_FORMAT_TB_SW_PACKED:
467+ info_packet->sb[5] = (0x6 << 4);
468+ break;
469+
470+ default:
471+ break;
472+ }
473+
474+ if (hdmi_vic_mode)
475+ info_packet->sb[5] = stream->timing.hdmi_vic;
476+
477+ info_packet->hb0 = HDMI_INFOFRAME_TYPE_VENDOR;
478+ info_packet->hb1 = 0x01;
479+ info_packet->hb2 = (uint8_t) (length);
480+
481+ if (bALLM)
482+ info_packet->sb[5] = (info_packet->sb[5] & ~0x02) | (bALLMVal << 1);
483+
484+ checksum += info_packet->hb0;
485+ checksum += info_packet->hb1;
486+ checksum += info_packet->hb2;
487+
488+ for (i = 1; i <= length; i++)
489+ checksum += info_packet->sb[i];
490+
491+ info_packet->sb[0] = (uint8_t) (0x100 - checksum);
492+
493+ info_packet->valid = true;
494+}
495+
drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_d.h+1−0
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #define mmMM_INDEX 0x0
2828 #define mmMM_INDEX_HI 0x6
2929 #define mmMM_DATA 0x1
30+#define mmCC_BIF_BX_FUSESTRAP0 0x14D7
3031 #define mmBUS_CNTL 0x1508
3132 #define mmCONFIG_CNTL 0x1509
3233 #define mmCONFIG_MEMSIZE 0x150a
drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_sh_mask.h+2−0
@@ -32,6 +32,8 @@ · 31 unmodified lines
3232 #define MM_INDEX_HI__MM_OFFSET_HI__SHIFT 0x0
3333 #define MM_DATA__MM_DATA_MASK 0xffffffff
3434 #define MM_DATA__MM_DATA__SHIFT 0x0
35+#define CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE_MASK 0x2
36+#define CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE__SHIFT 0x1
3537 #define BUS_CNTL__BIOS_ROM_WRT_EN_MASK 0x1
3638 #define BUS_CNTL__BIOS_ROM_WRT_EN__SHIFT 0x0
3739 #define BUS_CNTL__BIOS_ROM_DIS_MASK 0x2
drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_d.h+1−0
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #define mmMM_INDEX 0x0
2828 #define mmMM_INDEX_HI 0x6
2929 #define mmMM_DATA 0x1
30+#define mmCC_BIF_BX_FUSESTRAP0 0x14D7
3031 #define mmCC_BIF_BX_STRAP2 0x152A
3132 #define mmBIF_MM_INDACCESS_CNTL 0x1500
3233 #define mmBIF_DOORBELL_APER_EN 0x1501
drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_sh_mask.h+2−0
@@ -32,6 +32,8 @@ · 31 unmodified lines
3232 #define MM_INDEX_HI__MM_OFFSET_HI__SHIFT 0x0
3333 #define MM_DATA__MM_DATA_MASK 0xffffffff
3434 #define MM_DATA__MM_DATA__SHIFT 0x0
35+#define CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE_MASK 0x2
36+#define CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE__SHIFT 0x1
3537 #define BIF_MM_INDACCESS_CNTL__MM_INDACCESS_DIS_MASK 0x2
3638 #define BIF_MM_INDACCESS_CNTL__MM_INDACCESS_DIS__SHIFT 0x1
3739 #define BIF_DOORBELL_APER_EN__BIF_DOORBELL_APER_EN_MASK 0x1
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h+10−0
@@ -9859,6 +9859,8 @@ · 9858 unmodified lines
98599859 #define mmDP0_DP_STEER_FIFO_BASE_IDX 2
98609860 #define mmDP0_DP_MSA_MISC 0x210e
98619861 #define mmDP0_DP_MSA_MISC_BASE_IDX 2
9862+#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
9863+#define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
98629864 #define mmDP0_DP_VID_TIMING 0x2110
98639865 #define mmDP0_DP_VID_TIMING_BASE_IDX 2
98649866 #define mmDP0_DP_VID_N 0x2111
@@ -10187,6 +10189,8 @@ · 322 unmodified lines
1018710189 #define mmDP1_DP_STEER_FIFO_BASE_IDX 2
1018810190 #define mmDP1_DP_MSA_MISC 0x220e
1018910191 #define mmDP1_DP_MSA_MISC_BASE_IDX 2
10192+#define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
10193+#define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
1019010194 #define mmDP1_DP_VID_TIMING 0x2210
1019110195 #define mmDP1_DP_VID_TIMING_BASE_IDX 2
1019210196 #define mmDP1_DP_VID_N 0x2211
@@ -10515,6 +10519,8 @@ · 322 unmodified lines
1051510519 #define mmDP2_DP_STEER_FIFO_BASE_IDX 2
1051610520 #define mmDP2_DP_MSA_MISC 0x230e
1051710521 #define mmDP2_DP_MSA_MISC_BASE_IDX 2
10522+#define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
10523+#define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
1051810524 #define mmDP2_DP_VID_TIMING 0x2310
1051910525 #define mmDP2_DP_VID_TIMING_BASE_IDX 2
1052010526 #define mmDP2_DP_VID_N 0x2311
@@ -10843,6 +10849,8 @@ · 322 unmodified lines
1084310849 #define mmDP3_DP_STEER_FIFO_BASE_IDX 2
1084410850 #define mmDP3_DP_MSA_MISC 0x240e
1084510851 #define mmDP3_DP_MSA_MISC_BASE_IDX 2
10852+#define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
10853+#define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
1084610854 #define mmDP3_DP_VID_TIMING 0x2410
1084710855 #define mmDP3_DP_VID_TIMING_BASE_IDX 2
1084810856 #define mmDP3_DP_VID_N 0x2411
@@ -11171,6 +11179,8 @@ · 322 unmodified lines
1117111179 #define mmDP4_DP_STEER_FIFO_BASE_IDX 2
1117211180 #define mmDP4_DP_MSA_MISC 0x250e
1117311181 #define mmDP4_DP_MSA_MISC_BASE_IDX 2
11182+#define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
11183+#define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
1117411184 #define mmDP4_DP_VID_TIMING 0x2510
1117511185 #define mmDP4_DP_VID_TIMING_BASE_IDX 2
1117611186 #define mmDP4_DP_VID_N 0x2511
drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_0_offset.h+16−2
@@ -1146,7 +1146,14 @@ · 1145 unmodified lines
11461146 #define mmATC_L2_MEM_POWER_LS_BASE_IDX 0
11471147 #define mmATC_L2_CGTT_CLK_CTRL 0x080c
11481148 #define mmATC_L2_CGTT_CLK_CTRL_BASE_IDX 0
1149−
1149+#define mmATC_L2_CACHE_4K_EDC_INDEX 0x080e
1150+#define mmATC_L2_CACHE_4K_EDC_INDEX_BASE_IDX 0
1151+#define mmATC_L2_CACHE_2M_EDC_INDEX 0x080f
1152+#define mmATC_L2_CACHE_2M_EDC_INDEX_BASE_IDX 0
1153+#define mmATC_L2_CACHE_4K_EDC_CNT 0x0810
1154+#define mmATC_L2_CACHE_4K_EDC_CNT_BASE_IDX 0
1155+#define mmATC_L2_CACHE_2M_EDC_CNT 0x0811
1156+#define mmATC_L2_CACHE_2M_EDC_CNT_BASE_IDX 0
11501157
11511158 // addressBlock: gc_utcl2_vml2pfdec
11521159 // base address: 0xa100
@@ -1206,7 +1213,14 @@ · 53 unmodified lines
12061213 #define mmVM_L2_CACHE_PARITY_CNTL_BASE_IDX 0
12071214 #define mmVM_L2_CGTT_CLK_CTRL 0x085e
12081215 #define mmVM_L2_CGTT_CLK_CTRL_BASE_IDX 0
1209−
1216+#define mmVM_L2_MEM_ECC_INDEX 0x0860
1217+#define mmVM_L2_MEM_ECC_INDEX_BASE_IDX 0
1218+#define mmVM_L2_WALKER_MEM_ECC_INDEX 0x0861
1219+#define mmVM_L2_WALKER_MEM_ECC_INDEX_BASE_IDX 0
1220+#define mmVM_L2_MEM_ECC_CNT 0x0862
1221+#define mmVM_L2_MEM_ECC_CNT_BASE_IDX 0
1222+#define mmVM_L2_WALKER_MEM_ECC_CNT 0x0863
1223+#define mmVM_L2_WALKER_MEM_ECC_CNT_BASE_IDX 0
12101224
12111225 // addressBlock: gc_utcl2_vml2vcdec
12121226 // base address: 0xa200
drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_0_sh_mask.h+16−2
@@ -6661,7 +6661,6 @@ · 6660 unmodified lines
66616661 #define ATC_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L
66626662 #define ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK 0xFF000000L
66636663
6664−
66656664 // addressBlock: gc_utcl2_vml2pfdec
66666665 //VM_L2_CNTL
66676666 #define VM_L2_CNTL__ENABLE_L2_CACHE__SHIFT 0x0
@@ -6991,7 +6990,22 @@ · 323 unmodified lines
69916990 #define VM_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK 0x00008000L
69926991 #define VM_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L
69936992 #define VM_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK 0xFF000000L
6994−
6993+//VM_L2_MEM_ECC_INDEX
6994+#define VM_L2_MEM_ECC_INDEX__INDEX__SHIFT 0x0
6995+#define VM_L2_MEM_ECC_INDEX__INDEX_MASK 0x000000FFL
6996+//VM_L2_WALKER_MEM_ECC_INDEX
6997+#define VM_L2_WALKER_MEM_ECC_INDEX__INDEX__SHIFT 0x0
6998+#define VM_L2_WALKER_MEM_ECC_INDEX__INDEX_MASK 0x000000FFL
6999+//VM_L2_MEM_ECC_CNT
7000+#define VM_L2_MEM_ECC_CNT__SEC_COUNT__SHIFT 0xc
7001+#define VM_L2_MEM_ECC_CNT__DED_COUNT__SHIFT 0xe
7002+#define VM_L2_MEM_ECC_CNT__SEC_COUNT_MASK 0x00003000L
7003+#define VM_L2_MEM_ECC_CNT__DED_COUNT_MASK 0x0000C000L
7004+//VM_L2_WALKER_MEM_ECC_CNT
7005+#define VM_L2_WALKER_MEM_ECC_CNT__SEC_COUNT__SHIFT 0xc
7006+#define VM_L2_WALKER_MEM_ECC_CNT__DED_COUNT__SHIFT 0xe
7007+#define VM_L2_WALKER_MEM_ECC_CNT__SEC_COUNT_MASK 0x00003000L
7008+#define VM_L2_WALKER_MEM_ECC_CNT__DED_COUNT_MASK 0x0000C000L
69957009
69967010 // addressBlock: gc_utcl2_vml2vcdec
69977011 //VM_CONTEXT0_CNTL
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_0_1_d.h+1−0
@@ -49,6 +49,7 @@ · 48 unmodified lines
4949 #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150
5050 #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154
5151 #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158
52+#define ixCG_SPLL_STATUS 0xC050015C
5253 #define ixSPLL_CNTL_MODE 0xc0500160
5354 #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164
5455 #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_0_1_sh_mask.h+2−0
@@ -194,6 +194,8 @@ · 193 unmodified lines
194194 #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19
195195 #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff
196196 #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0
197+#define CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK 0x2
198+#define CG_SPLL_STATUS__SPLL_CHG_STATUS__SHIFT 0x1
197199 #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1
198200 #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0
199201 #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_2_d.h+1−0
@@ -49,6 +49,7 @@ · 48 unmodified lines
4949 #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150
5050 #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154
5151 #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158
52+#define ixCG_SPLL_STATUS 0xC050015C
5253 #define ixSPLL_CNTL_MODE 0xc0500160
5354 #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164
5455 #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_2_sh_mask.h+2−0
@@ -194,6 +194,8 @@ · 193 unmodified lines
194194 #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19
195195 #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff
196196 #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0
197+#define CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK 0x2
198+#define CG_SPLL_STATUS__SPLL_CHG_STATUS__SHIFT 0x1
197199 #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1
198200 #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0
199201 #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_3_d.h+1−0
@@ -52,6 +52,7 @@ · 51 unmodified lines
5252 #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150
5353 #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154
5454 #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158
55+#define ixCG_SPLL_STATUS 0xC050015C
5556 #define ixSPLL_CNTL_MODE 0xc0500160
5657 #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164
5758 #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_3_sh_mask.h+2−0
@@ -220,6 +220,8 @@ · 219 unmodified lines
220220 #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19
221221 #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff
222222 #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0
223+#define CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK 0x2
224+#define CG_SPLL_STATUS__SPLL_CHG_STATUS__SHIFT 0x1
223225 #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1
224226 #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0
225227 #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2
drivers/gpu/drm/amd/include/atomfirmware.h+21−6
@@ -492,12 +492,13 @@ struct atom_firmware_info_v3_1 · 491 unmodified lines
492492 /* Total 32bit cap indication */
493493 enum atombios_firmware_capability
494494 {
495− ATOM_FIRMWARE_CAP_FIRMWARE_POSTED = 0x00000001,
496− ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION = 0x00000002,
497− ATOM_FIRMWARE_CAP_WMI_SUPPORT = 0x00000040,
498− ATOM_FIRMWARE_CAP_HWEMU_ENABLE = 0x00000080,
499− ATOM_FIRMWARE_CAP_HWEMU_UMC_CFG = 0x00000100,
500− ATOM_FIRMWARE_CAP_SRAM_ECC = 0x00000200,
495+ ATOM_FIRMWARE_CAP_FIRMWARE_POSTED = 0x00000001,
496+ ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION = 0x00000002,
497+ ATOM_FIRMWARE_CAP_WMI_SUPPORT = 0x00000040,
498+ ATOM_FIRMWARE_CAP_HWEMU_ENABLE = 0x00000080,
499+ ATOM_FIRMWARE_CAP_HWEMU_UMC_CFG = 0x00000100,
500+ ATOM_FIRMWARE_CAP_SRAM_ECC = 0x00000200,
501+ ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING = 0x00000400,
501502 };
502503
503504 enum atom_cooling_solution_id{
@@ -671,6 +672,20 @@ struct vram_usagebyfirmware_v2_1 · 167 unmodified lines
671672 uint16_t used_by_driver_in_kb;
672673 };
673674
675+/* This is part of vram_usagebyfirmware_v2_1 */
676+struct vram_reserve_block
677+{
678+ uint32_t start_address_in_kb;
679+ uint16_t used_by_firmware_in_kb;
680+ uint16_t used_by_driver_in_kb;
681+};
682+
683+/* Definitions for constance */
684+enum atomfirmware_internal_constants
685+{
686+ ONE_KiB = 0x400,
687+ ONE_MiB = 0x100000,
688+};
674689
675690 /*
676691 ***************************************************************************
drivers/gpu/drm/amd/include/discovery.h+0−1
@@ -25,7 +25,6 @@ · 24 unmodified lines
2525 #define _DISCOVERY_H_
2626
2727 #define PSP_HEADER_SIZE 256
28−#define BINARY_MAX_SIZE (64 << 10)
2928 #define BINARY_SIGNATURE 0x28211407
3029 #define DISCOVERY_TABLE_SIGNATURE 0x53445049
3130
drivers/gpu/drm/amd/include/kgd_pp_interface.h+6−0
@@ -179,6 +179,11 @@ enum pp_mp1_state { · 178 unmodified lines
179179 PP_MP1_STATE_RESET,
180180 };
181181
182+enum pp_df_cstate {
183+ DF_CSTATE_DISALLOW = 0,
184+ DF_CSTATE_ALLOW,
185+};
186+
182187 #define PP_GROUP_MASK 0xF0000000
183188 #define PP_GROUP_SHIFT 28
184189
@@ -312,6 +317,7 @@ struct amd_pm_funcs { · 127 unmodified lines
312317 int (*get_ppfeature_status)(void *handle, char *buf);
313318 int (*set_ppfeature_status)(void *handle, uint64_t ppfeature_masks);
314319 int (*asic_reset_mode_2)(void *handle);
320+ int (*set_df_cstate)(void *handle, enum pp_df_cstate state);
315321 };
316322
317323 #endif
drivers/gpu/drm/amd/include/renoir_ip_offset.h+34−0
@@ -169,6 +169,11 @@ static const struct IP_BASE NBIF0_BASE ={ { { { 0x00000000, 0x00000014, 0x00000D · 168 unmodified lines
169169 { { 0, 0, 0, 0, 0 } },
170170 { { 0, 0, 0, 0, 0 } },
171171 { { 0, 0, 0, 0, 0 } } } };
172+static const struct IP_BASE DCN_BASE ={ { { { 0x00000012, 0x000000C0, 0x000034C0, 0, 0 } },
173+ { { 0, 0, 0, 0, 0 } },
174+ { { 0, 0, 0, 0, 0 } },
175+ { { 0, 0, 0, 0, 0 } },
176+ { { 0, 0, 0, 0, 0 } } } };
172177 static const struct IP_BASE OSSSYS_BASE ={ { { { 0x000010A0, 0x0240A000, 0, 0, 0 } },
173178 { { 0, 0, 0, 0, 0 } },
174179 { { 0, 0, 0, 0, 0 } },
@@ -1361,4 +1366,33 @@ static const struct IP_BASE UVD0_BASE ={ { { { 0x00007800, 0x00007E00, 0x0240300 · 1186 unmodified lines
13611366 #define UVD0_BASE__INST6_SEG3 0
13621367 #define UVD0_BASE__INST6_SEG4 0
13631368
1369+#define DCN_BASE__INST0_SEG0 0x00000012
1370+#define DCN_BASE__INST0_SEG1 0x000000C0
1371+#define DCN_BASE__INST0_SEG2 0x000034C0
1372+#define DCN_BASE__INST0_SEG3 0
1373+#define DCN_BASE__INST0_SEG4 0
1374+
1375+#define DCN_BASE__INST1_SEG0 0
1376+#define DCN_BASE__INST1_SEG1 0
1377+#define DCN_BASE__INST1_SEG2 0
1378+#define DCN_BASE__INST1_SEG3 0
1379+#define DCN_BASE__INST1_SEG4 0
1380+
1381+#define DCN_BASE__INST2_SEG0 0
1382+#define DCN_BASE__INST2_SEG1 0
1383+#define DCN_BASE__INST2_SEG2 0
1384+#define DCN_BASE__INST2_SEG3 0
1385+#define DCN_BASE__INST2_SEG4 0
1386+
1387+#define DCN_BASE__INST3_SEG0 0
1388+#define DCN_BASE__INST3_SEG1 0
1389+#define DCN_BASE__INST3_SEG2 0
1390+#define DCN_BASE__INST3_SEG3 0
1391+#define DCN_BASE__INST3_SEG4 0
1392+
1393+#define DCN_BASE__INST4_SEG0 0
1394+#define DCN_BASE__INST4_SEG1 0
1395+#define DCN_BASE__INST4_SEG2 0
1396+#define DCN_BASE__INST4_SEG3 0
1397+#define DCN_BASE__INST4_SEG4 0
13641398 #endif
drivers/gpu/drm/amd/powerplay/amd_powerplay.c+19−0
@@ -1421,6 +1421,7 @@ static int pp_get_asic_baco_capability(void *handle, bool *cap) · 1420 unmodified lines
14211421 {
14221422 struct pp_hwmgr *hwmgr = handle;
14231423
1424+ *cap = false;
14241425 if (!hwmgr)
14251426 return -EINVAL;
14261427
@@ -1548,6 +1549,23 @@ static int pp_smu_i2c_bus_access(void *handle, bool acquire) · 121 unmodified lines
15481549 return ret;
15491550 }
15501551
1552+static int pp_set_df_cstate(void *handle, enum pp_df_cstate state)
1553+{
1554+ struct pp_hwmgr *hwmgr = handle;
1555+
1556+ if (!hwmgr)
1557+ return -EINVAL;
1558+
1559+ if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_df_cstate)
1560+ return 0;
1561+
1562+ mutex_lock(&hwmgr->smu_lock);
1563+ hwmgr->hwmgr_func->set_df_cstate(hwmgr, state);
1564+ mutex_unlock(&hwmgr->smu_lock);
1565+
1566+ return 0;
1567+}
1568+
15511569 static const struct amd_pm_funcs pp_dpm_funcs = {
15521570 .load_firmware = pp_dpm_load_fw,
15531571 .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
@@ -1606,4 +1624,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = { · 52 unmodified lines
16061624 .set_ppfeature_status = pp_set_ppfeature_status,
16071625 .asic_reset_mode_2 = pp_asic_reset_mode_2,
16081626 .smu_i2c_bus_access = pp_smu_i2c_bus_access,
1627+ .set_df_cstate = pp_set_df_cstate,
16091628 };
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c+64−44
@@ -945,50 +945,6 @@ static int smu_fini_fb_allocations(struct smu_context *smu) · 944 unmodified lines
945945 return 0;
946946 }
947947
948−static int smu_override_pcie_parameters(struct smu_context *smu)
949−{
950− struct amdgpu_device *adev = smu->adev;
951− uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;
952− int ret;
953−
954− if (adev->flags & AMD_IS_APU)
955− return 0;
956−
957− if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
958− pcie_gen = 3;
959− else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
960− pcie_gen = 2;
961− else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
962− pcie_gen = 1;
963− else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)
964− pcie_gen = 0;
965−
966− /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1
967− * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
968− * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32
969− */
970− if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
971− pcie_width = 6;
972− else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
973− pcie_width = 5;
974− else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
975− pcie_width = 4;
976− else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
977− pcie_width = 3;
978− else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
979− pcie_width = 2;
980− else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
981− pcie_width = 1;
982−
983− smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width;
984− ret = smu_send_smc_msg_with_param(smu,
985− SMU_MSG_OverridePcieParameters,
986− smu_pcie_arg);
987− if (ret)
988− pr_err("[%s] Attempt to override pcie params failed!\n", __func__);
989− return ret;
990−}
991−
992948 static int smu_smc_table_hw_init(struct smu_context *smu,
993949 bool initialize)
994950 {
@@ -1232,6 +1188,7 @@ static int smu_hw_init(void *handle) · 237 unmodified lines
12321188 if (adev->flags & AMD_IS_APU) {
12331189 smu_powergate_sdma(&adev->smu, false);
12341190 smu_powergate_vcn(&adev->smu, false);
1191+ smu_set_gfx_cgpg(&adev->smu, true);
12351192 }
12361193
12371194 if (!smu->pm_enabled)
@@ -1394,6 +1351,11 @@ static int smu_resume(void *handle) · 156 unmodified lines
13941351 if (ret)
13951352 goto failed;
13961353
1354+ if (smu->is_apu)
1355+ smu_set_gfx_cgpg(&adev->smu, true);
1356+
1357+ smu->disable_uclk_switch = 0;
1358+
13971359 mutex_unlock(&smu->mutex);
13981360
13991361 pr_info("SMU is resumed successfully!\n");
@@ -1834,6 +1796,64 @@ int smu_set_mp1_state(struct smu_context *smu, · 434 unmodified lines
18341796 return ret;
18351797 }
18361798
1799+int smu_set_df_cstate(struct smu_context *smu,
1800+ enum pp_df_cstate state)
1801+{
1802+ int ret = 0;
1803+
1804+ /*
1805+ * The SMC is not fully ready. That may be
1806+ * expected as the IP may be masked.
1807+ * So, just return without error.
1808+ */
1809+ if (!smu->pm_enabled)
1810+ return 0;
1811+
1812+ if (!smu->ppt_funcs || !smu->ppt_funcs->set_df_cstate)
1813+ return 0;
1814+
1815+ ret = smu->ppt_funcs->set_df_cstate(smu, state);
1816+ if (ret)
1817+ pr_err("[SetDfCstate] failed!\n");
1818+
1819+ return ret;
1820+}
1821+
1822+int smu_write_watermarks_table(struct smu_context *smu)
1823+{
1824+ int ret = 0;
1825+ struct smu_table_context *smu_table = &smu->smu_table;
1826+ struct smu_table *table = NULL;
1827+
1828+ table = &smu_table->tables[SMU_TABLE_WATERMARKS];
1829+
1830+ if (!table->cpu_addr)
1831+ return -EINVAL;
1832+
1833+ ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr,
1834+ true);
1835+
1836+ return ret;
1837+}
1838+
1839+int smu_set_watermarks_for_clock_ranges(struct smu_context *smu,
1840+ struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges)
1841+{
1842+ int ret = 0;
1843+ struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS];
1844+ void *table = watermarks->cpu_addr;
1845+
1846+ if (!smu->disable_watermark &&
1847+ smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
1848+ smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
1849+ smu_set_watermarks_table(smu, table, clock_ranges);
1850+ smu->watermarks_bitmap |= WATERMARKS_EXIST;
1851+ smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
1852+ }
1853+
1854+ return ret;
1855+}
1856+
18371857 const struct amd_ip_funcs smu_ip_funcs = {
18381858 .name = "smu",
18391859 .early_init = smu_early_init,
drivers/gpu/drm/amd/powerplay/arcturus_ppt.c+30−0
@@ -1898,6 +1898,35 @@ static bool arcturus_is_dpm_running(struct smu_context *smu) · 1897 unmodified lines
18981898 return !!(feature_enabled & SMC_DPM_FEATURE);
18991899 }
19001900
1901+static int arcturus_dpm_set_uvd_enable(struct smu_context *smu, bool enable)
1902+{
1903+ struct smu_power_context *smu_power = &smu->smu_power;
1904+ struct smu_power_gate *power_gate = &smu_power->power_gate;
1905+ int ret = 0;
1906+
1907+ if (enable) {
1908+ if (!smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
1909+ ret = smu_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 1);
1910+ if (ret) {
1911+ pr_err("[EnableVCNDPM] failed!\n");
1912+ return ret;
1913+ }
1914+ }
1915+ power_gate->vcn_gated = false;
1916+ } else {
1917+ if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
1918+ ret = smu_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 0);
1919+ if (ret) {
1920+ pr_err("[DisableVCNDPM] failed!\n");
1921+ return ret;
1922+ }
1923+ }
1924+ power_gate->vcn_gated = true;
1925+ }
1926+
1927+ return ret;
1928+}
1929+
19011930 static const struct pptable_funcs arcturus_ppt_funcs = {
19021931 /* translate smu index into arcturus specific index */
19031932 .get_smu_msg_index = arcturus_get_smu_msg_index,
@@ -1936,6 +1965,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { · 32 unmodified lines
19361965 .dump_pptable = arcturus_dump_pptable,
19371966 .get_power_limit = arcturus_get_power_limit,
19381967 .is_dpm_running = arcturus_is_dpm_running,
1968+ .dpm_set_uvd_enable = arcturus_dpm_set_uvd_enable,
19391969 };
19401970
19411971 void arcturus_set_ppt_funcs(struct smu_context *smu)
drivers/gpu/drm/amd/powerplay/hwmgr/Makefile+2−1
@@ -36,7 +36,8 @@ HARDWARE_MGR = hwmgr.o processpptables.o \ · 35 unmodified lines
3636 pp_overdriver.o smu_helper.o \
3737 vega20_processpptables.o vega20_hwmgr.o vega20_powertune.o \
3838 vega20_thermal.o common_baco.o vega10_baco.o vega20_baco.o \
39− vega12_baco.o smu9_baco.o
39+ vega12_baco.o smu9_baco.o tonga_baco.o polaris_baco.o fiji_baco.o \
40+ ci_baco.o smu7_baco.o
4041
4142 AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR))
4243
drivers/gpu/drm/amd/powerplay/hwmgr/ci_baco.c+195−0
@@ -0,0 +1,195 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#include "amdgpu.h"
24+#include "ci_baco.h"
25+
26+#include "gmc/gmc_7_1_d.h"
27+#include "gmc/gmc_7_1_sh_mask.h"
28+
29+#include "bif/bif_4_1_d.h"
30+#include "bif/bif_4_1_sh_mask.h"
31+
32+#include "dce/dce_8_0_d.h"
33+#include "dce/dce_8_0_sh_mask.h"
34+
35+#include "smu/smu_7_0_1_d.h"
36+#include "smu/smu_7_0_1_sh_mask.h"
37+
38+#include "gca/gfx_7_2_d.h"
39+#include "gca/gfx_7_2_sh_mask.h"
40+
41+static const struct baco_cmd_entry gpio_tbl[] =
42+{
43+ { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 },
44+ { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 },
45+ { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 },
46+ { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff },
47+ { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 },
48+ { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff },
49+ { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 },
50+ { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 },
51+ { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 },
52+ { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 }
53+};
54+
55+static const struct baco_cmd_entry enable_fb_req_rej_tbl[] =
56+{
57+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 },
58+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 },
59+ { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 }
60+};
61+
62+static const struct baco_cmd_entry use_bclk_tbl[] =
63+{
64+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL },
65+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 },
66+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
67+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x1 },
68+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS },
69+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 },
70+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
71+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x0 },
72+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x1 },
73+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS },
74+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 },
75+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
76+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x0 },
77+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 },
78+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 },
79+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
80+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 },
81+ { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL_MASK, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL__SHIFT, 0, 0x1 },
82+ { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 }
83+};
84+
85+static const struct baco_cmd_entry turn_off_plls_tbl[] =
86+{
87+ { CMD_READMODIFYWRITE, mmDISPPLL_BG_CNTL, DISPPLL_BG_CNTL__DISPPLL_BG_PDN_MASK, DISPPLL_BG_CNTL__DISPPLL_BG_PDN__SHIFT, 0, 0x1 },
88+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_DC },
89+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_DC__OSC_EN_MASK, CG_CLKPIN_CNTL_DC__OSC_EN__SHIFT, 0, 0x0 },
90+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_DC__XTALIN_SEL_MASK, CG_CLKPIN_CNTL_DC__XTALIN_SEL__SHIFT, 0, 0x0 },
91+ { CMD_READMODIFYWRITE, mmPLL_CNTL, PLL_CNTL__PLL_RESET_MASK, PLL_CNTL__PLL_RESET__SHIFT, 0, 0x1 },
92+ { CMD_READMODIFYWRITE, mmPLL_CNTL, PLL_CNTL__PLL_POWER_DOWN_MASK, PLL_CNTL__PLL_POWER_DOWN__SHIFT, 0, 0x1 },
93+ { CMD_READMODIFYWRITE, mmPLL_CNTL, PLL_CNTL__PLL_BYPASS_CAL_MASK, PLL_CNTL__PLL_BYPASS_CAL__SHIFT, 0, 0x1 },
94+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL },
95+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 },
96+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 },
97+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 },
98+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x2000000, 0x19, 0, 0x1 },
99+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x8000000, 0x1b, 0, 0x0 },
100+ { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__GLOBAL_MPLL_RESET_MASK, MPLL_CNTL_MODE__GLOBAL_MPLL_RESET__SHIFT, 0, 0x1 },
101+ { CMD_WRITE, mmMPLL_CONTROL, 0, 0, 0, 0x00000006 },
102+ { CMD_WRITE, mmMC_IO_RXCNTL_DPHY0_D0, 0, 0, 0, 0x00007740 },
103+ { CMD_WRITE, mmMC_IO_RXCNTL_DPHY0_D1, 0, 0, 0, 0x00007740 },
104+ { CMD_WRITE, mmMC_IO_RXCNTL_DPHY1_D0, 0, 0, 0, 0x00007740 },
105+ { CMD_WRITE, mmMC_IO_RXCNTL_DPHY1_D1, 0, 0, 0, 0x00007740 },
106+ { CMD_READMODIFYWRITE, mmMCLK_PWRMGT_CNTL, MCLK_PWRMGT_CNTL__MRDCK0_PDNB_MASK, MCLK_PWRMGT_CNTL__MRDCK0_PDNB__SHIFT, 0, 0x0 },
107+ { CMD_READMODIFYWRITE, mmMCLK_PWRMGT_CNTL, MCLK_PWRMGT_CNTL__MRDCK1_PDNB_MASK, MCLK_PWRMGT_CNTL__MRDCK1_PDNB__SHIFT, 0, 0x0 },
108+ { CMD_READMODIFYWRITE, mmMC_SEQ_CNTL_2, MC_SEQ_CNTL_2__DRST_PU_MASK, MC_SEQ_CNTL_2__DRST_PU__SHIFT, 0, 0x0 },
109+ { CMD_READMODIFYWRITE, mmMC_SEQ_CNTL_2, MC_SEQ_CNTL_2__DRST_PD_MASK, MC_SEQ_CNTL_2__DRST_PD__SHIFT, 0, 0x0 },
110+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 },
111+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 },
112+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
113+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 },
114+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL },
115+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x2 },
116+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x2 },
117+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DFT_SMS_PG_CLK_SEL_MASK, MISC_CLK_CTRL__DFT_SMS_PG_CLK_SEL__SHIFT, 0, 0x2 },
118+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL },
119+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x2 },
120+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x2 }
121+};
122+
123+static const struct baco_cmd_entry enter_baco_tbl[] =
124+{
125+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 },
126+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 },
127+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 },
128+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 },
129+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 },
130+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 },
131+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 },
132+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 },
133+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 },
134+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 }
135+};
136+
137+#define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK
138+
139+static const struct baco_cmd_entry exit_baco_tbl[] =
140+{
141+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 },
142+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 },
143+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 },
144+ { CMD_DELAY_MS, 0, 0, 0, 20, 0 },
145+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x20 },
146+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 },
147+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c },
148+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 },
149+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 },
150+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x10 },
151+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 },
152+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 }
153+};
154+
155+static const struct baco_cmd_entry clean_baco_tbl[] =
156+{
157+ { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 },
158+ { CMD_WRITE, mmCP_PFP_UCODE_ADDR, 0, 0, 0, 0 }
159+};
160+
161+int ci_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
162+{
163+ enum BACO_STATE cur_state;
164+
165+ smu7_baco_get_state(hwmgr, &cur_state);
166+
167+ if (cur_state == state)
168+ /* aisc already in the target state */
169+ return 0;
170+
171+ if (state == BACO_STATE_IN) {
172+ baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl));
173+ baco_program_registers(hwmgr, enable_fb_req_rej_tbl,
174+ ARRAY_SIZE(enable_fb_req_rej_tbl));
175+ baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl));
176+ baco_program_registers(hwmgr, turn_off_plls_tbl,
177+ ARRAY_SIZE(turn_off_plls_tbl));
178+ if (baco_program_registers(hwmgr, enter_baco_tbl,
179+ ARRAY_SIZE(enter_baco_tbl)))
180+ return 0;
181+
182+ } else if (state == BACO_STATE_OUT) {
183+ /* HW requires at least 20ms between regulator off and on */
184+ msleep(20);
185+ /* Execute Hardware BACO exit sequence */
186+ if (baco_program_registers(hwmgr, exit_baco_tbl,
187+ ARRAY_SIZE(exit_baco_tbl))) {
188+ if (baco_program_registers(hwmgr, clean_baco_tbl,
189+ ARRAY_SIZE(clean_baco_tbl)))
190+ return 0;
191+ }
192+ }
193+
194+ return -EINVAL;
195+}
drivers/gpu/drm/amd/powerplay/hwmgr/ci_baco.h+29−0
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#ifndef __CI_BACO_H__
24+#define __CI_BACO_H__
25+#include "smu7_baco.h"
26+
27+extern int ci_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
28+
29+#endif
drivers/gpu/drm/amd/powerplay/hwmgr/common_baco.c+19−0
@@ -79,6 +79,25 @@ static bool baco_cmd_handler(struct pp_hwmgr *hwmgr, u32 command, u32 reg, u32 m · 78 unmodified lines
7979 return ret;
8080 }
8181
82+bool baco_program_registers(struct pp_hwmgr *hwmgr,
83+ const struct baco_cmd_entry *entry,
84+ const u32 array_size)
85+{
86+ u32 i, reg = 0;
87+
88+ for (i = 0; i < array_size; i++) {
89+ if ((entry[i].cmd == CMD_WRITE) ||
90+ (entry[i].cmd == CMD_READMODIFYWRITE) ||
91+ (entry[i].cmd == CMD_WAITFOR))
92+ reg = entry[i].reg_offset;
93+ if (!baco_cmd_handler(hwmgr, entry[i].cmd, reg, entry[i].mask,
94+ entry[i].shift, entry[i].val, entry[i].timeout))
95+ return false;
96+ }
97+
98+ return true;
99+}
100+
82101 bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr,
83102 const struct soc15_baco_cmd_entry *entry,
84103 const u32 array_size)
drivers/gpu/drm/amd/powerplay/hwmgr/common_baco.h+13−0
@@ -33,6 +33,15 @@ enum baco_cmd_type { · 32 unmodified lines
3333 CMD_DELAY_US,
3434 };
3535
36+struct baco_cmd_entry {
37+ enum baco_cmd_type cmd;
38+ uint32_t reg_offset;
39+ uint32_t mask;
40+ uint32_t shift;
41+ uint32_t timeout;
42+ uint32_t val;
43+};
44+
3645 struct soc15_baco_cmd_entry {
3746 enum baco_cmd_type cmd;
3847 uint32_t hwip;
@@ -44,6 +53,10 @@ struct soc15_baco_cmd_entry { · 5 unmodified lines
4453 uint32_t timeout;
4554 uint32_t val;
4655 };
56+
57+extern bool baco_program_registers(struct pp_hwmgr *hwmgr,
58+ const struct baco_cmd_entry *entry,
59+ const u32 array_size);
4760 extern bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr,
4861 const struct soc15_baco_cmd_entry *entry,
4962 const u32 array_size);
drivers/gpu/drm/amd/powerplay/hwmgr/fiji_baco.c+196−0
@@ -0,0 +1,196 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#include "amdgpu.h"
24+#include "fiji_baco.h"
25+
26+#include "gmc/gmc_8_1_d.h"
27+#include "gmc/gmc_8_1_sh_mask.h"
28+
29+#include "bif/bif_5_0_d.h"
30+#include "bif/bif_5_0_sh_mask.h"
31+
32+#include "dce/dce_10_0_d.h"
33+#include "dce/dce_10_0_sh_mask.h"
34+
35+#include "smu/smu_7_1_3_d.h"
36+#include "smu/smu_7_1_3_sh_mask.h"
37+
38+
39+static const struct baco_cmd_entry gpio_tbl[] =
40+{
41+ { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 },
42+ { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 },
43+ { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 },
44+ { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff },
45+ { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 },
46+ { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff },
47+ { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 },
48+ { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 },
49+ { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 },
50+ { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 }
51+};
52+
53+static const struct baco_cmd_entry enable_fb_req_rej_tbl[] =
54+{
55+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 },
56+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 },
57+ { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 }
58+};
59+
60+static const struct baco_cmd_entry use_bclk_tbl[] =
61+{
62+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL },
63+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 },
64+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
65+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x1 },
66+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS },
67+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 },
68+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
69+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x0 },
70+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x1 },
71+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS },
72+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 },
73+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
74+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x0 },
75+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 },
76+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 },
77+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
78+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 }
79+};
80+
81+static const struct baco_cmd_entry turn_off_plls_tbl[] =
82+{
83+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL },
84+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 },
85+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 },
86+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 },
87+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x2000000, 0x19, 0, 0x1 },
88+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x8000000, 0x1b, 0, 0x0 }
89+};
90+
91+static const struct baco_cmd_entry clk_req_b_tbl[] =
92+{
93+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 },
94+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 },
95+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
96+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 },
97+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL },
98+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x1 },
99+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x1 },
100+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL },
101+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL__BCLK_AS_XCLK_MASK, CG_CLKPIN_CNTL__BCLK_AS_XCLK__SHIFT, 0, 0x0 },
102+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL },
103+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x1 },
104+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 }
105+};
106+
107+static const struct baco_cmd_entry enter_baco_tbl[] =
108+{
109+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 },
110+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 },
111+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 },
112+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 },
113+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 },
114+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 },
115+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 },
116+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 },
117+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 },
118+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 },
119+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 },
120+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 }
121+};
122+
123+#define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK
124+
125+static const struct baco_cmd_entry exit_baco_tbl[] =
126+{
127+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 },
128+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 },
129+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 },
130+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 },
131+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 },
132+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 },
133+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 },
134+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 },
135+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 },
136+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 },
137+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 },
138+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 }
139+};
140+
141+static const struct baco_cmd_entry clean_baco_tbl[] =
142+{
143+ { CMD_WRITE, mmBIOS_SCRATCH_0, 0, 0, 0, 0 },
144+ { CMD_WRITE, mmBIOS_SCRATCH_1, 0, 0, 0, 0 },
145+ { CMD_WRITE, mmBIOS_SCRATCH_2, 0, 0, 0, 0 },
146+ { CMD_WRITE, mmBIOS_SCRATCH_3, 0, 0, 0, 0 },
147+ { CMD_WRITE, mmBIOS_SCRATCH_4, 0, 0, 0, 0 },
148+ { CMD_WRITE, mmBIOS_SCRATCH_5, 0, 0, 0, 0 },
149+ { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 },
150+ { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 },
151+ { CMD_WRITE, mmBIOS_SCRATCH_8, 0, 0, 0, 0 },
152+ { CMD_WRITE, mmBIOS_SCRATCH_9, 0, 0, 0, 0 },
153+ { CMD_WRITE, mmBIOS_SCRATCH_10, 0, 0, 0, 0 },
154+ { CMD_WRITE, mmBIOS_SCRATCH_11, 0, 0, 0, 0 },
155+ { CMD_WRITE, mmBIOS_SCRATCH_12, 0, 0, 0, 0 },
156+ { CMD_WRITE, mmBIOS_SCRATCH_13, 0, 0, 0, 0 },
157+ { CMD_WRITE, mmBIOS_SCRATCH_14, 0, 0, 0, 0 },
158+ { CMD_WRITE, mmBIOS_SCRATCH_15, 0, 0, 0, 0 }
159+};
160+
161+int fiji_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
162+{
163+ enum BACO_STATE cur_state;
164+
165+ smu7_baco_get_state(hwmgr, &cur_state);
166+
167+ if (cur_state == state)
168+ /* aisc already in the target state */
169+ return 0;
170+
171+ if (state == BACO_STATE_IN) {
172+ baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl));
173+ baco_program_registers(hwmgr, enable_fb_req_rej_tbl,
174+ ARRAY_SIZE(enable_fb_req_rej_tbl));
175+ baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl));
176+ baco_program_registers(hwmgr, turn_off_plls_tbl,
177+ ARRAY_SIZE(turn_off_plls_tbl));
178+ baco_program_registers(hwmgr, clk_req_b_tbl, ARRAY_SIZE(clk_req_b_tbl));
179+ if (baco_program_registers(hwmgr, enter_baco_tbl,
180+ ARRAY_SIZE(enter_baco_tbl)))
181+ return 0;
182+
183+ } else if (state == BACO_STATE_OUT) {
184+ /* HW requires at least 20ms between regulator off and on */
185+ msleep(20);
186+ /* Execute Hardware BACO exit sequence */
187+ if (baco_program_registers(hwmgr, exit_baco_tbl,
188+ ARRAY_SIZE(exit_baco_tbl))) {
189+ if (baco_program_registers(hwmgr, clean_baco_tbl,
190+ ARRAY_SIZE(clean_baco_tbl)))
191+ return 0;
192+ }
193+ }
194+
195+ return -EINVAL;
196+}
drivers/gpu/drm/amd/powerplay/hwmgr/fiji_baco.h+29−0
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#ifndef __FIJI_BACO_H__
24+#define __FIJI_BACO_H__
25+#include "smu7_baco.h"
26+
27+extern int fiji_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
28+
29+#endif
drivers/gpu/drm/amd/powerplay/hwmgr/polaris_baco.c+222−0
@@ -0,0 +1,222 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#include "amdgpu.h"
24+#include "polaris_baco.h"
25+
26+#include "gmc/gmc_8_1_d.h"
27+#include "gmc/gmc_8_1_sh_mask.h"
28+
29+#include "bif/bif_5_0_d.h"
30+#include "bif/bif_5_0_sh_mask.h"
31+
32+#include "dce/dce_11_0_d.h"
33+#include "dce/dce_11_0_sh_mask.h"
34+
35+#include "smu/smu_7_1_3_d.h"
36+#include "smu/smu_7_1_3_sh_mask.h"
37+
38+static const struct baco_cmd_entry gpio_tbl[] =
39+{
40+ { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 },
41+ { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 },
42+ { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 },
43+ { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff },
44+ { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 },
45+ { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff },
46+ { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 },
47+ { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 },
48+ { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 },
49+ { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 }
50+};
51+
52+static const struct baco_cmd_entry enable_fb_req_rej_tbl[] =
53+{
54+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 },
55+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 },
56+ { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 }
57+};
58+
59+static const struct baco_cmd_entry use_bclk_tbl[] =
60+{
61+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL },
62+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 },
63+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 },
64+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 },
65+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixGCK_DFS_BYPASS_CNTL },
66+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, GCK_DFS_BYPASS_CNTL__BYPASSACLK_MASK, GCK_DFS_BYPASS_CNTL__BYPASSACLK__SHIFT, 0, 0x1 },
67+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
68+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 },
69+ { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL_MASK, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL__SHIFT, 0, 0x1 },
70+ { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 }
71+};
72+
73+static const struct baco_cmd_entry turn_off_plls_tbl[] =
74+{
75+ { CMD_READMODIFYWRITE, mmDC_GPIO_PAD_STRENGTH_1, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP_MASK, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP__SHIFT, 0, 0x1 },
76+ { CMD_DELAY_US, 0, 0, 0, 1, 0x0 },
77+ { CMD_READMODIFYWRITE, mmMC_SEQ_DRAM, MC_SEQ_DRAM__RST_CTL_MASK, MC_SEQ_DRAM__RST_CTL__SHIFT, 0, 0x1 },
78+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC05002B0 },
79+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x10, 0x4, 0, 0x1 },
80+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, 0x10, 0, 1, 0 },
81+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC050032C },
82+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x10, 0x4, 0, 0x1 },
83+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, 0x10, 0, 1, 0 },
84+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500080 },
85+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 },
86+ { CMD_READMODIFYWRITE, 0xda2, 0x40, 0x6, 0, 0x0 },
87+ { CMD_DELAY_US, 0, 0, 0, 3, 0x0 },
88+ { CMD_READMODIFYWRITE, 0xda2, 0x8, 0x3, 0, 0x0 },
89+ { CMD_READMODIFYWRITE, 0xda2, 0x3fff00, 0x8, 0, 0x32 },
90+ { CMD_DELAY_US, 0, 0, 0, 3, 0x0 },
91+ { CMD_READMODIFYWRITE, mmMPLL_FUNC_CNTL_2, MPLL_FUNC_CNTL_2__ISO_DIS_P_MASK, MPLL_FUNC_CNTL_2__ISO_DIS_P__SHIFT, 0, 0x0 },
92+ { CMD_DELAY_US, 0, 0, 0, 5, 0x0 }
93+};
94+
95+static const struct baco_cmd_entry clk_req_b_tbl[] =
96+{
97+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL },
98+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x1 },
99+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 },
100+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL },
101+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x1 },
102+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x1 },
103+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL },
104+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL__BCLK_AS_XCLK_MASK, CG_CLKPIN_CNTL__BCLK_AS_XCLK__SHIFT, 0, 0x0 },
105+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 },
106+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 },
107+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
108+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 }
109+};
110+
111+static const struct baco_cmd_entry enter_baco_tbl[] =
112+{
113+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 },
114+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 },
115+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 },
116+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 },
117+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 },
118+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 },
119+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 },
120+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 },
121+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 },
122+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 },
123+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 },
124+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 }
125+};
126+
127+#define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK
128+
129+static const struct baco_cmd_entry exit_baco_tbl[] =
130+{
131+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 },
132+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 },
133+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 },
134+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 },
135+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 },
136+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 },
137+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 },
138+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 },
139+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 },
140+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 },
141+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 },
142+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 }
143+};
144+
145+static const struct baco_cmd_entry clean_baco_tbl[] =
146+{
147+ { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 },
148+ { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 }
149+};
150+
151+static const struct baco_cmd_entry use_bclk_tbl_vg[] =
152+{
153+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL },
154+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 },
155+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 },
156+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 },
157+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixGCK_DFS_BYPASS_CNTL },
158+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, GCK_DFS_BYPASS_CNTL__BYPASSACLK_MASK, GCK_DFS_BYPASS_CNTL__BYPASSACLK__SHIFT, 0, 0x1 },
159+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
160+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 }
161+};
162+
163+static const struct baco_cmd_entry turn_off_plls_tbl_vg[] =
164+{
165+ { CMD_READMODIFYWRITE, mmDC_GPIO_PAD_STRENGTH_1, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP_MASK, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP__SHIFT, 0, 0x1 },
166+ { CMD_DELAY_US, 0, 0, 0, 1, 0x0 },
167+ { CMD_READMODIFYWRITE, mmMC_SEQ_DRAM, MC_SEQ_DRAM__RST_CTL_MASK, MC_SEQ_DRAM__RST_CTL__SHIFT, 0, 0x1 },
168+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC05002B0 },
169+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x10, 0x4, 0, 0x1 },
170+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, 0x10, 0, 1, 0 },
171+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC050032C },
172+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x10, 0x4, 0, 0x1 },
173+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, 0x10, 0, 1, 0 },
174+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500080 },
175+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 },
176+ { CMD_DELAY_US, 0, 0, 0, 3, 0x0 },
177+ { CMD_DELAY_US, 0, 0, 0, 3, 0x0 },
178+ { CMD_DELAY_US, 0, 0, 0, 5, 0x0 }
179+};
180+
181+int polaris_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
182+{
183+ enum BACO_STATE cur_state;
184+
185+ smu7_baco_get_state(hwmgr, &cur_state);
186+
187+ if (cur_state == state)
188+ /* aisc already in the target state */
189+ return 0;
190+
191+ if (state == BACO_STATE_IN) {
192+ baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl));
193+ baco_program_registers(hwmgr, enable_fb_req_rej_tbl,
194+ ARRAY_SIZE(enable_fb_req_rej_tbl));
195+ if (hwmgr->chip_id == CHIP_VEGAM) {
196+ baco_program_registers(hwmgr, use_bclk_tbl_vg, ARRAY_SIZE(use_bclk_tbl_vg));
197+ baco_program_registers(hwmgr, turn_off_plls_tbl_vg,
198+ ARRAY_SIZE(turn_off_plls_tbl_vg));
199+ } else {
200+ baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl));
201+ baco_program_registers(hwmgr, turn_off_plls_tbl,
202+ ARRAY_SIZE(turn_off_plls_tbl));
203+ }
204+ baco_program_registers(hwmgr, clk_req_b_tbl, ARRAY_SIZE(clk_req_b_tbl));
205+ if (baco_program_registers(hwmgr, enter_baco_tbl,
206+ ARRAY_SIZE(enter_baco_tbl)))
207+ return 0;
208+
209+ } else if (state == BACO_STATE_OUT) {
210+ /* HW requires at least 20ms between regulator off and on */
211+ msleep(20);
212+ /* Execute Hardware BACO exit sequence */
213+ if (baco_program_registers(hwmgr, exit_baco_tbl,
214+ ARRAY_SIZE(exit_baco_tbl))) {
215+ if (baco_program_registers(hwmgr, clean_baco_tbl,
216+ ARRAY_SIZE(clean_baco_tbl)))
217+ return 0;
218+ }
219+ }
220+
221+ return -EINVAL;
222+}
drivers/gpu/drm/amd/powerplay/hwmgr/polaris_baco.h+29−0
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#ifndef __POLARIS_BACO_H__
24+#define __POLARIS_BACO_H__
25+#include "smu7_baco.h"
26+
27+extern int polaris_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
28+
29+#endif
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_baco.c+91−0
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#include "amdgpu.h"
24+#include "smu7_baco.h"
25+#include "tonga_baco.h"
26+#include "fiji_baco.h"
27+#include "polaris_baco.h"
28+#include "ci_baco.h"
29+
30+#include "bif/bif_5_0_d.h"
31+#include "bif/bif_5_0_sh_mask.h"
32+
33+#include "smu/smu_7_1_2_d.h"
34+#include "smu/smu_7_1_2_sh_mask.h"
35+
36+int smu7_baco_get_capability(struct pp_hwmgr *hwmgr, bool *cap)
37+{
38+ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
39+ uint32_t reg;
40+
41+ *cap = false;
42+ if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_BACO))
43+ return 0;
44+
45+ reg = RREG32(mmCC_BIF_BX_FUSESTRAP0);
46+
47+ if (reg & CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE_MASK)
48+ *cap = true;
49+
50+ return 0;
51+}
52+
53+int smu7_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state)
54+{
55+ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
56+ uint32_t reg;
57+
58+ reg = RREG32(mmBACO_CNTL);
59+
60+ if (reg & BACO_CNTL__BACO_MODE_MASK)
61+ /* gfx has already entered BACO state */
62+ *state = BACO_STATE_IN;
63+ else
64+ *state = BACO_STATE_OUT;
65+ return 0;
66+}
67+
68+int smu7_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
69+{
70+ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
71+
72+ switch (adev->asic_type) {
73+ case CHIP_TOPAZ:
74+ case CHIP_TONGA:
75+ return tonga_baco_set_state(hwmgr, state);
76+ case CHIP_FIJI:
77+ return fiji_baco_set_state(hwmgr, state);
78+ case CHIP_POLARIS10:
79+ case CHIP_POLARIS11:
80+ case CHIP_POLARIS12:
81+ case CHIP_VEGAM:
82+ return polaris_baco_set_state(hwmgr, state);
83+#ifdef CONFIG_DRM_AMDGPU_CIK
84+ case CHIP_BONAIRE:
85+ case CHIP_HAWAII:
86+ return ci_baco_set_state(hwmgr, state);
87+#endif
88+ default:
89+ return -EINVAL;
90+ }
91+}
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_baco.h+32−0
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#ifndef __SMU7_BACO_H__
24+#define __SMU7_BACO_H__
25+#include "hwmgr.h"
26+#include "common_baco.h"
27+
28+extern int smu7_baco_get_capability(struct pp_hwmgr *hwmgr, bool *cap);
29+extern int smu7_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state);
30+extern int smu7_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
31+
32+#endif
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c+6−4
@@ -48,6 +48,7 @@ · 47 unmodified lines
4848 #include "smu7_clockpowergating.h"
4949 #include "processpptables.h"
5050 #include "pp_thermal.h"
51+#include "smu7_baco.h"
5152
5253 #include "ivsrcid/ivsrcid_vislands30.h"
5354
@@ -1994,7 +1995,6 @@ static int smu7_sort_lookup_table(struct pp_hwmgr *hwmgr, · 1940 unmodified lines
19941995 struct phm_ppt_v1_voltage_lookup_table *lookup_table)
19951996 {
19961997 uint32_t table_size, i, j;
1997− struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record;
19981998 table_size = lookup_table->count;
19991999
20002000 PP_ASSERT_WITH_CODE(0 != lookup_table->count,
@@ -2005,9 +2005,8 @@ static int smu7_sort_lookup_table(struct pp_hwmgr *hwmgr, · 4 unmodified lines
20052005 for (j = i + 1; j > 0; j--) {
20062006 if (lookup_table->entries[j].us_vdd <
20072007 lookup_table->entries[j - 1].us_vdd) {
2008− tmp_voltage_lookup_record = lookup_table->entries[j - 1];
2009− lookup_table->entries[j - 1] = lookup_table->entries[j];
2010− lookup_table->entries[j] = tmp_voltage_lookup_record;
2008+ swap(lookup_table->entries[j - 1],
2009+ lookup_table->entries[j]);
20112010 }
20122011 }
20132012 }
@@ -5145,6 +5144,9 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { · 3131 unmodified lines
51455144 .get_power_profile_mode = smu7_get_power_profile_mode,
51465145 .set_power_profile_mode = smu7_set_power_profile_mode,
51475146 .get_performance_level = smu7_get_performance_level,
5147+ .get_asic_baco_capability = smu7_baco_get_capability,
5148+ .get_asic_baco_state = smu7_baco_get_state,
5149+ .set_asic_baco_state = smu7_baco_set_state,
51485150 .power_off_asic = smu7_power_off_asic,
51495151 };
51505152
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_baco.c+231−0
@@ -0,0 +1,231 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#include "amdgpu.h"
24+#include "tonga_baco.h"
25+
26+#include "gmc/gmc_8_1_d.h"
27+#include "gmc/gmc_8_1_sh_mask.h"
28+
29+#include "bif/bif_5_0_d.h"
30+#include "bif/bif_5_0_sh_mask.h"
31+
32+#include "dce/dce_10_0_d.h"
33+#include "dce/dce_10_0_sh_mask.h"
34+
35+#include "smu/smu_7_1_2_d.h"
36+#include "smu/smu_7_1_2_sh_mask.h"
37+
38+
39+static const struct baco_cmd_entry gpio_tbl[] =
40+{
41+ { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 },
42+ { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 },
43+ { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 },
44+ { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff },
45+ { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 },
46+ { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff },
47+ { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 },
48+ { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 },
49+ { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 },
50+ { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 }
51+};
52+
53+static const struct baco_cmd_entry enable_fb_req_rej_tbl[] =
54+{
55+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 },
56+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 },
57+ { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 }
58+};
59+
60+static const struct baco_cmd_entry use_bclk_tbl[] =
61+{
62+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL },
63+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 },
64+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
65+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x1 },
66+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS },
67+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 },
68+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
69+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x0 },
70+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x1 },
71+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS },
72+ { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 },
73+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 },
74+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x0 },
75+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 },
76+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 },
77+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
78+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 },
79+ { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL_MASK, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL__SHIFT, 0, 0x1 },
80+ { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 }
81+};
82+
83+static const struct baco_cmd_entry turn_off_plls_tbl[] =
84+{
85+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL },
86+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 },
87+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 },
88+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 },
89+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x2000000, 0x19, 0, 0x1 },
90+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x8000000, 0x1b, 0, 0x0 },
91+ { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__GLOBAL_MPLL_RESET_MASK, MPLL_CNTL_MODE__GLOBAL_MPLL_RESET__SHIFT, 0, 0x1 },
92+ { CMD_WRITE, mmMPLL_CONTROL, 0, 0, 0, 0x00000006 },
93+ { CMD_WRITE, mmMC_IO_RXCNTL_DPHY0_D0, 0, 0, 0, 0x00007740 },
94+ { CMD_WRITE, mmMC_IO_RXCNTL_DPHY0_D1, 0, 0, 0, 0x00007740 },
95+ { CMD_WRITE, mmMC_IO_RXCNTL_DPHY1_D0, 0, 0, 0, 0x00007740 },
96+ { CMD_WRITE, mmMC_IO_RXCNTL_DPHY1_D1, 0, 0, 0, 0x00007740 },
97+ { CMD_READMODIFYWRITE, mmMCLK_PWRMGT_CNTL, MCLK_PWRMGT_CNTL__MRDCK0_PDNB_MASK, MCLK_PWRMGT_CNTL__MRDCK0_PDNB__SHIFT, 0, 0x0 },
98+ { CMD_READMODIFYWRITE, mmMCLK_PWRMGT_CNTL, MCLK_PWRMGT_CNTL__MRDCK1_PDNB_MASK, MCLK_PWRMGT_CNTL__MRDCK1_PDNB__SHIFT, 0, 0x0 },
99+ { CMD_READMODIFYWRITE, mmMC_SEQ_CNTL_2, MC_SEQ_CNTL_2__DRST_PU_MASK, MC_SEQ_CNTL_2__DRST_PU__SHIFT, 0, 0x0 },
100+ { CMD_READMODIFYWRITE, mmMC_SEQ_CNTL_2, MC_SEQ_CNTL_2__DRST_PD_MASK, MC_SEQ_CNTL_2__DRST_PD__SHIFT, 0, 0x0 },
101+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 },
102+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 },
103+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL },
104+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 },
105+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL },
106+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x1 },
107+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x1 },
108+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL },
109+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL__BCLK_AS_XCLK_MASK, CG_CLKPIN_CNTL__BCLK_AS_XCLK__SHIFT, 0, 0x0 },
110+ { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL },
111+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x1 },
112+ { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 }
113+};
114+
115+static const struct baco_cmd_entry enter_baco_tbl[] =
116+{
117+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 },
118+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 },
119+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 },
120+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 },
121+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 },
122+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 },
123+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 },
124+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 },
125+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 },
126+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 },
127+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 },
128+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 }
129+};
130+
131+#define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK
132+
133+static const struct baco_cmd_entry exit_baco_tbl[] =
134+{
135+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 },
136+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 },
137+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 },
138+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 },
139+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 },
140+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 },
141+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 },
142+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 },
143+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 },
144+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 },
145+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 },
146+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 }
147+};
148+
149+static const struct baco_cmd_entry clean_baco_tbl[] =
150+{
151+ { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 },
152+ { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 }
153+};
154+
155+static const struct baco_cmd_entry gpio_tbl_iceland[] =
156+{
157+ { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 },
158+ { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 },
159+ { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 },
160+ { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff }
161+};
162+
163+static const struct baco_cmd_entry exit_baco_tbl_iceland[] =
164+{
165+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 },
166+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 },
167+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 },
168+ { CMD_DELAY_MS, 0, 0, 0, 20, 0 },
169+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 },
170+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 },
171+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 },
172+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 },
173+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 },
174+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 },
175+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 },
176+ { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 },
177+ { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 }
178+};
179+
180+static const struct baco_cmd_entry clean_baco_tbl_iceland[] =
181+{
182+ { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 }
183+};
184+
185+int tonga_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
186+{
187+ enum BACO_STATE cur_state;
188+
189+ smu7_baco_get_state(hwmgr, &cur_state);
190+
191+ if (cur_state == state)
192+ /* aisc already in the target state */
193+ return 0;
194+
195+ if (state == BACO_STATE_IN) {
196+ if (hwmgr->chip_id == CHIP_TOPAZ)
197+ baco_program_registers(hwmgr, gpio_tbl_iceland, ARRAY_SIZE(gpio_tbl_iceland));
198+ else
199+ baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl));
200+ baco_program_registers(hwmgr, enable_fb_req_rej_tbl,
201+ ARRAY_SIZE(enable_fb_req_rej_tbl));
202+ baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl));
203+ baco_program_registers(hwmgr, turn_off_plls_tbl,
204+ ARRAY_SIZE(turn_off_plls_tbl));
205+ if (baco_program_registers(hwmgr, enter_baco_tbl,
206+ ARRAY_SIZE(enter_baco_tbl)))
207+ return 0;
208+
209+ } else if (state == BACO_STATE_OUT) {
210+ /* HW requires at least 20ms between regulator off and on */
211+ msleep(20);
212+ /* Execute Hardware BACO exit sequence */
213+ if (hwmgr->chip_id == CHIP_TOPAZ) {
214+ if (baco_program_registers(hwmgr, exit_baco_tbl_iceland,
215+ ARRAY_SIZE(exit_baco_tbl_iceland))) {
216+ if (baco_program_registers(hwmgr, clean_baco_tbl_iceland,
217+ ARRAY_SIZE(clean_baco_tbl_iceland)))
218+ return 0;
219+ }
220+ } else {
221+ if (baco_program_registers(hwmgr, exit_baco_tbl,
222+ ARRAY_SIZE(exit_baco_tbl))) {
223+ if (baco_program_registers(hwmgr, clean_baco_tbl,
224+ ARRAY_SIZE(clean_baco_tbl)))
225+ return 0;
226+ }
227+ }
228+ }
229+
230+ return -EINVAL;
231+}
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_baco.h+29−0
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright 2019 Advanced Micro Devices, Inc.
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a
5+ * copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+#ifndef __TONGA_BACO_H__
24+#define __TONGA_BACO_H__
25+#include "smu7_baco.h"
26+
27+extern int tonga_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
28+
29+#endif
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c+2−4
@@ -712,7 +712,6 @@ static int vega10_sort_lookup_table(struct pp_hwmgr *hwmgr, · 711 unmodified lines
712712 struct phm_ppt_v1_voltage_lookup_table *lookup_table)
713713 {
714714 uint32_t table_size, i, j;
715− struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record;
716715
717716 PP_ASSERT_WITH_CODE(lookup_table && lookup_table->count,
718717 "Lookup table is empty", return -EINVAL);
@@ -724,9 +723,8 @@ static int vega10_sort_lookup_table(struct pp_hwmgr *hwmgr, · 5 unmodified lines
724723 for (j = i + 1; j > 0; j--) {
725724 if (lookup_table->entries[j].us_vdd <
726725 lookup_table->entries[j - 1].us_vdd) {
727− tmp_voltage_lookup_record = lookup_table->entries[j - 1];
728− lookup_table->entries[j - 1] = lookup_table->entries[j];
729− lookup_table->entries[j] = tmp_voltage_lookup_record;
726+ swap(lookup_table->entries[j - 1],
727+ lookup_table->entries[j]);
730728 }
731729 }
732730 }
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c+15−8
@@ -29,7 +29,7 @@ · 28 unmodified lines
2929 #include "vega20_baco.h"
3030 #include "vega20_smumgr.h"
3131
32−
32+#include "amdgpu_ras.h"
3333
3434 static const struct soc15_baco_cmd_entry clean_baco_tbl[] =
3535 {
@@ -74,6 +74,7 @@ int vega20_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state) · 38 unmodified lines
7474 int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
7575 {
7676 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
77+ struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
7778 enum BACO_STATE cur_state;
7879 uint32_t data;
7980
@@ -84,13 +85,19 @@ int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) · 4 unmodified lines
8485 return 0;
8586
8687 if (state == BACO_STATE_IN) {
87− data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL);
88− data |= 0x80000000;
89− WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data);
90−
91−
92− if(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0))
93− return -EINVAL;
88+ if (!ras || !ras->supported) {
89+ data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL);
90+ data |= 0x80000000;
91+ WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data);
92+
93+ if(smum_send_msg_to_smc_with_parameter(hwmgr,
94+ PPSMC_MSG_EnterBaco, 0))
95+ return -EINVAL;
96+ } else {
97+ if(smum_send_msg_to_smc_with_parameter(hwmgr,
98+ PPSMC_MSG_EnterBaco, 1))
99+ return -EINVAL;
100+ }
94101
95102 } else if (state == BACO_STATE_OUT) {
96103 if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco))
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c+24−2
@@ -182,6 +182,9 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr) · 181 unmodified lines
182182 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
183183 PHM_PlatformCaps_TablelessHardwareInterface);
184184
185+ phm_cap_set(hwmgr->platform_descriptor.platformCaps,
186+ PHM_PlatformCaps_BACO);
187+
185188 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
186189 PHM_PlatformCaps_EnableSMU7ThermalManagement);
187190
@@ -490,8 +493,8 @@ static int vega20_setup_asic_task(struct pp_hwmgr *hwmgr) · 302 unmodified lines
490493 "Failed to init sclk threshold!",
491494 return ret);
492495
493− if (adev->in_baco_reset) {
494− adev->in_baco_reset = 0;
496+ if (adev->in_gpu_reset &&
497+ (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) {
495498
496499 ret = vega20_baco_apply_vdci_flush_workaround(hwmgr);
497500 if (ret)
@@ -4155,6 +4158,24 @@ static int vega20_smu_i2c_bus_access(struct pp_hwmgr *hwmgr, bool acquire) · 3657 unmodified lines
41554158 return res;
41564159 }
41574160
4161+static int vega20_set_df_cstate(struct pp_hwmgr *hwmgr,
4162+ enum pp_df_cstate state)
4163+{
4164+ int ret;
4165+
4166+ /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */
4167+ if (hwmgr->smu_version < 0x283200) {
4168+ pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n");
4169+ return -EINVAL;
4170+ }
4171+
4172+ ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DFCstateControl, state);
4173+ if (ret)
4174+ pr_err("SetDfCstate failed!\n");
4175+
4176+ return ret;
4177+}
4178+
41584179 static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
41594180 /* init/fini related */
41604181 .backend_init = vega20_hwmgr_backend_init,
@@ -4223,6 +4244,7 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = { · 62 unmodified lines
42234244 .set_asic_baco_state = vega20_baco_set_state,
42244245 .set_mp1_state = vega20_set_mp1_state,
42254246 .smu_i2c_bus_access = vega20_smu_i2c_bus_access,
4247+ .set_df_cstate = vega20_set_df_cstate,
42264248 };
42274249
42284250 int vega20_hwmgr_init(struct pp_hwmgr *hwmgr)
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h+18−9
@@ -468,6 +468,9 @@ struct pptable_funcs { · 467 unmodified lines
468468 int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default);
469469 int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type,
470470 uint32_t dpm_level, uint32_t *freq);
471+ int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate state);
472+ int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap);
473+ int (*get_dpm_clock_table)(struct smu_context *smu, struct dpm_clocks *clock_table);
471474 };
472475
473476 struct smu_funcs
@@ -493,7 +496,6 @@ struct smu_funcs · 19 unmodified lines
493496 int (*set_min_dcef_deep_sleep)(struct smu_context *smu);
494497 int (*set_tool_table_location)(struct smu_context *smu);
495498 int (*notify_memory_pool_location)(struct smu_context *smu);
496− int (*write_watermarks_table)(struct smu_context *smu);
497499 int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu);
498500 int (*system_features_control)(struct smu_context *smu, bool en);
499501 int (*send_smc_msg)(struct smu_context *smu, uint16_t msg);
@@ -531,8 +533,6 @@ struct smu_funcs · 31 unmodified lines
531533 int (*get_current_shallow_sleep_clocks)(struct smu_context *smu,
532534 struct smu_clock_info *clocks);
533535 int (*notify_smu_enable_pwe)(struct smu_context *smu);
534− int (*set_watermarks_for_clock_ranges)(struct smu_context *smu,
535− struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
536536 int (*conv_power_profile_to_pplib_workload)(int power_profile);
537537 uint32_t (*get_fan_control_mode)(struct smu_context *smu);
538538 int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode);
@@ -550,6 +550,7 @@ struct smu_funcs · 11 unmodified lines
550550 int (*mode2_reset)(struct smu_context *smu);
551551 int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max);
552552 int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max);
553+ int (*override_pcie_parameters)(struct smu_context *smu);
553554 };
554555
555556 #define smu_init_microcode(smu) \
@@ -596,9 +597,6 @@ struct smu_funcs · 40 unmodified lines
596597 ((smu)->funcs->notify_memory_pool_location ? (smu)->funcs->notify_memory_pool_location((smu)) : 0)
597598 #define smu_gfx_off_control(smu, enable) \
598599 ((smu)->funcs->gfx_off_control ? (smu)->funcs->gfx_off_control((smu), (enable)) : 0)
599−
600−#define smu_write_watermarks_table(smu) \
601− ((smu)->funcs->write_watermarks_table ? (smu)->funcs->write_watermarks_table((smu)) : 0)
602600 #define smu_set_last_dcef_min_deep_sleep_clk(smu) \
603601 ((smu)->funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0)
604602 #define smu_system_features_control(smu, en) \
@@ -738,8 +736,6 @@ struct smu_funcs · 133 unmodified lines
738736 ((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0)
739737 #define smu_notify_smu_enable_pwe(smu) \
740738 ((smu)->funcs->notify_smu_enable_pwe ? (smu)->funcs->notify_smu_enable_pwe((smu)) : 0)
741−#define smu_set_watermarks_for_clock_ranges(smu, clock_ranges) \
742− ((smu)->funcs->set_watermarks_for_clock_ranges ? (smu)->funcs->set_watermarks_for_clock_ranges((smu), (clock_ranges)) : 0)
743739 #define smu_dpm_set_uvd_enable(smu, enable) \
744740 ((smu)->ppt_funcs->dpm_set_uvd_enable ? (smu)->ppt_funcs->dpm_set_uvd_enable((smu), (enable)) : 0)
745741 #define smu_dpm_set_vce_enable(smu, enable) \
@@ -776,9 +772,16 @@ struct smu_funcs · 30 unmodified lines
776772 ((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0)
777773 #define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) \
778774 ((smu)->ppt_funcs->get_dpm_clk_limited ? (smu)->ppt_funcs->get_dpm_clk_limited((smu), (clk_type), (dpm_level), (freq)) : -EINVAL)
779−
780775 #define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \
781776 ((smu)->funcs->set_soft_freq_limited_range ? (smu)->funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL)
777+#define smu_get_dpm_clock_table(smu, clock_table) \
778+ ((smu)->ppt_funcs->get_dpm_clock_table ? (smu)->ppt_funcs->get_dpm_clock_table((smu), (clock_table)) : -EINVAL)
779+
780+#define smu_override_pcie_parameters(smu) \
781+ ((smu)->funcs->override_pcie_parameters ? (smu)->funcs->override_pcie_parameters((smu)) : 0)
782+
783+#define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \
784+ ((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0)
782785
783786 extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
784787 uint16_t *size, uint8_t *frev, uint8_t *crev,
@@ -812,6 +815,10 @@ int smu_sys_get_pp_table(struct smu_context *smu, void **table); · 27 unmodified lines
812815 int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size);
813816 int smu_get_power_num_states(struct smu_context *smu, struct pp_states_info *state_info);
814817 enum amd_pm_state_type smu_get_current_power_state(struct smu_context *smu);
818+int smu_write_watermarks_table(struct smu_context *smu);
819+int smu_set_watermarks_for_clock_ranges(
820+ struct smu_context *smu,
821+ struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
815822
816823 /* smu to display interface */
817824 extern int smu_display_configuration_change(struct smu_context *smu, const
@@ -850,5 +857,7 @@ int smu_force_clk_levels(struct smu_context *smu, · 32 unmodified lines
850857 uint32_t mask);
851858 int smu_set_mp1_state(struct smu_context *smu,
852859 enum pp_mp1_state mp1_state);
860+int smu_set_df_cstate(struct smu_context *smu,
861+ enum pp_df_cstate state);
853862
854863 #endif
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h+1−0
@@ -355,6 +355,7 @@ struct pp_hwmgr_func { · 354 unmodified lines
355355 int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state);
356356 int (*asic_reset)(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mode);
357357 int (*smu_i2c_bus_access)(struct pp_hwmgr *hwmgr, bool aquire);
358+ int (*set_df_cstate)(struct pp_hwmgr *hwmgr, enum pp_df_cstate state);
358359 };
359360
360361 struct pp_table_func {
drivers/gpu/drm/amd/powerplay/inc/smu_types.h+1−0
@@ -169,6 +169,7 @@ · 168 unmodified lines
169169 __SMU_DUMMY_MAP(PowerGateAtHub), \
170170 __SMU_DUMMY_MAP(SetSoftMinJpeg), \
171171 __SMU_DUMMY_MAP(SetHardMinFclkByFreq), \
172+ __SMU_DUMMY_MAP(DFCstateControl), \
172173
173174 #undef __SMU_DUMMY_MAP
174175 #define __SMU_DUMMY_MAP(type) SMU_MSG_##type
drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h+2−1
@@ -120,7 +120,8 @@ · 119 unmodified lines
120120 #define PPSMC_MSG_SetMGpuFanBoostLimitRpm 0x5D
121121 #define PPSMC_MSG_GetAVFSVoltageByDpm 0x5F
122122 #define PPSMC_MSG_BacoWorkAroundFlushVDCI 0x60
123−#define PPSMC_Message_Count 0x61
123+#define PPSMC_MSG_DFCstateControl 0x63
124+#define PPSMC_Message_Count 0x64
124125
125126 typedef uint32_t PPSMC_Result;
126127 typedef uint32_t PPSMC_Msg;
drivers/gpu/drm/amd/powerplay/navi10_ppt.c+85−25
@@ -328,40 +328,52 @@ navi10_get_allowed_feature_mask(struct smu_context *smu, · 327 unmodified lines
328328 memset(feature_mask, 0, sizeof(uint32_t) * num);
329329
330330 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT)
331− | FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT)
332− | FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT)
333331 | FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)
334− | FEATURE_MASK(FEATURE_DPM_LINK_BIT)
335− | FEATURE_MASK(FEATURE_GFX_ULV_BIT)
336332 | FEATURE_MASK(FEATURE_RSMU_SMN_CG_BIT)
337333 | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT)
338334 | FEATURE_MASK(FEATURE_PPT_BIT)
339335 | FEATURE_MASK(FEATURE_TDC_BIT)
340336 | FEATURE_MASK(FEATURE_GFX_EDC_BIT)
337+ | FEATURE_MASK(FEATURE_APCC_PLUS_BIT)
341338 | FEATURE_MASK(FEATURE_VR0HOT_BIT)
342339 | FEATURE_MASK(FEATURE_FAN_CONTROL_BIT)
343340 | FEATURE_MASK(FEATURE_THERMAL_BIT)
344341 | FEATURE_MASK(FEATURE_LED_DISPLAY_BIT)
345− | FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)
346− | FEATURE_MASK(FEATURE_DS_GFXCLK_BIT)
342+ | FEATURE_MASK(FEATURE_DS_LCLK_BIT)
347343 | FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT)
348344 | FEATURE_MASK(FEATURE_FW_DSTATE_BIT)
349345 | FEATURE_MASK(FEATURE_BACO_BIT)
350346 | FEATURE_MASK(FEATURE_ACDC_BIT)
351347 | FEATURE_MASK(FEATURE_GFX_SS_BIT)
352348 | FEATURE_MASK(FEATURE_APCC_DFLL_BIT)
353− | FEATURE_MASK(FEATURE_FW_CTF_BIT);
349+ | FEATURE_MASK(FEATURE_FW_CTF_BIT)
350+ | FEATURE_MASK(FEATURE_OUT_OF_BAND_MONITOR_BIT);
351+
352+ if (adev->pm.pp_feature & PP_SOCCLK_DPM_MASK)
353+ *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT);
354+
355+ if (adev->pm.pp_feature & PP_SCLK_DPM_MASK)
356+ *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT);
357+
358+ if (adev->pm.pp_feature & PP_PCIE_DPM_MASK)
359+ *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_LINK_BIT);
360+
361+ if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK)
362+ *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT);
354363
355364 if (adev->pm.pp_feature & PP_MCLK_DPM_MASK)
356365 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT)
357366 | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT)
358367 | FEATURE_MASK(FEATURE_MEM_MVDD_SCALING_BIT);
359368
360− if (adev->pm.pp_feature & PP_GFXOFF_MASK) {
369+ if (adev->pm.pp_feature & PP_ULV_MASK)
370+ *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_ULV_BIT);
371+
372+ if (adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK)
373+ *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_GFXCLK_BIT);
374+
375+ if (adev->pm.pp_feature & PP_GFXOFF_MASK)
361376 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXOFF_BIT);
362− /* TODO: remove it once fw fix the bug */
363− *(uint64_t *)feature_mask &= ~FEATURE_MASK(FEATURE_FW_DSTATE_BIT);
364− }
365377
366378 if (smu->adev->pg_flags & AMD_PG_SUPPORT_MMHUB)
367379 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MMHUB_PG_BIT);
@@ -1452,18 +1464,47 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu) · 1084 unmodified lines
14521464 uint32_t sclk_freq = 0, uclk_freq = 0;
14531465 uint32_t uclk_level = 0;
14541466
1455− switch (adev->pdev->revision) {
1456− case 0xf0: /* XTX */
1457− case 0xc0:
1458− sclk_freq = NAVI10_PEAK_SCLK_XTX;
1459− break;
1460− case 0xf1: /* XT */
1461− case 0xc1:
1462− sclk_freq = NAVI10_PEAK_SCLK_XT;
1467+ switch (adev->asic_type) {
1468+ case CHIP_NAVI10:
1469+ switch (adev->pdev->revision) {
1470+ case 0xf0: /* XTX */
1471+ case 0xc0:
1472+ sclk_freq = NAVI10_PEAK_SCLK_XTX;
1473+ break;
1474+ case 0xf1: /* XT */
1475+ case 0xc1:
1476+ sclk_freq = NAVI10_PEAK_SCLK_XT;
1477+ break;
1478+ default: /* XL */
1479+ sclk_freq = NAVI10_PEAK_SCLK_XL;
1480+ break;
1481+ }
14631482 break;
1464− default: /* XL */
1465− sclk_freq = NAVI10_PEAK_SCLK_XL;
1483+ case CHIP_NAVI14:
1484+ switch (adev->pdev->revision) {
1485+ case 0xc7: /* XT */
1486+ case 0xf4:
1487+ sclk_freq = NAVI14_UMD_PSTATE_PEAK_XT_GFXCLK;
1488+ break;
1489+ case 0xc1: /* XTM */
1490+ case 0xf2:
1491+ sclk_freq = NAVI14_UMD_PSTATE_PEAK_XTM_GFXCLK;
1492+ break;
1493+ case 0xc3: /* XLM */
1494+ case 0xf3:
1495+ sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK;
1496+ break;
1497+ case 0xc5: /* XTX */
1498+ case 0xf6:
1499+ sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK;
1500+ break;
1501+ default: /* XL */
1502+ sclk_freq = NAVI14_UMD_PSTATE_PEAK_XL_GFXCLK;
1503+ break;
1504+ }
14661505 break;
1506+ default:
1507+ return -EINVAL;
14671508 }
14681509
14691510 ret = smu_get_dpm_level_count(smu, SMU_UCLK, &uclk_level);
@@ -1486,10 +1527,6 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu) · 16 unmodified lines
14861527 static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
14871528 {
14881529 int ret = 0;
1489− struct amdgpu_device *adev = smu->adev;
1490−
1491− if (adev->asic_type != CHIP_NAVI10)
1492− return -EINVAL;
14931530
14941531 switch (level) {
14951532 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
@@ -1592,6 +1629,28 @@ static int navi10_get_power_limit(struct smu_context *smu, · 96 unmodified lines
15921629 return 0;
15931630 }
15941631
1632+static int navi10_update_pcie_parameters(struct smu_context *smu,
1633+ uint32_t pcie_gen_cap,
1634+ uint32_t pcie_width_cap)
1635+{
1636+ PPTable_t *pptable = smu->smu_table.driver_pptable;
1637+ int ret, i;
1638+ uint32_t smu_pcie_arg;
1639+
1640+ for (i = 0; i < NUM_LINK_LEVELS; i++) {
1641+ smu_pcie_arg = (i << 16) |
1642+ ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) :
1643+ (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ?
1644+ pptable->PcieLaneCount[i] : pcie_width_cap);
1645+ ret = smu_send_smc_msg_with_param(smu,
1646+ SMU_MSG_OverridePcieParameters,
1647+ smu_pcie_arg);
1648+ }
1649+
1650+ return ret;
1651+}
1652+
1653+
15951654 static const struct pptable_funcs navi10_ppt_funcs = {
15961655 .tables_init = navi10_tables_init,
15971656 .alloc_dpm_context = navi10_allocate_dpm_context,
@@ -1630,6 +1689,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { · 32 unmodified lines
16301689 .get_thermal_temperature_range = navi10_get_thermal_temperature_range,
16311690 .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,
16321691 .get_power_limit = navi10_get_power_limit,
1692+ .update_pcie_parameters = navi10_update_pcie_parameters,
16331693 };
16341694
16351695 void navi10_set_ppt_funcs(struct smu_context *smu)
drivers/gpu/drm/amd/powerplay/navi10_ppt.h+6−0
@@ -27,6 +27,12 @@ · 26 unmodified lines
2727 #define NAVI10_PEAK_SCLK_XT (1755)
2828 #define NAVI10_PEAK_SCLK_XL (1625)
2929
30+#define NAVI14_UMD_PSTATE_PEAK_XT_GFXCLK (1670)
31+#define NAVI14_UMD_PSTATE_PEAK_XTM_GFXCLK (1448)
32+#define NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK (1181)
33+#define NAVI14_UMD_PSTATE_PEAK_XTX_GFXCLK (1717)
34+#define NAVI14_UMD_PSTATE_PEAK_XL_GFXCLK (1448)
35+
3036 extern void navi10_set_ppt_funcs(struct smu_context *smu);
3137
3238 #endif
drivers/gpu/drm/amd/powerplay/renoir_ppt.c+130−0
@@ -416,6 +416,40 @@ static int renoir_get_profiling_clk_mask(struct smu_context *smu, · 415 unmodified lines
416416 return 0;
417417 }
418418
419+/**
420+ * This interface get dpm clock table for dc
421+ */
422+static int renoir_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks *clock_table)
423+{
424+ DpmClocks_t *table = smu->smu_table.clocks_table;
425+ int i;
426+
427+ if (!clock_table || !table)
428+ return -EINVAL;
429+
430+ for (i = 0; i < NUM_DCFCLK_DPM_LEVELS; i++) {
431+ clock_table->DcfClocks[i].Freq = table->DcfClocks[i].Freq;
432+ clock_table->DcfClocks[i].Vol = table->DcfClocks[i].Vol;
433+ }
434+
435+ for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) {
436+ clock_table->SocClocks[i].Freq = table->SocClocks[i].Freq;
437+ clock_table->SocClocks[i].Vol = table->SocClocks[i].Vol;
438+ }
439+
440+ for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) {
441+ clock_table->FClocks[i].Freq = table->FClocks[i].Freq;
442+ clock_table->FClocks[i].Vol = table->FClocks[i].Vol;
443+ }
444+
445+ for (i = 0; i< NUM_MEMCLK_DPM_LEVELS; i++) {
446+ clock_table->MemClocks[i].Freq = table->MemClocks[i].Freq;
447+ clock_table->MemClocks[i].Vol = table->MemClocks[i].Vol;
448+ }
449+
450+ return 0;
451+}
452+
419453 static int renoir_force_clk_levels(struct smu_context *smu,
420454 enum smu_clk_type clk_type, uint32_t mask)
421455 {
@@ -546,6 +580,99 @@ static int renoir_set_performance_level(struct smu_context *smu, enum amd_dpm_fo · 124 unmodified lines
546580 return ret;
547581 }
548582
583+/* save watermark settings into pplib smu structure,
584+ * also pass data to smu controller
585+ */
586+static int renoir_set_watermarks_table(
587+ struct smu_context *smu,
588+ void *watermarks,
589+ struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges)
590+{
591+ int i;
592+ int ret = 0;
593+ Watermarks_t *table = watermarks;
594+
595+ if (!table || !clock_ranges)
596+ return -EINVAL;
597+
598+ if (clock_ranges->num_wm_dmif_sets > 4 ||
599+ clock_ranges->num_wm_mcif_sets > 4)
600+ return -EINVAL;
601+
602+ /* save into smu->smu_table.tables[SMU_TABLE_WATERMARKS]->cpu_addr*/
603+ for (i = 0; i < clock_ranges->num_wm_dmif_sets; i++) {
604+ table->WatermarkRow[WM_DCFCLK][i].MinClock =
605+ cpu_to_le16((uint16_t)
606+ (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz));
607+ table->WatermarkRow[WM_DCFCLK][i].MaxClock =
608+ cpu_to_le16((uint16_t)
609+ (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz));
610+ table->WatermarkRow[WM_DCFCLK][i].MinMclk =
611+ cpu_to_le16((uint16_t)
612+ (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz));
613+ table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
614+ cpu_to_le16((uint16_t)
615+ (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz));
616+ table->WatermarkRow[WM_DCFCLK][i].WmSetting = (uint8_t)
617+ clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
618+ }
619+
620+ for (i = 0; i < clock_ranges->num_wm_mcif_sets; i++) {
621+ table->WatermarkRow[WM_SOCCLK][i].MinClock =
622+ cpu_to_le16((uint16_t)
623+ (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz));
624+ table->WatermarkRow[WM_SOCCLK][i].MaxClock =
625+ cpu_to_le16((uint16_t)
626+ (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz));
627+ table->WatermarkRow[WM_SOCCLK][i].MinMclk =
628+ cpu_to_le16((uint16_t)
629+ (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz));
630+ table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
631+ cpu_to_le16((uint16_t)
632+ (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz));
633+ table->WatermarkRow[WM_SOCCLK][i].WmSetting = (uint8_t)
634+ clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
635+ }
636+
637+ /* pass data to smu controller */
638+ ret = smu_write_watermarks_table(smu);
639+
640+ return ret;
641+}
642+
643+static int renoir_get_power_profile_mode(struct smu_context *smu,
644+ char *buf)
645+{
646+ static const char *profile_name[] = {
647+ "BOOTUP_DEFAULT",
648+ "3D_FULL_SCREEN",
649+ "POWER_SAVING",
650+ "VIDEO",
651+ "VR",
652+ "COMPUTE",
653+ "CUSTOM"};
654+ uint32_t i, size = 0;
655+ int16_t workload_type = 0;
656+
657+ if (!smu->pm_enabled || !buf)
658+ return -EINVAL;
659+
660+ for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
661+ /*
662+ * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
663+ * Not all profile modes are supported on arcturus.
664+ */
665+ workload_type = smu_workload_get_type(smu, i);
666+ if (workload_type < 0)
667+ continue;
668+
669+ size += sprintf(buf + size, "%2d %14s%s\n",
670+ i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
671+ }
672+
673+ return size;
674+}
675+
549676 static const struct pptable_funcs renoir_ppt_funcs = {
550677 .get_smu_msg_index = renoir_get_smu_msg_index,
551678 .get_smu_table_index = renoir_get_smu_table_index,
@@ -562,6 +689,9 @@ static const struct pptable_funcs renoir_ppt_funcs = { · 10 unmodified lines
562689 .force_clk_levels = renoir_force_clk_levels,
563690 .set_power_profile_mode = renoir_set_power_profile_mode,
564691 .set_performance_level = renoir_set_performance_level,
692+ .get_dpm_clock_table = renoir_get_dpm_clock_table,
693+ .set_watermarks_table = renoir_set_watermarks_table,
694+ .get_power_profile_mode = renoir_get_power_profile_mode,
565695 };
566696
567697 void renoir_set_ppt_funcs(struct smu_context *smu)
drivers/gpu/drm/amd/powerplay/smu_v11_0.c+44−39
@@ -35,6 +35,7 @@ · 34 unmodified lines
3535 #include "vega20_ppt.h"
3636 #include "arcturus_ppt.h"
3737 #include "navi10_ppt.h"
38+#include "amd_pcie.h"
3839
3940 #include "asic_reg/thm/thm_11_0_2_offset.h"
4041 #include "asic_reg/thm/thm_11_0_2_sh_mask.h"
@@ -770,23 +771,6 @@ static int smu_v11_0_write_pptable(struct smu_context *smu) · 729 unmodified lines
770771 return ret;
771772 }
772773
773−static int smu_v11_0_write_watermarks_table(struct smu_context *smu)
774−{
775− int ret = 0;
776− struct smu_table_context *smu_table = &smu->smu_table;
777− struct smu_table *table = NULL;
778−
779− table = &smu_table->tables[SMU_TABLE_WATERMARKS];
780−
781− if (!table->cpu_addr)
782− return -EINVAL;
783−
784− ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr,
785− true);
786−
787− return ret;
788−}
789−
790774 static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk)
791775 {
792776 int ret;
@@ -1336,26 +1320,6 @@ failed: · 543 unmodified lines
13361320 return ret;
13371321 }
13381322
1339−static int
1340−smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct
1341− dm_pp_wm_sets_with_clock_ranges_soc15
1342− *clock_ranges)
1343−{
1344− int ret = 0;
1345− struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS];
1346− void *table = watermarks->cpu_addr;
1347−
1348− if (!smu->disable_watermark &&
1349− smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
1350− smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
1351− smu_set_watermarks_table(smu, table, clock_ranges);
1352− smu->watermarks_bitmap |= WATERMARKS_EXIST;
1353− smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
1354− }
1355−
1356− return ret;
1357−}
1358−
13591323 static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
13601324 {
13611325 int ret = 0;
@@ -1792,6 +1756,48 @@ static int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum s · 430 unmodified lines
17921756 return ret;
17931757 }
17941758
1759+static int smu_v11_0_override_pcie_parameters(struct smu_context *smu)
1760+{
1761+ struct amdgpu_device *adev = smu->adev;
1762+ uint32_t pcie_gen = 0, pcie_width = 0;
1763+ int ret;
1764+
1765+ if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
1766+ pcie_gen = 3;
1767+ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
1768+ pcie_gen = 2;
1769+ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
1770+ pcie_gen = 1;
1771+ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)
1772+ pcie_gen = 0;
1773+
1774+ /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1
1775+ * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
1776+ * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32
1777+ */
1778+ if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
1779+ pcie_width = 6;
1780+ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
1781+ pcie_width = 5;
1782+ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
1783+ pcie_width = 4;
1784+ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
1785+ pcie_width = 3;
1786+ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
1787+ pcie_width = 2;
1788+ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
1789+ pcie_width = 1;
1790+
1791+ ret = smu_update_pcie_parameters(smu, pcie_gen, pcie_width);
1792+
1793+ if (ret)
1794+ pr_err("[%s] Attempt to override pcie params failed!\n", __func__);
1795+
1796+ return ret;
1797+
1798+}
1799+
1800+
17951801 static const struct smu_funcs smu_v11_0_funcs = {
17961802 .init_microcode = smu_v11_0_init_microcode,
17971803 .load_microcode = smu_v11_0_load_microcode,
@@ -1812,7 +1818,6 @@ static const struct smu_funcs smu_v11_0_funcs = { · 14 unmodified lines
18121818 .parse_pptable = smu_v11_0_parse_pptable,
18131819 .populate_smc_tables = smu_v11_0_populate_smc_pptable,
18141820 .write_pptable = smu_v11_0_write_pptable,
1815− .write_watermarks_table = smu_v11_0_write_watermarks_table,
18161821 .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
18171822 .set_tool_table_location = smu_v11_0_set_tool_table_location,
18181823 .init_display_count = smu_v11_0_init_display_count,
@@ -1828,7 +1833,6 @@ static const struct smu_funcs smu_v11_0_funcs = { · 9 unmodified lines
18281833 .read_sensor = smu_v11_0_read_sensor,
18291834 .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
18301835 .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
1831− .set_watermarks_for_clock_ranges = smu_v11_0_set_watermarks_for_clock_ranges,
18321836 .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
18331837 .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
18341838 .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
@@ -1844,6 +1848,7 @@ static const struct smu_funcs smu_v11_0_funcs = { · 9 unmodified lines
18441848 .baco_reset = smu_v11_0_baco_reset,
18451849 .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
18461850 .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
1851+ .override_pcie_parameters = smu_v11_0_override_pcie_parameters,
18471852 };
18481853
18491854 void smu_v11_0_set_smu_funcs(struct smu_context *smu)
drivers/gpu/drm/amd/powerplay/smu_v12_0.c+0−9
@@ -244,15 +244,6 @@ static int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable) · 243 unmodified lines
244244 if (enable) {
245245 ret = smu_send_smc_msg(smu, SMU_MSG_AllowGfxOff);
246246
247− /* confirm gfx is back to "off" state, timeout is 5 seconds */
248− while (!(smu_v12_0_get_gfxoff_status(smu) == 0)) {
249− msleep(10);
250− timeout--;
251− if (timeout == 0) {
252− DRM_ERROR("enable gfxoff timeout and failed!\n");
253− break;
254− }
255− }
256247 } else {
257248 ret = smu_send_smc_msg(smu, SMU_MSG_DisallowGfxOff);
258249
drivers/gpu/drm/amd/powerplay/vega20_ppt.c+47−1
@@ -143,6 +143,7 @@ static struct smu_11_0_cmn2aisc_mapping vega20_message_map[SMU_MSG_MAX_COUNT] = · 142 unmodified lines
143143 MSG_MAP(PrepareMp1ForShutdown),
144144 MSG_MAP(SetMGpuFanBoostLimitRpm),
145145 MSG_MAP(GetAVFSVoltageByDpm),
146+ MSG_MAP(DFCstateControl),
146147 };
147148
148149 static struct smu_11_0_cmn2aisc_mapping vega20_clk_map[SMU_CLK_COUNT] = {
@@ -3135,6 +3136,49 @@ static int vega20_get_thermal_temperature_range(struct smu_context *smu, · 2986 unmodified lines
31353136 return 0;
31363137 }
31373138
3139+static int vega20_set_df_cstate(struct smu_context *smu,
3140+ enum pp_df_cstate state)
3141+{
3142+ uint32_t smu_version;
3143+ int ret;
3144+
3145+ ret = smu_get_smc_version(smu, NULL, &smu_version);
3146+ if (ret) {
3147+ pr_err("Failed to get smu version!\n");
3148+ return ret;
3149+ }
3150+
3151+ /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */
3152+ if (smu_version < 0x283200) {
3153+ pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n");
3154+ return -EINVAL;
3155+ }
3156+
3157+ return smu_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state);
3158+}
3159+
3160+static int vega20_update_pcie_parameters(struct smu_context *smu,
3161+ uint32_t pcie_gen_cap,
3162+ uint32_t pcie_width_cap)
3163+{
3164+ PPTable_t *pptable = smu->smu_table.driver_pptable;
3165+ int ret, i;
3166+ uint32_t smu_pcie_arg;
3167+
3168+ for (i = 0; i < NUM_LINK_LEVELS; i++) {
3169+ smu_pcie_arg = (i << 16) |
3170+ ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) :
3171+ (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ?
3172+ pptable->PcieLaneCount[i] : pcie_width_cap);
3173+ ret = smu_send_smc_msg_with_param(smu,
3174+ SMU_MSG_OverridePcieParameters,
3175+ smu_pcie_arg);
3176+ }
3177+
3178+ return ret;
3179+}
3180+
3181+
31383182 static const struct pptable_funcs vega20_ppt_funcs = {
31393183 .tables_init = vega20_tables_init,
31403184 .alloc_dpm_context = vega20_allocate_dpm_context,
@@ -3177,7 +3221,9 @@ static const struct pptable_funcs vega20_ppt_funcs = { · 36 unmodified lines
31773221 .get_fan_speed_percent = vega20_get_fan_speed_percent,
31783222 .get_fan_speed_rpm = vega20_get_fan_speed_rpm,
31793223 .set_watermarks_table = vega20_set_watermarks_table,
3180− .get_thermal_temperature_range = vega20_get_thermal_temperature_range
3224+ .get_thermal_temperature_range = vega20_get_thermal_temperature_range,
3225+ .set_df_cstate = vega20_set_df_cstate,
3226+ .update_pcie_parameters = vega20_update_pcie_parameters
31813227 };
31823228
31833229 void vega20_set_ppt_funcs(struct smu_context *smu)