History

Merge tag 'amd-drm-fixes-6.13-2024-12-04' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes

amd-drm-fixes-6.13-2024-12-04: amdgpu: - Jpeg work handler fix for VCN 1.0 - HDP flush fixes - ACPI EDID sanity check - OLED panel backlight fix - DC YCbCr fix - DC Detile buffer size debugging - DC prefetch calculation fix - DC VTotal handling fix - DC HBlank fix - ISP fix - SR-IOV fix - Workload profile fixes - DCN 4.0.1 resume fix amdkfd: - GC 12.x fix - GC 9.4.x fix

Simona Vetter committed 1 year ago

Commit 1995e7d2 parents 471f3a2 73dae6549 files · +1031 −615Browse files

Unified · Split

49 files
  1. drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +64 −26
  2. drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c +8 −4
  3. drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c +5 −2
  4. drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c +4 −2
  5. drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c +4 −2
  6. drivers/gpu/drm/amd/amdgpu/hdp_v7_0.c +4 −2
  7. drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c +1 −1
  8. drivers/gpu/drm/amd/amdkfd/kfd_crat.c +6 −0
  9. drivers/gpu/drm/amd/amdkfd/kfd_device.c +3 −0
  10. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 −0
  11. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +10 −3
  12. drivers/gpu/drm/amd/display/dc/core/dc.c +18 −0
  13. drivers/gpu/drm/amd/display/dc/core/dc_resource.c +41 −1
  14. drivers/gpu/drm/amd/display/dc/dc.h +4 −0
  15. drivers/gpu/drm/amd/display/dc/dc_spl_translate.c +1 −1
  16. drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c +1 −0
  17. drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c +44 −4
  18. drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +2 −1
  19. drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +6 −1
  20. drivers/gpu/drm/amd/display/dc/inc/core_types.h +3 −0
  21. drivers/gpu/drm/amd/display/dc/link/link_dpms.c +2 −1
  22. drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c +23 −0
  23. drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c +1 −0
  24. drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c +1 −0
  25. drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c +1 −0
  26. drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +7 −0
  27. drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h +3 −0
  28. drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c +1 −0
  29. drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +1 −0
  30. drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +1 −0
  31. drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +2 −0
  32. drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +1 −0
  33. drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +2 −0
  34. drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +2 −0
  35. drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c +1 −0
  36. drivers/gpu/drm/amd/display/modules/freesync/freesync.c +12 −1
  37. drivers/gpu/drm/amd/pm/amdgpu_pm.c +5 −1
  38. drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +92 −77
  39. drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +10 −7
  40. drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +95 −72
  41. drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +101 −69
  42. drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +102 −69
  43. drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +13 −28
  44. drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +13 −30
  45. drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +96 −79
  46. drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +85 −54
  47. drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +98 −67
  48. drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +25 −8
  49. drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +4 −2
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c+64−26
@@ -145,7 +145,7 @@ const char *amdgpu_asic_name[] = { · 144 unmodified lines
145 "LAST",145 "LAST",
146};146};
147 147
148#define AMDGPU_IP_BLK_MASK_ALL GENMASK(AMDGPU_MAX_IP_NUM - 1, 0)148#define AMDGPU_IP_BLK_MASK_ALL GENMASK(AMDGPU_MAX_IP_NUM, 0)
149/*149/*
150 * Default init level where all blocks are expected to be initialized. This is150 * Default init level where all blocks are expected to be initialized. This is
151 * the level of initialization expected by default and also after a full reset151 * the level of initialization expected by default and also after a full reset
@@ -3670,9 +3670,11 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) · 3518 unmodified lines
3670 continue;3670 continue;
3671 3671
3672 r = block->version->funcs->hw_init(&adev->ip_blocks[i]);3672 r = block->version->funcs->hw_init(&adev->ip_blocks[i]);
3673 DRM_INFO("RE-INIT-early: %s %s\n", block->version->funcs->name, r?"failed":"succeeded");3673 if (r) {
3674 if (r)3674 dev_err(adev->dev, "RE-INIT-early: %s failed\n",
3675 block->version->funcs->name);
3675 return r;3676 return r;
3677 }
3676 block->status.hw = true;3678 block->status.hw = true;
3677 }3679 }
3678 }3680 }
@@ -3682,7 +3684,8 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) · 3 unmodified lines
3682 3684
3683static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)3685static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
3684{3686{
3685 int i, r;3687 struct amdgpu_ip_block *block;
3688 int i, r = 0;
3686 3689
3687 static enum amd_ip_block_type ip_order[] = {3690 static enum amd_ip_block_type ip_order[] = {
3688 AMD_IP_BLOCK_TYPE_SMC,3691 AMD_IP_BLOCK_TYPE_SMC,
@@ -3697,34 +3700,28 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev) · 8 unmodified lines
3697 };3700 };
3698 3701
3699 for (i = 0; i < ARRAY_SIZE(ip_order); i++) {3702 for (i = 0; i < ARRAY_SIZE(ip_order); i++) {
3700 int j;3703 block = amdgpu_device_ip_get_ip_block(adev, ip_order[i]);
3701 struct amdgpu_ip_block *block;
3702
3703 for (j = 0; j < adev->num_ip_blocks; j++) {
3704 block = &adev->ip_blocks[j];
3705 3704
3706 if (block->version->type != ip_order[i] ||3705 if (!block)
3707 !block->status.valid ||3706 continue;
3708 block->status.hw)
3709 continue;
3710 3707
3708 if (block->status.valid && !block->status.hw) {
3711 if (block->version->type == AMD_IP_BLOCK_TYPE_SMC) {3709 if (block->version->type == AMD_IP_BLOCK_TYPE_SMC) {
3712 r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);3710 r = amdgpu_ip_block_resume(block);
3713 if (r)
3714 return r;
3715 } else {3711 } else {
3716 r = block->version->funcs->hw_init(&adev->ip_blocks[i]);3712 r = block->version->funcs->hw_init(block);
3717 if (r) {
3718 DRM_ERROR("hw_init of IP block <%s> failed %d\n",
3719 adev->ip_blocks[i].version->funcs->name, r);
3720 return r;
3721 }
3722 block->status.hw = true;
3723 }3713 }
3714
3715 if (r) {
3716 dev_err(adev->dev, "RE-INIT-late: %s failed\n",
3717 block->version->funcs->name);
3718 break;
3719 }
3720 block->status.hw = true;
3724 }3721 }
3725 }3722 }
3726 3723
3727 return 0;3724 return r;
3728}3725}
3729 3726
3730/**3727/**
@@ -3765,7 +3762,7 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev) · 34 unmodified lines
3765 *3762 *
3766 * @adev: amdgpu_device pointer3763 * @adev: amdgpu_device pointer
3767 *3764 *
3768 * First resume function for hardware IPs. The list of all the hardware3765 * Second resume function for hardware IPs. The list of all the hardware
3769 * IPs that make up the asic is walked and the resume callbacks are run for3766 * IPs that make up the asic is walked and the resume callbacks are run for
3770 * all blocks except COMMON, GMC, and IH. resume puts the hardware into a3767 * all blocks except COMMON, GMC, and IH. resume puts the hardware into a
3771 * functional state after a suspend and updates the software state as3768 * functional state after a suspend and updates the software state as
@@ -3783,6 +3780,7 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) · 11 unmodified lines
3783 if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||3780 if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
3784 adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||3781 adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
3785 adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ||3782 adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ||
3783 adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE ||
3786 adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)3784 adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)
3787 continue;3785 continue;
3788 r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);3786 r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
@@ -3793,6 +3791,36 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) · 4 unmodified lines
3793 return 0;3791 return 0;
3794}3792}
3795 3793
3794/**
3795 * amdgpu_device_ip_resume_phase3 - run resume for hardware IPs
3796 *
3797 * @adev: amdgpu_device pointer
3798 *
3799 * Third resume function for hardware IPs. The list of all the hardware
3800 * IPs that make up the asic is walked and the resume callbacks are run for
3801 * all DCE. resume puts the hardware into a functional state after a suspend
3802 * and updates the software state as necessary. This function is also used
3803 * for restoring the GPU after a GPU reset.
3804 *
3805 * Returns 0 on success, negative error code on failure.
3806 */
3807static int amdgpu_device_ip_resume_phase3(struct amdgpu_device *adev)
3808{
3809 int i, r;
3810
3811 for (i = 0; i < adev->num_ip_blocks; i++) {
3812 if (!adev->ip_blocks[i].status.valid || adev->ip_blocks[i].status.hw)
3813 continue;
3814 if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) {
3815 r = amdgpu_ip_block_resume(&adev->ip_blocks[i]);
3816 if (r)
3817 return r;
3818 }
3819 }
3820
3821 return 0;
3822}
3823
3796/**3824/**
3797 * amdgpu_device_ip_resume - run resume for hardware IPs3825 * amdgpu_device_ip_resume - run resume for hardware IPs
3798 *3826 *
@@ -3822,6 +3850,13 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev) · 23 unmodified lines
3822 if (adev->mman.buffer_funcs_ring->sched.ready)3850 if (adev->mman.buffer_funcs_ring->sched.ready)
3823 amdgpu_ttm_set_buffer_funcs_status(adev, true);3851 amdgpu_ttm_set_buffer_funcs_status(adev, true);
3824 3852
3853 if (r)
3854 return r;
3855
3856 amdgpu_fence_driver_hw_init(adev);
3857
3858 r = amdgpu_device_ip_resume_phase3(adev);
3859
3825 return r;3860 return r;
3826}3861}
3827 3862
@@ -4902,7 +4937,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients) · 1074 unmodified lines
4902 dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r);4937 dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r);
4903 goto exit;4938 goto exit;
4904 }4939 }
4905 amdgpu_fence_driver_hw_init(adev);
4906 4940
4907 if (!adev->in_s0ix) {4941 if (!adev->in_s0ix) {
4908 r = amdgpu_amdkfd_resume(adev, adev->in_runpm);4942 r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
@@ -5487,6 +5521,10 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context) · 578 unmodified lines
5487 if (tmp_adev->mman.buffer_funcs_ring->sched.ready)5521 if (tmp_adev->mman.buffer_funcs_ring->sched.ready)
5488 amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);5522 amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
5489 5523
5524 r = amdgpu_device_ip_resume_phase3(tmp_adev);
5525 if (r)
5526 goto out;
5527
5490 if (vram_lost)5528 if (vram_lost)
5491 amdgpu_device_fill_reset_magic(tmp_adev);5529 amdgpu_device_fill_reset_magic(tmp_adev);
5492 5530
drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c+8−4
@@ -40,10 +40,12 @@ · 39 unmodified lines
40static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev,40static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev,
41 struct amdgpu_ring *ring)41 struct amdgpu_ring *ring)
42{42{
43 if (!ring || !ring->funcs->emit_wreg)43 if (!ring || !ring->funcs->emit_wreg) {
44 WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);44 WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
45 else45 RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
46 } else {
46 amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);47 amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
48 }
47}49}
48 50
49static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev,51static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev,
@@ -54,11 +56,13 @@ static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev, · 4 unmodified lines
54 amdgpu_ip_version(adev, HDP_HWIP, 0) == IP_VERSION(4, 4, 5))56 amdgpu_ip_version(adev, HDP_HWIP, 0) == IP_VERSION(4, 4, 5))
55 return;57 return;
56 58
57 if (!ring || !ring->funcs->emit_wreg)59 if (!ring || !ring->funcs->emit_wreg) {
58 WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1);60 WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1);
59 else61 RREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE);
62 } else {
60 amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(63 amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(
61 HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);64 HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);
65 }
62}66}
63 67
64static void hdp_v4_0_query_ras_error_count(struct amdgpu_device *adev,68static void hdp_v4_0_query_ras_error_count(struct amdgpu_device *adev,
drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c+5−2
@@ -31,10 +31,12 @@ · 30 unmodified lines
31static void hdp_v5_0_flush_hdp(struct amdgpu_device *adev,31static void hdp_v5_0_flush_hdp(struct amdgpu_device *adev,
32 struct amdgpu_ring *ring)32 struct amdgpu_ring *ring)
33{33{
34 if (!ring || !ring->funcs->emit_wreg)34 if (!ring || !ring->funcs->emit_wreg) {
35 WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);35 WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
36 else36 RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
37 } else {
37 amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);38 amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
39 }
38}40}
39 41
40static void hdp_v5_0_invalidate_hdp(struct amdgpu_device *adev,42static void hdp_v5_0_invalidate_hdp(struct amdgpu_device *adev,
@@ -42,6 +44,7 @@ static void hdp_v5_0_invalidate_hdp(struct amdgpu_device *adev, · 1 unmodified line
42{44{
43 if (!ring || !ring->funcs->emit_wreg) {45 if (!ring || !ring->funcs->emit_wreg) {
44 WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1);46 WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1);
47 RREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE);
45 } else {48 } else {
46 amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(49 amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(
47 HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);50 HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);
drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c+4−2
@@ -31,13 +31,15 @@ · 30 unmodified lines
31static void hdp_v5_2_flush_hdp(struct amdgpu_device *adev,31static void hdp_v5_2_flush_hdp(struct amdgpu_device *adev,
32 struct amdgpu_ring *ring)32 struct amdgpu_ring *ring)
33{33{
34 if (!ring || !ring->funcs->emit_wreg)34 if (!ring || !ring->funcs->emit_wreg) {
35 WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,35 WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
36 0);36 0);
37 else37 RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
38 } else {
38 amdgpu_ring_emit_wreg(ring,39 amdgpu_ring_emit_wreg(ring,
39 (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,40 (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
40 0);41 0);
42 }
41}43}
42 44
43static void hdp_v5_2_update_mem_power_gating(struct amdgpu_device *adev,45static void hdp_v5_2_update_mem_power_gating(struct amdgpu_device *adev,
drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c+4−2
@@ -34,10 +34,12 @@ · 33 unmodified lines
34static void hdp_v6_0_flush_hdp(struct amdgpu_device *adev,34static void hdp_v6_0_flush_hdp(struct amdgpu_device *adev,
35 struct amdgpu_ring *ring)35 struct amdgpu_ring *ring)
36{36{
37 if (!ring || !ring->funcs->emit_wreg)37 if (!ring || !ring->funcs->emit_wreg) {
38 WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);38 WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
39 else39 RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
40 } else {
40 amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);41 amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
42 }
41}43}
42 44
43static void hdp_v6_0_update_clock_gating(struct amdgpu_device *adev,45static void hdp_v6_0_update_clock_gating(struct amdgpu_device *adev,
drivers/gpu/drm/amd/amdgpu/hdp_v7_0.c+4−2
@@ -31,10 +31,12 @@ · 30 unmodified lines
31static void hdp_v7_0_flush_hdp(struct amdgpu_device *adev,31static void hdp_v7_0_flush_hdp(struct amdgpu_device *adev,
32 struct amdgpu_ring *ring)32 struct amdgpu_ring *ring)
33{33{
34 if (!ring || !ring->funcs->emit_wreg)34 if (!ring || !ring->funcs->emit_wreg) {
35 WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);35 WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
36 else36 RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
37 } else {
37 amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);38 amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
39 }
38}40}
39 41
40static void hdp_v7_0_update_clock_gating(struct amdgpu_device *adev,42static void hdp_v7_0_update_clock_gating(struct amdgpu_device *adev,
drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c+1−1
@@ -604,7 +604,7 @@ static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev) · 603 unmodified lines
604static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring)604static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring)
605{605{
606 struct amdgpu_device *adev = ring->adev;606 struct amdgpu_device *adev = ring->adev;
607 bool set_clocks = !cancel_delayed_work_sync(&adev->jpeg.idle_work);607 bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
608 int cnt = 0;608 int cnt = 0;
609 609
610 mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);610 mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);
drivers/gpu/drm/amd/amdkfd/kfd_crat.c+6−0
@@ -1510,6 +1510,8 @@ static int kfd_fill_gpu_cache_info_from_gfx_config_v2(struct kfd_dev *kdev, · 1509 unmodified lines
1510 if (adev->gfx.config.gc_tcp_size_per_cu) {1510 if (adev->gfx.config.gc_tcp_size_per_cu) {
1511 pcache_info[i].cache_size = adev->gfx.config.gc_tcp_size_per_cu;1511 pcache_info[i].cache_size = adev->gfx.config.gc_tcp_size_per_cu;
1512 pcache_info[i].cache_level = 1;1512 pcache_info[i].cache_level = 1;
1513 /* Cacheline size not available in IP discovery for gc943,gc944 */
1514 pcache_info[i].cache_line_size = 128;
1513 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |1515 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
1514 CRAT_CACHE_FLAGS_DATA_CACHE |1516 CRAT_CACHE_FLAGS_DATA_CACHE |
1515 CRAT_CACHE_FLAGS_SIMD_CACHE);1517 CRAT_CACHE_FLAGS_SIMD_CACHE);
@@ -1521,6 +1523,7 @@ static int kfd_fill_gpu_cache_info_from_gfx_config_v2(struct kfd_dev *kdev, · 5 unmodified lines
1521 pcache_info[i].cache_size =1523 pcache_info[i].cache_size =
1522 adev->gfx.config.gc_l1_instruction_cache_size_per_sqc;1524 adev->gfx.config.gc_l1_instruction_cache_size_per_sqc;
1523 pcache_info[i].cache_level = 1;1525 pcache_info[i].cache_level = 1;
1526 pcache_info[i].cache_line_size = 64;
1524 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |1527 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
1525 CRAT_CACHE_FLAGS_INST_CACHE |1528 CRAT_CACHE_FLAGS_INST_CACHE |
1526 CRAT_CACHE_FLAGS_SIMD_CACHE);1529 CRAT_CACHE_FLAGS_SIMD_CACHE);
@@ -1531,6 +1534,7 @@ static int kfd_fill_gpu_cache_info_from_gfx_config_v2(struct kfd_dev *kdev, · 4 unmodified lines
1531 if (adev->gfx.config.gc_l1_data_cache_size_per_sqc) {1534 if (adev->gfx.config.gc_l1_data_cache_size_per_sqc) {
1532 pcache_info[i].cache_size = adev->gfx.config.gc_l1_data_cache_size_per_sqc;1535 pcache_info[i].cache_size = adev->gfx.config.gc_l1_data_cache_size_per_sqc;
1533 pcache_info[i].cache_level = 1;1536 pcache_info[i].cache_level = 1;
1537 pcache_info[i].cache_line_size = 64;
1534 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |1538 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
1535 CRAT_CACHE_FLAGS_DATA_CACHE |1539 CRAT_CACHE_FLAGS_DATA_CACHE |
1536 CRAT_CACHE_FLAGS_SIMD_CACHE);1540 CRAT_CACHE_FLAGS_SIMD_CACHE);
@@ -1541,6 +1545,7 @@ static int kfd_fill_gpu_cache_info_from_gfx_config_v2(struct kfd_dev *kdev, · 4 unmodified lines
1541 if (adev->gfx.config.gc_tcc_size) {1545 if (adev->gfx.config.gc_tcc_size) {
1542 pcache_info[i].cache_size = adev->gfx.config.gc_tcc_size;1546 pcache_info[i].cache_size = adev->gfx.config.gc_tcc_size;
1543 pcache_info[i].cache_level = 2;1547 pcache_info[i].cache_level = 2;
1548 pcache_info[i].cache_line_size = 128;
1544 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |1549 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
1545 CRAT_CACHE_FLAGS_DATA_CACHE |1550 CRAT_CACHE_FLAGS_DATA_CACHE |
1546 CRAT_CACHE_FLAGS_SIMD_CACHE);1551 CRAT_CACHE_FLAGS_SIMD_CACHE);
@@ -1551,6 +1556,7 @@ static int kfd_fill_gpu_cache_info_from_gfx_config_v2(struct kfd_dev *kdev, · 4 unmodified lines
1551 if (adev->gmc.mall_size) {1556 if (adev->gmc.mall_size) {
1552 pcache_info[i].cache_size = adev->gmc.mall_size / 1024;1557 pcache_info[i].cache_size = adev->gmc.mall_size / 1024;
1553 pcache_info[i].cache_level = 3;1558 pcache_info[i].cache_level = 3;
1559 pcache_info[i].cache_line_size = 64;
1554 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |1560 pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
1555 CRAT_CACHE_FLAGS_DATA_CACHE |1561 CRAT_CACHE_FLAGS_DATA_CACHE |
1556 CRAT_CACHE_FLAGS_SIMD_CACHE);1562 CRAT_CACHE_FLAGS_SIMD_CACHE);
drivers/gpu/drm/amd/amdkfd/kfd_device.c+3−0
@@ -235,6 +235,9 @@ static void kfd_device_info_init(struct kfd_dev *kfd, · 234 unmodified lines
235 */235 */
236 kfd->device_info.needs_pci_atomics = true;236 kfd->device_info.needs_pci_atomics = true;
237 kfd->device_info.no_atomic_fw_version = kfd->adev->gfx.rs64_enable ? 509 : 0;237 kfd->device_info.no_atomic_fw_version = kfd->adev->gfx.rs64_enable ? 509 : 0;
238 } else if (gc_version < IP_VERSION(13, 0, 0)) {
239 kfd->device_info.needs_pci_atomics = true;
240 kfd->device_info.no_atomic_fw_version = 2090;
238 } else {241 } else {
239 kfd->device_info.needs_pci_atomics = true;242 kfd->device_info.needs_pci_atomics = true;
240 }243 }
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c+2−0
@@ -3481,6 +3481,8 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) · 3480 unmodified lines
3481 caps->aux_support = false;3481 caps->aux_support = false;
3482 else if (amdgpu_backlight == 1)3482 else if (amdgpu_backlight == 1)
3483 caps->aux_support = true;3483 caps->aux_support = true;
3484 if (caps->aux_support)
3485 aconnector->dc_link->backlight_control_type = BACKLIGHT_CONTROL_AMD_AUX;
3484 3486
3485 luminance_range = &conn_base->display_info.luminance_range;3487 luminance_range = &conn_base->display_info.luminance_range;
3486 3488
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c+10−3
@@ -907,14 +907,14 @@ dm_helpers_probe_acpi_edid(void *data, u8 *buf, unsigned int block, size_t len) · 906 unmodified lines
907 struct drm_connector *connector = data;907 struct drm_connector *connector = data;
908 struct acpi_device *acpidev = ACPI_COMPANION(connector->dev->dev);908 struct acpi_device *acpidev = ACPI_COMPANION(connector->dev->dev);
909 unsigned char start = block * EDID_LENGTH;909 unsigned char start = block * EDID_LENGTH;
910 void *edid;910 struct edid *edid;
911 int r;911 int r;
912 912
913 if (!acpidev)913 if (!acpidev)
914 return -ENODEV;914 return -ENODEV;
915 915
916 /* fetch the entire edid from BIOS */916 /* fetch the entire edid from BIOS */
917 r = acpi_video_get_edid(acpidev, ACPI_VIDEO_DISPLAY_LCD, -1, &edid);917 r = acpi_video_get_edid(acpidev, ACPI_VIDEO_DISPLAY_LCD, -1, (void *)&edid);
918 if (r < 0) {918 if (r < 0) {
919 drm_dbg(connector->dev, "Failed to get EDID from ACPI: %d\n", r);919 drm_dbg(connector->dev, "Failed to get EDID from ACPI: %d\n", r);
920 return r;920 return r;
@@ -924,7 +924,14 @@ dm_helpers_probe_acpi_edid(void *data, u8 *buf, unsigned int block, size_t len) · 3 unmodified lines
924 goto cleanup;924 goto cleanup;
925 }925 }
926 926
927 memcpy(buf, edid + start, len);927 /* sanity check */
928 if (edid->revision < 4 || !(edid->input & DRM_EDID_INPUT_DIGITAL) ||
929 (edid->input & DRM_EDID_DIGITAL_TYPE_MASK) == DRM_EDID_DIGITAL_TYPE_UNDEF) {
930 r = -EINVAL;
931 goto cleanup;
932 }
933
934 memcpy(buf, (void *)edid + start, len);
928 r = 0;935 r = 0;
929 936
930cleanup:937cleanup:
drivers/gpu/drm/amd/display/dc/core/dc.c+18−0
@@ -6109,3 +6109,21 @@ struct dc_power_profile dc_get_power_profile_for_dc_state(const struct dc_state · 6108 unmodified lines
6109 profile.power_level = dc->res_pool->funcs->get_power_profile(context);6109 profile.power_level = dc->res_pool->funcs->get_power_profile(context);
6110 return profile;6110 return profile;
6111}6111}
6112
6113/*
6114 **********************************************************************************
6115 * dc_get_det_buffer_size_from_state() - extracts detile buffer size from dc state
6116 *
6117 * Called when DM wants to log detile buffer size from dc_state
6118 *
6119 **********************************************************************************
6120 */
6121unsigned int dc_get_det_buffer_size_from_state(const struct dc_state *context)
6122{
6123 struct dc *dc = context->clk_mgr->ctx->dc;
6124
6125 if (dc->res_pool->funcs->get_det_buffer_size)
6126 return dc->res_pool->funcs->get_det_buffer_size(context);
6127 else
6128 return 0;
6129}
drivers/gpu/drm/amd/display/dc/core/dc_resource.c+41−1
@@ -2094,7 +2094,8 @@ int resource_get_odm_slice_dst_width(struct pipe_ctx *otg_master, · 2093 unmodified lines
2094 count = resource_get_odm_slice_count(otg_master);2094 count = resource_get_odm_slice_count(otg_master);
2095 h_active = timing->h_addressable +2095 h_active = timing->h_addressable +
2096 timing->h_border_left +2096 timing->h_border_left +
2097 timing->h_border_right;2097 timing->h_border_right +
2098 otg_master->hblank_borrow;
2098 width = h_active / count;2099 width = h_active / count;
2099 2100
2100 if (otg_master->stream_res.tg)2101 if (otg_master->stream_res.tg)
@@ -4026,6 +4027,41 @@ fail: · 1925 unmodified lines
4026 return res;4027 return res;
4027}4028}
4028 4029
4030/**
4031 * decide_hblank_borrow - Decides the horizontal blanking borrow value for a given pipe context.
4032 * @pipe_ctx: Pointer to the pipe context structure.
4033 *
4034 * This function calculates the horizontal blanking borrow value for a given pipe context based on the
4035 * display stream compression (DSC) configuration. If the horizontal active pixels (hactive) are less
4036 * than the total width of the DSC slices, it sets the hblank_borrow value to the difference. If the
4037 * total horizontal timing minus the hblank_borrow value is less than 32, it resets the hblank_borrow
4038 * value to 0.
4039 */
4040static void decide_hblank_borrow(struct pipe_ctx *pipe_ctx)
4041{
4042 uint32_t hactive;
4043 uint32_t ceil_slice_width;
4044 struct dc_stream_state *stream = NULL;
4045
4046 if (!pipe_ctx)
4047 return;
4048
4049 stream = pipe_ctx->stream;
4050
4051 if (stream->timing.flags.DSC) {
4052 hactive = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
4053
4054 /* Assume if determined slices does not divide Hactive evenly, Hborrow is needed for padding*/
4055 if (hactive % stream->timing.dsc_cfg.num_slices_h != 0) {
4056 ceil_slice_width = (hactive / stream->timing.dsc_cfg.num_slices_h) + 1;
4057 pipe_ctx->hblank_borrow = ceil_slice_width * stream->timing.dsc_cfg.num_slices_h - hactive;
4058
4059 if (stream->timing.h_total - hactive - pipe_ctx->hblank_borrow < 32)
4060 pipe_ctx->hblank_borrow = 0;
4061 }
4062 }
4063}
4064
4029/**4065/**
4030 * dc_validate_global_state() - Determine if hardware can support a given state4066 * dc_validate_global_state() - Determine if hardware can support a given state
4031 *4067 *
@@ -4064,6 +4100,10 @@ enum dc_status dc_validate_global_state( · 32 unmodified lines
4064 if (pipe_ctx->stream != stream)4100 if (pipe_ctx->stream != stream)
4065 continue;4101 continue;
4066 4102
4103 /* Decide whether hblank borrow is needed and save it in pipe_ctx */
4104 if (dc->debug.enable_hblank_borrow)
4105 decide_hblank_borrow(pipe_ctx);
4106
4067 if (dc->res_pool->funcs->patch_unknown_plane_state &&4107 if (dc->res_pool->funcs->patch_unknown_plane_state &&
4068 pipe_ctx->plane_state &&4108 pipe_ctx->plane_state &&
4069 pipe_ctx->plane_state->tiling_info.gfx9.swizzle == DC_SW_UNKNOWN) {4109 pipe_ctx->plane_state->tiling_info.gfx9.swizzle == DC_SW_UNKNOWN) {
drivers/gpu/drm/amd/display/dc/dc.h+4−0
@@ -290,6 +290,7 @@ struct dc_caps { · 289 unmodified lines
290 uint16_t subvp_vertical_int_margin_us;290 uint16_t subvp_vertical_int_margin_us;
291 bool seamless_odm;291 bool seamless_odm;
292 uint32_t max_v_total;292 uint32_t max_v_total;
293 bool vtotal_limited_by_fp2;
293 uint32_t max_disp_clock_khz_at_vmin;294 uint32_t max_disp_clock_khz_at_vmin;
294 uint8_t subvp_drr_vblank_start_margin_us;295 uint8_t subvp_drr_vblank_start_margin_us;
295 bool cursor_not_scaled;296 bool cursor_not_scaled;
@@ -1068,6 +1069,7 @@ struct dc_debug_options { · 772 unmodified lines
1068 unsigned int scale_to_sharpness_policy;1069 unsigned int scale_to_sharpness_policy;
1069 bool skip_full_updated_if_possible;1070 bool skip_full_updated_if_possible;
1070 unsigned int enable_oled_edp_power_up_opt;1071 unsigned int enable_oled_edp_power_up_opt;
1072 bool enable_hblank_borrow;
1071};1073};
1072 1074
1073 1075
@@ -2550,6 +2552,8 @@ struct dc_power_profile { · 1476 unmodified lines
2550 2552
2551struct dc_power_profile dc_get_power_profile_for_dc_state(const struct dc_state *context);2553struct dc_power_profile dc_get_power_profile_for_dc_state(const struct dc_state *context);
2552 2554
2555unsigned int dc_get_det_buffer_size_from_state(const struct dc_state *context);
2556
2553/* DSC Interfaces */2557/* DSC Interfaces */
2554#include "dc_dsc.h"2558#include "dc_dsc.h"
2555 2559
drivers/gpu/drm/amd/display/dc/dc_spl_translate.c+1−1
@@ -120,7 +120,7 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl · 119 unmodified lines
120 spl_in->odm_slice_index = resource_get_odm_slice_index(pipe_ctx);120 spl_in->odm_slice_index = resource_get_odm_slice_index(pipe_ctx);
121 // Make spl input basic out info output_size width point to stream h active121 // Make spl input basic out info output_size width point to stream h active
122 spl_in->basic_out.output_size.width =122 spl_in->basic_out.output_size.width =
123 stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;123 stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right + pipe_ctx->hblank_borrow;
124 // Make spl input basic out info output_size height point to v active124 // Make spl input basic out info output_size height point to v active
125 spl_in->basic_out.output_size.height =125 spl_in->basic_out.output_size.height =
126 stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;126 stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c+1−0
@@ -1222,6 +1222,7 @@ static dml_bool_t CalculatePrefetchSchedule(struct display_mode_lib_scratch_st * · 1221 unmodified lines
1222 s->dst_y_prefetch_oto = s->Tvm_oto_lines + 2 * s->Tr0_oto_lines + s->Lsw_oto;1222 s->dst_y_prefetch_oto = s->Tvm_oto_lines + 2 * s->Tr0_oto_lines + s->Lsw_oto;
1223 1223
1224 s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + dml_max(p->TWait + p->TCalc, *p->Tdmdl)) / s->LineTime - (*p->DSTYAfterScaler + (dml_float_t) *p->DSTXAfterScaler / (dml_float_t)p->myPipe->HTotal);1224 s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + dml_max(p->TWait + p->TCalc, *p->Tdmdl)) / s->LineTime - (*p->DSTYAfterScaler + (dml_float_t) *p->DSTXAfterScaler / (dml_float_t)p->myPipe->HTotal);
1225 s->dst_y_prefetch_equ = dml_min(s->dst_y_prefetch_equ, 63.75); // limit to the reg limit of U6.2 for DST_Y_PREFETCH
1225 1226
1226#ifdef __DML_VBA_DEBUG__1227#ifdef __DML_VBA_DEBUG__
1227 dml_print("DML::%s: HTotal = %u\n", __func__, p->myPipe->HTotal);1228 dml_print("DML::%s: HTotal = %u\n", __func__, p->myPipe->HTotal);
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c+44−4
@@ -339,11 +339,22 @@ void dml21_apply_soc_bb_overrides(struct dml2_initialize_instance_in_out *dml_in · 338 unmodified lines
339 // }339 // }
340}340}
341 341
342static unsigned int calc_max_hardware_v_total(const struct dc_stream_state *stream)
343{
344 unsigned int max_hw_v_total = stream->ctx->dc->caps.max_v_total;
345
346 if (stream->ctx->dc->caps.vtotal_limited_by_fp2) {
347 max_hw_v_total -= stream->timing.v_front_porch + 1;
348 }
349
350 return max_hw_v_total;
351}
352
342static void populate_dml21_timing_config_from_stream_state(struct dml2_timing_cfg *timing,353static void populate_dml21_timing_config_from_stream_state(struct dml2_timing_cfg *timing,
343 struct dc_stream_state *stream,354 struct dc_stream_state *stream,
344 struct dml2_context *dml_ctx)355 struct dml2_context *dml_ctx)
345{356{
346 unsigned int hblank_start, vblank_start;357 unsigned int hblank_start, vblank_start, min_hardware_refresh_in_uhz;
347 358
348 timing->h_active = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;359 timing->h_active = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
349 timing->v_active = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;360 timing->v_active = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
@@ -371,11 +382,23 @@ static void populate_dml21_timing_config_from_stream_state(struct dml2_timing_cf · 21 unmodified lines
371 - stream->timing.v_border_top - stream->timing.v_border_bottom;382 - stream->timing.v_border_top - stream->timing.v_border_bottom;
372 383
373 timing->drr_config.enabled = stream->ignore_msa_timing_param;384 timing->drr_config.enabled = stream->ignore_msa_timing_param;
374 timing->drr_config.min_refresh_uhz = stream->timing.min_refresh_in_uhz;
375 timing->drr_config.drr_active_variable = stream->vrr_active_variable;385 timing->drr_config.drr_active_variable = stream->vrr_active_variable;
376 timing->drr_config.drr_active_fixed = stream->vrr_active_fixed;386 timing->drr_config.drr_active_fixed = stream->vrr_active_fixed;
377 timing->drr_config.disallowed = !stream->allow_freesync;387 timing->drr_config.disallowed = !stream->allow_freesync;
378 388
389 /* limit min refresh rate to DC cap */
390 min_hardware_refresh_in_uhz = stream->timing.min_refresh_in_uhz;
391 if (stream->ctx->dc->caps.max_v_total != 0) {
392 min_hardware_refresh_in_uhz = div64_u64((stream->timing.pix_clk_100hz * 100000000ULL),
393 (stream->timing.h_total * (long long)calc_max_hardware_v_total(stream)));
394 }
395
396 if (stream->timing.min_refresh_in_uhz > min_hardware_refresh_in_uhz) {
397 timing->drr_config.min_refresh_uhz = stream->timing.min_refresh_in_uhz;
398 } else {
399 timing->drr_config.min_refresh_uhz = min_hardware_refresh_in_uhz;
400 }
401
379 if (dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase &&402 if (dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase &&
380 stream->ctx->dc->config.enable_fpo_flicker_detection == 1)403 stream->ctx->dc->config.enable_fpo_flicker_detection == 1)
381 timing->drr_config.max_instant_vtotal_delta = dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase(stream, false);404 timing->drr_config.max_instant_vtotal_delta = dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase(stream, false);
@@ -422,6 +445,21 @@ static void populate_dml21_timing_config_from_stream_state(struct dml2_timing_cf · 40 unmodified lines
422 timing->vblank_nom = timing->v_total - timing->v_active;445 timing->vblank_nom = timing->v_total - timing->v_active;
423}446}
424 447
448/**
449 * adjust_dml21_hblank_timing_config_from_pipe_ctx - Adjusts the horizontal blanking timing configuration
450 * based on the pipe context.
451 * @timing: Pointer to the dml2_timing_cfg structure to be adjusted.
452 * @pipe: Pointer to the pipe_ctx structure containing the horizontal blanking borrow value.
453 *
454 * This function modifies the horizontal active and blank end timings by adding and subtracting
455 * the horizontal blanking borrow value from the pipe context, respectively.
456 */
457static void adjust_dml21_hblank_timing_config_from_pipe_ctx(struct dml2_timing_cfg *timing, struct pipe_ctx *pipe)
458{
459 timing->h_active += pipe->hblank_borrow;
460 timing->h_blank_end -= pipe->hblank_borrow;
461}
462
425static void populate_dml21_output_config_from_stream_state(struct dml2_link_output_cfg *output,463static void populate_dml21_output_config_from_stream_state(struct dml2_link_output_cfg *output,
426 struct dc_stream_state *stream, const struct pipe_ctx *pipe)464 struct dc_stream_state *stream, const struct pipe_ctx *pipe)
427{465{
@@ -709,6 +747,7 @@ static const struct scaler_data *get_scaler_data_for_plane( · 281 unmodified lines
709 temp_pipe->plane_state = pipe->plane_state;747 temp_pipe->plane_state = pipe->plane_state;
710 temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps;748 temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps;
711 temp_pipe->stream_res = pipe->stream_res;749 temp_pipe->stream_res = pipe->stream_res;
750 temp_pipe->hblank_borrow = pipe->hblank_borrow;
712 dml_ctx->config.callbacks.build_scaling_params(temp_pipe);751 dml_ctx->config.callbacks.build_scaling_params(temp_pipe);
713 break;752 break;
714 }753 }
@@ -973,6 +1012,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s · 258 unmodified lines
973 1012
974 ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);1013 ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);
975 populate_dml21_timing_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing, context->streams[stream_index], dml_ctx);1014 populate_dml21_timing_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing, context->streams[stream_index], dml_ctx);
1015 adjust_dml21_hblank_timing_config_from_pipe_ctx(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing, &context->res_ctx.pipe_ctx[stream_index]);
976 populate_dml21_output_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].output, context->streams[stream_index], &context->res_ctx.pipe_ctx[stream_index]);1016 populate_dml21_output_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].output, context->streams[stream_index], &context->res_ctx.pipe_ctx[stream_index]);
977 populate_dml21_stream_overrides_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location], context->streams[stream_index]);1017 populate_dml21_stream_overrides_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location], context->streams[stream_index]);
978 1018
@@ -1111,12 +1151,12 @@ void dml21_populate_pipe_ctx_dlg_params(struct dml2_context *dml_ctx, struct dc_ · 132 unmodified lines
1111 struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;1151 struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
1112 union dml2_global_sync_programming *global_sync = &stream_programming->global_sync;1152 union dml2_global_sync_programming *global_sync = &stream_programming->global_sync;
1113 1153
1114 hactive = timing->h_addressable + timing->h_border_left + timing->h_border_right;1154 hactive = timing->h_addressable + timing->h_border_left + timing->h_border_right + pipe_ctx->hblank_borrow;
1115 vactive = timing->v_addressable + timing->v_border_bottom + timing->v_border_top;1155 vactive = timing->v_addressable + timing->v_border_bottom + timing->v_border_top;
1116 hblank_start = pipe_ctx->stream->timing.h_total - pipe_ctx->stream->timing.h_front_porch;1156 hblank_start = pipe_ctx->stream->timing.h_total - pipe_ctx->stream->timing.h_front_porch;
1117 vblank_start = pipe_ctx->stream->timing.v_total - pipe_ctx->stream->timing.v_front_porch;1157 vblank_start = pipe_ctx->stream->timing.v_total - pipe_ctx->stream->timing.v_front_porch;
1118 1158
1119 hblank_end = hblank_start - timing->h_addressable - timing->h_border_left - timing->h_border_right;1159 hblank_end = hblank_start - timing->h_addressable - timing->h_border_left - timing->h_border_right - pipe_ctx->hblank_borrow;
1120 vblank_end = vblank_start - timing->v_addressable - timing->v_border_top - timing->v_border_bottom;1160 vblank_end = vblank_start - timing->v_addressable - timing->v_border_top - timing->v_border_bottom;
1121 1161
1122 if (dml_ctx->config.svp_pstate.callbacks.get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) {1162 if (dml_ctx->config.svp_pstate.callbacks.get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) {
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c+2−1
@@ -1049,7 +1049,8 @@ void dcn32_update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) · 1048 unmodified lines
1049 }1049 }
1050 1050
1051 /* Enable DSC hw block */1051 /* Enable DSC hw block */
1052 dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;1052 dsc_cfg.pic_width = (stream->timing.h_addressable + pipe_ctx->hblank_borrow +
1053 stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
1053 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;1054 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
1054 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;1055 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
1055 dsc_cfg.color_depth = stream->timing.display_color_depth;1056 dsc_cfg.color_depth = stream->timing.display_color_depth;
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c+6−1
@@ -820,6 +820,7 @@ enum dc_status dcn401_enable_stream_timing( · 819 unmodified lines
820 int opp_cnt = 1;820 int opp_cnt = 1;
821 int opp_inst[MAX_PIPES] = {0};821 int opp_inst[MAX_PIPES] = {0};
822 struct pipe_ctx *opp_heads[MAX_PIPES] = {0};822 struct pipe_ctx *opp_heads[MAX_PIPES] = {0};
823 struct dc_crtc_timing patched_crtc_timing = stream->timing;
823 bool manual_mode;824 bool manual_mode;
824 unsigned int tmds_div = PIXEL_RATE_DIV_NA;825 unsigned int tmds_div = PIXEL_RATE_DIV_NA;
825 unsigned int unused_div = PIXEL_RATE_DIV_NA;826 unsigned int unused_div = PIXEL_RATE_DIV_NA;
@@ -874,9 +875,13 @@ enum dc_status dcn401_enable_stream_timing( · 48 unmodified lines
874 if (dc->hwseq->funcs.PLAT_58856_wa && (!dc_is_dp_signal(stream->signal)))875 if (dc->hwseq->funcs.PLAT_58856_wa && (!dc_is_dp_signal(stream->signal)))
875 dc->hwseq->funcs.PLAT_58856_wa(context, pipe_ctx);876 dc->hwseq->funcs.PLAT_58856_wa(context, pipe_ctx);
876 877
878 /* if we are borrowing from hblank, h_addressable needs to be adjusted */
879 if (dc->debug.enable_hblank_borrow)
880 patched_crtc_timing.h_addressable = patched_crtc_timing.h_addressable + pipe_ctx->hblank_borrow;
881
877 pipe_ctx->stream_res.tg->funcs->program_timing(882 pipe_ctx->stream_res.tg->funcs->program_timing(
878 pipe_ctx->stream_res.tg,883 pipe_ctx->stream_res.tg,
879 &stream->timing,884 &patched_crtc_timing,
880 pipe_ctx->pipe_dlg_param.vready_offset,885 pipe_ctx->pipe_dlg_param.vready_offset,
881 pipe_ctx->pipe_dlg_param.vstartup_start,886 pipe_ctx->pipe_dlg_param.vstartup_start,
882 pipe_ctx->pipe_dlg_param.vupdate_offset,887 pipe_ctx->pipe_dlg_param.vupdate_offset,
drivers/gpu/drm/amd/display/dc/inc/core_types.h+3−0
@@ -219,6 +219,7 @@ struct resource_funcs { · 218 unmodified lines
219 * Get indicator of power from a context that went through full validation219 * Get indicator of power from a context that went through full validation
220 */220 */
221 int (*get_power_profile)(const struct dc_state *context);221 int (*get_power_profile)(const struct dc_state *context);
222 unsigned int (*get_det_buffer_size)(const struct dc_state *context);
222};223};
223 224
224struct audio_support{225struct audio_support{
@@ -477,6 +478,8 @@ struct pipe_ctx { · 252 unmodified lines
477 /* subvp_index: only valid if the pipe is a SUBVP_MAIN*/478 /* subvp_index: only valid if the pipe is a SUBVP_MAIN*/
478 uint8_t subvp_index;479 uint8_t subvp_index;
479 struct pixel_rate_divider pixel_rate_divider;480 struct pixel_rate_divider pixel_rate_divider;
481 /* pixels borrowed from hblank to hactive */
482 uint8_t hblank_borrow;
480};483};
481 484
482/* Data used for dynamic link encoder assignment.485/* Data used for dynamic link encoder assignment.
drivers/gpu/drm/amd/display/dc/link/link_dpms.c+2−1
@@ -808,7 +808,8 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) · 807 unmodified lines
808 enum optc_dsc_mode optc_dsc_mode;808 enum optc_dsc_mode optc_dsc_mode;
809 809
810 /* Enable DSC hw block */810 /* Enable DSC hw block */
811 dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;811 dsc_cfg.pic_width = (stream->timing.h_addressable + pipe_ctx->hblank_borrow +
812 stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
812 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;813 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
813 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;814 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
814 dsc_cfg.color_depth = stream->timing.display_color_depth;815 dsc_cfg.color_depth = stream->timing.display_color_depth;
drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c+23−0
@@ -1510,6 +1510,7 @@ bool dcn20_split_stream_for_odm( · 1509 unmodified lines
1510 1510
1511 if (prev_odm_pipe->plane_state) {1511 if (prev_odm_pipe->plane_state) {
1512 struct scaler_data *sd = &prev_odm_pipe->plane_res.scl_data;1512 struct scaler_data *sd = &prev_odm_pipe->plane_res.scl_data;
1513 struct output_pixel_processor *opp = next_odm_pipe->stream_res.opp;
1513 int new_width;1514 int new_width;
1514 1515
1515 /* HACTIVE halved for odm combine */1516 /* HACTIVE halved for odm combine */
@@ -1543,7 +1544,28 @@ bool dcn20_split_stream_for_odm( · 27 unmodified lines
1543 sd->viewport_c.x += dc_fixpt_floor(dc_fixpt_mul_int(1544 sd->viewport_c.x += dc_fixpt_floor(dc_fixpt_mul_int(
1544 sd->ratios.horz_c, sd->h_active - sd->recout.x));1545 sd->ratios.horz_c, sd->h_active - sd->recout.x));
1545 sd->recout.x = 0;1546 sd->recout.x = 0;
1547
1548 /*
1549 * When odm is used in YcbCr422 or 420 colour space, a split screen
1550 * will be seen with the previous calculations since the extra left
1551 * edge pixel is accounted for in fmt but not in viewport.
1552 *
1553 * Below are calculations which fix the split by fixing the calculations
1554 * if there is an extra left edge pixel.
1555 */
1556 if (opp && opp->funcs->opp_get_left_edge_extra_pixel_count
1557 && opp->funcs->opp_get_left_edge_extra_pixel_count(
1558 opp, next_odm_pipe->stream->timing.pixel_encoding,
1559 resource_is_pipe_type(next_odm_pipe, OTG_MASTER)) == 1) {
1560 sd->h_active += 1;
1561 sd->recout.width += 1;
1562 sd->viewport.x -= dc_fixpt_ceil(dc_fixpt_mul_int(sd->ratios.horz, 1));
1563 sd->viewport_c.x -= dc_fixpt_ceil(dc_fixpt_mul_int(sd->ratios.horz, 1));
1564 sd->viewport_c.width += dc_fixpt_ceil(dc_fixpt_mul_int(sd->ratios.horz, 1));
1565 sd->viewport.width += dc_fixpt_ceil(dc_fixpt_mul_int(sd->ratios.horz, 1));
1566 }
1546 }1567 }
1568
1547 if (!next_odm_pipe->top_pipe)1569 if (!next_odm_pipe->top_pipe)
1548 next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx];1570 next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx];
1549 else1571 else
@@ -2132,6 +2154,7 @@ bool dcn20_fast_validate_bw( · 582 unmodified lines
2132 ASSERT(0);2154 ASSERT(0);
2133 }2155 }
2134 }2156 }
2157
2135 /* Actual dsc count per stream dsc validation*/2158 /* Actual dsc count per stream dsc validation*/
2136 if (!dcn20_validate_dsc(dc, context)) {2159 if (!dcn20_validate_dsc(dc, context)) {
2137 context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states] =2160 context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states] =
drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c+1−0
@@ -2353,6 +2353,7 @@ static bool dcn30_resource_construct( · 2352 unmodified lines
2353 2353
2354 dc->caps.dp_hdmi21_pcon_support = true;2354 dc->caps.dp_hdmi21_pcon_support = true;
2355 dc->caps.max_v_total = (1 << 15) - 1;2355 dc->caps.max_v_total = (1 << 15) - 1;
2356 dc->caps.vtotal_limited_by_fp2 = true;
2356 2357
2357 /* read VBIOS LTTPR caps */2358 /* read VBIOS LTTPR caps */
2358 {2359 {
drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c+1−0
@@ -1233,6 +1233,7 @@ static bool dcn302_resource_construct( · 1232 unmodified lines
1233 dc->caps.extended_aux_timeout_support = true;1233 dc->caps.extended_aux_timeout_support = true;
1234 dc->caps.dmcub_support = true;1234 dc->caps.dmcub_support = true;
1235 dc->caps.max_v_total = (1 << 15) - 1;1235 dc->caps.max_v_total = (1 << 15) - 1;
1236 dc->caps.vtotal_limited_by_fp2 = true;
1236 1237
1237 /* Color pipeline capabilities */1238 /* Color pipeline capabilities */
1238 dc->caps.color.dpp.dcn_arch = 1;1239 dc->caps.color.dpp.dcn_arch = 1;
drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c+1−0
@@ -1178,6 +1178,7 @@ static bool dcn303_resource_construct( · 1177 unmodified lines
1178 dc->caps.extended_aux_timeout_support = true;1178 dc->caps.extended_aux_timeout_support = true;
1179 dc->caps.dmcub_support = true;1179 dc->caps.dmcub_support = true;
1180 dc->caps.max_v_total = (1 << 15) - 1;1180 dc->caps.max_v_total = (1 << 15) - 1;
1181 dc->caps.vtotal_limited_by_fp2 = true;
1181 1182
1182 /* Color pipeline capabilities */1183 /* Color pipeline capabilities */
1183 dc->caps.color.dpp.dcn_arch = 1;1184 dc->caps.color.dpp.dcn_arch = 1;
drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c+7−0
@@ -1720,6 +1720,12 @@ int dcn31_populate_dml_pipes_from_context( · 1719 unmodified lines
1720 return pipe_cnt;1720 return pipe_cnt;
1721}1721}
1722 1722
1723unsigned int dcn31_get_det_buffer_size(
1724 const struct dc_state *context)
1725{
1726 return context->bw_ctx.dml.ip.det_buffer_size_kbytes;
1727}
1728
1723void dcn31_calculate_wm_and_dlg(1729void dcn31_calculate_wm_and_dlg(
1724 struct dc *dc, struct dc_state *context,1730 struct dc *dc, struct dc_state *context,
1725 display_e2e_pipe_params_st *pipes,1731 display_e2e_pipe_params_st *pipes,
@@ -1842,6 +1848,7 @@ static struct resource_funcs dcn31_res_pool_funcs = { · 116 unmodified lines
1842 .update_bw_bounding_box = dcn31_update_bw_bounding_box,1848 .update_bw_bounding_box = dcn31_update_bw_bounding_box,
1843 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,1849 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1844 .get_panel_config_defaults = dcn31_get_panel_config_defaults,1850 .get_panel_config_defaults = dcn31_get_panel_config_defaults,
1851 .get_det_buffer_size = dcn31_get_det_buffer_size,
1845};1852};
1846 1853
1847static struct clock_source *dcn30_clock_source_create(1854static struct clock_source *dcn30_clock_source_create(
drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h+3−0
@@ -63,6 +63,9 @@ struct resource_pool *dcn31_create_resource_pool( · 62 unmodified lines
63 const struct dc_init_data *init_data,63 const struct dc_init_data *init_data,
64 struct dc *dc);64 struct dc *dc);
65 65
66unsigned int dcn31_get_det_buffer_size(
67 const struct dc_state *context);
68
66/*temp: B0 specific before switch to dcn313 headers*/69/*temp: B0 specific before switch to dcn313 headers*/
67#ifndef regPHYPLLF_PIXCLK_RESYNC_CNTL70#ifndef regPHYPLLF_PIXCLK_RESYNC_CNTL
68#define regPHYPLLF_PIXCLK_RESYNC_CNTL 0x007e71#define regPHYPLLF_PIXCLK_RESYNC_CNTL 0x007e
drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c+1−0
@@ -1777,6 +1777,7 @@ static struct resource_funcs dcn314_res_pool_funcs = { · 1776 unmodified lines
1777 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,1777 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1778 .get_panel_config_defaults = dcn314_get_panel_config_defaults,1778 .get_panel_config_defaults = dcn314_get_panel_config_defaults,
1779 .get_preferred_eng_id_dpia = dcn314_get_preferred_eng_id_dpia,1779 .get_preferred_eng_id_dpia = dcn314_get_preferred_eng_id_dpia,
1780 .get_det_buffer_size = dcn31_get_det_buffer_size,
1780};1781};
1781 1782
1782static struct clock_source *dcn30_clock_source_create(1783static struct clock_source *dcn30_clock_source_create(
drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c+1−0
@@ -1845,6 +1845,7 @@ static struct resource_funcs dcn315_res_pool_funcs = { · 1844 unmodified lines
1845 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,1845 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1846 .get_panel_config_defaults = dcn315_get_panel_config_defaults,1846 .get_panel_config_defaults = dcn315_get_panel_config_defaults,
1847 .get_power_profile = dcn315_get_power_profile,1847 .get_power_profile = dcn315_get_power_profile,
1848 .get_det_buffer_size = dcn31_get_det_buffer_size,
1848};1849};
1849 1850
1850static bool dcn315_resource_construct(1851static bool dcn315_resource_construct(
drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c+1−0
@@ -1719,6 +1719,7 @@ static struct resource_funcs dcn316_res_pool_funcs = { · 1718 unmodified lines
1719 .update_bw_bounding_box = dcn316_update_bw_bounding_box,1719 .update_bw_bounding_box = dcn316_update_bw_bounding_box,
1720 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,1720 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1721 .get_panel_config_defaults = dcn316_get_panel_config_defaults,1721 .get_panel_config_defaults = dcn316_get_panel_config_defaults,
1722 .get_det_buffer_size = dcn31_get_det_buffer_size,
1722};1723};
1723 1724
1724static bool dcn316_resource_construct(1725static bool dcn316_resource_construct(
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c+2−0
@@ -2189,6 +2189,7 @@ static bool dcn32_resource_construct( · 2188 unmodified lines
2189 dc->caps.dmcub_support = true;2189 dc->caps.dmcub_support = true;
2190 dc->caps.seamless_odm = true;2190 dc->caps.seamless_odm = true;
2191 dc->caps.max_v_total = (1 << 15) - 1;2191 dc->caps.max_v_total = (1 << 15) - 1;
2192 dc->caps.vtotal_limited_by_fp2 = true;
2192 2193
2193 /* Color pipeline capabilities */2194 /* Color pipeline capabilities */
2194 dc->caps.color.dpp.dcn_arch = 1;2195 dc->caps.color.dpp.dcn_arch = 1;
@@ -2803,6 +2804,7 @@ struct pipe_ctx *dcn32_acquire_free_pipe_as_secondary_opp_head( · 608 unmodified lines
2803 free_pipe->plane_res.xfm = pool->transforms[free_pipe_idx];2804 free_pipe->plane_res.xfm = pool->transforms[free_pipe_idx];
2804 free_pipe->plane_res.dpp = pool->dpps[free_pipe_idx];2805 free_pipe->plane_res.dpp = pool->dpps[free_pipe_idx];
2805 free_pipe->plane_res.mpcc_inst = pool->dpps[free_pipe_idx]->inst;2806 free_pipe->plane_res.mpcc_inst = pool->dpps[free_pipe_idx]->inst;
2807 free_pipe->hblank_borrow = otg_master->hblank_borrow;
2806 if (free_pipe->stream->timing.flags.DSC == 1) {2808 if (free_pipe->stream->timing.flags.DSC == 1) {
2807 dcn20_acquire_dsc(free_pipe->stream->ctx->dc,2809 dcn20_acquire_dsc(free_pipe->stream->ctx->dc,
2808 &new_ctx->res_ctx,2810 &new_ctx->res_ctx,
drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c+1−0
@@ -1742,6 +1742,7 @@ static bool dcn321_resource_construct( · 1741 unmodified lines
1742 dc->caps.extended_aux_timeout_support = true;1742 dc->caps.extended_aux_timeout_support = true;
1743 dc->caps.dmcub_support = true;1743 dc->caps.dmcub_support = true;
1744 dc->caps.max_v_total = (1 << 15) - 1;1744 dc->caps.max_v_total = (1 << 15) - 1;
1745 dc->caps.vtotal_limited_by_fp2 = true;
1745 1746
1746 /* Color pipeline capabilities */1747 /* Color pipeline capabilities */
1747 dc->caps.color.dpp.dcn_arch = 1;1748 dc->caps.color.dpp.dcn_arch = 1;
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c+2−0
@@ -1778,6 +1778,7 @@ static struct resource_funcs dcn35_res_pool_funcs = { · 1777 unmodified lines
1778 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,1778 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1779 .get_panel_config_defaults = dcn35_get_panel_config_defaults,1779 .get_panel_config_defaults = dcn35_get_panel_config_defaults,
1780 .get_preferred_eng_id_dpia = dcn35_get_preferred_eng_id_dpia,1780 .get_preferred_eng_id_dpia = dcn35_get_preferred_eng_id_dpia,
1781 .get_det_buffer_size = dcn31_get_det_buffer_size,
1781};1782};
1782 1783
1783static bool dcn35_resource_construct(1784static bool dcn35_resource_construct(
@@ -1849,6 +1850,7 @@ static bool dcn35_resource_construct( · 65 unmodified lines
1849 dc->caps.zstate_support = true;1850 dc->caps.zstate_support = true;
1850 dc->caps.ips_support = true;1851 dc->caps.ips_support = true;
1851 dc->caps.max_v_total = (1 << 15) - 1;1852 dc->caps.max_v_total = (1 << 15) - 1;
1853 dc->caps.vtotal_limited_by_fp2 = true;
1852 1854
1853 /* Color pipeline capabilities */1855 /* Color pipeline capabilities */
1854 dc->caps.color.dpp.dcn_arch = 1;1856 dc->caps.color.dpp.dcn_arch = 1;
drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c+2−0
@@ -1757,6 +1757,7 @@ static struct resource_funcs dcn351_res_pool_funcs = { · 1756 unmodified lines
1757 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,1757 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1758 .get_panel_config_defaults = dcn35_get_panel_config_defaults,1758 .get_panel_config_defaults = dcn35_get_panel_config_defaults,
1759 .get_preferred_eng_id_dpia = dcn351_get_preferred_eng_id_dpia,1759 .get_preferred_eng_id_dpia = dcn351_get_preferred_eng_id_dpia,
1760 .get_det_buffer_size = dcn31_get_det_buffer_size,
1760};1761};
1761 1762
1762static bool dcn351_resource_construct(1763static bool dcn351_resource_construct(
@@ -1828,6 +1829,7 @@ static bool dcn351_resource_construct( · 65 unmodified lines
1828 dc->caps.zstate_support = true;1829 dc->caps.zstate_support = true;
1829 dc->caps.ips_support = true;1830 dc->caps.ips_support = true;
1830 dc->caps.max_v_total = (1 << 15) - 1;1831 dc->caps.max_v_total = (1 << 15) - 1;
1832 dc->caps.vtotal_limited_by_fp2 = true;
1831 1833
1832 /* Color pipeline capabilities */1834 /* Color pipeline capabilities */
1833 dc->caps.color.dpp.dcn_arch = 1;1835 dc->caps.color.dpp.dcn_arch = 1;
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c+1−0
@@ -1864,6 +1864,7 @@ static bool dcn401_resource_construct( · 1863 unmodified lines
1864 dc->caps.extended_aux_timeout_support = true;1864 dc->caps.extended_aux_timeout_support = true;
1865 dc->caps.dmcub_support = true;1865 dc->caps.dmcub_support = true;
1866 dc->caps.max_v_total = (1 << 15) - 1;1866 dc->caps.max_v_total = (1 << 15) - 1;
1867 dc->caps.vtotal_limited_by_fp2 = true;
1867 1868
1868 if (ASICREV_IS_GC_12_0_1_A0(dc->ctx->asic_id.hw_internal_rev))1869 if (ASICREV_IS_GC_12_0_1_A0(dc->ctx->asic_id.hw_internal_rev))
1869 dc->caps.dcc_plane_width_limit = 7680;1870 dc->caps.dcc_plane_width_limit = 7680;
drivers/gpu/drm/amd/display/modules/freesync/freesync.c+12−1
@@ -122,6 +122,17 @@ static unsigned int calc_duration_in_us_from_v_total( · 121 unmodified lines
122 return duration_in_us;122 return duration_in_us;
123}123}
124 124
125static unsigned int calc_max_hardware_v_total(const struct dc_stream_state *stream)
126{
127 unsigned int max_hw_v_total = stream->ctx->dc->caps.max_v_total;
128
129 if (stream->ctx->dc->caps.vtotal_limited_by_fp2) {
130 max_hw_v_total -= stream->timing.v_front_porch + 1;
131 }
132
133 return max_hw_v_total;
134}
135
125unsigned int mod_freesync_calc_v_total_from_refresh(136unsigned int mod_freesync_calc_v_total_from_refresh(
126 const struct dc_stream_state *stream,137 const struct dc_stream_state *stream,
127 unsigned int refresh_in_uhz)138 unsigned int refresh_in_uhz)
@@ -1016,7 +1027,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, · 888 unmodified lines
1016 1027
1017 if (stream->ctx->dc->caps.max_v_total != 0 && stream->timing.h_total != 0) {1028 if (stream->ctx->dc->caps.max_v_total != 0 && stream->timing.h_total != 0) {
1018 min_hardware_refresh_in_uhz = div64_u64((stream->timing.pix_clk_100hz * 100000000ULL),1029 min_hardware_refresh_in_uhz = div64_u64((stream->timing.pix_clk_100hz * 100000000ULL),
1019 (stream->timing.h_total * (long long)stream->ctx->dc->caps.max_v_total));1030 (stream->timing.h_total * (long long)calc_max_hardware_v_total(stream)));
1020 }1031 }
1021 /* Limit minimum refresh rate to what can be supported by hardware */1032 /* Limit minimum refresh rate to what can be supported by hardware */
1022 min_refresh_in_uhz = min_hardware_refresh_in_uhz > in_config->min_refresh_in_uhz ?1033 min_refresh_in_uhz = min_hardware_refresh_in_uhz > in_config->min_refresh_in_uhz ?
drivers/gpu/drm/amd/pm/amdgpu_pm.c+5−1
@@ -1361,7 +1361,11 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, · 1360 unmodified lines
1361 * create a custom set of heuristics, write a string of numbers to the file1361 * create a custom set of heuristics, write a string of numbers to the file
1362 * starting with the number of the custom profile along with a setting1362 * starting with the number of the custom profile along with a setting
1363 * for each heuristic parameter. Due to differences across asic families1363 * for each heuristic parameter. Due to differences across asic families
1364 * the heuristic parameters vary from family to family.1364 * the heuristic parameters vary from family to family. Additionally,
1365 * you can apply the custom heuristics to different clock domains. Each
1366 * clock domain is considered a distinct operation so if you modify the
1367 * gfxclk heuristics and then the memclk heuristics, the all of the
1368 * custom heuristics will be retained until you switch to another profile.
1365 *1369 *
1366 */1370 */
1367 1371
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c+92−77
@@ -72,6 +72,10 @@ static int smu_set_power_limit(void *handle, uint32_t limit); · 71 unmodified lines
72static int smu_set_fan_speed_rpm(void *handle, uint32_t speed);72static int smu_set_fan_speed_rpm(void *handle, uint32_t speed);
73static int smu_set_gfx_cgpg(struct smu_context *smu, bool enabled);73static int smu_set_gfx_cgpg(struct smu_context *smu, bool enabled);
74static int smu_set_mp1_state(void *handle, enum pp_mp1_state mp1_state);74static int smu_set_mp1_state(void *handle, enum pp_mp1_state mp1_state);
75static void smu_power_profile_mode_get(struct smu_context *smu,
76 enum PP_SMC_POWER_PROFILE profile_mode);
77static void smu_power_profile_mode_put(struct smu_context *smu,
78 enum PP_SMC_POWER_PROFILE profile_mode);
75 79
76static int smu_sys_get_pp_feature_mask(void *handle,80static int smu_sys_get_pp_feature_mask(void *handle,
77 char *buf)81 char *buf)
@@ -1259,42 +1263,19 @@ static int smu_sw_init(struct amdgpu_ip_block *ip_block) · 1181 unmodified lines
1259 INIT_WORK(&smu->interrupt_work, smu_interrupt_work_fn);1263 INIT_WORK(&smu->interrupt_work, smu_interrupt_work_fn);
1260 atomic64_set(&smu->throttle_int_counter, 0);1264 atomic64_set(&smu->throttle_int_counter, 0);
1261 smu->watermarks_bitmap = 0;1265 smu->watermarks_bitmap = 0;
1262 smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
1263 smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
1264 smu->user_dpm_profile.user_workload_mask = 0;
1265 1266
1266 atomic_set(&smu->smu_power.power_gate.vcn_gated, 1);1267 atomic_set(&smu->smu_power.power_gate.vcn_gated, 1);
1267 atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1);1268 atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1);
1268 atomic_set(&smu->smu_power.power_gate.vpe_gated, 1);1269 atomic_set(&smu->smu_power.power_gate.vpe_gated, 1);
1269 atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1);1270 atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1);
1270 1271
1271 smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
1272 smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
1273 smu->workload_priority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
1274 smu->workload_priority[PP_SMC_POWER_PROFILE_VIDEO] = 3;
1275 smu->workload_priority[PP_SMC_POWER_PROFILE_VR] = 4;
1276 smu->workload_priority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
1277 smu->workload_priority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
1278
1279 if (smu->is_apu ||1272 if (smu->is_apu ||
1280 !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D)) {1273 !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D))
1281 smu->driver_workload_mask =1274 smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
1282 1 << smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];1275 else
1283 } else {1276 smu->power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
1284 smu->driver_workload_mask =1277 smu_power_profile_mode_get(smu, smu->power_profile_mode);
1285 1 << smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D];1278
1286 smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
1287 }
1288
1289 smu->workload_mask = smu->driver_workload_mask |
1290 smu->user_dpm_profile.user_workload_mask;
1291 smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
1292 smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
1293 smu->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;
1294 smu->workload_setting[3] = PP_SMC_POWER_PROFILE_VIDEO;
1295 smu->workload_setting[4] = PP_SMC_POWER_PROFILE_VR;
1296 smu->workload_setting[5] = PP_SMC_POWER_PROFILE_COMPUTE;
1297 smu->workload_setting[6] = PP_SMC_POWER_PROFILE_CUSTOM;
1298 smu->display_config = &adev->pm.pm_display_cfg;1279 smu->display_config = &adev->pm.pm_display_cfg;
1299 1280
1300 smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;1281 smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
@@ -1347,6 +1328,11 @@ static int smu_sw_fini(struct amdgpu_ip_block *ip_block) · 46 unmodified lines
1347 return ret;1328 return ret;
1348 }1329 }
1349 1330
1331 if (smu->custom_profile_params) {
1332 kfree(smu->custom_profile_params);
1333 smu->custom_profile_params = NULL;
1334 }
1335
1350 smu_fini_microcode(smu);1336 smu_fini_microcode(smu);
1351 1337
1352 return 0;1338 return 0;
@@ -2131,6 +2117,9 @@ static int smu_suspend(struct amdgpu_ip_block *ip_block) · 778 unmodified lines
2131 if (!ret)2117 if (!ret)
2132 adev->gfx.gfx_off_entrycount = count;2118 adev->gfx.gfx_off_entrycount = count;
2133 2119
2120 /* clear this on suspend so it will get reprogrammed on resume */
2121 smu->workload_mask = 0;
2122
2134 return 0;2123 return 0;
2135}2124}
2136 2125
@@ -2243,25 +2232,49 @@ static int smu_enable_umd_pstate(void *handle, · 106 unmodified lines
2243}2232}
2244 2233
2245static int smu_bump_power_profile_mode(struct smu_context *smu,2234static int smu_bump_power_profile_mode(struct smu_context *smu,
2246 long *param,2235 long *custom_params,
2247 uint32_t param_size)2236 u32 custom_params_max_idx)
2248{2237{
2249 int ret = 0;2238 u32 workload_mask = 0;
2239 int i, ret = 0;
2240
2241 for (i = 0; i < PP_SMC_POWER_PROFILE_COUNT; i++) {
2242 if (smu->workload_refcount[i])
2243 workload_mask |= 1 << i;
2244 }
2245
2246 if (smu->workload_mask == workload_mask)
2247 return 0;
2250 2248
2251 if (smu->ppt_funcs->set_power_profile_mode)2249 if (smu->ppt_funcs->set_power_profile_mode)
2252 ret = smu->ppt_funcs->set_power_profile_mode(smu, param, param_size);2250 ret = smu->ppt_funcs->set_power_profile_mode(smu, workload_mask,
2251 custom_params,
2252 custom_params_max_idx);
2253
2254 if (!ret)
2255 smu->workload_mask = workload_mask;
2253 2256
2254 return ret;2257 return ret;
2255}2258}
2256 2259
2260static void smu_power_profile_mode_get(struct smu_context *smu,
2261 enum PP_SMC_POWER_PROFILE profile_mode)
2262{
2263 smu->workload_refcount[profile_mode]++;
2264}
2265
2266static void smu_power_profile_mode_put(struct smu_context *smu,
2267 enum PP_SMC_POWER_PROFILE profile_mode)
2268{
2269 if (smu->workload_refcount[profile_mode])
2270 smu->workload_refcount[profile_mode]--;
2271}
2272
2257static int smu_adjust_power_state_dynamic(struct smu_context *smu,2273static int smu_adjust_power_state_dynamic(struct smu_context *smu,
2258 enum amd_dpm_forced_level level,2274 enum amd_dpm_forced_level level,
2259 bool skip_display_settings,2275 bool skip_display_settings)
2260 bool init)
2261{2276{
2262 int ret = 0;2277 int ret = 0;
2263 int index = 0;
2264 long workload[1];
2265 struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);2278 struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
2266 2279
2267 if (!skip_display_settings) {2280 if (!skip_display_settings) {
@@ -2298,14 +2311,8 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, · 30 unmodified lines
2298 }2311 }
2299 2312
2300 if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&2313 if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
2301 smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {2314 smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
2302 index = fls(smu->workload_mask);2315 smu_bump_power_profile_mode(smu, NULL, 0);
2303 index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
2304 workload[0] = smu->workload_setting[index];
2305
2306 if (init || smu->power_profile_mode != workload[0])
2307 smu_bump_power_profile_mode(smu, workload, 0);
2308 }
2309 2316
2310 return ret;2317 return ret;
2311}2318}
@@ -2324,13 +2331,13 @@ static int smu_handle_task(struct smu_context *smu, · 12 unmodified lines
2324 ret = smu_pre_display_config_changed(smu);2331 ret = smu_pre_display_config_changed(smu);
2325 if (ret)2332 if (ret)
2326 return ret;2333 return ret;
2327 ret = smu_adjust_power_state_dynamic(smu, level, false, false);2334 ret = smu_adjust_power_state_dynamic(smu, level, false);
2328 break;2335 break;
2329 case AMD_PP_TASK_COMPLETE_INIT:2336 case AMD_PP_TASK_COMPLETE_INIT:
2330 ret = smu_adjust_power_state_dynamic(smu, level, true, true);2337 ret = smu_adjust_power_state_dynamic(smu, level, true);
2331 break;2338 break;
2332 case AMD_PP_TASK_READJUST_POWER_STATE:2339 case AMD_PP_TASK_READJUST_POWER_STATE:
2333 ret = smu_adjust_power_state_dynamic(smu, level, true, false);2340 ret = smu_adjust_power_state_dynamic(smu, level, true);
2334 break;2341 break;
2335 default:2342 default:
2336 break;2343 break;
@@ -2352,12 +2359,11 @@ static int smu_handle_dpm_task(void *handle, · 15 unmodified lines
2352 2359
2353static int smu_switch_power_profile(void *handle,2360static int smu_switch_power_profile(void *handle,
2354 enum PP_SMC_POWER_PROFILE type,2361 enum PP_SMC_POWER_PROFILE type,
2355 bool en)2362 bool enable)
2356{2363{
2357 struct smu_context *smu = handle;2364 struct smu_context *smu = handle;
2358 struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);2365 struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
2359 long workload[1];2366 int ret;
2360 uint32_t index;
2361 2367
2362 if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)2368 if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
2363 return -EOPNOTSUPP;2369 return -EOPNOTSUPP;
@@ -2365,24 +2371,21 @@ static int smu_switch_power_profile(void *handle, · 1 unmodified line
2365 if (!(type < PP_SMC_POWER_PROFILE_CUSTOM))2371 if (!(type < PP_SMC_POWER_PROFILE_CUSTOM))
2366 return -EINVAL;2372 return -EINVAL;
2367 2373
2368 if (!en) {
2369 smu->driver_workload_mask &= ~(1 << smu->workload_priority[type]);
2370 index = fls(smu->workload_mask);
2371 index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
2372 workload[0] = smu->workload_setting[index];
2373 } else {
2374 smu->driver_workload_mask |= (1 << smu->workload_priority[type]);
2375 index = fls(smu->workload_mask);
2376 index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
2377 workload[0] = smu->workload_setting[index];
2378 }
2379
2380 smu->workload_mask = smu->driver_workload_mask |
2381 smu->user_dpm_profile.user_workload_mask;
2382
2383 if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&2374 if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
2384 smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)2375 smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
2385 smu_bump_power_profile_mode(smu, workload, 0);2376 if (enable)
2377 smu_power_profile_mode_get(smu, type);
2378 else
2379 smu_power_profile_mode_put(smu, type);
2380 ret = smu_bump_power_profile_mode(smu, NULL, 0);
2381 if (ret) {
2382 if (enable)
2383 smu_power_profile_mode_put(smu, type);
2384 else
2385 smu_power_profile_mode_get(smu, type);
2386 return ret;
2387 }
2388 }
2386 2389
2387 return 0;2390 return 0;
2388}2391}
@@ -3074,21 +3077,33 @@ static int smu_set_power_profile_mode(void *handle, · 685 unmodified lines
3074 uint32_t param_size)3077 uint32_t param_size)
3075{3078{
3076 struct smu_context *smu = handle;3079 struct smu_context *smu = handle;
3077 int ret;3080 bool custom = false;
3081 int ret = 0;
3078 3082
3079 if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled ||3083 if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled ||
3080 !smu->ppt_funcs->set_power_profile_mode)3084 !smu->ppt_funcs->set_power_profile_mode)
3081 return -EOPNOTSUPP;3085 return -EOPNOTSUPP;
3082 3086
3083 if (smu->user_dpm_profile.user_workload_mask &3087 if (param[param_size] == PP_SMC_POWER_PROFILE_CUSTOM) {
3084 (1 << smu->workload_priority[param[param_size]]))3088 custom = true;
3085 return 0;3089 /* clear frontend mask so custom changes propogate */
3090 smu->workload_mask = 0;
3091 }
3086 3092
3087 smu->user_dpm_profile.user_workload_mask =3093 if ((param[param_size] != smu->power_profile_mode) || custom) {
3088 (1 << smu->workload_priority[param[param_size]]);3094 /* clear the old user preference */
3089 smu->workload_mask = smu->user_dpm_profile.user_workload_mask |3095 smu_power_profile_mode_put(smu, smu->power_profile_mode);
3090 smu->driver_workload_mask;3096 /* set the new user preference */
3091 ret = smu_bump_power_profile_mode(smu, param, param_size);3097 smu_power_profile_mode_get(smu, param[param_size]);
3098 ret = smu_bump_power_profile_mode(smu,
3099 custom ? param : NULL,
3100 custom ? param_size : 0);
3101 if (ret)
3102 smu_power_profile_mode_put(smu, param[param_size]);
3103 else
3104 /* store the user's preference */
3105 smu->power_profile_mode = param[param_size];
3106 }
3092 3107
3093 return ret;3108 return ret;
3094}3109}
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h+10−7
@@ -240,7 +240,6 @@ struct smu_user_dpm_profile { · 239 unmodified lines
240 /* user clock state information */240 /* user clock state information */
241 uint32_t clk_mask[SMU_CLK_COUNT];241 uint32_t clk_mask[SMU_CLK_COUNT];
242 uint32_t clk_dependency;242 uint32_t clk_dependency;
243 uint32_t user_workload_mask;
244};243};
245 244
246#define SMU_TABLE_INIT(tables, table_id, s, a, d) \245#define SMU_TABLE_INIT(tables, table_id, s, a, d) \
@@ -557,12 +556,13 @@ struct smu_context { · 310 unmodified lines
557 uint32_t hard_min_uclk_req_from_dal;556 uint32_t hard_min_uclk_req_from_dal;
558 bool disable_uclk_switch;557 bool disable_uclk_switch;
559 558
559 /* asic agnostic workload mask */
560 uint32_t workload_mask;560 uint32_t workload_mask;
561 uint32_t driver_workload_mask;561 /* default/user workload preference */
562 uint32_t workload_priority[WORKLOAD_POLICY_MAX];
563 uint32_t workload_setting[WORKLOAD_POLICY_MAX];
564 uint32_t power_profile_mode;562 uint32_t power_profile_mode;
565 uint32_t default_power_profile_mode;563 uint32_t workload_refcount[PP_SMC_POWER_PROFILE_COUNT];
564 /* backend specific custom workload settings */
565 long *custom_profile_params;
566 bool pm_enabled;566 bool pm_enabled;
567 bool is_apu;567 bool is_apu;
568 568
@@ -733,9 +733,12 @@ struct pptable_funcs { · 164 unmodified lines
733 * @set_power_profile_mode: Set a power profile mode. Also used to733 * @set_power_profile_mode: Set a power profile mode. Also used to
734 * create/set custom power profile modes.734 * create/set custom power profile modes.
735 * &input: Power profile mode parameters.735 * &input: Power profile mode parameters.
736 * &size: Size of &input.736 * &workload_mask: mask of workloads to enable
737 * &custom_params: custom profile parameters
738 * &custom_params_max_idx: max valid idx into custom_params
737 */739 */
738 int (*set_power_profile_mode)(struct smu_context *smu, long *input, uint32_t size);740 int (*set_power_profile_mode)(struct smu_context *smu, u32 workload_mask,
741 long *custom_params, u32 custom_params_max_idx);
739 742
740 /**743 /**
741 * @dpm_set_vcn_enable: Enable/disable VCN engine dynamic power744 * @dpm_set_vcn_enable: Enable/disable VCN engine dynamic power
drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c+95−72
@@ -1445,97 +1445,120 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu, · 1444 unmodified lines
1445 return size;1445 return size;
1446}1446}
1447 1447
1448static int arcturus_set_power_profile_mode(struct smu_context *smu,1448#define ARCTURUS_CUSTOM_PARAMS_COUNT 10
1449 long *input,1449#define ARCTURUS_CUSTOM_PARAMS_CLOCK_COUNT 2
1450 uint32_t size)1450#define ARCTURUS_CUSTOM_PARAMS_SIZE (ARCTURUS_CUSTOM_PARAMS_CLOCK_COUNT * ARCTURUS_CUSTOM_PARAMS_COUNT * sizeof(long))
1451
1452static int arcturus_set_power_profile_mode_coeff(struct smu_context *smu,
1453 long *input)
1451{1454{
1452 DpmActivityMonitorCoeffInt_t activity_monitor;1455 DpmActivityMonitorCoeffInt_t activity_monitor;
1453 int workload_type = 0;1456 int ret, idx;
1454 uint32_t profile_mode = input[size];
1455 int ret = 0;
1456 1457
1457 if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {1458 ret = smu_cmn_update_table(smu,
1458 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);1459 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1459 return -EINVAL;1460 WORKLOAD_PPLIB_CUSTOM_BIT,
1461 (void *)(&activity_monitor),
1462 false);
1463 if (ret) {
1464 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1465 return ret;
1460 }1466 }
1461 1467
1462 if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&1468 idx = 0 * ARCTURUS_CUSTOM_PARAMS_COUNT;
1463 (smu->smc_fw_version >= 0x360d00)) {1469 if (input[idx]) {
1464 if (size != 10)1470 /* Gfxclk */
1465 return -EINVAL;1471 activity_monitor.Gfx_FPS = input[idx + 1];
1472 activity_monitor.Gfx_UseRlcBusy = input[idx + 2];
1473 activity_monitor.Gfx_MinActiveFreqType = input[idx + 3];
1474 activity_monitor.Gfx_MinActiveFreq = input[idx + 4];
1475 activity_monitor.Gfx_BoosterFreqType = input[idx + 5];
1476 activity_monitor.Gfx_BoosterFreq = input[idx + 6];
1477 activity_monitor.Gfx_PD_Data_limit_c = input[idx + 7];
1478 activity_monitor.Gfx_PD_Data_error_coeff = input[idx + 8];
1479 activity_monitor.Gfx_PD_Data_error_rate_coeff = input[idx + 9];
1480 }
1481 idx = 1 * ARCTURUS_CUSTOM_PARAMS_COUNT;
1482 if (input[idx]) {
1483 /* Uclk */
1484 activity_monitor.Mem_FPS = input[idx + 1];
1485 activity_monitor.Mem_UseRlcBusy = input[idx + 2];
1486 activity_monitor.Mem_MinActiveFreqType = input[idx + 3];
1487 activity_monitor.Mem_MinActiveFreq = input[idx + 4];
1488 activity_monitor.Mem_BoosterFreqType = input[idx + 5];
1489 activity_monitor.Mem_BoosterFreq = input[idx + 6];
1490 activity_monitor.Mem_PD_Data_limit_c = input[idx + 7];
1491 activity_monitor.Mem_PD_Data_error_coeff = input[idx + 8];
1492 activity_monitor.Mem_PD_Data_error_rate_coeff = input[idx + 9];
1493 }
1466 1494
1467 ret = smu_cmn_update_table(smu,1495 ret = smu_cmn_update_table(smu,
1468 SMU_TABLE_ACTIVITY_MONITOR_COEFF,1496 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1469 WORKLOAD_PPLIB_CUSTOM_BIT,1497 WORKLOAD_PPLIB_CUSTOM_BIT,
1470 (void *)(&activity_monitor),1498 (void *)(&activity_monitor),
1471 false);1499 true);
1472 if (ret) {1500 if (ret) {
1473 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);1501 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
1474 return ret;1502 return ret;
1475 }1503 }
1476 1504
1477 switch (input[0]) {1505 return ret;
1478 case 0: /* Gfxclk */1506}
1479 activity_monitor.Gfx_FPS = input[1];1507
1480 activity_monitor.Gfx_UseRlcBusy = input[2];1508static int arcturus_set_power_profile_mode(struct smu_context *smu,
1481 activity_monitor.Gfx_MinActiveFreqType = input[3];1509 u32 workload_mask,
1482 activity_monitor.Gfx_MinActiveFreq = input[4];1510 long *custom_params,
1483 activity_monitor.Gfx_BoosterFreqType = input[5];1511 u32 custom_params_max_idx)
1484 activity_monitor.Gfx_BoosterFreq = input[6];1512{
1485 activity_monitor.Gfx_PD_Data_limit_c = input[7];1513 u32 backend_workload_mask = 0;
1486 activity_monitor.Gfx_PD_Data_error_coeff = input[8];1514 int ret, idx = -1, i;
1487 activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9];1515
1488 break;1516 smu_cmn_get_backend_workload_mask(smu, workload_mask,
1489 case 1: /* Uclk */1517 &backend_workload_mask);
1490 activity_monitor.Mem_FPS = input[1];1518
1491 activity_monitor.Mem_UseRlcBusy = input[2];1519 if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) {
1492 activity_monitor.Mem_MinActiveFreqType = input[3];1520 if (smu->smc_fw_version < 0x360d00)
1493 activity_monitor.Mem_MinActiveFreq = input[4];
1494 activity_monitor.Mem_BoosterFreqType = input[5];
1495 activity_monitor.Mem_BoosterFreq = input[6];
1496 activity_monitor.Mem_PD_Data_limit_c = input[7];
1497 activity_monitor.Mem_PD_Data_error_coeff = input[8];
1498 activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
1499 break;
1500 default:
1501 return -EINVAL;1521 return -EINVAL;
1522 if (!smu->custom_profile_params) {
1523 smu->custom_profile_params =
1524 kzalloc(ARCTURUS_CUSTOM_PARAMS_SIZE, GFP_KERNEL);
1525 if (!smu->custom_profile_params)
1526 return -ENOMEM;
1502 }1527 }
1503 1528 if (custom_params && custom_params_max_idx) {
1504 ret = smu_cmn_update_table(smu,1529 if (custom_params_max_idx != ARCTURUS_CUSTOM_PARAMS_COUNT)
1505 SMU_TABLE_ACTIVITY_MONITOR_COEFF,1530 return -EINVAL;
1506 WORKLOAD_PPLIB_CUSTOM_BIT,1531 if (custom_params[0] >= ARCTURUS_CUSTOM_PARAMS_CLOCK_COUNT)
1507 (void *)(&activity_monitor),1532 return -EINVAL;
1508 true);1533 idx = custom_params[0] * ARCTURUS_CUSTOM_PARAMS_COUNT;
1534 smu->custom_profile_params[idx] = 1;
1535 for (i = 1; i < custom_params_max_idx; i++)
1536 smu->custom_profile_params[idx + i] = custom_params[i];
1537 }
1538 ret = arcturus_set_power_profile_mode_coeff(smu,
1539 smu->custom_profile_params);
1509 if (ret) {1540 if (ret) {
1510 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);1541 if (idx != -1)
1542 smu->custom_profile_params[idx] = 0;
1511 return ret;1543 return ret;
1512 }1544 }
1513 }1545 } else if (smu->custom_profile_params) {
1514 1546 memset(smu->custom_profile_params, 0, ARCTURUS_CUSTOM_PARAMS_SIZE);
1515 /*
1516 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1517 * Not all profile modes are supported on arcturus.
1518 */
1519 workload_type = smu_cmn_to_asic_specific_index(smu,
1520 CMN2ASIC_MAPPING_WORKLOAD,
1521 profile_mode);
1522 if (workload_type < 0) {
1523 dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on arcturus\n", profile_mode);
1524 return -EINVAL;
1525 }1547 }
1526 1548
1527 ret = smu_cmn_send_smc_msg_with_param(smu,1549 ret = smu_cmn_send_smc_msg_with_param(smu,
1528 SMU_MSG_SetWorkloadMask,1550 SMU_MSG_SetWorkloadMask,
1529 smu->workload_mask,1551 backend_workload_mask,
1530 NULL);1552 NULL);
1531 if (ret) {1553 if (ret) {
1532 dev_err(smu->adev->dev, "Fail to set workload type %d\n", workload_type);1554 dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n",
1555 workload_mask);
1556 if (idx != -1)
1557 smu->custom_profile_params[idx] = 0;
1533 return ret;1558 return ret;
1534 }1559 }
1535 1560
1536 smu_cmn_assign_power_profile(smu);1561 return ret;
1537
1538 return 0;
1539}1562}
1540 1563
1541static int arcturus_set_performance_level(struct smu_context *smu,1564static int arcturus_set_performance_level(struct smu_context *smu,
drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c+101−69
@@ -2006,90 +2006,122 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) · 2005 unmodified lines
2006 return size;2006 return size;
2007}2007}
2008 2008
2009static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)2009#define NAVI10_CUSTOM_PARAMS_COUNT 10
2010#define NAVI10_CUSTOM_PARAMS_CLOCKS_COUNT 3
2011#define NAVI10_CUSTOM_PARAMS_SIZE (NAVI10_CUSTOM_PARAMS_CLOCKS_COUNT * NAVI10_CUSTOM_PARAMS_COUNT * sizeof(long))
2012
2013static int navi10_set_power_profile_mode_coeff(struct smu_context *smu,
2014 long *input)
2010{2015{
2011 DpmActivityMonitorCoeffInt_t activity_monitor;2016 DpmActivityMonitorCoeffInt_t activity_monitor;
2012 int workload_type, ret = 0;2017 int ret, idx;
2013 2018
2014 smu->power_profile_mode = input[size];2019 ret = smu_cmn_update_table(smu,
2020 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
2021 (void *)(&activity_monitor), false);
2022 if (ret) {
2023 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
2024 return ret;
2025 }
2015 2026
2016 if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {2027 idx = 0 * NAVI10_CUSTOM_PARAMS_COUNT;
2017 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);2028 if (input[idx]) {
2018 return -EINVAL;2029 /* Gfxclk */
2030 activity_monitor.Gfx_FPS = input[idx + 1];
2031 activity_monitor.Gfx_MinFreqStep = input[idx + 2];
2032 activity_monitor.Gfx_MinActiveFreqType = input[idx + 3];
2033 activity_monitor.Gfx_MinActiveFreq = input[idx + 4];
2034 activity_monitor.Gfx_BoosterFreqType = input[idx + 5];
2035 activity_monitor.Gfx_BoosterFreq = input[idx + 6];
2036 activity_monitor.Gfx_PD_Data_limit_c = input[idx + 7];
2037 activity_monitor.Gfx_PD_Data_error_coeff = input[idx + 8];
2038 activity_monitor.Gfx_PD_Data_error_rate_coeff = input[idx + 9];
2039 }
2040 idx = 1 * NAVI10_CUSTOM_PARAMS_COUNT;
2041 if (input[idx]) {
2042 /* Socclk */
2043 activity_monitor.Soc_FPS = input[idx + 1];
2044 activity_monitor.Soc_MinFreqStep = input[idx + 2];
2045 activity_monitor.Soc_MinActiveFreqType = input[idx + 3];
2046 activity_monitor.Soc_MinActiveFreq = input[idx + 4];
2047 activity_monitor.Soc_BoosterFreqType = input[idx + 5];
2048 activity_monitor.Soc_BoosterFreq = input[idx + 6];
2049 activity_monitor.Soc_PD_Data_limit_c = input[idx + 7];
2050 activity_monitor.Soc_PD_Data_error_coeff = input[idx + 8];
2051 activity_monitor.Soc_PD_Data_error_rate_coeff = input[idx + 9];
2052 }
2053 idx = 2 * NAVI10_CUSTOM_PARAMS_COUNT;
2054 if (input[idx]) {
2055 /* Memclk */
2056 activity_monitor.Mem_FPS = input[idx + 1];
2057 activity_monitor.Mem_MinFreqStep = input[idx + 2];
2058 activity_monitor.Mem_MinActiveFreqType = input[idx + 3];
2059 activity_monitor.Mem_MinActiveFreq = input[idx + 4];
2060 activity_monitor.Mem_BoosterFreqType = input[idx + 5];
2061 activity_monitor.Mem_BoosterFreq = input[idx + 6];
2062 activity_monitor.Mem_PD_Data_limit_c = input[idx + 7];
2063 activity_monitor.Mem_PD_Data_error_coeff = input[idx + 8];
2064 activity_monitor.Mem_PD_Data_error_rate_coeff = input[idx + 9];
2065 }
2066
2067 ret = smu_cmn_update_table(smu,
2068 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
2069 (void *)(&activity_monitor), true);
2070 if (ret) {
2071 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
2072 return ret;
2019 }2073 }
2020 2074
2021 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {2075 return ret;
2022 if (size != 10)2076}
2023 return -EINVAL;
2024 2077
2025 ret = smu_cmn_update_table(smu,2078static int navi10_set_power_profile_mode(struct smu_context *smu,
2026 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,2079 u32 workload_mask,
2027 (void *)(&activity_monitor), false);2080 long *custom_params,
2028 if (ret) {2081 u32 custom_params_max_idx)
2029 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);2082{
2030 return ret;2083 u32 backend_workload_mask = 0;
2031 }2084 int ret, idx = -1, i;
2032 2085
2033 switch (input[0]) {2086 smu_cmn_get_backend_workload_mask(smu, workload_mask,
2034 case 0: /* Gfxclk */2087 &backend_workload_mask);
2035 activity_monitor.Gfx_FPS = input[1];
2036 activity_monitor.Gfx_MinFreqStep = input[2];
2037 activity_monitor.Gfx_MinActiveFreqType = input[3];
2038 activity_monitor.Gfx_MinActiveFreq = input[4];
2039 activity_monitor.Gfx_BoosterFreqType = input[5];
2040 activity_monitor.Gfx_BoosterFreq = input[6];
2041 activity_monitor.Gfx_PD_Data_limit_c = input[7];
2042 activity_monitor.Gfx_PD_Data_error_coeff = input[8];
2043 activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9];
2044 break;
2045 case 1: /* Socclk */
2046 activity_monitor.Soc_FPS = input[1];
2047 activity_monitor.Soc_MinFreqStep = input[2];
2048 activity_monitor.Soc_MinActiveFreqType = input[3];
2049 activity_monitor.Soc_MinActiveFreq = input[4];
2050 activity_monitor.Soc_BoosterFreqType = input[5];
2051 activity_monitor.Soc_BoosterFreq = input[6];
2052 activity_monitor.Soc_PD_Data_limit_c = input[7];
2053 activity_monitor.Soc_PD_Data_error_coeff = input[8];
2054 activity_monitor.Soc_PD_Data_error_rate_coeff = input[9];
2055 break;
2056 case 2: /* Memclk */
2057 activity_monitor.Mem_FPS = input[1];
2058 activity_monitor.Mem_MinFreqStep = input[2];
2059 activity_monitor.Mem_MinActiveFreqType = input[3];
2060 activity_monitor.Mem_MinActiveFreq = input[4];
2061 activity_monitor.Mem_BoosterFreqType = input[5];
2062 activity_monitor.Mem_BoosterFreq = input[6];
2063 activity_monitor.Mem_PD_Data_limit_c = input[7];
2064 activity_monitor.Mem_PD_Data_error_coeff = input[8];
2065 activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
2066 break;
2067 default:
2068 return -EINVAL;
2069 }
2070 2088
2071 ret = smu_cmn_update_table(smu,2089 if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) {
2072 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,2090 if (!smu->custom_profile_params) {
2073 (void *)(&activity_monitor), true);2091 smu->custom_profile_params = kzalloc(NAVI10_CUSTOM_PARAMS_SIZE, GFP_KERNEL);
2092 if (!smu->custom_profile_params)
2093 return -ENOMEM;
2094 }
2095 if (custom_params && custom_params_max_idx) {
2096 if (custom_params_max_idx != NAVI10_CUSTOM_PARAMS_COUNT)
2097 return -EINVAL;
2098 if (custom_params[0] >= NAVI10_CUSTOM_PARAMS_CLOCKS_COUNT)
2099 return -EINVAL;
2100 idx = custom_params[0] * NAVI10_CUSTOM_PARAMS_COUNT;
2101 smu->custom_profile_params[idx] = 1;
2102 for (i = 1; i < custom_params_max_idx; i++)
2103 smu->custom_profile_params[idx + i] = custom_params[i];
2104 }
2105 ret = navi10_set_power_profile_mode_coeff(smu,
2106 smu->custom_profile_params);
2074 if (ret) {2107 if (ret) {
2075 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);2108 if (idx != -1)
2109 smu->custom_profile_params[idx] = 0;
2076 return ret;2110 return ret;
2077 }2111 }
2112 } else if (smu->custom_profile_params) {
2113 memset(smu->custom_profile_params, 0, NAVI10_CUSTOM_PARAMS_SIZE);
2078 }2114 }
2079 2115
2080 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
2081 workload_type = smu_cmn_to_asic_specific_index(smu,
2082 CMN2ASIC_MAPPING_WORKLOAD,
2083 smu->power_profile_mode);
2084 if (workload_type < 0)
2085 return -EINVAL;
2086
2087 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,2116 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
2088 smu->workload_mask, NULL);2117 backend_workload_mask, NULL);
2089 if (ret)2118 if (ret) {
2090 dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);2119 dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n",
2091 else2120 workload_mask);
2092 smu_cmn_assign_power_profile(smu);2121 if (idx != -1)
2122 smu->custom_profile_params[idx] = 0;
2123 return ret;
2124 }
2093 2125
2094 return ret;2126 return ret;
2095}2127}
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c+102−69
@@ -1708,93 +1708,126 @@ static int sienna_cichlid_get_power_profile_mode(struct smu_context *smu, char * · 1707 unmodified lines
1708 return size;1708 return size;
1709}1709}
1710 1710
1711static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)1711#define SIENNA_CICHLID_CUSTOM_PARAMS_COUNT 10
1712#define SIENNA_CICHLID_CUSTOM_PARAMS_CLOCK_COUNT 3
1713#define SIENNA_CICHLID_CUSTOM_PARAMS_SIZE (SIENNA_CICHLID_CUSTOM_PARAMS_CLOCK_COUNT * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT * sizeof(long))
1714
1715static int sienna_cichlid_set_power_profile_mode_coeff(struct smu_context *smu,
1716 long *input)
1712{1717{
1713 1718
1714 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;1719 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
1715 DpmActivityMonitorCoeffInt_t *activity_monitor =1720 DpmActivityMonitorCoeffInt_t *activity_monitor =
1716 &(activity_monitor_external.DpmActivityMonitorCoeffInt);1721 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
1717 int workload_type, ret = 0;1722 int ret, idx;
1718 1723
1719 smu->power_profile_mode = input[size];1724 ret = smu_cmn_update_table(smu,
1725 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
1726 (void *)(&activity_monitor_external), false);
1727 if (ret) {
1728 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1729 return ret;
1730 }
1720 1731
1721 if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {1732 idx = 0 * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT;
1722 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);1733 if (input[idx]) {
1723 return -EINVAL;1734 /* Gfxclk */
1735 activity_monitor->Gfx_FPS = input[idx + 1];
1736 activity_monitor->Gfx_MinFreqStep = input[idx + 2];
1737 activity_monitor->Gfx_MinActiveFreqType = input[idx + 3];
1738 activity_monitor->Gfx_MinActiveFreq = input[idx + 4];
1739 activity_monitor->Gfx_BoosterFreqType = input[idx + 5];
1740 activity_monitor->Gfx_BoosterFreq = input[idx + 6];
1741 activity_monitor->Gfx_PD_Data_limit_c = input[idx + 7];
1742 activity_monitor->Gfx_PD_Data_error_coeff = input[idx + 8];
1743 activity_monitor->Gfx_PD_Data_error_rate_coeff = input[idx + 9];
1744 }
1745 idx = 1 * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT;
1746 if (input[idx]) {
1747 /* Socclk */
1748 activity_monitor->Fclk_FPS = input[idx + 1];
1749 activity_monitor->Fclk_MinFreqStep = input[idx + 2];
1750 activity_monitor->Fclk_MinActiveFreqType = input[idx + 3];
1751 activity_monitor->Fclk_MinActiveFreq = input[idx + 4];
1752 activity_monitor->Fclk_BoosterFreqType = input[idx + 5];
1753 activity_monitor->Fclk_BoosterFreq = input[idx + 6];
1754 activity_monitor->Fclk_PD_Data_limit_c = input[idx + 7];
1755 activity_monitor->Fclk_PD_Data_error_coeff = input[idx + 8];
1756 activity_monitor->Fclk_PD_Data_error_rate_coeff = input[idx + 9];
1757 }
1758 idx = 2 * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT;
1759 if (input[idx]) {
1760 /* Memclk */
1761 activity_monitor->Mem_FPS = input[idx + 1];
1762 activity_monitor->Mem_MinFreqStep = input[idx + 2];
1763 activity_monitor->Mem_MinActiveFreqType = input[idx + 3];
1764 activity_monitor->Mem_MinActiveFreq = input[idx + 4];
1765 activity_monitor->Mem_BoosterFreqType = input[idx + 5];
1766 activity_monitor->Mem_BoosterFreq = input[idx + 6];
1767 activity_monitor->Mem_PD_Data_limit_c = input[idx + 7];
1768 activity_monitor->Mem_PD_Data_error_coeff = input[idx + 8];
1769 activity_monitor->Mem_PD_Data_error_rate_coeff = input[idx + 9];
1724 }1770 }
1725 1771
1726 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {1772 ret = smu_cmn_update_table(smu,
1727 if (size != 10)1773 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
1728 return -EINVAL;1774 (void *)(&activity_monitor_external), true);
1775 if (ret) {
1776 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
1777 return ret;
1778 }
1729 1779
1730 ret = smu_cmn_update_table(smu,1780 return ret;
1731 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,1781}
1732 (void *)(&activity_monitor_external), false);
1733 if (ret) {
1734 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1735 return ret;
1736 }
1737 1782
1738 switch (input[0]) {1783static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu,
1739 case 0: /* Gfxclk */1784 u32 workload_mask,
1740 activity_monitor->Gfx_FPS = input[1];1785 long *custom_params,
1741 activity_monitor->Gfx_MinFreqStep = input[2];1786 u32 custom_params_max_idx)
1742 activity_monitor->Gfx_MinActiveFreqType = input[3];1787{
1743 activity_monitor->Gfx_MinActiveFreq = input[4];1788 u32 backend_workload_mask = 0;
1744 activity_monitor->Gfx_BoosterFreqType = input[5];1789 int ret, idx = -1, i;
1745 activity_monitor->Gfx_BoosterFreq = input[6];1790
1746 activity_monitor->Gfx_PD_Data_limit_c = input[7];1791 smu_cmn_get_backend_workload_mask(smu, workload_mask,
1747 activity_monitor->Gfx_PD_Data_error_coeff = input[8];1792 &backend_workload_mask);
1748 activity_monitor->Gfx_PD_Data_error_rate_coeff = input[9];
1749 break;
1750 case 1: /* Socclk */
1751 activity_monitor->Fclk_FPS = input[1];
1752 activity_monitor->Fclk_MinFreqStep = input[2];
1753 activity_monitor->Fclk_MinActiveFreqType = input[3];
1754 activity_monitor->Fclk_MinActiveFreq = input[4];
1755 activity_monitor->Fclk_BoosterFreqType = input[5];
1756 activity_monitor->Fclk_BoosterFreq = input[6];
1757 activity_monitor->Fclk_PD_Data_limit_c = input[7];
1758 activity_monitor->Fclk_PD_Data_error_coeff = input[8];
1759 activity_monitor->Fclk_PD_Data_error_rate_coeff = input[9];
1760 break;
1761 case 2: /* Memclk */
1762 activity_monitor->Mem_FPS = input[1];
1763 activity_monitor->Mem_MinFreqStep = input[2];
1764 activity_monitor->Mem_MinActiveFreqType = input[3];
1765 activity_monitor->Mem_MinActiveFreq = input[4];
1766 activity_monitor->Mem_BoosterFreqType = input[5];
1767 activity_monitor->Mem_BoosterFreq = input[6];
1768 activity_monitor->Mem_PD_Data_limit_c = input[7];
1769 activity_monitor->Mem_PD_Data_error_coeff = input[8];
1770 activity_monitor->Mem_PD_Data_error_rate_coeff = input[9];
1771 break;
1772 default:
1773 return -EINVAL;
1774 }
1775 1793
1776 ret = smu_cmn_update_table(smu,1794 if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) {
1777 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,1795 if (!smu->custom_profile_params) {
1778 (void *)(&activity_monitor_external), true);1796 smu->custom_profile_params =
1797 kzalloc(SIENNA_CICHLID_CUSTOM_PARAMS_SIZE, GFP_KERNEL);
1798 if (!smu->custom_profile_params)
1799 return -ENOMEM;
1800 }
1801 if (custom_params && custom_params_max_idx) {
1802 if (custom_params_max_idx != SIENNA_CICHLID_CUSTOM_PARAMS_COUNT)
1803 return -EINVAL;
1804 if (custom_params[0] >= SIENNA_CICHLID_CUSTOM_PARAMS_CLOCK_COUNT)
1805 return -EINVAL;
1806 idx = custom_params[0] * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT;
1807 smu->custom_profile_params[idx] = 1;
1808 for (i = 1; i < custom_params_max_idx; i++)
1809 smu->custom_profile_params[idx + i] = custom_params[i];
1810 }
1811 ret = sienna_cichlid_set_power_profile_mode_coeff(smu,
1812 smu->custom_profile_params);
1779 if (ret) {1813 if (ret) {
1780 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);1814 if (idx != -1)
1815 smu->custom_profile_params[idx] = 0;
1781 return ret;1816 return ret;
1782 }1817 }
1818 } else if (smu->custom_profile_params) {
1819 memset(smu->custom_profile_params, 0, SIENNA_CICHLID_CUSTOM_PARAMS_SIZE);
1783 }1820 }
1784 1821
1785 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1786 workload_type = smu_cmn_to_asic_specific_index(smu,
1787 CMN2ASIC_MAPPING_WORKLOAD,
1788 smu->power_profile_mode);
1789 if (workload_type < 0)
1790 return -EINVAL;
1791
1792 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,1822 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1793 smu->workload_mask, NULL);1823 backend_workload_mask, NULL);
1794 if (ret)1824 if (ret) {
1795 dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);1825 dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n",
1796 else1826 workload_mask);
1797 smu_cmn_assign_power_profile(smu);1827 if (idx != -1)
1828 smu->custom_profile_params[idx] = 0;
1829 return ret;
1830 }
1798 1831
1799 return ret;1832 return ret;
1800}1833}
drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c+13−28
@@ -1056,42 +1056,27 @@ static int vangogh_get_power_profile_mode(struct smu_context *smu, · 1055 unmodified lines
1056 return size;1056 return size;
1057}1057}
1058 1058
1059static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)1059static int vangogh_set_power_profile_mode(struct smu_context *smu,
1060 u32 workload_mask,
1061 long *custom_params,
1062 u32 custom_params_max_idx)
1060{1063{
1061 int workload_type, ret;1064 u32 backend_workload_mask = 0;
1062 uint32_t profile_mode = input[size];1065 int ret;
1063 1066
1064 if (profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {1067 smu_cmn_get_backend_workload_mask(smu, workload_mask,
1065 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);1068 &backend_workload_mask);
1066 return -EINVAL;
1067 }
1068
1069 if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT ||
1070 profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)
1071 return 0;
1072
1073 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1074 workload_type = smu_cmn_to_asic_specific_index(smu,
1075 CMN2ASIC_MAPPING_WORKLOAD,
1076 profile_mode);
1077 if (workload_type < 0) {
1078 dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on VANGOGH\n",
1079 profile_mode);
1080 return -EINVAL;
1081 }
1082 1069
1083 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,1070 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
1084 smu->workload_mask,1071 backend_workload_mask,
1085 NULL);1072 NULL);
1086 if (ret) {1073 if (ret) {
1087 dev_err_once(smu->adev->dev, "Fail to set workload type %d\n",1074 dev_err_once(smu->adev->dev, "Fail to set workload mask 0x%08x\n",
1088 workload_type);1075 workload_mask);
1089 return ret;1076 return ret;
1090 }1077 }
1091 1078
1092 smu_cmn_assign_power_profile(smu);1079 return ret;
1093
1094 return 0;
1095}1080}
1096 1081
1097static int vangogh_set_soft_freq_limited_range(struct smu_context *smu,1082static int vangogh_set_soft_freq_limited_range(struct smu_context *smu,
drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c+13−30
@@ -864,44 +864,27 @@ static int renoir_force_clk_levels(struct smu_context *smu, · 863 unmodified lines
864 return ret;864 return ret;
865}865}
866 866
867static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)867static int renoir_set_power_profile_mode(struct smu_context *smu,
868 u32 workload_mask,
869 long *custom_params,
870 u32 custom_params_max_idx)
868{871{
869 int workload_type, ret;872 int ret;
870 uint32_t profile_mode = input[size];873 u32 backend_workload_mask = 0;
871 874
872 if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {875 smu_cmn_get_backend_workload_mask(smu, workload_mask,
873 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);876 &backend_workload_mask);
874 return -EINVAL;
875 }
876
877 if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT ||
878 profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)
879 return 0;
880
881 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
882 workload_type = smu_cmn_to_asic_specific_index(smu,
883 CMN2ASIC_MAPPING_WORKLOAD,
884 profile_mode);
885 if (workload_type < 0) {
886 /*
887 * TODO: If some case need switch to powersave/default power mode
888 * then can consider enter WORKLOAD_COMPUTE/WORKLOAD_CUSTOM for power saving.
889 */
890 dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on RENOIR\n", profile_mode);
891 return -EINVAL;
892 }
893 877
894 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,878 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
895 smu->workload_mask,879 backend_workload_mask,
896 NULL);880 NULL);
897 if (ret) {881 if (ret) {
898 dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", workload_type);882 dev_err_once(smu->adev->dev, "Failed to set workload mask 0x08%x\n",
883 workload_mask);
899 return ret;884 return ret;
900 }885 }
901 886
902 smu_cmn_assign_power_profile(smu);887 return ret;
903
904 return 0;
905}888}
906 889
907static int renoir_set_peak_clock_by_device(struct smu_context *smu)890static int renoir_set_peak_clock_by_device(struct smu_context *smu)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c+96−79
@@ -2571,82 +2571,76 @@ static int smu_v13_0_0_get_power_profile_mode(struct smu_context *smu, · 2570 unmodified lines
2571 return size;2571 return size;
2572}2572}
2573 2573
2574static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,2574#define SMU_13_0_0_CUSTOM_PARAMS_COUNT 9
2575 long *input,2575#define SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT 2
2576 uint32_t size)2576#define SMU_13_0_0_CUSTOM_PARAMS_SIZE (SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT * SMU_13_0_0_CUSTOM_PARAMS_COUNT * sizeof(long))
2577
2578static int smu_v13_0_0_set_power_profile_mode_coeff(struct smu_context *smu,
2579 long *input)
2577{2580{
2578 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;2581 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
2579 DpmActivityMonitorCoeffInt_t *activity_monitor =2582 DpmActivityMonitorCoeffInt_t *activity_monitor =
2580 &(activity_monitor_external.DpmActivityMonitorCoeffInt);2583 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
2581 int workload_type, ret = 0;2584 int ret, idx;
2582 u32 workload_mask;
2583
2584 smu->power_profile_mode = input[size];
2585 2585
2586 if (smu->power_profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {2586 ret = smu_cmn_update_table(smu,
2587 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);2587 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
2588 return -EINVAL;2588 WORKLOAD_PPLIB_CUSTOM_BIT,
2589 (void *)(&activity_monitor_external),
2590 false);
2591 if (ret) {
2592 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
2593 return ret;
2589 }2594 }
2590 2595
2591 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {2596 idx = 0 * SMU_13_0_0_CUSTOM_PARAMS_COUNT;
2592 if (size != 9)2597 if (input[idx]) {
2593 return -EINVAL;2598 /* Gfxclk */
2594 2599 activity_monitor->Gfx_FPS = input[idx + 1];
2595 ret = smu_cmn_update_table(smu,2600 activity_monitor->Gfx_MinActiveFreqType = input[idx + 2];
2596 SMU_TABLE_ACTIVITY_MONITOR_COEFF,2601 activity_monitor->Gfx_MinActiveFreq = input[idx + 3];
2597 WORKLOAD_PPLIB_CUSTOM_BIT,2602 activity_monitor->Gfx_BoosterFreqType = input[idx + 4];
2598 (void *)(&activity_monitor_external),2603 activity_monitor->Gfx_BoosterFreq = input[idx + 5];
2599 false);2604 activity_monitor->Gfx_PD_Data_limit_c = input[idx + 6];
2600 if (ret) {2605 activity_monitor->Gfx_PD_Data_error_coeff = input[idx + 7];
2601 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);2606 activity_monitor->Gfx_PD_Data_error_rate_coeff = input[idx + 8];
2602 return ret;2607 }
2603 }2608 idx = 1 * SMU_13_0_0_CUSTOM_PARAMS_COUNT;
2604 2609 if (input[idx]) {
2605 switch (input[0]) {2610 /* Fclk */
2606 case 0: /* Gfxclk */2611 activity_monitor->Fclk_FPS = input[idx + 1];
2607 activity_monitor->Gfx_FPS = input[1];2612 activity_monitor->Fclk_MinActiveFreqType = input[idx + 2];
2608 activity_monitor->Gfx_MinActiveFreqType = input[2];2613 activity_monitor->Fclk_MinActiveFreq = input[idx + 3];
2609 activity_monitor->Gfx_MinActiveFreq = input[3];2614 activity_monitor->Fclk_BoosterFreqType = input[idx + 4];
2610 activity_monitor->Gfx_BoosterFreqType = input[4];2615 activity_monitor->Fclk_BoosterFreq = input[idx + 5];
2611 activity_monitor->Gfx_BoosterFreq = input[5];2616 activity_monitor->Fclk_PD_Data_limit_c = input[idx + 6];
2612 activity_monitor->Gfx_PD_Data_limit_c = input[6];2617 activity_monitor->Fclk_PD_Data_error_coeff = input[idx + 7];
2613 activity_monitor->Gfx_PD_Data_error_coeff = input[7];2618 activity_monitor->Fclk_PD_Data_error_rate_coeff = input[idx + 8];
2614 activity_monitor->Gfx_PD_Data_error_rate_coeff = input[8];2619 }
2615 break;
2616 case 1: /* Fclk */
2617 activity_monitor->Fclk_FPS = input[1];
2618 activity_monitor->Fclk_MinActiveFreqType = input[2];
2619 activity_monitor->Fclk_MinActiveFreq = input[3];
2620 activity_monitor->Fclk_BoosterFreqType = input[4];
2621 activity_monitor->Fclk_BoosterFreq = input[5];
2622 activity_monitor->Fclk_PD_Data_limit_c = input[6];
2623 activity_monitor->Fclk_PD_Data_error_coeff = input[7];
2624 activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8];
2625 break;
2626 default:
2627 return -EINVAL;
2628 }
2629 2620
2630 ret = smu_cmn_update_table(smu,2621 ret = smu_cmn_update_table(smu,
2631 SMU_TABLE_ACTIVITY_MONITOR_COEFF,2622 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
2632 WORKLOAD_PPLIB_CUSTOM_BIT,2623 WORKLOAD_PPLIB_CUSTOM_BIT,
2633 (void *)(&activity_monitor_external),2624 (void *)(&activity_monitor_external),
2634 true);2625 true);
2635 if (ret) {2626 if (ret) {
2636 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);2627 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
2637 return ret;2628 return ret;
2638 }
2639 }2629 }
2640 2630
2641 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */2631 return ret;
2642 workload_type = smu_cmn_to_asic_specific_index(smu,2632}
2643 CMN2ASIC_MAPPING_WORKLOAD,
2644 smu->power_profile_mode);
2645 2633
2646 if (workload_type < 0)2634static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
2647 return -EINVAL;2635 u32 workload_mask,
2636 long *custom_params,
2637 u32 custom_params_max_idx)
2638{
2639 u32 backend_workload_mask = 0;
2640 int workload_type, ret, idx = -1, i;
2648 2641
2649 workload_mask = 1 << workload_type;2642 smu_cmn_get_backend_workload_mask(smu, workload_mask,
2643 &backend_workload_mask);
2650 2644
2651 /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */2645 /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */
2652 if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&2646 if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
@@ -2658,24 +2652,47 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, · 5 unmodified lines
2658 CMN2ASIC_MAPPING_WORKLOAD,2652 CMN2ASIC_MAPPING_WORKLOAD,
2659 PP_SMC_POWER_PROFILE_POWERSAVING);2653 PP_SMC_POWER_PROFILE_POWERSAVING);
2660 if (workload_type >= 0)2654 if (workload_type >= 0)
2661 workload_mask |= 1 << workload_type;2655 backend_workload_mask |= 1 << workload_type;
2662 }2656 }
2663 2657
2664 smu->workload_mask |= workload_mask;2658 if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) {
2665 ret = smu_cmn_send_smc_msg_with_param(smu,2659 if (!smu->custom_profile_params) {
2666 SMU_MSG_SetWorkloadMask,2660 smu->custom_profile_params =
2667 smu->workload_mask,2661 kzalloc(SMU_13_0_0_CUSTOM_PARAMS_SIZE, GFP_KERNEL);
2668 NULL);2662 if (!smu->custom_profile_params)
2669 if (!ret) {2663 return -ENOMEM;
2670 smu_cmn_assign_power_profile(smu);
2671 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING) {
2672 workload_type = smu_cmn_to_asic_specific_index(smu,
2673 CMN2ASIC_MAPPING_WORKLOAD,
2674 PP_SMC_POWER_PROFILE_FULLSCREEN3D);
2675 smu->power_profile_mode = smu->workload_mask & (1 << workload_type)
2676 ? PP_SMC_POWER_PROFILE_FULLSCREEN3D
2677 : PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
2678 }2664 }
2665 if (custom_params && custom_params_max_idx) {
2666 if (custom_params_max_idx != SMU_13_0_0_CUSTOM_PARAMS_COUNT)
2667 return -EINVAL;
2668 if (custom_params[0] >= SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT)
2669 return -EINVAL;
2670 idx = custom_params[0] * SMU_13_0_0_CUSTOM_PARAMS_COUNT;
2671 smu->custom_profile_params[idx] = 1;
2672 for (i = 1; i < custom_params_max_idx; i++)
2673 smu->custom_profile_params[idx + i] = custom_params[i];
2674 }
2675 ret = smu_v13_0_0_set_power_profile_mode_coeff(smu,
2676 smu->custom_profile_params);
2677 if (ret) {
2678 if (idx != -1)
2679 smu->custom_profile_params[idx] = 0;
2680 return ret;
2681 }
2682 } else if (smu->custom_profile_params) {
2683 memset(smu->custom_profile_params, 0, SMU_13_0_0_CUSTOM_PARAMS_SIZE);
2684 }
2685
2686 ret = smu_cmn_send_smc_msg_with_param(smu,
2687 SMU_MSG_SetWorkloadMask,
2688 backend_workload_mask,
2689 NULL);
2690 if (ret) {
2691 dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n",
2692 workload_mask);
2693 if (idx != -1)
2694 smu->custom_profile_params[idx] = 0;
2695 return ret;
2679 }2696 }
2680 2697
2681 return ret;2698 return ret;
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c+85−54
@@ -2530,79 +2530,110 @@ out: · 2529 unmodified lines
2530 return result;2530 return result;
2531}2531}
2532 2532
2533static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)2533#define SMU_13_0_7_CUSTOM_PARAMS_COUNT 8
2534#define SMU_13_0_7_CUSTOM_PARAMS_CLOCK_COUNT 2
2535#define SMU_13_0_7_CUSTOM_PARAMS_SIZE (SMU_13_0_7_CUSTOM_PARAMS_CLOCK_COUNT * SMU_13_0_7_CUSTOM_PARAMS_COUNT * sizeof(long))
2536
2537static int smu_v13_0_7_set_power_profile_mode_coeff(struct smu_context *smu,
2538 long *input)
2534{2539{
2535 2540
2536 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;2541 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
2537 DpmActivityMonitorCoeffInt_t *activity_monitor =2542 DpmActivityMonitorCoeffInt_t *activity_monitor =
2538 &(activity_monitor_external.DpmActivityMonitorCoeffInt);2543 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
2539 int workload_type, ret = 0;2544 int ret, idx;
2540 2545
2541 smu->power_profile_mode = input[size];2546 ret = smu_cmn_update_table(smu,
2547 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
2548 (void *)(&activity_monitor_external), false);
2549 if (ret) {
2550 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
2551 return ret;
2552 }
2542 2553
2543 if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_WINDOW3D) {2554 idx = 0 * SMU_13_0_7_CUSTOM_PARAMS_COUNT;
2544 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);2555 if (input[idx]) {
2545 return -EINVAL;2556 /* Gfxclk */
2557 activity_monitor->Gfx_ActiveHystLimit = input[idx + 1];
2558 activity_monitor->Gfx_IdleHystLimit = input[idx + 2];
2559 activity_monitor->Gfx_FPS = input[idx + 3];
2560 activity_monitor->Gfx_MinActiveFreqType = input[idx + 4];
2561 activity_monitor->Gfx_BoosterFreqType = input[idx + 5];
2562 activity_monitor->Gfx_MinActiveFreq = input[idx + 6];
2563 activity_monitor->Gfx_BoosterFreq = input[idx + 7];
2564 }
2565 idx = 1 * SMU_13_0_7_CUSTOM_PARAMS_COUNT;
2566 if (input[idx]) {
2567 /* Fclk */
2568 activity_monitor->Fclk_ActiveHystLimit = input[idx + 1];
2569 activity_monitor->Fclk_IdleHystLimit = input[idx + 2];
2570 activity_monitor->Fclk_FPS = input[idx + 3];
2571 activity_monitor->Fclk_MinActiveFreqType = input[idx + 4];
2572 activity_monitor->Fclk_BoosterFreqType = input[idx + 5];
2573 activity_monitor->Fclk_MinActiveFreq = input[idx + 6];
2574 activity_monitor->Fclk_BoosterFreq = input[idx + 7];
2546 }2575 }
2547 2576
2548 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {2577 ret = smu_cmn_update_table(smu,
2549 if (size != 8)2578 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
2550 return -EINVAL;2579 (void *)(&activity_monitor_external), true);
2580 if (ret) {
2581 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
2582 return ret;
2583 }
2551 2584
2552 ret = smu_cmn_update_table(smu,2585 return ret;
2553 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,2586}
2554 (void *)(&activity_monitor_external), false);
2555 if (ret) {
2556 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
2557 return ret;
2558 }
2559 2587
2560 switch (input[0]) {2588static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu,
2561 case 0: /* Gfxclk */2589 u32 workload_mask,
2562 activity_monitor->Gfx_ActiveHystLimit = input[1];2590 long *custom_params,
2563 activity_monitor->Gfx_IdleHystLimit = input[2];2591 u32 custom_params_max_idx)
2564 activity_monitor->Gfx_FPS = input[3];2592{
2565 activity_monitor->Gfx_MinActiveFreqType = input[4];2593 u32 backend_workload_mask = 0;
2566 activity_monitor->Gfx_BoosterFreqType = input[5];2594 int ret, idx = -1, i;
2567 activity_monitor->Gfx_MinActiveFreq = input[6];2595
2568 activity_monitor->Gfx_BoosterFreq = input[7];2596 smu_cmn_get_backend_workload_mask(smu, workload_mask,
2569 break;2597 &backend_workload_mask);
2570 case 1: /* Fclk */2598
2571 activity_monitor->Fclk_ActiveHystLimit = input[1];2599 if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) {
2572 activity_monitor->Fclk_IdleHystLimit = input[2];2600 if (!smu->custom_profile_params) {
2573 activity_monitor->Fclk_FPS = input[3];2601 smu->custom_profile_params =
2574 activity_monitor->Fclk_MinActiveFreqType = input[4];2602 kzalloc(SMU_13_0_7_CUSTOM_PARAMS_SIZE, GFP_KERNEL);
2575 activity_monitor->Fclk_BoosterFreqType = input[5];2603 if (!smu->custom_profile_params)
2576 activity_monitor->Fclk_MinActiveFreq = input[6];2604 return -ENOMEM;
2577 activity_monitor->Fclk_BoosterFreq = input[7];
2578 break;
2579 default:
2580 return -EINVAL;
2581 }2605 }
2582 2606 if (custom_params && custom_params_max_idx) {
2583 ret = smu_cmn_update_table(smu,2607 if (custom_params_max_idx != SMU_13_0_7_CUSTOM_PARAMS_COUNT)
2584 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,2608 return -EINVAL;
2585 (void *)(&activity_monitor_external), true);2609 if (custom_params[0] >= SMU_13_0_7_CUSTOM_PARAMS_CLOCK_COUNT)
2610 return -EINVAL;
2611 idx = custom_params[0] * SMU_13_0_7_CUSTOM_PARAMS_COUNT;
2612 smu->custom_profile_params[idx] = 1;
2613 for (i = 1; i < custom_params_max_idx; i++)
2614 smu->custom_profile_params[idx + i] = custom_params[i];
2615 }
2616 ret = smu_v13_0_7_set_power_profile_mode_coeff(smu,
2617 smu->custom_profile_params);
2586 if (ret) {2618 if (ret) {
2587 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);2619 if (idx != -1)
2620 smu->custom_profile_params[idx] = 0;
2588 return ret;2621 return ret;
2589 }2622 }
2623 } else if (smu->custom_profile_params) {
2624 memset(smu->custom_profile_params, 0, SMU_13_0_7_CUSTOM_PARAMS_SIZE);
2590 }2625 }
2591 2626
2592 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
2593 workload_type = smu_cmn_to_asic_specific_index(smu,
2594 CMN2ASIC_MAPPING_WORKLOAD,
2595 smu->power_profile_mode);
2596 if (workload_type < 0)
2597 return -EINVAL;
2598
2599 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,2627 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
2600 smu->workload_mask, NULL);2628 backend_workload_mask, NULL);
2601 2629
2602 if (ret)2630 if (ret) {
2603 dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);2631 dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n",
2604 else2632 workload_mask);
2605 smu_cmn_assign_power_profile(smu);2633 if (idx != -1)
2634 smu->custom_profile_params[idx] = 0;
2635 return ret;
2636 }
2606 2637
2607 return ret;2638 return ret;
2608}2639}
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c+98−67
@@ -1739,89 +1739,120 @@ static int smu_v14_0_2_get_power_profile_mode(struct smu_context *smu, · 1738 unmodified lines
1739 return size;1739 return size;
1740}1740}
1741 1741
1742static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,1742#define SMU_14_0_2_CUSTOM_PARAMS_COUNT 9
1743 long *input,1743#define SMU_14_0_2_CUSTOM_PARAMS_CLOCK_COUNT 2
1744 uint32_t size)1744#define SMU_14_0_2_CUSTOM_PARAMS_SIZE (SMU_14_0_2_CUSTOM_PARAMS_CLOCK_COUNT * SMU_14_0_2_CUSTOM_PARAMS_COUNT * sizeof(long))
1745
1746static int smu_v14_0_2_set_power_profile_mode_coeff(struct smu_context *smu,
1747 long *input)
1745{1748{
1746 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;1749 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
1747 DpmActivityMonitorCoeffInt_t *activity_monitor =1750 DpmActivityMonitorCoeffInt_t *activity_monitor =
1748 &(activity_monitor_external.DpmActivityMonitorCoeffInt);1751 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
1749 int workload_type, ret = 0;1752 int ret, idx;
1750 uint32_t current_profile_mode = smu->power_profile_mode;
1751 smu->power_profile_mode = input[size];
1752 1753
1753 if (smu->power_profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {1754 ret = smu_cmn_update_table(smu,
1754 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);1755 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1755 return -EINVAL;1756 WORKLOAD_PPLIB_CUSTOM_BIT,
1757 (void *)(&activity_monitor_external),
1758 false);
1759 if (ret) {
1760 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1761 return ret;
1756 }1762 }
1757 1763
1758 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {1764 idx = 0 * SMU_14_0_2_CUSTOM_PARAMS_COUNT;
1759 if (size != 9)1765 if (input[idx]) {
1760 return -EINVAL;1766 /* Gfxclk */
1767 activity_monitor->Gfx_FPS = input[idx + 1];
1768 activity_monitor->Gfx_MinActiveFreqType = input[idx + 2];
1769 activity_monitor->Gfx_MinActiveFreq = input[idx + 3];
1770 activity_monitor->Gfx_BoosterFreqType = input[idx + 4];
1771 activity_monitor->Gfx_BoosterFreq = input[idx + 5];
1772 activity_monitor->Gfx_PD_Data_limit_c = input[idx + 6];
1773 activity_monitor->Gfx_PD_Data_error_coeff = input[idx + 7];
1774 activity_monitor->Gfx_PD_Data_error_rate_coeff = input[idx + 8];
1775 }
1776 idx = 1 * SMU_14_0_2_CUSTOM_PARAMS_COUNT;
1777 if (input[idx]) {
1778 /* Fclk */
1779 activity_monitor->Fclk_FPS = input[idx + 1];
1780 activity_monitor->Fclk_MinActiveFreqType = input[idx + 2];
1781 activity_monitor->Fclk_MinActiveFreq = input[idx + 3];
1782 activity_monitor->Fclk_BoosterFreqType = input[idx + 4];
1783 activity_monitor->Fclk_BoosterFreq = input[idx + 5];
1784 activity_monitor->Fclk_PD_Data_limit_c = input[idx + 6];
1785 activity_monitor->Fclk_PD_Data_error_coeff = input[idx + 7];
1786 activity_monitor->Fclk_PD_Data_error_rate_coeff = input[idx + 8];
1787 }
1761 1788
1762 ret = smu_cmn_update_table(smu,1789 ret = smu_cmn_update_table(smu,
1763 SMU_TABLE_ACTIVITY_MONITOR_COEFF,1790 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1764 WORKLOAD_PPLIB_CUSTOM_BIT,1791 WORKLOAD_PPLIB_CUSTOM_BIT,
1765 (void *)(&activity_monitor_external),1792 (void *)(&activity_monitor_external),
1766 false);1793 true);
1767 if (ret) {1794 if (ret) {
1768 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);1795 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
1769 return ret;1796 return ret;
1770 }1797 }
1771 1798
1772 switch (input[0]) {1799 return ret;
1773 case 0: /* Gfxclk */1800}
1774 activity_monitor->Gfx_FPS = input[1];
1775 activity_monitor->Gfx_MinActiveFreqType = input[2];
1776 activity_monitor->Gfx_MinActiveFreq = input[3];
1777 activity_monitor->Gfx_BoosterFreqType = input[4];
1778 activity_monitor->Gfx_BoosterFreq = input[5];
1779 activity_monitor->Gfx_PD_Data_limit_c = input[6];
1780 activity_monitor->Gfx_PD_Data_error_coeff = input[7];
1781 activity_monitor->Gfx_PD_Data_error_rate_coeff = input[8];
1782 break;
1783 case 1: /* Fclk */
1784 activity_monitor->Fclk_FPS = input[1];
1785 activity_monitor->Fclk_MinActiveFreqType = input[2];
1786 activity_monitor->Fclk_MinActiveFreq = input[3];
1787 activity_monitor->Fclk_BoosterFreqType = input[4];
1788 activity_monitor->Fclk_BoosterFreq = input[5];
1789 activity_monitor->Fclk_PD_Data_limit_c = input[6];
1790 activity_monitor->Fclk_PD_Data_error_coeff = input[7];
1791 activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8];
1792 break;
1793 default:
1794 return -EINVAL;
1795 }
1796 1801
1797 ret = smu_cmn_update_table(smu,1802static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,
1798 SMU_TABLE_ACTIVITY_MONITOR_COEFF,1803 u32 workload_mask,
1799 WORKLOAD_PPLIB_CUSTOM_BIT,1804 long *custom_params,
1800 (void *)(&activity_monitor_external),1805 u32 custom_params_max_idx)
1801 true);1806{
1802 if (ret) {1807 u32 backend_workload_mask = 0;
1803 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);1808 int ret, idx = -1, i;
1804 return ret;1809
1805 }1810 smu_cmn_get_backend_workload_mask(smu, workload_mask,
1806 }1811 &backend_workload_mask);
1807 1812
1808 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE)1813 /* disable deep sleep if compute is enabled */
1814 if (workload_mask & (1 << PP_SMC_POWER_PROFILE_COMPUTE))
1809 smu_v14_0_deep_sleep_control(smu, false);1815 smu_v14_0_deep_sleep_control(smu, false);
1810 else if (current_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE)1816 else
1811 smu_v14_0_deep_sleep_control(smu, true);1817 smu_v14_0_deep_sleep_control(smu, true);
1812 1818
1813 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */1819 if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) {
1814 workload_type = smu_cmn_to_asic_specific_index(smu,1820 if (!smu->custom_profile_params) {
1815 CMN2ASIC_MAPPING_WORKLOAD,1821 smu->custom_profile_params =
1816 smu->power_profile_mode);1822 kzalloc(SMU_14_0_2_CUSTOM_PARAMS_SIZE, GFP_KERNEL);
1817 if (workload_type < 0)1823 if (!smu->custom_profile_params)
1818 return -EINVAL;1824 return -ENOMEM;
1825 }
1826 if (custom_params && custom_params_max_idx) {
1827 if (custom_params_max_idx != SMU_14_0_2_CUSTOM_PARAMS_COUNT)
1828 return -EINVAL;
1829 if (custom_params[0] >= SMU_14_0_2_CUSTOM_PARAMS_CLOCK_COUNT)
1830 return -EINVAL;
1831 idx = custom_params[0] * SMU_14_0_2_CUSTOM_PARAMS_COUNT;
1832 smu->custom_profile_params[idx] = 1;
1833 for (i = 1; i < custom_params_max_idx; i++)
1834 smu->custom_profile_params[idx + i] = custom_params[i];
1835 }
1836 ret = smu_v14_0_2_set_power_profile_mode_coeff(smu,
1837 smu->custom_profile_params);
1838 if (ret) {
1839 if (idx != -1)
1840 smu->custom_profile_params[idx] = 0;
1841 return ret;
1842 }
1843 } else if (smu->custom_profile_params) {
1844 memset(smu->custom_profile_params, 0, SMU_14_0_2_CUSTOM_PARAMS_SIZE);
1845 }
1819 1846
1820 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,1847 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1821 smu->workload_mask, NULL);1848 backend_workload_mask, NULL);
1822 1849 if (ret) {
1823 if (!ret)1850 dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n",
1824 smu_cmn_assign_power_profile(smu);1851 workload_mask);
1852 if (idx != -1)
1853 smu->custom_profile_params[idx] = 0;
1854 return ret;
1855 }
1825 1856
1826 return ret;1857 return ret;
1827}1858}
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c+25−8
@@ -1144,14 +1144,6 @@ int smu_cmn_set_mp1_state(struct smu_context *smu, · 1143 unmodified lines
1144 return ret;1144 return ret;
1145}1145}
1146 1146
1147void smu_cmn_assign_power_profile(struct smu_context *smu)
1148{
1149 uint32_t index;
1150 index = fls(smu->workload_mask);
1151 index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
1152 smu->power_profile_mode = smu->workload_setting[index];
1153}
1154
1155bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev)1147bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev)
1156{1148{
1157 struct pci_dev *p = NULL;1149 struct pci_dev *p = NULL;
@@ -1229,3 +1221,28 @@ void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy) · 71 unmodified lines
1229{1221{
1230 policy->desc = &xgmi_plpd_policy_desc;1222 policy->desc = &xgmi_plpd_policy_desc;
1231}1223}
1224
1225void smu_cmn_get_backend_workload_mask(struct smu_context *smu,
1226 u32 workload_mask,
1227 u32 *backend_workload_mask)
1228{
1229 int workload_type;
1230 u32 profile_mode;
1231
1232 *backend_workload_mask = 0;
1233
1234 for (profile_mode = 0; profile_mode < PP_SMC_POWER_PROFILE_COUNT; profile_mode++) {
1235 if (!(workload_mask & (1 << profile_mode)))
1236 continue;
1237
1238 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1239 workload_type = smu_cmn_to_asic_specific_index(smu,
1240 CMN2ASIC_MAPPING_WORKLOAD,
1241 profile_mode);
1242
1243 if (workload_type < 0)
1244 continue;
1245
1246 *backend_workload_mask |= 1 << workload_type;
1247 }
1248}
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h+4−2
@@ -130,8 +130,6 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev); · 129 unmodified lines
130int smu_cmn_set_mp1_state(struct smu_context *smu,130int smu_cmn_set_mp1_state(struct smu_context *smu,
131 enum pp_mp1_state mp1_state);131 enum pp_mp1_state mp1_state);
132 132
133void smu_cmn_assign_power_profile(struct smu_context *smu);
134
135/*133/*
136 * Helper function to make sysfs_emit_at() happy. Align buf to134 * Helper function to make sysfs_emit_at() happy. Align buf to
137 * the current page boundary and record the offset.135 * the current page boundary and record the offset.
@@ -149,5 +147,9 @@ bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev); · 11 unmodified lines
149void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy);147void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy);
150void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy);148void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy);
151 149
150void smu_cmn_get_backend_workload_mask(struct smu_context *smu,
151 u32 workload_mask,
152 u32 *backend_workload_mask);
153
152#endif154#endif
153#endif155#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t