Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'amd-drm-next-5.16-2021-10-29' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-5.16-2021-10-29:

amdgpu:
- RAS fixes
- Fix a potential memory leak in device tear down
- Add a stutter mode quirk
- Misc display fixes
- Further display FP refactoring
- Display USB4 fixes
- Display DP2.0 fixes
- DCN 3.1 fixes
- Display 8 ch audio fix
- Fix DMA mask regression for SI parts
- Aldebaran fixes

amdkfd:
- userptr fix
- BO lifetime fix
- Misc code cleanup

UAPI:
- Minor header cleanup (no functional change)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211029184338.4863-1-alexander.deucher@amd.com

+2055 -1335
+1
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 205 205 extern int amdgpu_ras_enable; 206 206 extern uint amdgpu_ras_mask; 207 207 extern int amdgpu_bad_page_threshold; 208 + extern bool amdgpu_ignore_bad_page_threshold; 208 209 extern struct amdgpu_watchdog_timer amdgpu_watchdog_timer; 209 210 extern int amdgpu_async_gfx_ring; 210 211 extern int amdgpu_mcbp;
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
··· 279 279 struct kgd_dev *kgd, struct kgd_mem *mem, bool intr); 280 280 int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd, 281 281 struct kgd_mem *mem, void **kptr, uint64_t *size); 282 + void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_dev *kgd, struct kgd_mem *mem); 283 + 282 284 int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info, 283 285 struct dma_fence **ef); 284 286 int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
+27 -10
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
··· 1871 1871 return ret; 1872 1872 } 1873 1873 1874 + void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_dev *kgd, struct kgd_mem *mem) 1875 + { 1876 + struct amdgpu_bo *bo = mem->bo; 1877 + 1878 + amdgpu_bo_reserve(bo, true); 1879 + amdgpu_bo_kunmap(bo); 1880 + amdgpu_bo_unpin(bo); 1881 + amdgpu_bo_unreserve(bo); 1882 + } 1883 + 1874 1884 int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd, 1875 1885 struct kfd_vm_fault_info *mem) 1876 1886 { ··· 2051 2041 /* Get updated user pages */ 2052 2042 ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); 2053 2043 if (ret) { 2054 - pr_debug("%s: Failed to get user pages: %d\n", 2055 - __func__, ret); 2044 + pr_debug("Failed %d to get user pages\n", ret); 2056 2045 2057 - /* Return error -EBUSY or -ENOMEM, retry restore */ 2058 - return ret; 2046 + /* Return -EFAULT bad address error as success. It will 2047 + * fail later with a VM fault if the GPU tries to access 2048 + * it. Better than hanging indefinitely with stalled 2049 + * user mode queues. 2050 + * 2051 + * Return other error -EBUSY or -ENOMEM to retry restore 2052 + */ 2053 + if (ret != -EFAULT) 2054 + return ret; 2055 + } else { 2056 + 2057 + /* 2058 + * FIXME: Cannot ignore the return code, must hold 2059 + * notifier_lock 2060 + */ 2061 + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); 2059 2062 } 2060 - 2061 - /* 2062 - * FIXME: Cannot ignore the return code, must hold 2063 - * notifier_lock 2064 - */ 2065 - amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); 2066 2063 2067 2064 /* Mark the BO as valid unless it was invalidated 2068 2065 * again concurrently.
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 3852 3852 3853 3853 void amdgpu_device_fini_sw(struct amdgpu_device *adev) 3854 3854 { 3855 - amdgpu_device_ip_fini(adev); 3856 3855 amdgpu_fence_driver_sw_fini(adev); 3856 + amdgpu_device_ip_fini(adev); 3857 3857 release_firmware(adev->firmware.gpu_info_fw); 3858 3858 adev->firmware.gpu_info_fw = NULL; 3859 3859 adev->accel_working = false;
+17
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
··· 931 931 adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 0); 932 932 adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 0); 933 933 adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 0); 934 + adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 0); 934 935 adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0); 935 936 adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 1, 0); 936 937 adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 0, 0); ··· 952 951 adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 1); 953 952 adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 1); 954 953 adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 1); 954 + adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 1); 955 955 adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 5, 0); 956 956 adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 2, 0); 957 957 adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 0); ··· 1011 1009 adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 0); 1012 1010 adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 0); 1013 1011 adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 0); 1012 + adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 0); 1014 1013 adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 0); 1015 1014 adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 0); 1016 1015 adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 1); ··· 1021 1018 adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 2); 1022 1019 adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 0); 1023 1020 adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 2, 0); 1021 + adev->ip_versions[UVD_HWIP][1] = IP_VERSION(7, 2, 0); 1024 1022 adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 1, 0); 1025 1023 adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 1, 0); 1026 1024 break; ··· 1034 1030 adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 1); 1035 1031 adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 1); 1036 1032 adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 2); 1033 + adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 2); 1034 + adev->ip_versions[SDMA1_HWIP][1] = IP_VERSION(4, 2, 2); 1035 + adev->ip_versions[SDMA1_HWIP][2] = IP_VERSION(4, 2, 2); 1036 + adev->ip_versions[SDMA1_HWIP][3] = IP_VERSION(4, 2, 2); 1037 + adev->ip_versions[SDMA1_HWIP][4] = IP_VERSION(4, 2, 2); 1038 + adev->ip_versions[SDMA1_HWIP][5] = IP_VERSION(4, 2, 2); 1039 + adev->ip_versions[SDMA1_HWIP][6] = IP_VERSION(4, 2, 2); 1037 1040 adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 1); 1038 1041 adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 1); 1039 1042 adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 2); ··· 1050 1039 adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 3); 1051 1040 adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 1); 1052 1041 adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 5, 0); 1042 + adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 5, 0); 1053 1043 break; 1054 1044 case CHIP_ALDEBARAN: 1055 1045 aldebaran_reg_base_init(adev); ··· 1061 1049 adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 4, 0); 1062 1050 adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 4, 0); 1063 1051 adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 4, 0); 1052 + adev->ip_versions[SDMA0_HWIP][1] = IP_VERSION(4, 4, 0); 1053 + adev->ip_versions[SDMA0_HWIP][2] = IP_VERSION(4, 4, 0); 1054 + adev->ip_versions[SDMA0_HWIP][3] = IP_VERSION(4, 4, 0); 1055 + adev->ip_versions[SDMA0_HWIP][4] = IP_VERSION(4, 4, 0); 1064 1056 adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 2); 1065 1057 adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 4); 1066 1058 adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 7, 0); ··· 1074 1058 adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(13, 0, 2); 1075 1059 adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 2); 1076 1060 adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 6, 0); 1061 + adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 6, 0); 1077 1062 adev->ip_versions[XGMI_HWIP][0] = IP_VERSION(6, 1, 0); 1078 1063 break; 1079 1064 default:
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 877 877 * result in the GPU entering bad status when the number of total 878 878 * faulty pages by ECC exceeds the threshold value. 879 879 */ 880 - MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = auto(default value), 0 = disable bad page retirement)"); 880 + MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = auto(default value), 0 = disable bad page retirement, -2 = ignore bad page threshold)"); 881 881 module_param_named(bad_page_threshold, amdgpu_bad_page_threshold, int, 0444); 882 882 883 883 MODULE_PARM_DESC(num_kcq, "number of kernel compute queue user want to setup (8 if set to greater than 8 or less than 0, only affect gfx 8+)");
+6 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
··· 340 340 case AMDGPU_INFO_FW_TA: 341 341 switch (query_fw->index) { 342 342 case TA_FW_TYPE_PSP_XGMI: 343 - fw_info->ver = adev->psp.ta_fw_version; 343 + fw_info->ver = adev->psp.xgmi_context.context.bin_desc.fw_version; 344 344 fw_info->feature = adev->psp.xgmi_context.context 345 345 .bin_desc.feature_version; 346 346 break; 347 347 case TA_FW_TYPE_PSP_RAS: 348 - fw_info->ver = adev->psp.ta_fw_version; 348 + fw_info->ver = adev->psp.ras_context.context.bin_desc.fw_version; 349 349 fw_info->feature = adev->psp.ras_context.context 350 350 .bin_desc.feature_version; 351 351 break; 352 352 case TA_FW_TYPE_PSP_HDCP: 353 - fw_info->ver = adev->psp.ta_fw_version; 353 + fw_info->ver = adev->psp.hdcp_context.context.bin_desc.fw_version; 354 354 fw_info->feature = adev->psp.hdcp_context.context 355 355 .bin_desc.feature_version; 356 356 break; 357 357 case TA_FW_TYPE_PSP_DTM: 358 - fw_info->ver = adev->psp.ta_fw_version; 358 + fw_info->ver = adev->psp.dtm_context.context.bin_desc.fw_version; 359 359 fw_info->feature = adev->psp.dtm_context.context 360 360 .bin_desc.feature_version; 361 361 break; 362 362 case TA_FW_TYPE_PSP_RAP: 363 - fw_info->ver = adev->psp.ta_fw_version; 363 + fw_info->ver = adev->psp.rap_context.context.bin_desc.fw_version; 364 364 fw_info->feature = adev->psp.rap_context.context 365 365 .bin_desc.feature_version; 366 366 break; 367 367 case TA_FW_TYPE_PSP_SECUREDISPLAY: 368 - fw_info->ver = adev->psp.ta_fw_version; 368 + fw_info->ver = adev->psp.securedisplay_context.context.bin_desc.fw_version; 369 369 fw_info->feature = 370 370 adev->psp.securedisplay_context.context.bin_desc 371 371 .feature_version;
+7 -7
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 1115 1115 static bool psp_xgmi_peer_link_info_supported(struct psp_context *psp) 1116 1116 { 1117 1117 return psp->adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 2) && 1118 - psp->xgmi_context.context.bin_desc.feature_version >= 0x2000000b; 1118 + psp->xgmi_context.context.bin_desc.fw_version >= 0x2000000b; 1119 1119 } 1120 1120 1121 1121 /* ··· 3108 3108 psp->asd_context.bin_desc.start_addr = ucode_start_addr; 3109 3109 break; 3110 3110 case TA_FW_TYPE_PSP_XGMI: 3111 - psp->xgmi_context.context.bin_desc.feature_version = le32_to_cpu(desc->fw_version); 3111 + psp->xgmi_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); 3112 3112 psp->xgmi_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); 3113 3113 psp->xgmi_context.context.bin_desc.start_addr = ucode_start_addr; 3114 3114 break; 3115 3115 case TA_FW_TYPE_PSP_RAS: 3116 - psp->ras_context.context.bin_desc.feature_version = le32_to_cpu(desc->fw_version); 3116 + psp->ras_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); 3117 3117 psp->ras_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); 3118 3118 psp->ras_context.context.bin_desc.start_addr = ucode_start_addr; 3119 3119 break; 3120 3120 case TA_FW_TYPE_PSP_HDCP: 3121 - psp->hdcp_context.context.bin_desc.feature_version = le32_to_cpu(desc->fw_version); 3121 + psp->hdcp_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); 3122 3122 psp->hdcp_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); 3123 3123 psp->hdcp_context.context.bin_desc.start_addr = ucode_start_addr; 3124 3124 break; 3125 3125 case TA_FW_TYPE_PSP_DTM: 3126 - psp->dtm_context.context.bin_desc.feature_version = le32_to_cpu(desc->fw_version); 3126 + psp->dtm_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); 3127 3127 psp->dtm_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); 3128 3128 psp->dtm_context.context.bin_desc.start_addr = ucode_start_addr; 3129 3129 break; 3130 3130 case TA_FW_TYPE_PSP_RAP: 3131 - psp->rap_context.context.bin_desc.feature_version = le32_to_cpu(desc->fw_version); 3131 + psp->rap_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); 3132 3132 psp->rap_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); 3133 3133 psp->rap_context.context.bin_desc.start_addr = ucode_start_addr; 3134 3134 break; 3135 3135 case TA_FW_TYPE_PSP_SECUREDISPLAY: 3136 - psp->securedisplay_context.context.bin_desc.feature_version = 3136 + psp->securedisplay_context.context.bin_desc.fw_version = 3137 3137 le32_to_cpu(desc->fw_version); 3138 3138 psp->securedisplay_context.context.bin_desc.size_bytes = 3139 3139 le32_to_cpu(desc->size_bytes);
+18 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
··· 1077 1077 if (res) 1078 1078 DRM_ERROR("RAS table incorrect checksum or error:%d\n", 1079 1079 res); 1080 + 1081 + /* Warn if we are at 90% of the threshold or above 1082 + */ 1083 + if (10 * control->ras_num_recs >= 9 * ras->bad_page_cnt_threshold) 1084 + dev_warn(adev->dev, "RAS records:%u exceeds 90%% of threshold:%d", 1085 + control->ras_num_recs, 1086 + ras->bad_page_cnt_threshold); 1080 1087 } else if (hdr->header == RAS_TABLE_HDR_BAD && 1081 1088 amdgpu_bad_page_threshold != 0) { 1082 1089 res = __verify_ras_table_checksum(control); ··· 1105 1098 res = amdgpu_ras_eeprom_correct_header_tag(control, 1106 1099 RAS_TABLE_HDR_VAL); 1107 1100 } else { 1108 - *exceed_err_limit = true; 1109 - dev_err(adev->dev, 1110 - "RAS records:%d exceed threshold:%d, " 1111 - "GPU will not be initialized. Replace this GPU or increase the threshold", 1101 + dev_err(adev->dev, "RAS records:%d exceed threshold:%d", 1112 1102 control->ras_num_recs, ras->bad_page_cnt_threshold); 1103 + if (amdgpu_bad_page_threshold == -2) { 1104 + dev_warn(adev->dev, "GPU will be initialized due to bad_page_threshold = -2."); 1105 + res = 0; 1106 + } else { 1107 + *exceed_err_limit = true; 1108 + dev_err(adev->dev, 1109 + "RAS records:%d exceed threshold:%d, " 1110 + "GPU will not be initialized. Replace this GPU or increase the threshold", 1111 + control->ras_num_recs, ras->bad_page_cnt_threshold); 1112 + } 1113 1113 } 1114 1114 } else { 1115 1115 DRM_INFO("Creating a new EEPROM table");
+3
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 696 696 true, NULL); 697 697 out_unlock: 698 698 mmap_read_unlock(mm); 699 + if (r) 700 + pr_debug("failed %d to get user pages 0x%lx\n", r, start); 701 + 699 702 mmput(mm); 700 703 701 704 return r;
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
··· 527 527 FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version); 528 528 FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos.fw_version); 529 529 FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_context.bin_desc.fw_version); 530 - FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras_context.context.bin_desc.feature_version); 531 - FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.xgmi_context.context.bin_desc.feature_version); 530 + FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras_context.context.bin_desc.fw_version); 531 + FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.xgmi_context.context.bin_desc.fw_version); 532 532 FW_VERSION_ATTR(smc_fw_version, 0444, pm.fw_version); 533 533 FW_VERSION_ATTR(sdma_fw_version, 0444, sdma.instance[0].fw_version); 534 534 FW_VERSION_ATTR(sdma2_fw_version, 0444, sdma.instance[1].fw_version);
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
··· 535 535 POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_ASD, 536 536 adev->psp.asd_context.bin_desc.fw_version); 537 537 POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_RAS, 538 - adev->psp.ras_context.context.bin_desc.feature_version); 538 + adev->psp.ras_context.context.bin_desc.fw_version); 539 539 POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_XGMI, 540 - adev->psp.xgmi_context.context.bin_desc.feature_version); 540 + adev->psp.xgmi_context.context.bin_desc.fw_version); 541 541 POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SMC, adev->pm.fw_version); 542 542 POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SDMA, adev->sdma.instance[0].fw_version); 543 543 POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SDMA2, adev->sdma.instance[1].fw_version);
+5
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
··· 706 706 if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX)) 707 707 return 0; 708 708 709 + /* Workaround for ALDEBARAN, skip GPRs init in GPU reset. 710 + Will remove it once GPRs init algorithm works for all CU settings. */ 711 + if (amdgpu_in_reset(adev)) 712 + return 0; 713 + 709 714 gfx_v9_4_2_do_sgprs_init(adev); 710 715 711 716 gfx_v9_4_2_do_vgprs_init(adev);
+2 -2
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
··· 841 841 842 842 adev->gmc.mc_mask = 0xffffffffffULL; 843 843 844 - r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44)); 844 + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40)); 845 845 if (r) { 846 846 dev_warn(adev->dev, "No suitable DMA available.\n"); 847 847 return r; 848 848 } 849 - adev->need_swiotlb = drm_need_swiotlb(44); 849 + adev->need_swiotlb = drm_need_swiotlb(40); 850 850 851 851 r = gmc_v6_0_init_microcode(adev); 852 852 if (r) {
+3 -3
drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
··· 84 84 85 85 ta_hdr = (const struct ta_firmware_header_v1_0 *) 86 86 adev->psp.ta_fw->data; 87 - adev->psp.hdcp_context.context.bin_desc.feature_version = 87 + adev->psp.hdcp_context.context.bin_desc.fw_version = 88 88 le32_to_cpu(ta_hdr->hdcp.fw_version); 89 89 adev->psp.hdcp_context.context.bin_desc.size_bytes = 90 90 le32_to_cpu(ta_hdr->hdcp.size_bytes); ··· 92 92 (uint8_t *)ta_hdr + 93 93 le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); 94 94 95 - adev->psp.dtm_context.context.bin_desc.feature_version = 95 + adev->psp.dtm_context.context.bin_desc.fw_version = 96 96 le32_to_cpu(ta_hdr->dtm.fw_version); 97 97 adev->psp.dtm_context.context.bin_desc.size_bytes = 98 98 le32_to_cpu(ta_hdr->dtm.size_bytes); ··· 100 100 (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr + 101 101 le32_to_cpu(ta_hdr->dtm.offset_bytes); 102 102 103 - adev->psp.securedisplay_context.context.bin_desc.feature_version = 103 + adev->psp.securedisplay_context.context.bin_desc.fw_version = 104 104 le32_to_cpu(ta_hdr->securedisplay.fw_version); 105 105 adev->psp.securedisplay_context.context.bin_desc.size_bytes = 106 106 le32_to_cpu(ta_hdr->securedisplay.size_bytes);
+4 -4
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
··· 151 151 goto out2; 152 152 153 153 ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data; 154 - adev->psp.xgmi_context.context.bin_desc.feature_version = 154 + adev->psp.xgmi_context.context.bin_desc.fw_version = 155 155 le32_to_cpu(ta_hdr->xgmi.fw_version); 156 156 adev->psp.xgmi_context.context.bin_desc.size_bytes = 157 157 le32_to_cpu(ta_hdr->xgmi.size_bytes); ··· 159 159 (uint8_t *)ta_hdr + 160 160 le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); 161 161 adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); 162 - adev->psp.ras_context.context.bin_desc.feature_version = 162 + adev->psp.ras_context.context.bin_desc.fw_version = 163 163 le32_to_cpu(ta_hdr->ras.fw_version); 164 164 adev->psp.ras_context.context.bin_desc.size_bytes = 165 165 le32_to_cpu(ta_hdr->ras.size_bytes); ··· 192 192 goto out2; 193 193 194 194 ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data; 195 - adev->psp.hdcp_context.context.bin_desc.feature_version = 195 + adev->psp.hdcp_context.context.bin_desc.fw_version = 196 196 le32_to_cpu(ta_hdr->hdcp.fw_version); 197 197 adev->psp.hdcp_context.context.bin_desc.size_bytes = 198 198 le32_to_cpu(ta_hdr->hdcp.size_bytes); ··· 203 203 204 204 adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); 205 205 206 - adev->psp.dtm_context.context.bin_desc.feature_version = 206 + adev->psp.dtm_context.context.bin_desc.fw_version = 207 207 le32_to_cpu(ta_hdr->dtm.fw_version); 208 208 adev->psp.dtm_context.context.bin_desc.size_bytes = 209 209 le32_to_cpu(ta_hdr->dtm.size_bytes);
+2 -2
drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
··· 84 84 85 85 ta_hdr = (const struct ta_firmware_header_v1_0 *) 86 86 adev->psp.ta_fw->data; 87 - adev->psp.hdcp_context.context.bin_desc.feature_version = 87 + adev->psp.hdcp_context.context.bin_desc.fw_version = 88 88 le32_to_cpu(ta_hdr->hdcp.fw_version); 89 89 adev->psp.hdcp_context.context.bin_desc.size_bytes = 90 90 le32_to_cpu(ta_hdr->hdcp.size_bytes); ··· 94 94 95 95 adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); 96 96 97 - adev->psp.dtm_context.context.bin_desc.feature_version = 97 + adev->psp.dtm_context.context.bin_desc.fw_version = 98 98 le32_to_cpu(ta_hdr->dtm.fw_version); 99 99 adev->psp.dtm_context.context.bin_desc.size_bytes = 100 100 le32_to_cpu(ta_hdr->dtm.size_bytes);
+39 -23
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 405 405 406 406 mutex_lock(&p->mutex); 407 407 408 - retval = pqm_update_queue(&p->pqm, args->queue_id, &properties); 408 + retval = pqm_update_queue_properties(&p->pqm, args->queue_id, &properties); 409 409 410 410 mutex_unlock(&p->mutex); 411 411 ··· 418 418 int retval; 419 419 const int max_num_cus = 1024; 420 420 struct kfd_ioctl_set_cu_mask_args *args = data; 421 - struct queue_properties properties; 421 + struct mqd_update_info minfo = {0}; 422 422 uint32_t __user *cu_mask_ptr = (uint32_t __user *)args->cu_mask_ptr; 423 423 size_t cu_mask_size = sizeof(uint32_t) * (args->num_cu_mask / 32); 424 424 ··· 428 428 return -EINVAL; 429 429 } 430 430 431 - properties.cu_mask_count = args->num_cu_mask; 432 - if (properties.cu_mask_count == 0) { 431 + minfo.cu_mask.count = args->num_cu_mask; 432 + if (minfo.cu_mask.count == 0) { 433 433 pr_debug("CU mask cannot be 0"); 434 434 return -EINVAL; 435 435 } ··· 438 438 * limit of max_num_cus bits. We can then just drop any CU mask bits 439 439 * past max_num_cus bits and just use the first max_num_cus bits. 440 440 */ 441 - if (properties.cu_mask_count > max_num_cus) { 441 + if (minfo.cu_mask.count > max_num_cus) { 442 442 pr_debug("CU mask cannot be greater than 1024 bits"); 443 - properties.cu_mask_count = max_num_cus; 443 + minfo.cu_mask.count = max_num_cus; 444 444 cu_mask_size = sizeof(uint32_t) * (max_num_cus/32); 445 445 } 446 446 447 - properties.cu_mask = kzalloc(cu_mask_size, GFP_KERNEL); 448 - if (!properties.cu_mask) 447 + minfo.cu_mask.ptr = kzalloc(cu_mask_size, GFP_KERNEL); 448 + if (!minfo.cu_mask.ptr) 449 449 return -ENOMEM; 450 450 451 - retval = copy_from_user(properties.cu_mask, cu_mask_ptr, cu_mask_size); 451 + retval = copy_from_user(minfo.cu_mask.ptr, cu_mask_ptr, cu_mask_size); 452 452 if (retval) { 453 453 pr_debug("Could not copy CU mask from userspace"); 454 - kfree(properties.cu_mask); 455 - return -EFAULT; 454 + retval = -EFAULT; 455 + goto out; 456 456 } 457 + 458 + minfo.update_flag = UPDATE_FLAG_CU_MASK; 457 459 458 460 mutex_lock(&p->mutex); 459 461 460 - retval = pqm_set_cu_mask(&p->pqm, args->queue_id, &properties); 462 + retval = pqm_update_mqd(&p->pqm, args->queue_id, &minfo); 461 463 462 464 mutex_unlock(&p->mutex); 463 465 464 - if (retval) 465 - kfree(properties.cu_mask); 466 - 466 + out: 467 + kfree(minfo.cu_mask.ptr); 467 468 return retval; 468 469 } 469 470 ··· 1012 1011 void *mem, *kern_addr; 1013 1012 uint64_t size; 1014 1013 1015 - if (p->signal_page) { 1016 - pr_err("Event page is already set\n"); 1017 - return -EINVAL; 1018 - } 1019 - 1020 1014 kfd = kfd_device_by_id(GET_GPU_ID(args->event_page_offset)); 1021 1015 if (!kfd) { 1022 1016 pr_err("Getting device by id failed in %s\n", __func__); ··· 1019 1023 } 1020 1024 1021 1025 mutex_lock(&p->mutex); 1026 + 1027 + if (p->signal_page) { 1028 + pr_err("Event page is already set\n"); 1029 + err = -EINVAL; 1030 + goto out_unlock; 1031 + } 1032 + 1022 1033 pdd = kfd_bind_process_to_device(kfd, p); 1023 1034 if (IS_ERR(pdd)) { 1024 1035 err = PTR_ERR(pdd); ··· 1040 1037 err = -EINVAL; 1041 1038 goto out_unlock; 1042 1039 } 1043 - mutex_unlock(&p->mutex); 1044 1040 1045 1041 err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kfd->kgd, 1046 1042 mem, &kern_addr, &size); 1047 1043 if (err) { 1048 1044 pr_err("Failed to map event page to kernel\n"); 1049 - return err; 1045 + goto out_unlock; 1050 1046 } 1051 1047 1052 1048 err = kfd_event_page_set(p, kern_addr, size); 1053 1049 if (err) { 1054 1050 pr_err("Failed to set event page\n"); 1055 - return err; 1051 + amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kfd->kgd, mem); 1052 + goto out_unlock; 1056 1053 } 1054 + 1055 + p->signal_handle = args->event_page_offset; 1056 + 1057 + mutex_unlock(&p->mutex); 1057 1058 } 1058 1059 1059 1060 err = kfd_event_create(filp, p, args->event_type, ··· 1375 1368 return -EINVAL; 1376 1369 1377 1370 mutex_lock(&p->mutex); 1371 + /* 1372 + * Safeguard to prevent user space from freeing signal BO. 1373 + * It will be freed at process termination. 1374 + */ 1375 + if (p->signal_handle && (p->signal_handle == args->handle)) { 1376 + pr_err("Free signal BO is not allowed\n"); 1377 + ret = -EPERM; 1378 + goto err_unlock; 1379 + } 1378 1380 1379 1381 pdd = kfd_get_process_device_data(dev, p); 1380 1382 if (!pdd) {
+3 -2
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
··· 557 557 return retval; 558 558 } 559 559 560 - static int update_queue(struct device_queue_manager *dqm, struct queue *q) 560 + static int update_queue(struct device_queue_manager *dqm, struct queue *q, 561 + struct mqd_update_info *minfo) 561 562 { 562 563 int retval = 0; 563 564 struct mqd_manager *mqd_mgr; ··· 606 605 } 607 606 } 608 607 609 - mqd_mgr->update_mqd(mqd_mgr, q->mqd, &q->properties); 608 + mqd_mgr->update_mqd(mqd_mgr, q->mqd, &q->properties, minfo); 610 609 611 610 /* 612 611 * check active state vs. the previous state and modify
+1 -1
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
··· 93 93 struct queue *q); 94 94 95 95 int (*update_queue)(struct device_queue_manager *dqm, 96 - struct queue *q); 96 + struct queue *q, struct mqd_update_info *minfo); 97 97 98 98 int (*register_process)(struct device_queue_manager *dqm, 99 99 struct qcm_process_device *qpd);
-1
drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
··· 136 136 prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr; 137 137 prop.eop_ring_buffer_address = kq->eop_gpu_addr; 138 138 prop.eop_ring_buffer_size = PAGE_SIZE; 139 - prop.cu_mask = NULL; 140 139 141 140 if (init_queue(&kq->queue, &prop) != 0) 142 141 goto err_init_queue;
+2 -1
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
··· 80 80 struct mm_struct *mms); 81 81 82 82 void (*update_mqd)(struct mqd_manager *mm, void *mqd, 83 - struct queue_properties *q); 83 + struct queue_properties *q, 84 + struct mqd_update_info *minfo); 84 85 85 86 int (*destroy_mqd)(struct mqd_manager *mm, void *mqd, 86 87 enum kfd_preempt_type type,
+19 -13
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
··· 42 42 } 43 43 44 44 static void update_cu_mask(struct mqd_manager *mm, void *mqd, 45 - struct queue_properties *q) 45 + struct mqd_update_info *minfo) 46 46 { 47 47 struct cik_mqd *m; 48 48 uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */ 49 49 50 - if (q->cu_mask_count == 0) 50 + if (!minfo || (minfo->update_flag != UPDATE_FLAG_CU_MASK) || 51 + !minfo->cu_mask.ptr) 51 52 return; 52 53 53 54 mqd_symmetrically_map_cu_mask(mm, 54 - q->cu_mask, q->cu_mask_count, se_mask); 55 + minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); 55 56 56 57 m = get_mqd(mqd); 57 58 m->compute_static_thread_mgmt_se0 = se_mask[0]; ··· 136 135 *mqd = m; 137 136 if (gart_addr) 138 137 *gart_addr = addr; 139 - mm->update_mqd(mm, m, q); 138 + mm->update_mqd(mm, m, q, NULL); 140 139 } 141 140 142 141 static void init_mqd_sdma(struct mqd_manager *mm, void **mqd, ··· 153 152 if (gart_addr) 154 153 *gart_addr = mqd_mem_obj->gpu_addr; 155 154 156 - mm->update_mqd(mm, m, q); 155 + mm->update_mqd(mm, m, q, NULL); 157 156 } 158 157 159 158 static void free_mqd(struct mqd_manager *mm, void *mqd, ··· 186 185 } 187 186 188 187 static void __update_mqd(struct mqd_manager *mm, void *mqd, 189 - struct queue_properties *q, unsigned int atc_bit) 188 + struct queue_properties *q, struct mqd_update_info *minfo, 189 + unsigned int atc_bit) 190 190 { 191 191 struct cik_mqd *m; 192 192 ··· 216 214 if (q->format == KFD_QUEUE_FORMAT_AQL) 217 215 m->cp_hqd_pq_control |= NO_UPDATE_RPTR; 218 216 219 - update_cu_mask(mm, mqd, q); 217 + update_cu_mask(mm, mqd, minfo); 220 218 set_priority(m, q); 221 219 222 220 q->is_active = QUEUE_IS_ACTIVE(*q); 223 221 } 224 222 225 223 static void update_mqd(struct mqd_manager *mm, void *mqd, 226 - struct queue_properties *q) 224 + struct queue_properties *q, 225 + struct mqd_update_info *minfo) 227 226 { 228 - __update_mqd(mm, mqd, q, 1); 227 + __update_mqd(mm, mqd, q, minfo, 1); 229 228 } 230 229 231 230 static uint32_t read_doorbell_id(void *mqd) ··· 237 234 } 238 235 239 236 static void update_mqd_hawaii(struct mqd_manager *mm, void *mqd, 240 - struct queue_properties *q) 237 + struct queue_properties *q, 238 + struct mqd_update_info *minfo) 241 239 { 242 - __update_mqd(mm, mqd, q, 0); 240 + __update_mqd(mm, mqd, q, minfo, 0); 243 241 } 244 242 245 243 static void update_mqd_sdma(struct mqd_manager *mm, void *mqd, 246 - struct queue_properties *q) 244 + struct queue_properties *q, 245 + struct mqd_update_info *minfo) 247 246 { 248 247 struct cik_sdma_rlc_registers *m; 249 248 ··· 323 318 } 324 319 325 320 static void update_mqd_hiq(struct mqd_manager *mm, void *mqd, 326 - struct queue_properties *q) 321 + struct queue_properties *q, 322 + struct mqd_update_info *minfo) 327 323 { 328 324 struct cik_mqd *m; 329 325
+11 -8
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
··· 42 42 } 43 43 44 44 static void update_cu_mask(struct mqd_manager *mm, void *mqd, 45 - struct queue_properties *q) 45 + struct mqd_update_info *minfo) 46 46 { 47 47 struct v10_compute_mqd *m; 48 48 uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */ 49 49 50 - if (q->cu_mask_count == 0) 50 + if (!minfo || (minfo->update_flag != UPDATE_FLAG_CU_MASK) || 51 + !minfo->cu_mask.ptr) 51 52 return; 52 53 53 54 mqd_symmetrically_map_cu_mask(mm, 54 - q->cu_mask, q->cu_mask_count, se_mask); 55 + minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); 55 56 56 57 m = get_mqd(mqd); 57 58 m->compute_static_thread_mgmt_se0 = se_mask[0]; ··· 137 136 *mqd = m; 138 137 if (gart_addr) 139 138 *gart_addr = addr; 140 - mm->update_mqd(mm, m, q); 139 + mm->update_mqd(mm, m, q, NULL); 141 140 } 142 141 143 142 static int load_mqd(struct mqd_manager *mm, void *mqd, ··· 163 162 } 164 163 165 164 static void update_mqd(struct mqd_manager *mm, void *mqd, 166 - struct queue_properties *q) 165 + struct queue_properties *q, 166 + struct mqd_update_info *minfo) 167 167 { 168 168 struct v10_compute_mqd *m; 169 169 ··· 220 218 if (mm->dev->cwsr_enabled) 221 219 m->cp_hqd_ctx_save_control = 0; 222 220 223 - update_cu_mask(mm, mqd, q); 221 + update_cu_mask(mm, mqd, minfo); 224 222 set_priority(m, q); 225 223 226 224 q->is_active = QUEUE_IS_ACTIVE(*q); ··· 313 311 if (gart_addr) 314 312 *gart_addr = mqd_mem_obj->gpu_addr; 315 313 316 - mm->update_mqd(mm, m, q); 314 + mm->update_mqd(mm, m, q, NULL); 317 315 } 318 316 319 317 static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, ··· 328 326 #define SDMA_RLC_DUMMY_DEFAULT 0xf 329 327 330 328 static void update_mqd_sdma(struct mqd_manager *mm, void *mqd, 331 - struct queue_properties *q) 329 + struct queue_properties *q, 330 + struct mqd_update_info *minfo) 332 331 { 333 332 struct v10_sdma_mqd *m; 334 333
+11 -8
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
··· 43 43 } 44 44 45 45 static void update_cu_mask(struct mqd_manager *mm, void *mqd, 46 - struct queue_properties *q) 46 + struct mqd_update_info *minfo) 47 47 { 48 48 struct v9_mqd *m; 49 49 uint32_t se_mask[KFD_MAX_NUM_SE] = {0}; 50 50 51 - if (q->cu_mask_count == 0) 51 + if (!minfo || (minfo->update_flag != UPDATE_FLAG_CU_MASK) || 52 + !minfo->cu_mask.ptr) 52 53 return; 53 54 54 55 mqd_symmetrically_map_cu_mask(mm, 55 - q->cu_mask, q->cu_mask_count, se_mask); 56 + minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); 56 57 57 58 m = get_mqd(mqd); 58 59 m->compute_static_thread_mgmt_se0 = se_mask[0]; ··· 189 188 *mqd = m; 190 189 if (gart_addr) 191 190 *gart_addr = addr; 192 - mm->update_mqd(mm, m, q); 191 + mm->update_mqd(mm, m, q, NULL); 193 192 } 194 193 195 194 static int load_mqd(struct mqd_manager *mm, void *mqd, ··· 213 212 } 214 213 215 214 static void update_mqd(struct mqd_manager *mm, void *mqd, 216 - struct queue_properties *q) 215 + struct queue_properties *q, 216 + struct mqd_update_info *minfo) 217 217 { 218 218 struct v9_mqd *m; 219 219 ··· 271 269 if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address) 272 270 m->cp_hqd_ctx_save_control = 0; 273 271 274 - update_cu_mask(mm, mqd, q); 272 + update_cu_mask(mm, mqd, minfo); 275 273 set_priority(m, q); 276 274 277 275 q->is_active = QUEUE_IS_ACTIVE(*q); ··· 368 366 if (gart_addr) 369 367 *gart_addr = mqd_mem_obj->gpu_addr; 370 368 371 - mm->update_mqd(mm, m, q); 369 + mm->update_mqd(mm, m, q, NULL); 372 370 } 373 371 374 372 static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, ··· 383 381 #define SDMA_RLC_DUMMY_DEFAULT 0xf 384 382 385 383 static void update_mqd_sdma(struct mqd_manager *mm, void *mqd, 386 - struct queue_properties *q) 384 + struct queue_properties *q, 385 + struct mqd_update_info *minfo) 387 386 { 388 387 struct v9_sdma_mqd *m; 389 388
+20 -15
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
··· 45 45 } 46 46 47 47 static void update_cu_mask(struct mqd_manager *mm, void *mqd, 48 - struct queue_properties *q) 48 + struct mqd_update_info *minfo) 49 49 { 50 50 struct vi_mqd *m; 51 51 uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */ 52 52 53 - if (q->cu_mask_count == 0) 53 + if (!minfo || (minfo->update_flag != UPDATE_FLAG_CU_MASK) || 54 + !minfo->cu_mask.ptr) 54 55 return; 55 56 56 57 mqd_symmetrically_map_cu_mask(mm, 57 - q->cu_mask, q->cu_mask_count, se_mask); 58 + minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); 58 59 59 60 m = get_mqd(mqd); 60 61 m->compute_static_thread_mgmt_se0 = se_mask[0]; ··· 151 150 *mqd = m; 152 151 if (gart_addr) 153 152 *gart_addr = addr; 154 - mm->update_mqd(mm, m, q); 153 + mm->update_mqd(mm, m, q, NULL); 155 154 } 156 155 157 156 static int load_mqd(struct mqd_manager *mm, void *mqd, ··· 168 167 } 169 168 170 169 static void __update_mqd(struct mqd_manager *mm, void *mqd, 171 - struct queue_properties *q, unsigned int mtype, 172 - unsigned int atc_bit) 170 + struct queue_properties *q, struct mqd_update_info *minfo, 171 + unsigned int mtype, unsigned int atc_bit) 173 172 { 174 173 struct vi_mqd *m; 175 174 ··· 231 230 atc_bit << CP_HQD_CTX_SAVE_CONTROL__ATC__SHIFT | 232 231 mtype << CP_HQD_CTX_SAVE_CONTROL__MTYPE__SHIFT; 233 232 234 - update_cu_mask(mm, mqd, q); 233 + update_cu_mask(mm, mqd, minfo); 235 234 set_priority(m, q); 236 235 237 236 q->is_active = QUEUE_IS_ACTIVE(*q); ··· 239 238 240 239 241 240 static void update_mqd(struct mqd_manager *mm, void *mqd, 242 - struct queue_properties *q) 241 + struct queue_properties *q, 242 + struct mqd_update_info *minfo) 243 243 { 244 - __update_mqd(mm, mqd, q, MTYPE_CC, 1); 244 + __update_mqd(mm, mqd, q, minfo, MTYPE_CC, 1); 245 245 } 246 246 247 247 static uint32_t read_doorbell_id(void *mqd) ··· 253 251 } 254 252 255 253 static void update_mqd_tonga(struct mqd_manager *mm, void *mqd, 256 - struct queue_properties *q) 254 + struct queue_properties *q, 255 + struct mqd_update_info *minfo) 257 256 { 258 - __update_mqd(mm, mqd, q, MTYPE_UC, 0); 257 + __update_mqd(mm, mqd, q, minfo, MTYPE_UC, 0); 259 258 } 260 259 261 260 static int destroy_mqd(struct mqd_manager *mm, void *mqd, ··· 320 317 } 321 318 322 319 static void update_mqd_hiq(struct mqd_manager *mm, void *mqd, 323 - struct queue_properties *q) 320 + struct queue_properties *q, 321 + struct mqd_update_info *minfo) 324 322 { 325 - __update_mqd(mm, mqd, q, MTYPE_UC, 0); 323 + __update_mqd(mm, mqd, q, minfo, MTYPE_UC, 0); 326 324 } 327 325 328 326 static void init_mqd_sdma(struct mqd_manager *mm, void **mqd, ··· 340 336 if (gart_addr) 341 337 *gart_addr = mqd_mem_obj->gpu_addr; 342 338 343 - mm->update_mqd(mm, m, q); 339 + mm->update_mqd(mm, m, q, NULL); 344 340 } 345 341 346 342 static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, ··· 353 349 } 354 350 355 351 static void update_mqd_sdma(struct mqd_manager *mm, void *mqd, 356 - struct queue_properties *q) 352 + struct queue_properties *q, 353 + struct mqd_update_info *minfo) 357 354 { 358 355 struct vi_sdma_mqd *m; 359 356
+20 -6
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
··· 472 472 uint32_t ctl_stack_size; 473 473 uint64_t tba_addr; 474 474 uint64_t tma_addr; 475 - /* Relevant for CU */ 476 - uint32_t cu_mask_count; /* Must be a multiple of 32 */ 477 - uint32_t *cu_mask; 478 475 }; 479 476 480 477 #define QUEUE_IS_ACTIVE(q) ((q).queue_size > 0 && \ 481 478 (q).queue_address != 0 && \ 482 479 (q).queue_percent > 0 && \ 483 480 !(q).is_evicted) 481 + 482 + enum mqd_update_flag { 483 + UPDATE_FLAG_CU_MASK = 0, 484 + }; 485 + 486 + struct mqd_update_info { 487 + union { 488 + struct { 489 + uint32_t count; /* Must be a multiple of 32 */ 490 + uint32_t *ptr; 491 + } cu_mask; 492 + }; 493 + enum mqd_update_flag update_flag; 494 + }; 484 495 485 496 /** 486 497 * struct queue ··· 619 608 uint32_t sh_hidden_private_base; 620 609 621 610 /* CWSR memory */ 611 + struct kgd_mem *cwsr_mem; 622 612 void *cwsr_kaddr; 623 613 uint64_t cwsr_base; 624 614 uint64_t tba_addr; 625 615 uint64_t tma_addr; 626 616 627 617 /* IB memory */ 618 + struct kgd_mem *ib_mem; 628 619 uint64_t ib_base; 629 620 void *ib_kaddr; 630 621 ··· 821 808 /* Event ID allocator and lookup */ 822 809 struct idr event_idr; 823 810 /* Event page */ 811 + u64 signal_handle; 824 812 struct kfd_signal_page *signal_page; 825 813 size_t signal_mapped_size; 826 814 size_t signal_event_count; ··· 1045 1031 unsigned int *qid, 1046 1032 uint32_t *p_doorbell_offset_in_process); 1047 1033 int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid); 1048 - int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, 1034 + int pqm_update_queue_properties(struct process_queue_manager *pqm, unsigned int qid, 1049 1035 struct queue_properties *p); 1050 - int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid, 1051 - struct queue_properties *p); 1036 + int pqm_update_mqd(struct process_queue_manager *pqm, unsigned int qid, 1037 + struct mqd_update_info *minfo); 1052 1038 int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid, 1053 1039 void *gws); 1054 1040 struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
+80 -29
drivers/gpu/drm/amd/amdkfd/kfd_process.c
··· 72 72 static void evict_process_worker(struct work_struct *work); 73 73 static void restore_process_worker(struct work_struct *work); 74 74 75 + static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd); 76 + 75 77 struct kfd_procfs_tree { 76 78 struct kobject *kobj; 77 79 }; ··· 687 685 } 688 686 689 687 static void kfd_process_free_gpuvm(struct kgd_mem *mem, 690 - struct kfd_process_device *pdd) 688 + struct kfd_process_device *pdd, void *kptr) 691 689 { 692 690 struct kfd_dev *dev = pdd->dev; 691 + 692 + if (kptr) { 693 + amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(dev->kgd, mem); 694 + kptr = NULL; 695 + } 693 696 694 697 amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->kgd, mem, pdd->drm_priv); 695 698 amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, mem, pdd->drm_priv, ··· 709 702 */ 710 703 static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd, 711 704 uint64_t gpu_va, uint32_t size, 712 - uint32_t flags, void **kptr) 705 + uint32_t flags, struct kgd_mem **mem, void **kptr) 713 706 { 714 707 struct kfd_dev *kdev = pdd->dev; 715 - struct kgd_mem *mem = NULL; 716 - int handle; 717 708 int err; 718 709 719 710 err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(kdev->kgd, gpu_va, size, 720 - pdd->drm_priv, &mem, NULL, flags); 711 + pdd->drm_priv, mem, NULL, flags); 721 712 if (err) 722 713 goto err_alloc_mem; 723 714 724 - err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, mem, 715 + err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, *mem, 725 716 pdd->drm_priv, NULL); 726 717 if (err) 727 718 goto err_map_mem; 728 719 729 - err = amdgpu_amdkfd_gpuvm_sync_memory(kdev->kgd, mem, true); 720 + err = amdgpu_amdkfd_gpuvm_sync_memory(kdev->kgd, *mem, true); 730 721 if (err) { 731 722 pr_debug("Sync memory failed, wait interrupted by user signal\n"); 732 723 goto sync_memory_failed; 733 724 } 734 725 735 - /* Create an obj handle so kfd_process_device_remove_obj_handle 736 - * will take care of the bo removal when the process finishes. 737 - * We do not need to take p->mutex, because the process is just 738 - * created and the ioctls have not had the chance to run. 739 - */ 740 - handle = kfd_process_device_create_obj_handle(pdd, mem); 741 - 742 - if (handle < 0) { 743 - err = handle; 744 - goto free_gpuvm; 745 - } 746 - 747 726 if (kptr) { 748 727 err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kdev->kgd, 749 - (struct kgd_mem *)mem, kptr, NULL); 728 + (struct kgd_mem *)*mem, kptr, NULL); 750 729 if (err) { 751 730 pr_debug("Map GTT BO to kernel failed\n"); 752 - goto free_obj_handle; 731 + goto sync_memory_failed; 753 732 } 754 733 } 755 734 756 735 return err; 757 736 758 - free_obj_handle: 759 - kfd_process_device_remove_obj_handle(pdd, handle); 760 - free_gpuvm: 761 737 sync_memory_failed: 762 - kfd_process_free_gpuvm(mem, pdd); 763 - return err; 738 + amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(kdev->kgd, *mem, pdd->drm_priv); 764 739 765 740 err_map_mem: 766 - amdgpu_amdkfd_gpuvm_free_memory_of_gpu(kdev->kgd, mem, pdd->drm_priv, 741 + amdgpu_amdkfd_gpuvm_free_memory_of_gpu(kdev->kgd, *mem, pdd->drm_priv, 767 742 NULL); 768 743 err_alloc_mem: 744 + *mem = NULL; 769 745 *kptr = NULL; 770 746 return err; 771 747 } ··· 766 776 KFD_IOC_ALLOC_MEM_FLAGS_NO_SUBSTITUTE | 767 777 KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE | 768 778 KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE; 779 + struct kgd_mem *mem; 769 780 void *kaddr; 770 781 int ret; 771 782 ··· 775 784 776 785 /* ib_base is only set for dGPU */ 777 786 ret = kfd_process_alloc_gpuvm(pdd, qpd->ib_base, PAGE_SIZE, flags, 778 - &kaddr); 787 + &mem, &kaddr); 779 788 if (ret) 780 789 return ret; 781 790 791 + qpd->ib_mem = mem; 782 792 qpd->ib_kaddr = kaddr; 783 793 784 794 return 0; 795 + } 796 + 797 + static void kfd_process_device_destroy_ib_mem(struct kfd_process_device *pdd) 798 + { 799 + struct qcm_process_device *qpd = &pdd->qpd; 800 + 801 + if (!qpd->ib_kaddr || !qpd->ib_base) 802 + return; 803 + 804 + kfd_process_free_gpuvm(qpd->ib_mem, pdd, qpd->ib_kaddr); 785 805 } 786 806 787 807 struct kfd_process *kfd_create_process(struct file *filep) ··· 949 947 } 950 948 } 951 949 950 + /* 951 + * Just kunmap and unpin signal BO here. It will be freed in 952 + * kfd_process_free_outstanding_kfd_bos() 953 + */ 954 + static void kfd_process_kunmap_signal_bo(struct kfd_process *p) 955 + { 956 + struct kfd_process_device *pdd; 957 + struct kfd_dev *kdev; 958 + void *mem; 959 + 960 + kdev = kfd_device_by_id(GET_GPU_ID(p->signal_handle)); 961 + if (!kdev) 962 + return; 963 + 964 + mutex_lock(&p->mutex); 965 + 966 + pdd = kfd_get_process_device_data(kdev, p); 967 + if (!pdd) 968 + goto out; 969 + 970 + mem = kfd_process_device_translate_handle( 971 + pdd, GET_IDR_HANDLE(p->signal_handle)); 972 + if (!mem) 973 + goto out; 974 + 975 + amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kdev->kgd, mem); 976 + 977 + out: 978 + mutex_unlock(&p->mutex); 979 + } 980 + 952 981 static void kfd_process_free_outstanding_kfd_bos(struct kfd_process *p) 953 982 { 954 983 int i; ··· 997 964 998 965 pr_debug("Releasing pdd (topology id %d) for process (pasid 0x%x)\n", 999 966 pdd->dev->id, p->pasid); 967 + 968 + kfd_process_device_destroy_cwsr_dgpu(pdd); 969 + kfd_process_device_destroy_ib_mem(pdd); 1000 970 1001 971 if (pdd->drm_file) { 1002 972 amdgpu_amdkfd_gpuvm_release_process_vm( ··· 1085 1049 { 1086 1050 struct kfd_process *p = container_of(work, struct kfd_process, 1087 1051 release_work); 1052 + 1088 1053 kfd_process_remove_sysfs(p); 1089 1054 kfd_iommu_unbind_process(p); 1090 1055 1056 + kfd_process_kunmap_signal_bo(p); 1091 1057 kfd_process_free_outstanding_kfd_bos(p); 1092 1058 svm_range_list_fini(p); 1093 1059 ··· 1236 1198 uint32_t flags = KFD_IOC_ALLOC_MEM_FLAGS_GTT 1237 1199 | KFD_IOC_ALLOC_MEM_FLAGS_NO_SUBSTITUTE 1238 1200 | KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE; 1201 + struct kgd_mem *mem; 1239 1202 void *kaddr; 1240 1203 int ret; 1241 1204 ··· 1245 1206 1246 1207 /* cwsr_base is only set for dGPU */ 1247 1208 ret = kfd_process_alloc_gpuvm(pdd, qpd->cwsr_base, 1248 - KFD_CWSR_TBA_TMA_SIZE, flags, &kaddr); 1209 + KFD_CWSR_TBA_TMA_SIZE, flags, &mem, &kaddr); 1249 1210 if (ret) 1250 1211 return ret; 1251 1212 1213 + qpd->cwsr_mem = mem; 1252 1214 qpd->cwsr_kaddr = kaddr; 1253 1215 qpd->tba_addr = qpd->cwsr_base; 1254 1216 ··· 1260 1220 qpd->tba_addr, qpd->tma_addr, qpd->cwsr_kaddr); 1261 1221 1262 1222 return 0; 1223 + } 1224 + 1225 + static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd) 1226 + { 1227 + struct kfd_dev *dev = pdd->dev; 1228 + struct qcm_process_device *qpd = &pdd->qpd; 1229 + 1230 + if (!dev->cwsr_enabled || !qpd->cwsr_kaddr || !qpd->cwsr_base) 1231 + return; 1232 + 1233 + kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, qpd->cwsr_kaddr); 1263 1234 } 1264 1235 1265 1236 void kfd_process_set_trap_handler(struct qcm_process_device *qpd,
+7 -17
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
··· 121 121 pdd->qpd.num_gws = gws ? amdgpu_amdkfd_get_num_gws(dev->kgd) : 0; 122 122 123 123 return pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm, 124 - pqn->q); 124 + pqn->q, NULL); 125 125 } 126 126 127 127 void kfd_process_dequeue_from_all_devices(struct kfd_process *p) ··· 394 394 pdd->qpd.num_gws = 0; 395 395 } 396 396 397 - kfree(pqn->q->properties.cu_mask); 398 - pqn->q->properties.cu_mask = NULL; 399 397 uninit_queue(pqn->q); 400 398 } 401 399 ··· 409 411 return retval; 410 412 } 411 413 412 - int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, 413 - struct queue_properties *p) 414 + int pqm_update_queue_properties(struct process_queue_manager *pqm, 415 + unsigned int qid, struct queue_properties *p) 414 416 { 415 417 int retval; 416 418 struct process_queue_node *pqn; ··· 427 429 pqn->q->properties.priority = p->priority; 428 430 429 431 retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm, 430 - pqn->q); 432 + pqn->q, NULL); 431 433 if (retval != 0) 432 434 return retval; 433 435 434 436 return 0; 435 437 } 436 438 437 - int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid, 438 - struct queue_properties *p) 439 + int pqm_update_mqd(struct process_queue_manager *pqm, 440 + unsigned int qid, struct mqd_update_info *minfo) 439 441 { 440 442 int retval; 441 443 struct process_queue_node *pqn; ··· 446 448 return -EFAULT; 447 449 } 448 450 449 - /* Free the old CU mask memory if it is already allocated, then 450 - * allocate memory for the new CU mask. 451 - */ 452 - kfree(pqn->q->properties.cu_mask); 453 - 454 - pqn->q->properties.cu_mask_count = p->cu_mask_count; 455 - pqn->q->properties.cu_mask = p->cu_mask; 456 - 457 451 retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm, 458 - pqn->q); 452 + pqn->q, minfo); 459 453 if (retval != 0) 460 454 return retval; 461 455
+64 -8
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 730 730 dmub_hpd_wrk->adev->dm.dmub_callback[dmub_hpd_wrk->dmub_notify->type](dmub_hpd_wrk->adev, 731 731 dmub_hpd_wrk->dmub_notify); 732 732 } 733 + 734 + kfree(dmub_hpd_wrk->dmub_notify); 733 735 kfree(dmub_hpd_wrk); 734 736 735 737 } ··· 757 755 758 756 if (dc_enable_dmub_notifications(adev->dm.dc) && 759 757 irq_params->irq_src == DC_IRQ_SOURCE_DMCUB_OUTBOX) { 760 - dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC); 761 - if (!dmub_hpd_wrk) { 762 - DRM_ERROR("Failed to allocate dmub_hpd_wrk"); 763 - return; 764 - } 765 - INIT_WORK(&dmub_hpd_wrk->handle_hpd_work, dm_handle_hpd_work); 766 758 767 759 do { 768 760 dc_stat_get_dmub_notification(adev->dm.dc, &notify); ··· 765 769 continue; 766 770 } 767 771 if (dm->dmub_thread_offload[notify.type] == true) { 768 - dmub_hpd_wrk->dmub_notify = &notify; 772 + dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC); 773 + if (!dmub_hpd_wrk) { 774 + DRM_ERROR("Failed to allocate dmub_hpd_wrk"); 775 + return; 776 + } 777 + dmub_hpd_wrk->dmub_notify = kzalloc(sizeof(struct dmub_notification), GFP_ATOMIC); 778 + if (!dmub_hpd_wrk->dmub_notify) { 779 + kfree(dmub_hpd_wrk); 780 + DRM_ERROR("Failed to allocate dmub_hpd_wrk->dmub_notify"); 781 + return; 782 + } 783 + INIT_WORK(&dmub_hpd_wrk->handle_hpd_work, dm_handle_hpd_work); 784 + if (dmub_hpd_wrk->dmub_notify) 785 + memcpy(dmub_hpd_wrk->dmub_notify, &notify, sizeof(struct dmub_notification)); 769 786 dmub_hpd_wrk->adev = adev; 770 787 if (notify.type == DMUB_NOTIFICATION_HPD) { 771 788 plink = adev->dm.dc->links[notify.link_index]; ··· 1017 1008 const unsigned char *fw_inst_const, *fw_bss_data; 1018 1009 uint32_t i, fw_inst_const_size, fw_bss_data_size; 1019 1010 bool has_hw_support; 1011 + struct dc *dc = adev->dm.dc; 1020 1012 1021 1013 if (!dmub_srv) 1022 1014 /* DMUB isn't supported on the ASIC. */ ··· 1103 1093 1104 1094 for (i = 0; i < fb_info->num_fb; ++i) 1105 1095 hw_params.fb[i] = &fb_info->fb[i]; 1096 + 1097 + switch (adev->asic_type) { 1098 + case CHIP_YELLOW_CARP: 1099 + if (dc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_A0) { 1100 + hw_params.dpia_supported = true; 1101 + #if defined(CONFIG_DRM_AMD_DC_DCN) 1102 + hw_params.disable_dpia = dc->debug.dpia_debug.bits.disable_dpia; 1103 + #endif 1104 + } 1105 + break; 1106 + default: 1107 + break; 1108 + } 1106 1109 1107 1110 status = dmub_srv_hw_init(dmub_srv, &hw_params); 1108 1111 if (status != DMUB_STATUS_OK) { ··· 1318 1295 return hpd_rx_offload_wq; 1319 1296 } 1320 1297 1298 + struct amdgpu_stutter_quirk { 1299 + u16 chip_vendor; 1300 + u16 chip_device; 1301 + u16 subsys_vendor; 1302 + u16 subsys_device; 1303 + u8 revision; 1304 + }; 1305 + 1306 + static const struct amdgpu_stutter_quirk amdgpu_stutter_quirk_list[] = { 1307 + /* https://bugzilla.kernel.org/show_bug.cgi?id=214417 */ 1308 + { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 }, 1309 + { 0, 0, 0, 0, 0 }, 1310 + }; 1311 + 1312 + static bool dm_should_disable_stutter(struct pci_dev *pdev) 1313 + { 1314 + const struct amdgpu_stutter_quirk *p = amdgpu_stutter_quirk_list; 1315 + 1316 + while (p && p->chip_device != 0) { 1317 + if (pdev->vendor == p->chip_vendor && 1318 + pdev->device == p->chip_device && 1319 + pdev->subsystem_vendor == p->subsys_vendor && 1320 + pdev->subsystem_device == p->subsys_device && 1321 + pdev->revision == p->revision) { 1322 + return true; 1323 + } 1324 + ++p; 1325 + } 1326 + return false; 1327 + } 1328 + 1321 1329 static int amdgpu_dm_init(struct amdgpu_device *adev) 1322 1330 { 1323 1331 struct dc_init_data init_data; ··· 1460 1406 1461 1407 if (adev->asic_type != CHIP_CARRIZO && adev->asic_type != CHIP_STONEY) 1462 1408 adev->dm.dc->debug.disable_stutter = amdgpu_pp_feature_mask & PP_STUTTER_MODE ? false : true; 1409 + if (dm_should_disable_stutter(adev->pdev)) 1410 + adev->dm.dc->debug.disable_stutter = true; 1463 1411 1464 1412 if (amdgpu_dc_debug_mask & DC_DISABLE_STUTTER) 1465 1413 adev->dm.dc->debug.disable_stutter = true; ··· 1848 1792 break; 1849 1793 case IP_VERSION(3, 1, 2): 1850 1794 case IP_VERSION(3, 1, 3): 1851 - dmub_asic = DMUB_ASIC_DCN31; 1795 + dmub_asic = (adev->external_rev_id == YELLOW_CARP_B0) ? DMUB_ASIC_DCN31B : DMUB_ASIC_DCN31; 1852 1796 fw_name_dmub = FIRMWARE_YELLOW_CARP_DMUB; 1853 1797 break; 1854 1798
+9 -9
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
··· 491 491 if (!wr_buf) 492 492 return -ENOSPC; 493 493 494 - if (parse_write_buffer_into_params(wr_buf, size, 494 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 495 495 (long *)param, buf, 496 496 max_param_num, 497 497 &param_nums)) { ··· 643 643 if (!wr_buf) 644 644 return -ENOSPC; 645 645 646 - if (parse_write_buffer_into_params(wr_buf, size, 646 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 647 647 (long *)param, buf, 648 648 max_param_num, 649 649 &param_nums)) { ··· 918 918 return -ENOSPC; 919 919 } 920 920 921 - if (parse_write_buffer_into_params(wr_buf, size, 921 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 922 922 &param, buf, 923 923 max_param_num, 924 924 &param_nums)) { ··· 1215 1215 return -ENOSPC; 1216 1216 } 1217 1217 1218 - if (parse_write_buffer_into_params(wr_buf, size, 1218 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 1219 1219 (long *)param, buf, 1220 1220 max_param_num, 1221 1221 &param_nums)) { ··· 1400 1400 return -ENOSPC; 1401 1401 } 1402 1402 1403 - if (parse_write_buffer_into_params(wr_buf, size, 1403 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 1404 1404 (long *)param, buf, 1405 1405 max_param_num, 1406 1406 &param_nums)) { ··· 1585 1585 return -ENOSPC; 1586 1586 } 1587 1587 1588 - if (parse_write_buffer_into_params(wr_buf, size, 1588 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 1589 1589 (long *)param, buf, 1590 1590 max_param_num, 1591 1591 &param_nums)) { ··· 1770 1770 return -ENOSPC; 1771 1771 } 1772 1772 1773 - if (parse_write_buffer_into_params(wr_buf, size, 1773 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 1774 1774 (long *)param, buf, 1775 1775 max_param_num, 1776 1776 &param_nums)) { ··· 1948 1948 return -ENOSPC; 1949 1949 } 1950 1950 1951 - if (parse_write_buffer_into_params(wr_buf, size, 1951 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 1952 1952 (long *)param, buf, 1953 1953 max_param_num, 1954 1954 &param_nums)) { ··· 2386 2386 return -ENOSPC; 2387 2387 } 2388 2388 2389 - if (parse_write_buffer_into_params(wr_buf, size, 2389 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 2390 2390 (long *)param, buf, 2391 2391 max_param_num, 2392 2392 &param_nums)) {
+2
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
··· 64 64 payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0; 65 65 payload.write = (msg->request & DP_AUX_I2C_READ) == 0; 66 66 payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0; 67 + payload.write_status_update = 68 + (msg->request & DP_AUX_I2C_WRITE_STATUS_UPDATE) != 0; 67 69 payload.defer_delay = 0; 68 70 69 71 result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload,
+8 -2
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
··· 107 107 */ 108 108 // Init fail safe of 2 frames static 109 109 unsigned int num_frames_static = 2; 110 + unsigned int power_opt = 0; 111 + bool psr_enable = true; 110 112 111 113 DRM_DEBUG_DRIVER("Enabling psr...\n"); 112 114 ··· 135 133 &stream, 1, 136 134 &params); 137 135 138 - return dc_link_set_psr_allow_active(link, true, false, false); 136 + power_opt |= psr_power_opt_z10_static_screen; 137 + 138 + return dc_link_set_psr_allow_active(link, &psr_enable, false, false, &power_opt); 139 139 } 140 140 141 141 /* ··· 148 144 */ 149 145 bool amdgpu_dm_psr_disable(struct dc_stream_state *stream) 150 146 { 147 + unsigned int power_opt = 0; 148 + bool psr_enable = false; 151 149 152 150 DRM_DEBUG_DRIVER("Disabling psr...\n"); 153 151 154 - return dc_link_set_psr_allow_active(stream->link, false, true, false); 152 + return dc_link_set_psr_allow_active(stream->link, &psr_enable, true, false, &power_opt); 155 153 } 156 154 157 155 /*
+2
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
··· 2321 2321 2322 2322 info->ext_disp_conn_info.checksum = 2323 2323 info_v2_2->extdispconninfo.checksum; 2324 + info->ext_disp_conn_info.fixdpvoltageswing = 2325 + info_v2_2->extdispconninfo.fixdpvoltageswing; 2324 2326 2325 2327 info->edp1_info.edp_backlight_pwm_hz = 2326 2328 le16_to_cpu(info_v2_2->edp1_info.edp_backlight_pwm_hz);
+6 -10
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
··· 100 100 101 101 if (edp_num) { 102 102 for (panel_inst = 0; panel_inst < edp_num; panel_inst++) { 103 + bool allow_active = false; 104 + 103 105 edp_link = edp_links[panel_inst]; 104 106 if (!edp_link->psr_settings.psr_feature_enabled) 105 107 continue; 106 108 clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active; 107 - dc_link_set_psr_allow_active(edp_link, false, false, false); 109 + dc_link_set_psr_allow_active(edp_link, &allow_active, false, false, NULL); 108 110 } 109 111 } 110 112 ··· 126 124 if (!edp_link->psr_settings.psr_feature_enabled) 127 125 continue; 128 126 dc_link_set_psr_allow_active(edp_link, 129 - clk_mgr->psr_allow_active_cache, false, false); 127 + &clk_mgr->psr_allow_active_cache, false, false, NULL); 130 128 } 131 129 } 132 130 ··· 285 283 BREAK_TO_DEBUGGER(); 286 284 return NULL; 287 285 } 288 - if (ASICREV_IS_YELLOW_CARP(asic_id.hw_internal_rev)) { 289 - /* TODO: to add DCN31 clk_mgr support, once CLK IP header files are available, 290 - * for now use DCN3.0 clk mgr. 291 - */ 292 - dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 293 - return &clk_mgr->base.base; 294 - } 286 + 287 + dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 295 288 return &clk_mgr->base.base; 296 289 } 297 290 #endif ··· 323 326 break; 324 327 325 328 case FAMILY_YELLOW_CARP: 326 - if (ASICREV_IS_YELLOW_CARP(clk_mgr_base->ctx->asic_id.hw_internal_rev)) 327 329 dcn31_clk_mgr_destroy(clk_mgr); 328 330 break; 329 331
+10 -3
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
··· 523 523 unsigned int voltage) 524 524 { 525 525 int i; 526 + int max_voltage = 0; 527 + int clock = 0; 526 528 527 529 for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) { 528 - if (clock_table->SocVoltage[i] == voltage) 530 + if (clock_table->SocVoltage[i] == voltage) { 529 531 return clocks[i]; 532 + } else if (clock_table->SocVoltage[i] >= max_voltage && 533 + clock_table->SocVoltage[i] < voltage) { 534 + max_voltage = clock_table->SocVoltage[i]; 535 + clock = clocks[i]; 536 + } 530 537 } 531 538 532 - ASSERT(0); 533 - return 0; 539 + ASSERT(clock); 540 + return clock; 534 541 } 535 542 536 543 void dcn31_clk_mgr_helper_populate_bw_params(
+67 -4
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 1897 1897 static void process_deferred_updates(struct dc *dc) 1898 1898 { 1899 1899 #ifdef CONFIG_DRM_AMD_DC_DCN 1900 - int i; 1900 + int i = 0; 1901 1901 1902 - if (dc->debug.enable_mem_low_power.bits.cm) 1902 + if (dc->debug.enable_mem_low_power.bits.cm) { 1903 + ASSERT(dc->dcn_ip->max_num_dpp); 1903 1904 for (i = 0; i < dc->dcn_ip->max_num_dpp; i++) 1904 1905 if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update) 1905 1906 dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]); 1907 + } 1906 1908 #endif 1907 1909 } 1908 1910 ··· 2285 2283 update_flags->bits.gamma_change = 1; 2286 2284 } 2287 2285 2286 + if (u->lut3d_func || u->func_shaper) 2287 + update_flags->bits.lut_3d = 1; 2288 + 2288 2289 if (u->hdr_mult.value) 2289 2290 if (u->hdr_mult.value != u->surface->hdr_mult.value) { 2290 2291 update_flags->bits.hdr_mult = 1; ··· 2301 2296 2302 2297 if (update_flags->bits.input_csc_change 2303 2298 || update_flags->bits.coeff_reduction_change 2299 + || update_flags->bits.lut_3d 2304 2300 || update_flags->bits.gamma_change 2305 2301 || update_flags->bits.gamut_remap_change) { 2306 2302 type = UPDATE_TYPE_FULL; ··· 3499 3493 bool dc_set_psr_allow_active(struct dc *dc, bool enable) 3500 3494 { 3501 3495 int i; 3496 + bool allow_active; 3502 3497 3503 3498 for (i = 0; i < dc->current_state->stream_count ; i++) { 3504 3499 struct dc_link *link; ··· 3511 3504 3512 3505 if (link->psr_settings.psr_feature_enabled) { 3513 3506 if (enable && !link->psr_settings.psr_allow_active) { 3514 - if (!dc_link_set_psr_allow_active(link, true, false, false)) 3507 + allow_active = true; 3508 + if (!dc_link_set_psr_allow_active(link, &allow_active, false, false, NULL)) 3515 3509 return false; 3516 3510 } else if (!enable && link->psr_settings.psr_allow_active) { 3517 - if (!dc_link_set_psr_allow_active(link, false, true, false)) 3511 + allow_active = false; 3512 + if (!dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL)) 3518 3513 return false; 3519 3514 } 3520 3515 } ··· 3748 3739 is_cmd_complete = false; 3749 3740 3750 3741 return is_cmd_complete; 3742 + } 3743 + 3744 + /** 3745 + ***************************************************************************** 3746 + * Function: dc_process_dmub_set_mst_slots 3747 + * 3748 + * @brief 3749 + * Submits mst slot allocation command to dmub via inbox message 3750 + * 3751 + * @param 3752 + * [in] dc: dc structure 3753 + * [in] link_index: link index 3754 + * [in] mst_alloc_slots: mst slots to be allotted 3755 + * [out] mst_slots_in_use: mst slots in use returned in failure case 3756 + * 3757 + * @return 3758 + * DC_OK if successful, DC_ERROR if failure 3759 + ***************************************************************************** 3760 + */ 3761 + enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc, 3762 + uint32_t link_index, 3763 + uint8_t mst_alloc_slots, 3764 + uint8_t *mst_slots_in_use) 3765 + { 3766 + union dmub_rb_cmd cmd = {0}; 3767 + struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; 3768 + 3769 + /* prepare MST_ALLOC_SLOTS command */ 3770 + cmd.set_mst_alloc_slots.header.type = DMUB_CMD__DPIA; 3771 + cmd.set_mst_alloc_slots.header.sub_type = DMUB_CMD__DPIA_MST_ALLOC_SLOTS; 3772 + 3773 + cmd.set_mst_alloc_slots.mst_slots_control.instance = dc->links[link_index]->ddc_hw_inst; 3774 + cmd.set_mst_alloc_slots.mst_slots_control.mst_alloc_slots = mst_alloc_slots; 3775 + 3776 + if (!dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd)) 3777 + /* command is not processed by dmub */ 3778 + return DC_ERROR_UNEXPECTED; 3779 + 3780 + /* command processed by dmub, if ret_status is 1 */ 3781 + if (cmd.set_config_access.header.ret_status != 1) 3782 + /* command processing error */ 3783 + return DC_ERROR_UNEXPECTED; 3784 + 3785 + /* command processed and we have a status of 2, mst not enabled in dpia */ 3786 + if (cmd.set_mst_alloc_slots.mst_slots_control.immed_status == 2) 3787 + return DC_FAIL_UNSUPPORTED_1; 3788 + 3789 + /* previously configured mst alloc and used slots did not match */ 3790 + if (cmd.set_mst_alloc_slots.mst_slots_control.immed_status == 3) { 3791 + *mst_slots_in_use = cmd.set_mst_alloc_slots.mst_slots_control.mst_slots_in_use; 3792 + return DC_NOT_SUPPORTED; 3793 + } 3794 + 3795 + return DC_OK; 3751 3796 } 3752 3797 3753 3798 /**
+132 -14
drivers/gpu/drm/amd/display/dc/core/dc_link.c
··· 1660 1660 DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw); 1661 1661 DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps); 1662 1662 } 1663 + 1664 + if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) { 1665 + link->bios_forced_drive_settings.VOLTAGE_SWING = 1666 + (info->ext_disp_conn_info.fixdpvoltageswing & 0x3); 1667 + link->bios_forced_drive_settings.PRE_EMPHASIS = 1668 + ((info->ext_disp_conn_info.fixdpvoltageswing >> 2) & 0x3); 1669 + } 1670 + 1663 1671 break; 1664 1672 } 1665 1673 } ··· 1764 1756 /* TODO: Create link encoder */ 1765 1757 1766 1758 link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; 1759 + 1760 + /* Some docks seem to NAK I2C writes to segment pointer with mot=0. */ 1761 + link->wa_flags.dp_mot_reset_segment = true; 1767 1762 1768 1763 return true; 1769 1764 ··· 2927 2916 return true; 2928 2917 } 2929 2918 2930 - bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, 2931 - bool wait, bool force_static) 2919 + bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active, 2920 + bool wait, bool force_static, const unsigned int *power_opts) 2932 2921 { 2933 2922 struct dc *dc = link->ctx->dc; 2934 2923 struct dmcu *dmcu = dc->res_pool->dmcu; ··· 2941 2930 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 2942 2931 return false; 2943 2932 2944 - link->psr_settings.psr_allow_active = allow_active; 2933 + /* Set power optimization flag */ 2934 + if (power_opts && link->psr_settings.psr_power_opt != *power_opts) { 2935 + link->psr_settings.psr_power_opt = *power_opts; 2936 + 2937 + if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt) 2938 + psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt); 2939 + } 2940 + 2941 + /* Enable or Disable PSR */ 2942 + if (allow_active && link->psr_settings.psr_allow_active != *allow_active) { 2943 + link->psr_settings.psr_allow_active = *allow_active; 2944 + 2945 2945 #if defined(CONFIG_DRM_AMD_DC_DCN) 2946 - if (!allow_active) 2947 - dc_z10_restore(dc); 2946 + if (!link->psr_settings.psr_allow_active) 2947 + dc_z10_restore(dc); 2948 2948 #endif 2949 2949 2950 - if (psr != NULL && link->psr_settings.psr_feature_enabled) { 2951 - if (force_static && psr->funcs->psr_force_static) 2952 - psr->funcs->psr_force_static(psr, panel_inst); 2953 - psr->funcs->psr_enable(psr, allow_active, wait, panel_inst); 2954 - } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled) 2955 - dmcu->funcs->set_psr_enable(dmcu, allow_active, wait); 2956 - else 2957 - return false; 2950 + if (psr != NULL && link->psr_settings.psr_feature_enabled) { 2951 + if (force_static && psr->funcs->psr_force_static) 2952 + psr->funcs->psr_force_static(psr, panel_inst); 2953 + psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst); 2954 + } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && 2955 + link->psr_settings.psr_feature_enabled) 2956 + dmcu->funcs->set_psr_enable(dmcu, link->psr_settings.psr_allow_active, wait); 2957 + else 2958 + return false; 2959 + } 2958 2960 2959 2961 return true; 2960 2962 } ··· 3499 3475 3500 3476 ASSERT(proposed_table.stream_count > 0); 3501 3477 3478 + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { 3479 + static enum dc_status status; 3480 + uint8_t mst_alloc_slots = 0, prev_mst_slots_in_use = 0xFF; 3481 + 3482 + for (i = 0; i < link->mst_stream_alloc_table.stream_count; i++) 3483 + mst_alloc_slots += link->mst_stream_alloc_table.stream_allocations[i].slot_count; 3484 + 3485 + status = dc_process_dmub_set_mst_slots(link->dc, link->link_index, 3486 + mst_alloc_slots, &prev_mst_slots_in_use); 3487 + ASSERT(status == DC_OK); 3488 + DC_LOG_MST("dpia : status[%d]: alloc_slots[%d]: used_slots[%d]\n", 3489 + status, mst_alloc_slots, prev_mst_slots_in_use); 3490 + } 3491 + 3502 3492 /* program DP source TX for payload */ 3503 3493 #if defined(CONFIG_DRM_AMD_DC_DCN) 3504 3494 switch (dp_get_link_encoding_format(&link->cur_link_settings)) { ··· 3856 3818 #endif 3857 3819 } 3858 3820 3821 + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { 3822 + enum dc_status status; 3823 + uint8_t mst_alloc_slots = 0, prev_mst_slots_in_use = 0xFF; 3824 + 3825 + for (i = 0; i < link->mst_stream_alloc_table.stream_count; i++) 3826 + mst_alloc_slots += link->mst_stream_alloc_table.stream_allocations[i].slot_count; 3827 + 3828 + status = dc_process_dmub_set_mst_slots(link->dc, link->link_index, 3829 + mst_alloc_slots, &prev_mst_slots_in_use); 3830 + ASSERT(status != DC_NOT_SUPPORTED); 3831 + DC_LOG_MST("dpia : status[%d]: alloc_slots[%d]: used_slots[%d]\n", 3832 + status, mst_alloc_slots, prev_mst_slots_in_use); 3833 + } 3834 + 3859 3835 #if defined(CONFIG_DRM_AMD_DC_DCN) 3860 3836 switch (dp_get_link_encoding_format(&link->cur_link_settings)) { 3861 3837 case DP_8b_10b_ENCODING: ··· 3913 3861 struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp; 3914 3862 #if defined(CONFIG_DRM_AMD_DC_DCN) 3915 3863 struct link_encoder *link_enc = NULL; 3864 + struct dc_state *state = pipe_ctx->stream->ctx->dc->current_state; 3865 + struct link_enc_assignment link_enc_assign; 3866 + int i; 3916 3867 #endif 3917 3868 3918 3869 if (cp_psp && cp_psp->funcs.update_stream_config) { ··· 3929 3874 config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst; 3930 3875 #if defined(CONFIG_DRM_AMD_DC_DCN) 3931 3876 config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA; 3932 - if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY) { 3877 + 3878 + if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY || 3879 + pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { 3933 3880 link_enc = pipe_ctx->stream->link->link_enc; 3881 + config.dio_output_type = pipe_ctx->stream->link->ep_type; 3882 + config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A; 3883 + if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY) 3884 + link_enc = pipe_ctx->stream->link->link_enc; 3885 + else if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) 3886 + if (pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign) { 3887 + link_enc = link_enc_cfg_get_link_enc_used_by_stream( 3888 + pipe_ctx->stream->ctx->dc, 3889 + pipe_ctx->stream); 3890 + } 3891 + // Initialize PHY ID with ABCDE - 01234 mapping except when it is B0 3934 3892 config.phy_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A; 3893 + 3894 + //look up the link_enc_assignment for the current pipe_ctx 3895 + for (i = 0; i < state->stream_count; i++) { 3896 + if (pipe_ctx->stream == state->streams[i]) { 3897 + link_enc_assign = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; 3898 + } 3899 + } 3900 + // Add flag to guard new A0 DIG mapping 3901 + if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 == true) { 3902 + config.dig_be = link_enc_assign.eng_id; 3903 + config.dio_output_type = pipe_ctx->stream->link->ep_type; 3904 + config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A; 3905 + } else { 3906 + config.dio_output_type = 0; 3907 + config.dio_output_idx = 0; 3908 + } 3909 + 3910 + // Add flag to guard B0 implementation 3911 + if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 == true && 3912 + link_enc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { 3913 + if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { 3914 + link_enc = link_enc_assign.stream->link_enc; 3915 + 3916 + // enum ID 1-4 maps to DPIA PHY ID 0-3 3917 + config.phy_idx = link_enc_assign.ep_id.link_id.enum_id - ENUM_ID_1; 3918 + } else { // for non DPIA mode over B0, ABCDE maps to 01564 3919 + 3920 + switch (link_enc->transmitter) { 3921 + case TRANSMITTER_UNIPHY_A: 3922 + config.phy_idx = 0; 3923 + break; 3924 + case TRANSMITTER_UNIPHY_B: 3925 + config.phy_idx = 1; 3926 + break; 3927 + case TRANSMITTER_UNIPHY_C: 3928 + config.phy_idx = 5; 3929 + break; 3930 + case TRANSMITTER_UNIPHY_D: 3931 + config.phy_idx = 6; 3932 + break; 3933 + case TRANSMITTER_UNIPHY_E: 3934 + config.phy_idx = 4; 3935 + break; 3936 + default: 3937 + config.phy_idx = 0; 3938 + break; 3939 + } 3940 + 3941 + } 3942 + } 3935 3943 } else if (pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign) { 3936 3944 link_enc = link_enc_cfg_get_link_enc_used_by_stream( 3937 3945 pipe_ctx->stream->ctx->dc,
+11 -3
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 1155 1155 pipe_ctx->plane_res.scl_data.recout.x += pipe_ctx->plane_res.scl_data.recout.width; 1156 1156 } 1157 1157 1158 - if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE || 1159 - pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) 1160 - res = false; 1158 + if (!pipe_ctx->stream->ctx->dc->config.enable_windowed_mpo_odm) { 1159 + if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE || 1160 + pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) 1161 + res = false; 1162 + } else { 1163 + /* Clamp minimum viewport size */ 1164 + if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE) 1165 + pipe_ctx->plane_res.scl_data.viewport.height = MIN_VIEWPORT_SIZE; 1166 + if (pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) 1167 + pipe_ctx->plane_res.scl_data.viewport.width = MIN_VIEWPORT_SIZE; 1168 + } 1161 1169 1162 1170 DC_LOG_SCALER("%s pipe %d:\nViewport: height:%d width:%d x:%d y:%d Recout: height:%d width:%d x:%d y:%d HACTIVE:%d VACTIVE:%d\n" 1163 1171 "src_rect: height:%d width:%d x:%d y:%d dst_rect: height:%d width:%d x:%d y:%d clip_rect: height:%d width:%d x:%d y:%d\n",
+23 -6
drivers/gpu/drm/amd/display/dc/dc.h
··· 47 47 struct set_config_cmd_payload; 48 48 struct dmub_notification; 49 49 50 - #define DC_VER "3.2.157" 50 + #define DC_VER "3.2.159" 51 51 52 52 #define MAX_SURFACES 3 53 53 #define MAX_PLANES 6 ··· 211 211 unsigned int max_uncompressed_blk_size; 212 212 bool independent_64b_blks; 213 213 #if defined(CONFIG_DRM_AMD_DC_DCN) 214 - //These bitfields to be used starting with DCN 3.0 214 + //These bitfields to be used starting with DCN 215 215 struct { 216 - uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN 3.0 (the worst compression case) 217 - uint32_t dcc_128_128_uncontrained : 1; //available in ASICs before DCN 3.0 218 - uint32_t dcc_256_128_128 : 1; //available starting with DCN 3.0 219 - uint32_t dcc_256_256_unconstrained : 1; //available in ASICs before DCN 3.0 (the best compression case) 216 + uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN (the worst compression case) 217 + uint32_t dcc_128_128_uncontrained : 1; //available in ASICs before DCN 218 + uint32_t dcc_256_128_128 : 1; //available starting with DCN 219 + uint32_t dcc_256_256_unconstrained : 1; //available in ASICs before DCN (the best compression case) 220 220 } dcc_controls; 221 221 #endif 222 222 }; ··· 323 323 bool multi_mon_pp_mclk_switch; 324 324 bool disable_dmcu; 325 325 bool enable_4to1MPC; 326 + bool enable_windowed_mpo_odm; 326 327 bool allow_edp_hotplug_detection; 327 328 #if defined(CONFIG_DRM_AMD_DC_DCN) 328 329 bool clamp_min_dcfclk; ··· 341 340 VISUAL_CONFIRM_MPCTREE = 4, 342 341 VISUAL_CONFIRM_PSR = 5, 343 342 VISUAL_CONFIRM_SWIZZLE = 9, 343 + }; 344 + 345 + enum dc_psr_power_opts { 346 + psr_power_opt_invalid = 0x0, 347 + psr_power_opt_smu_opt_static_screen = 0x1, 348 + psr_power_opt_z10_static_screen = 0x10, 344 349 }; 345 350 346 351 enum dcc_option { ··· 732 725 #if defined(CONFIG_DRM_AMD_DC_DCN) 733 726 bool idle_optimizations_allowed; 734 727 #endif 728 + #if defined(CONFIG_DRM_AMD_DC_DCN) 729 + bool enable_c20_dtm_b0; 730 + #endif 735 731 736 732 /* Require to maintain clocks and bandwidth for UEFI enabled HW */ 737 733 ··· 941 931 uint32_t bandwidth_change:1; 942 932 uint32_t clock_change:1; 943 933 uint32_t stereo_format_change:1; 934 + uint32_t lut_3d:1; 944 935 uint32_t full_update:1; 945 936 } bits; 946 937 ··· 1428 1417 uint32_t link_index, 1429 1418 struct set_config_cmd_payload *payload, 1430 1419 struct dmub_notification *notify); 1420 + 1421 + enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc, 1422 + uint32_t link_index, 1423 + uint8_t mst_alloc_slots, 1424 + uint8_t *mst_slots_in_use); 1425 + 1431 1426 /******************************************************************************* 1432 1427 * DSC Interfaces 1433 1428 ******************************************************************************/
-5
drivers/gpu/drm/amd/display/dc/dc_dp_types.h
··· 174 174 #endif 175 175 }; 176 176 177 - struct dc_link_training_settings { 178 - struct dc_link_settings link; 179 - struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]; 180 - }; 181 - 182 177 struct dc_link_training_overrides { 183 178 enum dc_voltage_swing *voltage_swing; 184 179 enum dc_pre_emphasis *pre_emphasis;
+11 -2
drivers/gpu/drm/amd/display/dc/dc_link.h
··· 85 85 */ 86 86 bool psr_frame_capture_indication_req; 87 87 unsigned int psr_sdp_transmit_line_num_deadline; 88 + unsigned int psr_power_opt; 88 89 }; 89 90 90 91 /* ··· 124 123 struct dc_link_settings cur_link_settings; 125 124 struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX]; 126 125 struct dc_link_settings preferred_link_setting; 126 + /* preferred_training_settings are override values that 127 + * come from DM. DM is responsible for the memory 128 + * management of the override pointers. 129 + */ 127 130 struct dc_link_training_overrides preferred_training_settings; 128 131 struct dp_audio_test_data audio_test_data; 129 132 ··· 182 177 183 178 struct psr_settings psr_settings; 184 179 180 + /* Drive settings read from integrated info table */ 181 + struct dc_lane_settings bios_forced_drive_settings; 182 + 185 183 /* MST record stream using this link */ 186 184 struct link_flags { 187 185 bool dp_keep_receiver_powered; 188 186 bool dp_skip_DID2; 189 187 bool dp_skip_reset_segment; 188 + bool dp_mot_reset_segment; 190 189 } wa_flags; 191 190 struct link_mst_stream_allocation_table mst_stream_alloc_table; 192 191 ··· 276 267 277 268 int dc_link_get_target_backlight_pwm(const struct dc_link *link); 278 269 279 - bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, 280 - bool wait, bool force_static); 270 + bool dc_link_set_psr_allow_active(struct dc_link *dc_link, const bool *enable, 271 + bool wait, bool force_static, const unsigned int *power_opts); 281 272 282 273 bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state); 283 274
+4 -2
drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
··· 514 514 union audio_sample_rates sample_rates = 515 515 audio_mode->sample_rates; 516 516 uint8_t byte2 = audio_mode->max_bit_rate; 517 + uint8_t channel_count = audio_mode->channel_count; 517 518 518 519 /* adjust specific properties */ 519 520 switch (audio_format_code) { 520 521 case AUDIO_FORMAT_CODE_LINEARPCM: { 522 + 521 523 check_audio_bandwidth( 522 524 crtc_info, 523 - audio_mode->channel_count, 525 + channel_count, 524 526 signal, 525 527 &sample_rates); 526 528 ··· 550 548 551 549 /* fill audio format data */ 552 550 set_reg_field_value(value, 553 - audio_mode->channel_count - 1, 551 + channel_count - 1, 554 552 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, 555 553 MAX_CHANNELS); 556 554
+31 -3
drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
··· 534 534 static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload) 535 535 { 536 536 if (payload->i2c_over_aux) { 537 + if (payload->write_status_update) { 538 + if (payload->mot) 539 + return I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT; 540 + else 541 + return I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST; 542 + } 537 543 if (payload->write) { 538 544 if (payload->mot) 539 545 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT; 540 - return I2CAUX_TRANSACTION_ACTION_I2C_WRITE; 546 + else 547 + return I2CAUX_TRANSACTION_ACTION_I2C_WRITE; 541 548 } 542 549 if (payload->mot) 543 550 return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT; 551 + 544 552 return I2CAUX_TRANSACTION_ACTION_I2C_READ; 545 553 } 546 554 if (payload->write) 547 555 return I2CAUX_TRANSACTION_ACTION_DP_WRITE; 556 + 548 557 return I2CAUX_TRANSACTION_ACTION_DP_READ; 549 558 } 550 559 ··· 707 698 aux_defer_retries = 0, 708 699 aux_i2c_defer_retries = 0, 709 700 aux_timeout_retries = 0, 710 - aux_invalid_reply_retries = 0; 701 + aux_invalid_reply_retries = 0, 702 + aux_ack_m_retries = 0; 711 703 712 704 if (ddc_pin) { 713 705 aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]; ··· 768 758 aux_defer_retries, 769 759 AUX_MAX_RETRIES); 770 760 goto fail; 771 - } else { 761 + } else 772 762 udelay(300); 763 + } else if (payload->write && ret > 0) { 764 + /* sink requested more time to complete the write via AUX_ACKM */ 765 + if (++aux_ack_m_retries >= AUX_MAX_RETRIES) { 766 + DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 767 + LOG_FLAG_Error_I2cAux, 768 + "dce_aux_transfer_with_retries: FAILURE: aux_ack_m_retries=%d >= AUX_MAX_RETRIES=%d", 769 + aux_ack_m_retries, 770 + AUX_MAX_RETRIES); 771 + goto fail; 773 772 } 773 + 774 + /* retry reading the write status until complete 775 + * NOTE: payload is modified here 776 + */ 777 + payload->write = false; 778 + payload->write_status_update = true; 779 + payload->length = 0; 780 + udelay(300); 781 + 774 782 } else 775 783 return true; 776 784 break;
+2 -1
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
··· 1151 1151 type DOMAIN_POWER_GATE;\ 1152 1152 type DOMAIN_PGFSM_PWR_STATUS;\ 1153 1153 type HPO_HDMISTREAMCLK_G_GATE_DIS;\ 1154 - type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE; 1154 + type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE;\ 1155 + type I2C_LIGHT_SLEEP_FORCE; 1155 1156 1156 1157 struct dce_hwseq_shift { 1157 1158 HWSEQ_REG_FIELD_LIST(uint8_t)
+20
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
··· 227 227 dc_dmub_srv_wait_idle(dc->dmub_srv); 228 228 } 229 229 230 + /** 231 + * Set PSR power optimization flags. 232 + */ 233 + static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt) 234 + { 235 + union dmub_rb_cmd cmd; 236 + struct dc_context *dc = dmub->ctx; 237 + 238 + memset(&cmd, 0, sizeof(cmd)); 239 + cmd.psr_set_power_opt.header.type = DMUB_CMD__PSR; 240 + cmd.psr_set_power_opt.header.sub_type = DMUB_CMD__SET_PSR_POWER_OPT; 241 + cmd.psr_set_power_opt.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_power_opt_data); 242 + cmd.psr_set_power_opt.psr_set_power_opt_data.power_opt = power_opt; 243 + 244 + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); 245 + dc_dmub_srv_cmd_execute(dc->dmub_srv); 246 + dc_dmub_srv_wait_idle(dc->dmub_srv); 247 + } 248 + 230 249 /* 231 250 * Setup PSR by programming phy registers and sending psr hw context values to firmware. 232 251 */ ··· 377 358 .psr_set_level = dmub_psr_set_level, 378 359 .psr_force_static = dmub_psr_force_static, 379 360 .psr_get_residency = dmub_psr_get_residency, 361 + .psr_set_power_opt = dmub_psr_set_power_opt, 380 362 }; 381 363 382 364 /*
+1
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
··· 46 46 void (*psr_force_static)(struct dmub_psr *dmub, uint8_t panel_inst); 47 47 void (*psr_get_residency)(struct dmub_psr *dmub, uint32_t *residency, 48 48 uint8_t panel_inst); 49 + void (*psr_set_power_opt)(struct dmub_psr *dmub, unsigned int power_opt); 49 50 }; 50 51 51 52 struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
+10 -2
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
··· 205 205 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); 206 206 207 207 if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) { 208 - REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, power_on ? 0 : 3); 209 - if (power_on) 208 + if (power_on) { 209 + REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 0); 210 210 REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5); 211 + } else { 212 + if (dpp->base.ctx->dc->debug.enable_mem_low_power.bits.dscl) { 213 + dpp->base.ctx->dc->optimized_required = true; 214 + dpp->base.deferred_reg_writes.bits.disable_dscl = true; 215 + } else { 216 + REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3); 217 + } 218 + } 211 219 } 212 220 } 213 221
+6
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
··· 1378 1378 if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) 1379 1379 dc->clk_mgr->funcs->init_clocks(dc->clk_mgr); 1380 1380 1381 + /* Align bw context with hw config when system resume. */ 1382 + if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) { 1383 + dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz = dc->clk_mgr->clks.dispclk_khz; 1384 + dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz = dc->clk_mgr->clks.dppclk_khz; 1385 + } 1386 + 1381 1387 // Initialize the dccg 1382 1388 if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->dccg_init) 1383 1389 dc->res_pool->dccg->funcs->dccg_init(res_pool->dccg);
+9 -10
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
··· 3660 3660 return DML_PROJECT_NAVI10v2; 3661 3661 } 3662 3662 3663 - #define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) 3664 - #define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) 3665 - 3666 3663 static bool init_soc_bounding_box(struct dc *dc, 3667 3664 struct dcn20_resource_pool *pool) 3668 3665 { ··· 3695 3698 clock_limits_available = (status == PP_SMU_RESULT_OK); 3696 3699 } 3697 3700 3698 - if (clock_limits_available && uclk_states_available && num_states) 3701 + if (clock_limits_available && uclk_states_available && num_states) { 3702 + DC_FP_START(); 3699 3703 dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states); 3700 - else if (clock_limits_available) 3704 + DC_FP_END(); 3705 + } else if (clock_limits_available) { 3706 + DC_FP_START(); 3701 3707 dcn20_cap_soc_clocks(loaded_bb, max_clocks); 3708 + DC_FP_END(); 3709 + } 3702 3710 } 3703 3711 3704 3712 loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; 3705 3713 loaded_ip->max_num_dpp = pool->base.pipe_count; 3714 + DC_FP_START(); 3706 3715 dcn20_patch_bounding_box(dc, loaded_bb); 3707 - 3716 + DC_FP_END(); 3708 3717 return true; 3709 3718 } 3710 3719 ··· 3729 3726 get_asic_rev_ip_params(ctx->asic_id.hw_internal_rev); 3730 3727 enum dml_project dml_project_version = 3731 3728 get_dml_project_version(ctx->asic_id.hw_internal_rev); 3732 - 3733 - DC_FP_START(); 3734 3729 3735 3730 ctx->dc_bios->regs = &bios_regs; 3736 3731 pool->base.funcs = &dcn20_res_pool_funcs; ··· 4078 4077 pool->base.oem_device = NULL; 4079 4078 } 4080 4079 4081 - DC_FP_END(); 4082 4080 return true; 4083 4081 4084 4082 create_fail: 4085 4083 4086 - DC_FP_END(); 4087 4084 dcn20_resource_destruct(pool); 4088 4085 4089 4086 return false;
+14
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
··· 494 494 int bypass_state; 495 495 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 496 496 497 + if (dpp_base->deferred_reg_writes.bits.disable_dscl) { 498 + REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3); 499 + dpp_base->deferred_reg_writes.bits.disable_dscl = false; 500 + } 501 + 502 + if (dpp_base->deferred_reg_writes.bits.disable_gamcor) { 503 + REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state); 504 + if (bypass_state == 0) { // only program if bypass was latched 505 + REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3); 506 + } else 507 + ASSERT(0); // LUT select was updated again before vupdate 508 + dpp_base->deferred_reg_writes.bits.disable_gamcor = false; 509 + } 510 + 497 511 if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) { 498 512 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state); 499 513 if (bypass_state == 0) { // only program if bypass was latched
+6 -2
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
··· 136 136 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 137 137 138 138 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { 139 - REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, power_on ? 0 : 3); 140 - if (power_on) 139 + if (power_on) { 140 + REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0); 141 141 REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5); 142 + } else { 143 + dpp_base->ctx->dc->optimized_required = true; 144 + dpp_base->deferred_reg_writes.bits.disable_gamcor = true; 145 + } 142 146 } else 143 147 REG_SET(CM_MEM_PWR_CTRL, 0, 144 148 GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1);
+18 -17
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
··· 1707 1707 return ret; 1708 1708 } 1709 1709 1710 - #define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) 1711 - #define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) 1712 - 1713 1710 static bool is_soc_bounding_box_valid(struct dc *dc) 1714 1711 { 1715 1712 uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev; ··· 1926 1929 if (vlevel == context->bw_ctx.dml.soc.num_states) 1927 1930 goto validate_fail; 1928 1931 1929 - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { 1930 - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; 1931 - struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; 1932 + if (!dc->config.enable_windowed_mpo_odm) { 1933 + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { 1934 + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; 1935 + struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; 1932 1936 1933 - if (!pipe->stream) 1934 - continue; 1937 + if (!pipe->stream) 1938 + continue; 1935 1939 1936 - /* We only support full screen mpo with ODM */ 1937 - if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled 1938 - && pipe->plane_state && mpo_pipe 1939 - && memcmp(&mpo_pipe->plane_res.scl_data.recout, 1940 - &pipe->plane_res.scl_data.recout, 1941 - sizeof(struct rect)) != 0) { 1942 - ASSERT(mpo_pipe->plane_state != pipe->plane_state); 1943 - goto validate_fail; 1940 + /* We only support full screen mpo with ODM */ 1941 + if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled 1942 + && pipe->plane_state && mpo_pipe 1943 + && memcmp(&mpo_pipe->plane_res.scl_data.recout, 1944 + &pipe->plane_res.scl_data.recout, 1945 + sizeof(struct rect)) != 0) { 1946 + ASSERT(mpo_pipe->plane_state != pipe->plane_state); 1947 + goto validate_fail; 1948 + } 1949 + pipe_idx++; 1944 1950 } 1945 - pipe_idx++; 1946 1951 } 1947 1952 1948 1953 /* merge pipes if necessary */ ··· 2322 2323 goto validate_out; 2323 2324 } 2324 2325 2326 + DC_FP_START(); 2325 2327 dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); 2328 + DC_FP_END(); 2326 2329 2327 2330 BW_VAL_TRACE_END_WATERMARKS(); 2328 2331
-26
drivers/gpu/drm/amd/display/dc/dcn301/Makefile
··· 13 13 DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \ 14 14 dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o 15 15 16 - ifdef CONFIG_X86 17 - CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -msse 18 - endif 19 - 20 - ifdef CONFIG_PPC64 21 - CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec 22 - endif 23 - 24 - ifdef CONFIG_CC_IS_GCC 25 - ifeq ($(call cc-ifversion, -lt, 0701, y), y) 26 - IS_OLD_GCC = 1 27 - endif 28 - CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mhard-float 29 - endif 30 - 31 - ifdef CONFIG_X86 32 - ifdef IS_OLD_GCC 33 - # Stack alignment mismatch, proceed with caution. 34 - # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 35 - # (8B stack alignment). 36 - CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mpreferred-stack-boundary=4 37 - else 38 - CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -msse2 39 - endif 40 - endif 41 - 42 16 AMD_DAL_DCN301 = $(addprefix $(AMDDALPATH)/dc/dcn301/,$(DCN301)) 43 17 44 18 AMD_DISPLAY_FILES += $(AMD_DAL_DCN301)
+10 -339
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
··· 82 82 #include "dce/dce_i2c.h" 83 83 84 84 #include "dml/dcn30/display_mode_vba_30.h" 85 + #include "dml/dcn301/dcn301_fpu.h" 85 86 #include "vm_helper.h" 86 87 #include "dcn20/dcn20_vmid.h" 87 88 #include "amdgpu_socbb.h" ··· 91 90 container_of(pool, struct dcn301_resource_pool, base) 92 91 93 92 #define DC_LOGGER_INIT(logger) 94 - 95 - struct _vcs_dpi_ip_params_st dcn3_01_ip = { 96 - .odm_capable = 1, 97 - .gpuvm_enable = 1, 98 - .hostvm_enable = 1, 99 - .gpuvm_max_page_table_levels = 1, 100 - .hostvm_max_page_table_levels = 2, 101 - .hostvm_cached_page_table_levels = 0, 102 - .pte_group_size_bytes = 2048, 103 - .num_dsc = 3, 104 - .rob_buffer_size_kbytes = 184, 105 - .det_buffer_size_kbytes = 184, 106 - .dpte_buffer_size_in_pte_reqs_luma = 64, 107 - .dpte_buffer_size_in_pte_reqs_chroma = 32, 108 - .pde_proc_buffer_size_64k_reqs = 48, 109 - .dpp_output_buffer_pixels = 2560, 110 - .opp_output_buffer_lines = 1, 111 - .pixel_chunk_size_kbytes = 8, 112 - .meta_chunk_size_kbytes = 2, 113 - .writeback_chunk_size_kbytes = 8, 114 - .line_buffer_size_bits = 789504, 115 - .is_line_buffer_bpp_fixed = 0, // ? 116 - .line_buffer_fixed_bpp = 48, // ? 117 - .dcc_supported = true, 118 - .writeback_interface_buffer_size_kbytes = 90, 119 - .writeback_line_buffer_buffer_size = 656640, 120 - .max_line_buffer_lines = 12, 121 - .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 122 - .writeback_chroma_buffer_size_kbytes = 8, 123 - .writeback_chroma_line_buffer_width_pixels = 4, 124 - .writeback_max_hscl_ratio = 1, 125 - .writeback_max_vscl_ratio = 1, 126 - .writeback_min_hscl_ratio = 1, 127 - .writeback_min_vscl_ratio = 1, 128 - .writeback_max_hscl_taps = 1, 129 - .writeback_max_vscl_taps = 1, 130 - .writeback_line_buffer_luma_buffer_size = 0, 131 - .writeback_line_buffer_chroma_buffer_size = 14643, 132 - .cursor_buffer_size = 8, 133 - .cursor_chunk_size = 2, 134 - .max_num_otg = 4, 135 - .max_num_dpp = 4, 136 - .max_num_wb = 1, 137 - .max_dchub_pscl_bw_pix_per_clk = 4, 138 - .max_pscl_lb_bw_pix_per_clk = 2, 139 - .max_lb_vscl_bw_pix_per_clk = 4, 140 - .max_vscl_hscl_bw_pix_per_clk = 4, 141 - .max_hscl_ratio = 6, 142 - .max_vscl_ratio = 6, 143 - .hscl_mults = 4, 144 - .vscl_mults = 4, 145 - .max_hscl_taps = 8, 146 - .max_vscl_taps = 8, 147 - .dispclk_ramp_margin_percent = 1, 148 - .underscan_factor = 1.11, 149 - .min_vblank_lines = 32, 150 - .dppclk_delay_subtotal = 46, 151 - .dynamic_metadata_vm_enabled = true, 152 - .dppclk_delay_scl_lb_only = 16, 153 - .dppclk_delay_scl = 50, 154 - .dppclk_delay_cnvc_formatter = 27, 155 - .dppclk_delay_cnvc_cursor = 6, 156 - .dispclk_delay_subtotal = 119, 157 - .dcfclk_cstate_latency = 5.2, // SRExitTime 158 - .max_inter_dcn_tile_repeaters = 8, 159 - .max_num_hdmi_frl_outputs = 0, 160 - .odm_combine_4to1_supported = true, 161 - 162 - .xfc_supported = false, 163 - .xfc_fill_bw_overhead_percent = 10.0, 164 - .xfc_fill_constant_bytes = 0, 165 - .gfx7_compat_tiling_supported = 0, 166 - .number_of_cursors = 1, 167 - }; 168 - 169 - struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = { 170 - .clock_limits = { 171 - { 172 - .state = 0, 173 - .dram_speed_mts = 2400.0, 174 - .fabricclk_mhz = 600, 175 - .socclk_mhz = 278.0, 176 - .dcfclk_mhz = 400.0, 177 - .dscclk_mhz = 206.0, 178 - .dppclk_mhz = 1015.0, 179 - .dispclk_mhz = 1015.0, 180 - .phyclk_mhz = 600.0, 181 - }, 182 - { 183 - .state = 1, 184 - .dram_speed_mts = 2400.0, 185 - .fabricclk_mhz = 688, 186 - .socclk_mhz = 278.0, 187 - .dcfclk_mhz = 400.0, 188 - .dscclk_mhz = 206.0, 189 - .dppclk_mhz = 1015.0, 190 - .dispclk_mhz = 1015.0, 191 - .phyclk_mhz = 600.0, 192 - }, 193 - { 194 - .state = 2, 195 - .dram_speed_mts = 4267.0, 196 - .fabricclk_mhz = 1067, 197 - .socclk_mhz = 278.0, 198 - .dcfclk_mhz = 608.0, 199 - .dscclk_mhz = 296.0, 200 - .dppclk_mhz = 1015.0, 201 - .dispclk_mhz = 1015.0, 202 - .phyclk_mhz = 810.0, 203 - }, 204 - 205 - { 206 - .state = 3, 207 - .dram_speed_mts = 4267.0, 208 - .fabricclk_mhz = 1067, 209 - .socclk_mhz = 715.0, 210 - .dcfclk_mhz = 676.0, 211 - .dscclk_mhz = 338.0, 212 - .dppclk_mhz = 1015.0, 213 - .dispclk_mhz = 1015.0, 214 - .phyclk_mhz = 810.0, 215 - }, 216 - 217 - { 218 - .state = 4, 219 - .dram_speed_mts = 4267.0, 220 - .fabricclk_mhz = 1067, 221 - .socclk_mhz = 953.0, 222 - .dcfclk_mhz = 810.0, 223 - .dscclk_mhz = 338.0, 224 - .dppclk_mhz = 1015.0, 225 - .dispclk_mhz = 1015.0, 226 - .phyclk_mhz = 810.0, 227 - }, 228 - }, 229 - 230 - .sr_exit_time_us = 9.0, 231 - .sr_enter_plus_exit_time_us = 11.0, 232 - .urgent_latency_us = 4.0, 233 - .urgent_latency_pixel_data_only_us = 4.0, 234 - .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, 235 - .urgent_latency_vm_data_only_us = 4.0, 236 - .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, 237 - .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, 238 - .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, 239 - .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, 240 - .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0, 241 - .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, 242 - .max_avg_sdp_bw_use_normal_percent = 60.0, 243 - .max_avg_dram_bw_use_normal_percent = 60.0, 244 - .writeback_latency_us = 12.0, 245 - .max_request_size_bytes = 256, 246 - .dram_channel_width_bytes = 4, 247 - .fabric_datapath_to_dcn_data_return_bytes = 32, 248 - .dcn_downspread_percent = 0.5, 249 - .downspread_percent = 0.38, 250 - .dram_page_open_time_ns = 50.0, 251 - .dram_rw_turnaround_time_ns = 17.5, 252 - .dram_return_buffer_per_channel_bytes = 8192, 253 - .round_trip_ping_latency_dcfclk_cycles = 191, 254 - .urgent_out_of_order_return_per_channel_bytes = 4096, 255 - .channel_interleave_bytes = 256, 256 - .num_banks = 8, 257 - .num_chans = 4, 258 - .gpuvm_min_page_size_bytes = 4096, 259 - .hostvm_min_page_size_bytes = 4096, 260 - .dram_clock_change_latency_us = 23.84, 261 - .writeback_dram_clock_change_latency_us = 23.0, 262 - .return_bus_width_bytes = 64, 263 - .dispclk_dppclk_vco_speed_mhz = 3550, 264 - .xfc_bus_transport_time_us = 20, // ? 265 - .xfc_xbuf_latency_tolerance_us = 4, // ? 266 - .use_urgent_burst_bw = 1, // ? 267 - .num_states = 5, 268 - .do_urgent_latency_adjustment = false, 269 - .urgent_latency_adjustment_fabric_clock_component_us = 0, 270 - .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, 271 - }; 272 93 273 94 enum dcn301_clk_src_array_id { 274 95 DCN301_CLK_SRC_PLL0, ··· 1303 1480 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap 1304 1481 }; 1305 1482 1306 - #define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) 1307 - #define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) 1308 1483 1309 1484 static bool is_soc_bounding_box_valid(struct dc *dc) 1310 1485 { ··· 1329 1508 1330 1509 loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; 1331 1510 loaded_ip->max_num_dpp = pool->base.pipe_count; 1511 + DC_FP_START(); 1332 1512 dcn20_patch_bounding_box(dc, loaded_bb); 1513 + DC_FP_END(); 1333 1514 1334 1515 if (dc->ctx->dc_bios->funcs->get_soc_bb_info) { 1335 1516 struct bp_soc_bb_info bb_info = {0}; 1336 1517 1337 1518 if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { 1338 - if (bb_info.dram_clock_change_latency_100ns > 0) 1339 - dcn3_01_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; 1340 - 1341 - if (bb_info.dram_sr_enter_exit_latency_100ns > 0) 1342 - dcn3_01_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; 1343 - 1344 - if (bb_info.dram_sr_exit_latency_100ns > 0) 1345 - dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; 1519 + DC_FP_START(); 1520 + dcn301_fpu_init_soc_bounding_box(bb_info); 1521 + DC_FP_END(); 1346 1522 } 1347 1523 } 1348 1524 1349 1525 return true; 1350 1526 } 1527 + 1351 1528 1352 1529 static void set_wm_ranges( 1353 1530 struct pp_smu_funcs *pp_smu, ··· 1369 1550 ranges.reader_wm_sets[i].wm_inst = i; 1370 1551 ranges.reader_wm_sets[i].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN; 1371 1552 ranges.reader_wm_sets[i].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; 1372 - ranges.reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0; 1373 - ranges.reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16; 1374 - 1553 + DC_FP_START(); 1554 + dcn301_fpu_set_wm_ranges(i, &ranges, loaded_bb); 1555 + DC_FP_END(); 1375 1556 ranges.num_reader_wm_sets = i + 1; 1376 1557 } 1377 1558 ··· 1389 1570 1390 1571 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ 1391 1572 pp_smu->nv_funcs.set_wm_ranges(&pp_smu->nv_funcs.pp_smu, &ranges); 1392 - } 1393 - 1394 - static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) 1395 - { 1396 - struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool); 1397 - struct clk_limit_table *clk_table = &bw_params->clk_table; 1398 - struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; 1399 - unsigned int i, closest_clk_lvl; 1400 - int j; 1401 - 1402 - // Default clock levels are used for diags, which may lead to overclocking. 1403 - if (!IS_DIAG_DC(dc->ctx->dce_environment)) { 1404 - dcn3_01_ip.max_num_otg = pool->base.res_cap->num_timing_generator; 1405 - dcn3_01_ip.max_num_dpp = pool->base.pipe_count; 1406 - dcn3_01_soc.num_chans = bw_params->num_channels; 1407 - 1408 - ASSERT(clk_table->num_entries); 1409 - for (i = 0; i < clk_table->num_entries; i++) { 1410 - /* loop backwards*/ 1411 - for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) { 1412 - if ((unsigned int) dcn3_01_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { 1413 - closest_clk_lvl = j; 1414 - break; 1415 - } 1416 - } 1417 - 1418 - clock_limits[i].state = i; 1419 - clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; 1420 - clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; 1421 - clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; 1422 - clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; 1423 - 1424 - clock_limits[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; 1425 - clock_limits[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; 1426 - clock_limits[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; 1427 - clock_limits[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz; 1428 - clock_limits[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; 1429 - clock_limits[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; 1430 - clock_limits[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz; 1431 - } 1432 - for (i = 0; i < clk_table->num_entries; i++) 1433 - dcn3_01_soc.clock_limits[i] = clock_limits[i]; 1434 - if (clk_table->num_entries) { 1435 - dcn3_01_soc.num_states = clk_table->num_entries; 1436 - /* duplicate last level */ 1437 - dcn3_01_soc.clock_limits[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1]; 1438 - dcn3_01_soc.clock_limits[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states; 1439 - } 1440 - } 1441 - 1442 - dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 1443 - dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 1444 - 1445 - dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30); 1446 - } 1447 - 1448 - static void calculate_wm_set_for_vlevel( 1449 - int vlevel, 1450 - struct wm_range_table_entry *table_entry, 1451 - struct dcn_watermarks *wm_set, 1452 - struct display_mode_lib *dml, 1453 - display_e2e_pipe_params_st *pipes, 1454 - int pipe_cnt) 1455 - { 1456 - double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us; 1457 - 1458 - ASSERT(vlevel < dml->soc.num_states); 1459 - /* only pipe 0 is read for voltage and dcf/soc clocks */ 1460 - pipes[0].clks_cfg.voltage = vlevel; 1461 - pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz; 1462 - pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz; 1463 - 1464 - dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us; 1465 - dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us; 1466 - dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us; 1467 - 1468 - wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000; 1469 - wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000; 1470 - wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000; 1471 - wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000; 1472 - wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000; 1473 - wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000; 1474 - wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000; 1475 - wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000; 1476 - dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached; 1477 - 1478 - } 1479 - 1480 - static void dcn301_calculate_wm_and_dlg( 1481 - struct dc *dc, struct dc_state *context, 1482 - display_e2e_pipe_params_st *pipes, 1483 - int pipe_cnt, 1484 - int vlevel_req) 1485 - { 1486 - int i, pipe_idx; 1487 - int vlevel, vlevel_max; 1488 - struct wm_range_table_entry *table_entry; 1489 - struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; 1490 - 1491 - ASSERT(bw_params); 1492 - 1493 - vlevel_max = bw_params->clk_table.num_entries - 1; 1494 - 1495 - /* WM Set D */ 1496 - table_entry = &bw_params->wm_table.entries[WM_D]; 1497 - if (table_entry->wm_type == WM_TYPE_RETRAINING) 1498 - vlevel = 0; 1499 - else 1500 - vlevel = vlevel_max; 1501 - calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d, 1502 - &context->bw_ctx.dml, pipes, pipe_cnt); 1503 - /* WM Set C */ 1504 - table_entry = &bw_params->wm_table.entries[WM_C]; 1505 - vlevel = min(max(vlevel_req, 2), vlevel_max); 1506 - calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, 1507 - &context->bw_ctx.dml, pipes, pipe_cnt); 1508 - /* WM Set B */ 1509 - table_entry = &bw_params->wm_table.entries[WM_B]; 1510 - vlevel = min(max(vlevel_req, 1), vlevel_max); 1511 - calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, 1512 - &context->bw_ctx.dml, pipes, pipe_cnt); 1513 - 1514 - /* WM Set A */ 1515 - table_entry = &bw_params->wm_table.entries[WM_A]; 1516 - vlevel = min(vlevel_req, vlevel_max); 1517 - calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a, 1518 - &context->bw_ctx.dml, pipes, pipe_cnt); 1519 - 1520 - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { 1521 - if (!context->res_ctx.pipe_ctx[i].stream) 1522 - continue; 1523 - 1524 - pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); 1525 - pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); 1526 - 1527 - if (dc->config.forced_clocks) { 1528 - pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; 1529 - pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; 1530 - } 1531 - if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) 1532 - pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; 1533 - if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) 1534 - pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; 1535 - 1536 - pipe_idx++; 1537 - } 1538 - 1539 - dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); 1540 1573 } 1541 1574 1542 1575 static struct resource_funcs dcn301_res_pool_funcs = {
+3
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h
··· 32 32 struct resource_pool; 33 33 struct _vcs_dpi_display_pipe_params_st; 34 34 35 + extern struct _vcs_dpi_ip_params_st dcn3_01_ip; 36 + extern struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc; 37 + 35 38 struct dcn301_resource_pool { 36 39 struct resource_pool base; 37 40 };
+14
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
··· 1344 1344 dcn3_03_soc.clock_limits[i].phyclk_d18_mhz = dcn3_03_soc.clock_limits[0].phyclk_d18_mhz; 1345 1345 dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz; 1346 1346 } 1347 + 1348 + // WA: patch strobe modes to compensate for DCN303 BW issue 1349 + if (dcn3_03_soc.num_chans <= 4) { 1350 + for (i = 0; i < dcn3_03_soc.num_states; i++) { 1351 + if (dcn3_03_soc.clock_limits[i].dram_speed_mts > 1700) 1352 + break; 1353 + 1354 + if (dcn3_03_soc.clock_limits[i].dram_speed_mts >= 1500) { 1355 + dcn3_03_soc.clock_limits[i].dcfclk_mhz = 100; 1356 + dcn3_03_soc.clock_limits[i].fabricclk_mhz = 100; 1357 + } 1358 + } 1359 + } 1360 + 1347 1361 /* re-init DML with updated bb */ 1348 1362 dml_init_instance(&dc->dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30); 1349 1363 if (dc->current_state)
+5
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
··· 50 50 #include "dcn10/dcn10_hw_sequencer.h" 51 51 #include "inc/link_enc_cfg.h" 52 52 #include "dcn30/dcn30_vpg.h" 53 + #include "dce/dce_i2c_hw.h" 53 54 54 55 #define DC_LOGGER_INIT(logger) 55 56 ··· 259 258 260 259 /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ 261 260 REG_WRITE(DIO_MEM_PWR_CTRL, 0); 261 + 262 + // Set i2c to light sleep until engine is setup 263 + if (dc->debug.enable_mem_low_power.bits.i2c) 264 + REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1); 262 265 263 266 if (!dc->debug.disable_clock_gate) { 264 267 /* enable all DCN clock gating */
+6 -5
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
··· 101 101 #include "link_enc_cfg.h" 102 102 103 103 #define DC_LOGGER_INIT(logger) 104 - #define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) 105 - #define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) 106 104 107 105 #define DCN3_1_DEFAULT_DET_SIZE 384 108 106 ··· 897 899 HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \ 898 900 HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \ 899 901 HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \ 900 - HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh) 902 + HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh), \ 903 + HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh) 901 904 902 905 static const struct dce_hwseq_shift hwseq_shift = { 903 906 HWSEQ_DCN31_MASK_SH_LIST(__SHIFT) ··· 1832 1833 return pipe_cnt; 1833 1834 } 1834 1835 1835 - static void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) 1836 + void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) 1836 1837 { 1837 1838 if (dc->clk_mgr->bw_params->wm_table.entries[WM_A].valid) { 1838 1839 context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].pstate_latency_us; ··· 1976 1977 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); 1977 1978 } 1978 1979 1979 - static void dcn31_calculate_wm_and_dlg( 1980 + void dcn31_calculate_wm_and_dlg( 1980 1981 struct dc *dc, struct dc_state *context, 1981 1982 display_e2e_pipe_params_st *pipes, 1982 1983 int pipe_cnt, ··· 2457 2458 dc->caps.planes[i] = plane_cap; 2458 2459 2459 2460 dc->cap_funcs = cap_funcs; 2461 + 2462 + dc->dcn_ip->max_num_dpp = dcn3_1_ip.max_num_dpp; 2460 2463 2461 2464 DC_FP_END(); 2462 2465
+10
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
··· 35 35 struct resource_pool base; 36 36 }; 37 37 38 + bool dcn31_validate_bandwidth(struct dc *dc, 39 + struct dc_state *context, 40 + bool fast_validate); 41 + void dcn31_calculate_wm_and_dlg( 42 + struct dc *dc, struct dc_state *context, 43 + display_e2e_pipe_params_st *pipes, 44 + int pipe_cnt, 45 + int vlevel); 46 + void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context); 47 + 38 48 struct resource_pool *dcn31_create_resource_pool( 39 49 const struct dc_init_data *init_data, 40 50 struct dc *dc);
+2
drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
··· 35 35 uint8_t link_enc_idx; 36 36 uint8_t stream_enc_idx; 37 37 uint8_t phy_idx; 38 + uint8_t dio_output_idx; 39 + uint8_t dio_output_type; 38 40 uint8_t assr_enabled; 39 41 uint8_t mst_enabled; 40 42 uint8_t dp2_enabled;
+6
drivers/gpu/drm/amd/display/dc/dml/Makefile
··· 70 70 CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags) 71 71 CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag) 72 72 CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags) 73 + CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags) 74 + CFLAGS_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_ccflags) 73 75 CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags) 74 76 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_rcflags) 75 77 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn2x/dcn2x.o := $(dml_rcflags) ··· 85 83 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_rcflags) 86 84 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_rcflags) 87 85 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_rcflags) 86 + CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_rcflags) 88 87 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_rcflags) 88 + CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_rcflags) 89 89 endif 90 90 CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags) 91 91 CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags) ··· 103 99 DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o 104 100 DML += dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o 105 101 DML += dcn31/display_mode_vba_31.o dcn31/display_rq_dlg_calc_31.o 102 + DML += dcn301/dcn301_fpu.o 103 + DML += dsc/rc_calc_fpu.o 106 104 endif 107 105 108 106 AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
+390
drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
··· 1 + /* 2 + * Copyright 2019-2021 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + * Authors: AMD 23 + * 24 + */ 25 + #include "resource.h" 26 + #include "clk_mgr.h" 27 + #include "dcn20/dcn20_resource.h" 28 + #include "dcn301/dcn301_resource.h" 29 + 30 + #include "dml/dcn20/dcn20_fpu.h" 31 + #include "dcn301_fpu.h" 32 + 33 + #define TO_DCN301_RES_POOL(pool)\ 34 + container_of(pool, struct dcn301_resource_pool, base) 35 + 36 + /* Based on: //vidip/dc/dcn3/doc/architecture/DCN3x_Display_Mode.xlsm#83 */ 37 + struct _vcs_dpi_ip_params_st dcn3_01_ip = { 38 + .odm_capable = 1, 39 + .gpuvm_enable = 1, 40 + .hostvm_enable = 1, 41 + .gpuvm_max_page_table_levels = 1, 42 + .hostvm_max_page_table_levels = 2, 43 + .hostvm_cached_page_table_levels = 0, 44 + .pte_group_size_bytes = 2048, 45 + .num_dsc = 3, 46 + .rob_buffer_size_kbytes = 184, 47 + .det_buffer_size_kbytes = 184, 48 + .dpte_buffer_size_in_pte_reqs_luma = 64, 49 + .dpte_buffer_size_in_pte_reqs_chroma = 32, 50 + .pde_proc_buffer_size_64k_reqs = 48, 51 + .dpp_output_buffer_pixels = 2560, 52 + .opp_output_buffer_lines = 1, 53 + .pixel_chunk_size_kbytes = 8, 54 + .meta_chunk_size_kbytes = 2, 55 + .writeback_chunk_size_kbytes = 8, 56 + .line_buffer_size_bits = 789504, 57 + .is_line_buffer_bpp_fixed = 0, // ? 58 + .line_buffer_fixed_bpp = 48, // ? 59 + .dcc_supported = true, 60 + .writeback_interface_buffer_size_kbytes = 90, 61 + .writeback_line_buffer_buffer_size = 656640, 62 + .max_line_buffer_lines = 12, 63 + .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 64 + .writeback_chroma_buffer_size_kbytes = 8, 65 + .writeback_chroma_line_buffer_width_pixels = 4, 66 + .writeback_max_hscl_ratio = 1, 67 + .writeback_max_vscl_ratio = 1, 68 + .writeback_min_hscl_ratio = 1, 69 + .writeback_min_vscl_ratio = 1, 70 + .writeback_max_hscl_taps = 1, 71 + .writeback_max_vscl_taps = 1, 72 + .writeback_line_buffer_luma_buffer_size = 0, 73 + .writeback_line_buffer_chroma_buffer_size = 14643, 74 + .cursor_buffer_size = 8, 75 + .cursor_chunk_size = 2, 76 + .max_num_otg = 4, 77 + .max_num_dpp = 4, 78 + .max_num_wb = 1, 79 + .max_dchub_pscl_bw_pix_per_clk = 4, 80 + .max_pscl_lb_bw_pix_per_clk = 2, 81 + .max_lb_vscl_bw_pix_per_clk = 4, 82 + .max_vscl_hscl_bw_pix_per_clk = 4, 83 + .max_hscl_ratio = 6, 84 + .max_vscl_ratio = 6, 85 + .hscl_mults = 4, 86 + .vscl_mults = 4, 87 + .max_hscl_taps = 8, 88 + .max_vscl_taps = 8, 89 + .dispclk_ramp_margin_percent = 1, 90 + .underscan_factor = 1.11, 91 + .min_vblank_lines = 32, 92 + .dppclk_delay_subtotal = 46, 93 + .dynamic_metadata_vm_enabled = true, 94 + .dppclk_delay_scl_lb_only = 16, 95 + .dppclk_delay_scl = 50, 96 + .dppclk_delay_cnvc_formatter = 27, 97 + .dppclk_delay_cnvc_cursor = 6, 98 + .dispclk_delay_subtotal = 119, 99 + .dcfclk_cstate_latency = 5.2, // SRExitTime 100 + .max_inter_dcn_tile_repeaters = 8, 101 + .max_num_hdmi_frl_outputs = 0, 102 + .odm_combine_4to1_supported = true, 103 + 104 + .xfc_supported = false, 105 + .xfc_fill_bw_overhead_percent = 10.0, 106 + .xfc_fill_constant_bytes = 0, 107 + .gfx7_compat_tiling_supported = 0, 108 + .number_of_cursors = 1, 109 + }; 110 + 111 + struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = { 112 + .clock_limits = { 113 + { 114 + .state = 0, 115 + .dram_speed_mts = 2400.0, 116 + .fabricclk_mhz = 600, 117 + .socclk_mhz = 278.0, 118 + .dcfclk_mhz = 400.0, 119 + .dscclk_mhz = 206.0, 120 + .dppclk_mhz = 1015.0, 121 + .dispclk_mhz = 1015.0, 122 + .phyclk_mhz = 600.0, 123 + }, 124 + 125 + { 126 + .state = 1, 127 + .dram_speed_mts = 2400.0, 128 + .fabricclk_mhz = 688, 129 + .socclk_mhz = 278.0, 130 + .dcfclk_mhz = 400.0, 131 + .dscclk_mhz = 206.0, 132 + .dppclk_mhz = 1015.0, 133 + .dispclk_mhz = 1015.0, 134 + .phyclk_mhz = 600.0, 135 + }, 136 + 137 + { 138 + .state = 2, 139 + .dram_speed_mts = 4267.0, 140 + .fabricclk_mhz = 1067, 141 + .socclk_mhz = 278.0, 142 + .dcfclk_mhz = 608.0, 143 + .dscclk_mhz = 296.0, 144 + .dppclk_mhz = 1015.0, 145 + .dispclk_mhz = 1015.0, 146 + .phyclk_mhz = 810.0, 147 + }, 148 + 149 + { 150 + .state = 3, 151 + .dram_speed_mts = 4267.0, 152 + .fabricclk_mhz = 1067, 153 + .socclk_mhz = 715.0, 154 + .dcfclk_mhz = 676.0, 155 + .dscclk_mhz = 338.0, 156 + .dppclk_mhz = 1015.0, 157 + .dispclk_mhz = 1015.0, 158 + .phyclk_mhz = 810.0, 159 + }, 160 + 161 + { 162 + .state = 4, 163 + .dram_speed_mts = 4267.0, 164 + .fabricclk_mhz = 1067, 165 + .socclk_mhz = 953.0, 166 + .dcfclk_mhz = 810.0, 167 + .dscclk_mhz = 338.0, 168 + .dppclk_mhz = 1015.0, 169 + .dispclk_mhz = 1015.0, 170 + .phyclk_mhz = 810.0, 171 + }, 172 + }, 173 + 174 + .sr_exit_time_us = 9.0, 175 + .sr_enter_plus_exit_time_us = 11.0, 176 + .urgent_latency_us = 4.0, 177 + .urgent_latency_pixel_data_only_us = 4.0, 178 + .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, 179 + .urgent_latency_vm_data_only_us = 4.0, 180 + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, 181 + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, 182 + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, 183 + .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, 184 + .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0, 185 + .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, 186 + .max_avg_sdp_bw_use_normal_percent = 60.0, 187 + .max_avg_dram_bw_use_normal_percent = 60.0, 188 + .writeback_latency_us = 12.0, 189 + .max_request_size_bytes = 256, 190 + .dram_channel_width_bytes = 4, 191 + .fabric_datapath_to_dcn_data_return_bytes = 32, 192 + .dcn_downspread_percent = 0.5, 193 + .downspread_percent = 0.38, 194 + .dram_page_open_time_ns = 50.0, 195 + .dram_rw_turnaround_time_ns = 17.5, 196 + .dram_return_buffer_per_channel_bytes = 8192, 197 + .round_trip_ping_latency_dcfclk_cycles = 191, 198 + .urgent_out_of_order_return_per_channel_bytes = 4096, 199 + .channel_interleave_bytes = 256, 200 + .num_banks = 8, 201 + .num_chans = 4, 202 + .gpuvm_min_page_size_bytes = 4096, 203 + .hostvm_min_page_size_bytes = 4096, 204 + .dram_clock_change_latency_us = 23.84, 205 + .writeback_dram_clock_change_latency_us = 23.0, 206 + .return_bus_width_bytes = 64, 207 + .dispclk_dppclk_vco_speed_mhz = 3550, 208 + .xfc_bus_transport_time_us = 20, // ? 209 + .xfc_xbuf_latency_tolerance_us = 4, // ? 210 + .use_urgent_burst_bw = 1, // ? 211 + .num_states = 5, 212 + .do_urgent_latency_adjustment = false, 213 + .urgent_latency_adjustment_fabric_clock_component_us = 0, 214 + .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, 215 + }; 216 + 217 + static void calculate_wm_set_for_vlevel(int vlevel, 218 + struct wm_range_table_entry *table_entry, 219 + struct dcn_watermarks *wm_set, 220 + struct display_mode_lib *dml, 221 + display_e2e_pipe_params_st *pipes, 222 + int pipe_cnt) 223 + { 224 + double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us; 225 + 226 + ASSERT(vlevel < dml->soc.num_states); 227 + /* only pipe 0 is read for voltage and dcf/soc clocks */ 228 + pipes[0].clks_cfg.voltage = vlevel; 229 + pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz; 230 + pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz; 231 + 232 + dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us; 233 + dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us; 234 + dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us; 235 + 236 + wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000; 237 + wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000; 238 + wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000; 239 + wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000; 240 + wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000; 241 + wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000; 242 + wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000; 243 + wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000; 244 + dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached; 245 + 246 + } 247 + 248 + void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) 249 + { 250 + struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool); 251 + struct clk_limit_table *clk_table = &bw_params->clk_table; 252 + struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; 253 + unsigned int i, closest_clk_lvl; 254 + int j; 255 + 256 + dc_assert_fp_enabled(); 257 + 258 + /* Default clock levels are used for diags, which may lead to overclocking. */ 259 + if (!IS_DIAG_DC(dc->ctx->dce_environment)) { 260 + dcn3_01_ip.max_num_otg = pool->base.res_cap->num_timing_generator; 261 + dcn3_01_ip.max_num_dpp = pool->base.pipe_count; 262 + dcn3_01_soc.num_chans = bw_params->num_channels; 263 + 264 + ASSERT(clk_table->num_entries); 265 + for (i = 0; i < clk_table->num_entries; i++) { 266 + /* loop backwards*/ 267 + for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) { 268 + if ((unsigned int) dcn3_01_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { 269 + closest_clk_lvl = j; 270 + break; 271 + } 272 + } 273 + 274 + clock_limits[i].state = i; 275 + clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; 276 + clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; 277 + clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; 278 + clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; 279 + 280 + clock_limits[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; 281 + clock_limits[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; 282 + clock_limits[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; 283 + clock_limits[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz; 284 + clock_limits[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; 285 + clock_limits[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; 286 + clock_limits[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz; 287 + } 288 + 289 + for (i = 0; i < clk_table->num_entries; i++) 290 + dcn3_01_soc.clock_limits[i] = clock_limits[i]; 291 + 292 + if (clk_table->num_entries) { 293 + dcn3_01_soc.num_states = clk_table->num_entries; 294 + /* duplicate last level */ 295 + dcn3_01_soc.clock_limits[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1]; 296 + dcn3_01_soc.clock_limits[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states; 297 + } 298 + } 299 + 300 + dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 301 + dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 302 + 303 + dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30); 304 + } 305 + 306 + void dcn301_fpu_set_wm_ranges(int i, 307 + struct pp_smu_wm_range_sets *ranges, 308 + struct _vcs_dpi_soc_bounding_box_st *loaded_bb) 309 + { 310 + dc_assert_fp_enabled(); 311 + 312 + ranges->reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0; 313 + ranges->reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16; 314 + } 315 + 316 + void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info) 317 + { 318 + dc_assert_fp_enabled(); 319 + 320 + if (bb_info.dram_clock_change_latency_100ns > 0) 321 + dcn3_01_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; 322 + 323 + if (bb_info.dram_sr_enter_exit_latency_100ns > 0) 324 + dcn3_01_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; 325 + 326 + if (bb_info.dram_sr_exit_latency_100ns > 0) 327 + dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; 328 + } 329 + 330 + void dcn301_calculate_wm_and_dlg(struct dc *dc, 331 + struct dc_state *context, 332 + display_e2e_pipe_params_st *pipes, 333 + int pipe_cnt, 334 + int vlevel_req) 335 + { 336 + int i, pipe_idx; 337 + int vlevel, vlevel_max; 338 + struct wm_range_table_entry *table_entry; 339 + struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; 340 + 341 + ASSERT(bw_params); 342 + dc_assert_fp_enabled(); 343 + 344 + vlevel_max = bw_params->clk_table.num_entries - 1; 345 + 346 + /* WM Set D */ 347 + table_entry = &bw_params->wm_table.entries[WM_D]; 348 + if (table_entry->wm_type == WM_TYPE_RETRAINING) 349 + vlevel = 0; 350 + else 351 + vlevel = vlevel_max; 352 + calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d, 353 + &context->bw_ctx.dml, pipes, pipe_cnt); 354 + /* WM Set C */ 355 + table_entry = &bw_params->wm_table.entries[WM_C]; 356 + vlevel = min(max(vlevel_req, 2), vlevel_max); 357 + calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, 358 + &context->bw_ctx.dml, pipes, pipe_cnt); 359 + /* WM Set B */ 360 + table_entry = &bw_params->wm_table.entries[WM_B]; 361 + vlevel = min(max(vlevel_req, 1), vlevel_max); 362 + calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, 363 + &context->bw_ctx.dml, pipes, pipe_cnt); 364 + 365 + /* WM Set A */ 366 + table_entry = &bw_params->wm_table.entries[WM_A]; 367 + vlevel = min(vlevel_req, vlevel_max); 368 + calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a, 369 + &context->bw_ctx.dml, pipes, pipe_cnt); 370 + 371 + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { 372 + if (!context->res_ctx.pipe_ctx[i].stream) 373 + continue; 374 + 375 + pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); 376 + pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); 377 + 378 + if (dc->config.forced_clocks) { 379 + pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; 380 + pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; 381 + } 382 + if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) 383 + pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; 384 + if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) 385 + pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; 386 + pipe_idx++; 387 + } 388 + 389 + dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); 390 + }
+42
drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
··· 1 + /* 2 + * Copyright 2019-2021 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + * Authors: AMD 23 + * 24 + */ 25 + 26 + #ifndef __DCN301_FPU_H__ 27 + #define __DCN301_FPU_H__ 28 + 29 + void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params); 30 + 31 + void dcn301_fpu_set_wm_ranges(int i, 32 + struct pp_smu_wm_range_sets *ranges, 33 + struct _vcs_dpi_soc_bounding_box_st *loaded_bb); 34 + 35 + void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info); 36 + 37 + void dcn301_calculate_wm_and_dlg(struct dc *dc, 38 + struct dc_state *context, 39 + display_e2e_pipe_params_st *pipes, 40 + int pipe_cnt, 41 + int vlevel_req); 42 + #endif /* __DCN301_FPU_H__*/
+291
drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
··· 1 + /* 2 + * Copyright 2021 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + * Authors: AMD 23 + * 24 + */ 25 + 26 + #include "rc_calc_fpu.h" 27 + 28 + #include "qp_tables.h" 29 + #include "amdgpu_dm/dc_fpu.h" 30 + 31 + #define table_hash(mode, bpc, max_min) ((mode << 16) | (bpc << 8) | max_min) 32 + 33 + #define MODE_SELECT(val444, val422, val420) \ 34 + (cm == CM_444 || cm == CM_RGB) ? (val444) : (cm == CM_422 ? (val422) : (val420)) 35 + 36 + 37 + #define TABLE_CASE(mode, bpc, max) case (table_hash(mode, BPC_##bpc, max)): \ 38 + table = qp_table_##mode##_##bpc##bpc_##max; \ 39 + table_size = sizeof(qp_table_##mode##_##bpc##bpc_##max)/sizeof(*qp_table_##mode##_##bpc##bpc_##max); \ 40 + break 41 + 42 + static int median3(int a, int b, int c) 43 + { 44 + if (a > b) 45 + swap(a, b); 46 + if (b > c) 47 + swap(b, c); 48 + if (a > b) 49 + swap(b, c); 50 + 51 + return b; 52 + } 53 + 54 + static double dsc_roundf(double num) 55 + { 56 + if (num < 0.0) 57 + num = num - 0.5; 58 + else 59 + num = num + 0.5; 60 + 61 + return (int)(num); 62 + } 63 + 64 + static double dsc_ceil(double num) 65 + { 66 + double retval = (int)num; 67 + 68 + if (retval != num && num > 0) 69 + retval = num + 1; 70 + 71 + return (int)retval; 72 + } 73 + 74 + static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, 75 + enum max_min max_min, float bpp) 76 + { 77 + int mode = MODE_SELECT(444, 422, 420); 78 + int sel = table_hash(mode, bpc, max_min); 79 + int table_size = 0; 80 + int index; 81 + const struct qp_entry *table = 0L; 82 + 83 + // alias enum 84 + enum { min = DAL_MM_MIN, max = DAL_MM_MAX }; 85 + switch (sel) { 86 + TABLE_CASE(444, 8, max); 87 + TABLE_CASE(444, 8, min); 88 + TABLE_CASE(444, 10, max); 89 + TABLE_CASE(444, 10, min); 90 + TABLE_CASE(444, 12, max); 91 + TABLE_CASE(444, 12, min); 92 + TABLE_CASE(422, 8, max); 93 + TABLE_CASE(422, 8, min); 94 + TABLE_CASE(422, 10, max); 95 + TABLE_CASE(422, 10, min); 96 + TABLE_CASE(422, 12, max); 97 + TABLE_CASE(422, 12, min); 98 + TABLE_CASE(420, 8, max); 99 + TABLE_CASE(420, 8, min); 100 + TABLE_CASE(420, 10, max); 101 + TABLE_CASE(420, 10, min); 102 + TABLE_CASE(420, 12, max); 103 + TABLE_CASE(420, 12, min); 104 + } 105 + 106 + if (table == 0) 107 + return; 108 + 109 + index = (bpp - table[0].bpp) * 2; 110 + 111 + /* requested size is bigger than the table */ 112 + if (index >= table_size) { 113 + dm_error("ERROR: Requested rc_calc to find a bpp entry that exceeds the table size\n"); 114 + return; 115 + } 116 + 117 + memcpy(qps, table[index].qps, sizeof(qp_set)); 118 + } 119 + 120 + static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp) 121 + { 122 + int *p = ofs; 123 + 124 + if (mode == CM_444 || mode == CM_RGB) { 125 + *p++ = (bpp <= 6) ? (0) : ((((bpp >= 8) && (bpp <= 12))) ? (2) : ((bpp >= 15) ? (10) : ((((bpp > 6) && (bpp < 8))) ? (0 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (2 + dsc_roundf((bpp - 12) * (8 / 3.0)))))); 126 + *p++ = (bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (8) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (8 / 3.0)))))); 127 + *p++ = (bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (6) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); 128 + *p++ = (bpp <= 6) ? (-4) : ((((bpp >= 8) && (bpp <= 12))) ? (-2) : ((bpp >= 15) ? (4) : ((((bpp > 6) && (bpp < 8))) ? (-4 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-2 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); 129 + *p++ = (bpp <= 6) ? (-6) : ((((bpp >= 8) && (bpp <= 12))) ? (-4) : ((bpp >= 15) ? (2) : ((((bpp > 6) && (bpp < 8))) ? (-6 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-4 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); 130 + *p++ = (bpp <= 12) ? (-6) : ((bpp >= 15) ? (0) : (-6 + dsc_roundf((bpp - 12) * (6 / 3.0)))); 131 + *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-2) : (-8 + dsc_roundf((bpp - 12) * (6 / 3.0)))); 132 + *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-4) : (-8 + dsc_roundf((bpp - 12) * (4 / 3.0)))); 133 + *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-6) : (-8 + dsc_roundf((bpp - 12) * (2 / 3.0)))); 134 + *p++ = (bpp <= 12) ? (-10) : ((bpp >= 15) ? (-8) : (-10 + dsc_roundf((bpp - 12) * (2 / 3.0)))); 135 + *p++ = -10; 136 + *p++ = (bpp <= 6) ? (-12) : ((bpp >= 8) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2 / 2.0)))); 137 + *p++ = -12; 138 + *p++ = -12; 139 + *p++ = -12; 140 + } else if (mode == CM_422) { 141 + *p++ = (bpp <= 8) ? (2) : ((bpp >= 10) ? (10) : (2 + dsc_roundf((bpp - 8) * (8 / 2.0)))); 142 + *p++ = (bpp <= 8) ? (0) : ((bpp >= 10) ? (8) : (0 + dsc_roundf((bpp - 8) * (8 / 2.0)))); 143 + *p++ = (bpp <= 8) ? (0) : ((bpp >= 10) ? (6) : (0 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 144 + *p++ = (bpp <= 8) ? (-2) : ((bpp >= 10) ? (4) : (-2 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 145 + *p++ = (bpp <= 8) ? (-4) : ((bpp >= 10) ? (2) : (-4 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 146 + *p++ = (bpp <= 8) ? (-6) : ((bpp >= 10) ? (0) : (-6 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 147 + *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-2) : (-8 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 148 + *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-4) : (-8 + dsc_roundf((bpp - 8) * (4 / 2.0)))); 149 + *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-6) : (-8 + dsc_roundf((bpp - 8) * (2 / 2.0)))); 150 + *p++ = (bpp <= 8) ? (-10) : ((bpp >= 10) ? (-8) : (-10 + dsc_roundf((bpp - 8) * (2 / 2.0)))); 151 + *p++ = -10; 152 + *p++ = (bpp <= 6) ? (-12) : ((bpp >= 7) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2.0 / 1)))); 153 + *p++ = -12; 154 + *p++ = -12; 155 + *p++ = -12; 156 + } else { 157 + *p++ = (bpp <= 6) ? (2) : ((bpp >= 8) ? (10) : (2 + dsc_roundf((bpp - 6) * (8 / 2.0)))); 158 + *p++ = (bpp <= 6) ? (0) : ((bpp >= 8) ? (8) : (0 + dsc_roundf((bpp - 6) * (8 / 2.0)))); 159 + *p++ = (bpp <= 6) ? (0) : ((bpp >= 8) ? (6) : (0 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 160 + *p++ = (bpp <= 6) ? (-2) : ((bpp >= 8) ? (4) : (-2 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 161 + *p++ = (bpp <= 6) ? (-4) : ((bpp >= 8) ? (2) : (-4 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 162 + *p++ = (bpp <= 6) ? (-6) : ((bpp >= 8) ? (0) : (-6 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 163 + *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-2) : (-8 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 164 + *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-4) : (-8 + dsc_roundf((bpp - 6) * (4 / 2.0)))); 165 + *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-6) : (-8 + dsc_roundf((bpp - 6) * (2 / 2.0)))); 166 + *p++ = (bpp <= 6) ? (-10) : ((bpp >= 8) ? (-8) : (-10 + dsc_roundf((bpp - 6) * (2 / 2.0)))); 167 + *p++ = -10; 168 + *p++ = (bpp <= 4) ? (-12) : ((bpp >= 5) ? (-10) : (-12 + dsc_roundf((bpp - 4) * (2 / 1.0)))); 169 + *p++ = -12; 170 + *p++ = -12; 171 + *p++ = -12; 172 + } 173 + } 174 + 175 + void _do_calc_rc_params(struct rc_params *rc, 176 + enum colour_mode cm, 177 + enum bits_per_comp bpc, 178 + u16 drm_bpp, 179 + bool is_navite_422_or_420, 180 + int slice_width, 181 + int slice_height, 182 + int minor_version) 183 + { 184 + float bpp; 185 + float bpp_group; 186 + float initial_xmit_delay_factor; 187 + int padding_pixels; 188 + int i; 189 + 190 + dc_assert_fp_enabled(); 191 + 192 + bpp = ((float)drm_bpp / 16.0); 193 + /* in native_422 or native_420 modes, the bits_per_pixel is double the 194 + * target bpp (the latter is what calc_rc_params expects) 195 + */ 196 + if (is_navite_422_or_420) 197 + bpp /= 2.0; 198 + 199 + rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); 200 + rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); 201 + 202 + bpp_group = MODE_SELECT(bpp, bpp * 2.0, bpp * 2.0); 203 + 204 + switch (cm) { 205 + case CM_420: 206 + rc->initial_fullness_offset = (bpp >= 6) ? (2048) : ((bpp <= 4) ? (6144) : ((((bpp > 4) && (bpp <= 5))) ? (6144 - dsc_roundf((bpp - 4) * (512))) : (5632 - dsc_roundf((bpp - 5) * (3584))))); 207 + rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 3) - (3 * bpp_group))); 208 + rc->second_line_bpg_offset = median3(0, 12, (int)((3 * bpc * 3) - (3 * bpp_group))); 209 + break; 210 + case CM_422: 211 + rc->initial_fullness_offset = (bpp >= 8) ? (2048) : ((bpp <= 7) ? (5632) : (5632 - dsc_roundf((bpp - 7) * (3584)))); 212 + rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 4) - (3 * bpp_group))); 213 + rc->second_line_bpg_offset = 0; 214 + break; 215 + case CM_444: 216 + case CM_RGB: 217 + rc->initial_fullness_offset = (bpp >= 12) ? (2048) : ((bpp <= 8) ? (6144) : ((((bpp > 8) && (bpp <= 10))) ? (6144 - dsc_roundf((bpp - 8) * (512 / 2))) : (5632 - dsc_roundf((bpp - 10) * (3584 / 2))))); 218 + rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)(((3 * bpc + (cm == CM_444 ? 0 : 2)) * 3) - (3 * bpp_group))); 219 + rc->second_line_bpg_offset = 0; 220 + break; 221 + } 222 + 223 + initial_xmit_delay_factor = (cm == CM_444 || cm == CM_RGB) ? 1.0 : 2.0; 224 + rc->initial_xmit_delay = dsc_roundf(8192.0/2.0/bpp/initial_xmit_delay_factor); 225 + 226 + if (cm == CM_422 || cm == CM_420) 227 + slice_width /= 2; 228 + 229 + padding_pixels = ((slice_width % 3) != 0) ? (3 - (slice_width % 3)) * (rc->initial_xmit_delay / slice_width) : 0; 230 + if (3 * bpp_group >= (((rc->initial_xmit_delay + 2) / 3) * (3 + (cm == CM_422)))) { 231 + if ((rc->initial_xmit_delay + padding_pixels) % 3 == 1) 232 + rc->initial_xmit_delay++; 233 + } 234 + 235 + rc->flatness_min_qp = ((bpc == BPC_8) ? (3) : ((bpc == BPC_10) ? (7) : (11))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); 236 + rc->flatness_max_qp = ((bpc == BPC_8) ? (12) : ((bpc == BPC_10) ? (16) : (20))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); 237 + rc->flatness_det_thresh = 2 << (bpc - 8); 238 + 239 + get_qp_set(rc->qp_min, cm, bpc, DAL_MM_MIN, bpp); 240 + get_qp_set(rc->qp_max, cm, bpc, DAL_MM_MAX, bpp); 241 + if (cm == CM_444 && minor_version == 1) { 242 + for (i = 0; i < QP_SET_SIZE; ++i) { 243 + rc->qp_min[i] = rc->qp_min[i] > 0 ? rc->qp_min[i] - 1 : 0; 244 + rc->qp_max[i] = rc->qp_max[i] > 0 ? rc->qp_max[i] - 1 : 0; 245 + } 246 + } 247 + get_ofs_set(rc->ofs, cm, bpp); 248 + 249 + /* fixed parameters */ 250 + rc->rc_model_size = 8192; 251 + rc->rc_edge_factor = 6; 252 + rc->rc_tgt_offset_hi = 3; 253 + rc->rc_tgt_offset_lo = 3; 254 + 255 + rc->rc_buf_thresh[0] = 896; 256 + rc->rc_buf_thresh[1] = 1792; 257 + rc->rc_buf_thresh[2] = 2688; 258 + rc->rc_buf_thresh[3] = 3584; 259 + rc->rc_buf_thresh[4] = 4480; 260 + rc->rc_buf_thresh[5] = 5376; 261 + rc->rc_buf_thresh[6] = 6272; 262 + rc->rc_buf_thresh[7] = 6720; 263 + rc->rc_buf_thresh[8] = 7168; 264 + rc->rc_buf_thresh[9] = 7616; 265 + rc->rc_buf_thresh[10] = 7744; 266 + rc->rc_buf_thresh[11] = 7872; 267 + rc->rc_buf_thresh[12] = 8000; 268 + rc->rc_buf_thresh[13] = 8064; 269 + } 270 + 271 + u32 _do_bytes_per_pixel_calc(int slice_width, 272 + u16 drm_bpp, 273 + bool is_navite_422_or_420) 274 + { 275 + float bpp; 276 + u32 bytes_per_pixel; 277 + double d_bytes_per_pixel; 278 + 279 + dc_assert_fp_enabled(); 280 + 281 + bpp = ((float)drm_bpp / 16.0); 282 + d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width; 283 + // TODO: Make sure the formula for calculating this is precise (ceiling 284 + // vs. floor, and at what point they should be applied) 285 + if (is_navite_422_or_420) 286 + d_bytes_per_pixel /= 2; 287 + 288 + bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000); 289 + 290 + return bytes_per_pixel; 291 + }
+94
drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h
··· 1 + /* 2 + * Copyright 2021 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + * Authors: AMD 23 + * 24 + */ 25 + 26 + #ifndef __RC_CALC_FPU_H__ 27 + #define __RC_CALC_FPU_H__ 28 + 29 + #include "os_types.h" 30 + #include <drm/drm_dsc.h> 31 + 32 + #define QP_SET_SIZE 15 33 + 34 + typedef int qp_set[QP_SET_SIZE]; 35 + 36 + struct rc_params { 37 + int rc_quant_incr_limit0; 38 + int rc_quant_incr_limit1; 39 + int initial_fullness_offset; 40 + int initial_xmit_delay; 41 + int first_line_bpg_offset; 42 + int second_line_bpg_offset; 43 + int flatness_min_qp; 44 + int flatness_max_qp; 45 + int flatness_det_thresh; 46 + qp_set qp_min; 47 + qp_set qp_max; 48 + qp_set ofs; 49 + int rc_model_size; 50 + int rc_edge_factor; 51 + int rc_tgt_offset_hi; 52 + int rc_tgt_offset_lo; 53 + int rc_buf_thresh[QP_SET_SIZE - 1]; 54 + }; 55 + 56 + enum colour_mode { 57 + CM_RGB, /* 444 RGB */ 58 + CM_444, /* 444 YUV or simple 422 */ 59 + CM_422, /* native 422 */ 60 + CM_420 /* native 420 */ 61 + }; 62 + 63 + enum bits_per_comp { 64 + BPC_8 = 8, 65 + BPC_10 = 10, 66 + BPC_12 = 12 67 + }; 68 + 69 + enum max_min { 70 + DAL_MM_MIN = 0, 71 + DAL_MM_MAX = 1 72 + }; 73 + 74 + struct qp_entry { 75 + float bpp; 76 + const qp_set qps; 77 + }; 78 + 79 + typedef struct qp_entry qp_table[]; 80 + 81 + u32 _do_bytes_per_pixel_calc(int slice_width, 82 + u16 drm_bpp, 83 + bool is_navite_422_or_420); 84 + 85 + void _do_calc_rc_params(struct rc_params *rc, 86 + enum colour_mode cm, 87 + enum bits_per_comp bpc, 88 + u16 drm_bpp, 89 + bool is_navite_422_or_420, 90 + int slice_width, 91 + int slice_height, 92 + int minor_version); 93 + 94 + #endif
-29
drivers/gpu/drm/amd/display/dc/dsc/Makefile
··· 1 1 # SPDX-License-Identifier: MIT 2 2 # 3 3 # Makefile for the 'dsc' sub-component of DAL. 4 - 5 - ifdef CONFIG_X86 6 - dsc_ccflags := -mhard-float -msse 7 - endif 8 - 9 - ifdef CONFIG_PPC64 10 - dsc_ccflags := -mhard-float -maltivec 11 - endif 12 - 13 - ifdef CONFIG_CC_IS_GCC 14 - ifeq ($(call cc-ifversion, -lt, 0701, y), y) 15 - IS_OLD_GCC = 1 16 - endif 17 - endif 18 - 19 - ifdef CONFIG_X86 20 - ifdef IS_OLD_GCC 21 - # Stack alignment mismatch, proceed with caution. 22 - # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 23 - # (8B stack alignment). 24 - dsc_ccflags += -mpreferred-stack-boundary=4 25 - else 26 - dsc_ccflags += -msse2 27 - endif 28 - endif 29 - 30 - CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_ccflags) 31 - CFLAGS_REMOVE_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_rcflags) 32 - 33 4 DSC = dc_dsc.o rc_calc.o rc_calc_dpi.o 34 5 35 6 AMD_DAL_DSC = $(addprefix $(AMDDALPATH)/dc/dsc/,$(DSC))
drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h
-259
drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
··· 23 23 * Authors: AMD 24 24 * 25 25 */ 26 - #include <drm/drm_dsc.h> 27 - 28 - #include "os_types.h" 29 26 #include "rc_calc.h" 30 - #include "qp_tables.h" 31 - 32 - #define table_hash(mode, bpc, max_min) ((mode << 16) | (bpc << 8) | max_min) 33 - 34 - #define MODE_SELECT(val444, val422, val420) \ 35 - (cm == CM_444 || cm == CM_RGB) ? (val444) : (cm == CM_422 ? (val422) : (val420)) 36 - 37 - 38 - #define TABLE_CASE(mode, bpc, max) case (table_hash(mode, BPC_##bpc, max)): \ 39 - table = qp_table_##mode##_##bpc##bpc_##max; \ 40 - table_size = sizeof(qp_table_##mode##_##bpc##bpc_##max)/sizeof(*qp_table_##mode##_##bpc##bpc_##max); \ 41 - break 42 - 43 - 44 - static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, 45 - enum max_min max_min, float bpp) 46 - { 47 - int mode = MODE_SELECT(444, 422, 420); 48 - int sel = table_hash(mode, bpc, max_min); 49 - int table_size = 0; 50 - int index; 51 - const struct qp_entry *table = 0L; 52 - 53 - // alias enum 54 - enum { min = DAL_MM_MIN, max = DAL_MM_MAX }; 55 - switch (sel) { 56 - TABLE_CASE(444, 8, max); 57 - TABLE_CASE(444, 8, min); 58 - TABLE_CASE(444, 10, max); 59 - TABLE_CASE(444, 10, min); 60 - TABLE_CASE(444, 12, max); 61 - TABLE_CASE(444, 12, min); 62 - TABLE_CASE(422, 8, max); 63 - TABLE_CASE(422, 8, min); 64 - TABLE_CASE(422, 10, max); 65 - TABLE_CASE(422, 10, min); 66 - TABLE_CASE(422, 12, max); 67 - TABLE_CASE(422, 12, min); 68 - TABLE_CASE(420, 8, max); 69 - TABLE_CASE(420, 8, min); 70 - TABLE_CASE(420, 10, max); 71 - TABLE_CASE(420, 10, min); 72 - TABLE_CASE(420, 12, max); 73 - TABLE_CASE(420, 12, min); 74 - } 75 - 76 - if (table == 0) 77 - return; 78 - 79 - index = (bpp - table[0].bpp) * 2; 80 - 81 - /* requested size is bigger than the table */ 82 - if (index >= table_size) { 83 - dm_error("ERROR: Requested rc_calc to find a bpp entry that exceeds the table size\n"); 84 - return; 85 - } 86 - 87 - memcpy(qps, table[index].qps, sizeof(qp_set)); 88 - } 89 - 90 - static double dsc_roundf(double num) 91 - { 92 - if (num < 0.0) 93 - num = num - 0.5; 94 - else 95 - num = num + 0.5; 96 - 97 - return (int)(num); 98 - } 99 - 100 - static double dsc_ceil(double num) 101 - { 102 - double retval = (int)num; 103 - 104 - if (retval != num && num > 0) 105 - retval = num + 1; 106 - 107 - return (int)retval; 108 - } 109 - 110 - static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp) 111 - { 112 - int *p = ofs; 113 - 114 - if (mode == CM_444 || mode == CM_RGB) { 115 - *p++ = (bpp <= 6) ? (0) : ((((bpp >= 8) && (bpp <= 12))) ? (2) : ((bpp >= 15) ? (10) : ((((bpp > 6) && (bpp < 8))) ? (0 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (2 + dsc_roundf((bpp - 12) * (8 / 3.0)))))); 116 - *p++ = (bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (8) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (8 / 3.0)))))); 117 - *p++ = (bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (6) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); 118 - *p++ = (bpp <= 6) ? (-4) : ((((bpp >= 8) && (bpp <= 12))) ? (-2) : ((bpp >= 15) ? (4) : ((((bpp > 6) && (bpp < 8))) ? (-4 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-2 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); 119 - *p++ = (bpp <= 6) ? (-6) : ((((bpp >= 8) && (bpp <= 12))) ? (-4) : ((bpp >= 15) ? (2) : ((((bpp > 6) && (bpp < 8))) ? (-6 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-4 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); 120 - *p++ = (bpp <= 12) ? (-6) : ((bpp >= 15) ? (0) : (-6 + dsc_roundf((bpp - 12) * (6 / 3.0)))); 121 - *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-2) : (-8 + dsc_roundf((bpp - 12) * (6 / 3.0)))); 122 - *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-4) : (-8 + dsc_roundf((bpp - 12) * (4 / 3.0)))); 123 - *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-6) : (-8 + dsc_roundf((bpp - 12) * (2 / 3.0)))); 124 - *p++ = (bpp <= 12) ? (-10) : ((bpp >= 15) ? (-8) : (-10 + dsc_roundf((bpp - 12) * (2 / 3.0)))); 125 - *p++ = -10; 126 - *p++ = (bpp <= 6) ? (-12) : ((bpp >= 8) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2 / 2.0)))); 127 - *p++ = -12; 128 - *p++ = -12; 129 - *p++ = -12; 130 - } else if (mode == CM_422) { 131 - *p++ = (bpp <= 8) ? (2) : ((bpp >= 10) ? (10) : (2 + dsc_roundf((bpp - 8) * (8 / 2.0)))); 132 - *p++ = (bpp <= 8) ? (0) : ((bpp >= 10) ? (8) : (0 + dsc_roundf((bpp - 8) * (8 / 2.0)))); 133 - *p++ = (bpp <= 8) ? (0) : ((bpp >= 10) ? (6) : (0 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 134 - *p++ = (bpp <= 8) ? (-2) : ((bpp >= 10) ? (4) : (-2 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 135 - *p++ = (bpp <= 8) ? (-4) : ((bpp >= 10) ? (2) : (-4 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 136 - *p++ = (bpp <= 8) ? (-6) : ((bpp >= 10) ? (0) : (-6 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 137 - *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-2) : (-8 + dsc_roundf((bpp - 8) * (6 / 2.0)))); 138 - *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-4) : (-8 + dsc_roundf((bpp - 8) * (4 / 2.0)))); 139 - *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-6) : (-8 + dsc_roundf((bpp - 8) * (2 / 2.0)))); 140 - *p++ = (bpp <= 8) ? (-10) : ((bpp >= 10) ? (-8) : (-10 + dsc_roundf((bpp - 8) * (2 / 2.0)))); 141 - *p++ = -10; 142 - *p++ = (bpp <= 6) ? (-12) : ((bpp >= 7) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2.0 / 1)))); 143 - *p++ = -12; 144 - *p++ = -12; 145 - *p++ = -12; 146 - } else { 147 - *p++ = (bpp <= 6) ? (2) : ((bpp >= 8) ? (10) : (2 + dsc_roundf((bpp - 6) * (8 / 2.0)))); 148 - *p++ = (bpp <= 6) ? (0) : ((bpp >= 8) ? (8) : (0 + dsc_roundf((bpp - 6) * (8 / 2.0)))); 149 - *p++ = (bpp <= 6) ? (0) : ((bpp >= 8) ? (6) : (0 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 150 - *p++ = (bpp <= 6) ? (-2) : ((bpp >= 8) ? (4) : (-2 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 151 - *p++ = (bpp <= 6) ? (-4) : ((bpp >= 8) ? (2) : (-4 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 152 - *p++ = (bpp <= 6) ? (-6) : ((bpp >= 8) ? (0) : (-6 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 153 - *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-2) : (-8 + dsc_roundf((bpp - 6) * (6 / 2.0)))); 154 - *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-4) : (-8 + dsc_roundf((bpp - 6) * (4 / 2.0)))); 155 - *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-6) : (-8 + dsc_roundf((bpp - 6) * (2 / 2.0)))); 156 - *p++ = (bpp <= 6) ? (-10) : ((bpp >= 8) ? (-8) : (-10 + dsc_roundf((bpp - 6) * (2 / 2.0)))); 157 - *p++ = -10; 158 - *p++ = (bpp <= 4) ? (-12) : ((bpp >= 5) ? (-10) : (-12 + dsc_roundf((bpp - 4) * (2 / 1.0)))); 159 - *p++ = -12; 160 - *p++ = -12; 161 - *p++ = -12; 162 - } 163 - } 164 - 165 - static int median3(int a, int b, int c) 166 - { 167 - if (a > b) 168 - swap(a, b); 169 - if (b > c) 170 - swap(b, c); 171 - if (a > b) 172 - swap(b, c); 173 - 174 - return b; 175 - } 176 - 177 - static void _do_calc_rc_params(struct rc_params *rc, enum colour_mode cm, 178 - enum bits_per_comp bpc, u16 drm_bpp, 179 - bool is_navite_422_or_420, 180 - int slice_width, int slice_height, 181 - int minor_version) 182 - { 183 - float bpp; 184 - float bpp_group; 185 - float initial_xmit_delay_factor; 186 - int padding_pixels; 187 - int i; 188 - 189 - bpp = ((float)drm_bpp / 16.0); 190 - /* in native_422 or native_420 modes, the bits_per_pixel is double the 191 - * target bpp (the latter is what calc_rc_params expects) 192 - */ 193 - if (is_navite_422_or_420) 194 - bpp /= 2.0; 195 - 196 - rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); 197 - rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); 198 - 199 - bpp_group = MODE_SELECT(bpp, bpp * 2.0, bpp * 2.0); 200 - 201 - switch (cm) { 202 - case CM_420: 203 - rc->initial_fullness_offset = (bpp >= 6) ? (2048) : ((bpp <= 4) ? (6144) : ((((bpp > 4) && (bpp <= 5))) ? (6144 - dsc_roundf((bpp - 4) * (512))) : (5632 - dsc_roundf((bpp - 5) * (3584))))); 204 - rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 3) - (3 * bpp_group))); 205 - rc->second_line_bpg_offset = median3(0, 12, (int)((3 * bpc * 3) - (3 * bpp_group))); 206 - break; 207 - case CM_422: 208 - rc->initial_fullness_offset = (bpp >= 8) ? (2048) : ((bpp <= 7) ? (5632) : (5632 - dsc_roundf((bpp - 7) * (3584)))); 209 - rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 4) - (3 * bpp_group))); 210 - rc->second_line_bpg_offset = 0; 211 - break; 212 - case CM_444: 213 - case CM_RGB: 214 - rc->initial_fullness_offset = (bpp >= 12) ? (2048) : ((bpp <= 8) ? (6144) : ((((bpp > 8) && (bpp <= 10))) ? (6144 - dsc_roundf((bpp - 8) * (512 / 2))) : (5632 - dsc_roundf((bpp - 10) * (3584 / 2))))); 215 - rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)(((3 * bpc + (cm == CM_444 ? 0 : 2)) * 3) - (3 * bpp_group))); 216 - rc->second_line_bpg_offset = 0; 217 - break; 218 - } 219 - 220 - initial_xmit_delay_factor = (cm == CM_444 || cm == CM_RGB) ? 1.0 : 2.0; 221 - rc->initial_xmit_delay = dsc_roundf(8192.0/2.0/bpp/initial_xmit_delay_factor); 222 - 223 - if (cm == CM_422 || cm == CM_420) 224 - slice_width /= 2; 225 - 226 - padding_pixels = ((slice_width % 3) != 0) ? (3 - (slice_width % 3)) * (rc->initial_xmit_delay / slice_width) : 0; 227 - if (3 * bpp_group >= (((rc->initial_xmit_delay + 2) / 3) * (3 + (cm == CM_422)))) { 228 - if ((rc->initial_xmit_delay + padding_pixels) % 3 == 1) 229 - rc->initial_xmit_delay++; 230 - } 231 - 232 - rc->flatness_min_qp = ((bpc == BPC_8) ? (3) : ((bpc == BPC_10) ? (7) : (11))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); 233 - rc->flatness_max_qp = ((bpc == BPC_8) ? (12) : ((bpc == BPC_10) ? (16) : (20))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); 234 - rc->flatness_det_thresh = 2 << (bpc - 8); 235 - 236 - get_qp_set(rc->qp_min, cm, bpc, DAL_MM_MIN, bpp); 237 - get_qp_set(rc->qp_max, cm, bpc, DAL_MM_MAX, bpp); 238 - if (cm == CM_444 && minor_version == 1) { 239 - for (i = 0; i < QP_SET_SIZE; ++i) { 240 - rc->qp_min[i] = rc->qp_min[i] > 0 ? rc->qp_min[i] - 1 : 0; 241 - rc->qp_max[i] = rc->qp_max[i] > 0 ? rc->qp_max[i] - 1 : 0; 242 - } 243 - } 244 - get_ofs_set(rc->ofs, cm, bpp); 245 - 246 - /* fixed parameters */ 247 - rc->rc_model_size = 8192; 248 - rc->rc_edge_factor = 6; 249 - rc->rc_tgt_offset_hi = 3; 250 - rc->rc_tgt_offset_lo = 3; 251 - 252 - rc->rc_buf_thresh[0] = 896; 253 - rc->rc_buf_thresh[1] = 1792; 254 - rc->rc_buf_thresh[2] = 2688; 255 - rc->rc_buf_thresh[3] = 3584; 256 - rc->rc_buf_thresh[4] = 4480; 257 - rc->rc_buf_thresh[5] = 5376; 258 - rc->rc_buf_thresh[6] = 6272; 259 - rc->rc_buf_thresh[7] = 6720; 260 - rc->rc_buf_thresh[8] = 7168; 261 - rc->rc_buf_thresh[9] = 7616; 262 - rc->rc_buf_thresh[10] = 7744; 263 - rc->rc_buf_thresh[11] = 7872; 264 - rc->rc_buf_thresh[12] = 8000; 265 - rc->rc_buf_thresh[13] = 8064; 266 - } 267 - 268 - static u32 _do_bytes_per_pixel_calc(int slice_width, u16 drm_bpp, 269 - bool is_navite_422_or_420) 270 - { 271 - float bpp; 272 - u32 bytes_per_pixel; 273 - double d_bytes_per_pixel; 274 - 275 - bpp = ((float)drm_bpp / 16.0); 276 - d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width; 277 - // TODO: Make sure the formula for calculating this is precise (ceiling 278 - // vs. floor, and at what point they should be applied) 279 - if (is_navite_422_or_420) 280 - d_bytes_per_pixel /= 2; 281 - 282 - bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000); 283 - 284 - return bytes_per_pixel; 285 - } 286 27 287 28 /** 288 29 * calc_rc_params - reads the user's cmdline mode
+1 -49
drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
··· 27 27 #ifndef __RC_CALC_H__ 28 28 #define __RC_CALC_H__ 29 29 30 - 31 - #define QP_SET_SIZE 15 32 - 33 - typedef int qp_set[QP_SET_SIZE]; 34 - 35 - struct rc_params { 36 - int rc_quant_incr_limit0; 37 - int rc_quant_incr_limit1; 38 - int initial_fullness_offset; 39 - int initial_xmit_delay; 40 - int first_line_bpg_offset; 41 - int second_line_bpg_offset; 42 - int flatness_min_qp; 43 - int flatness_max_qp; 44 - int flatness_det_thresh; 45 - qp_set qp_min; 46 - qp_set qp_max; 47 - qp_set ofs; 48 - int rc_model_size; 49 - int rc_edge_factor; 50 - int rc_tgt_offset_hi; 51 - int rc_tgt_offset_lo; 52 - int rc_buf_thresh[QP_SET_SIZE - 1]; 53 - }; 54 - 55 - enum colour_mode { 56 - CM_RGB, /* 444 RGB */ 57 - CM_444, /* 444 YUV or simple 422 */ 58 - CM_422, /* native 422 */ 59 - CM_420 /* native 420 */ 60 - }; 61 - 62 - enum bits_per_comp { 63 - BPC_8 = 8, 64 - BPC_10 = 10, 65 - BPC_12 = 12 66 - }; 67 - 68 - enum max_min { 69 - DAL_MM_MIN = 0, 70 - DAL_MM_MAX = 1 71 - }; 72 - 73 - struct qp_entry { 74 - float bpp; 75 - const qp_set qps; 76 - }; 77 - 78 - typedef struct qp_entry qp_table[]; 30 + #include "dml/dsc/rc_calc_fpu.h" 79 31 80 32 void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps); 81 33 u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps);
-1
drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
··· 22 22 * Authors: AMD 23 23 * 24 24 */ 25 - #include "os_types.h" 26 25 #include <drm/drm_dsc.h> 27 26 #include "dscc_types.h" 28 27 #include "rc_calc.h"
+2
drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
··· 34 34 bool disable_blnd_lut:1; 35 35 bool disable_3dlut:1; 36 36 bool disable_shaper:1; 37 + bool disable_gamcor:1; 38 + bool disable_dscl:1; 37 39 } bits; 38 40 uint32_t raw; 39 41 };
+2
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
··· 97 97 DMUB_ASIC_DCN302, 98 98 DMUB_ASIC_DCN303, 99 99 DMUB_ASIC_DCN31, 100 + DMUB_ASIC_DCN31B, 100 101 DMUB_ASIC_MAX, 101 102 }; 102 103 ··· 238 237 bool load_inst_const; 239 238 bool skip_panel_power_sequence; 240 239 bool disable_z10; 240 + bool dpia_supported; 241 241 bool disable_dpia; 242 242 }; 243 243
+78 -4
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
··· 46 46 47 47 /* Firmware versioning. */ 48 48 #ifdef DMUB_EXPOSE_VERSION 49 - #define DMUB_FW_VERSION_GIT_HASH 0xd146258f 49 + #define DMUB_FW_VERSION_GIT_HASH 0x9525efb5 50 50 #define DMUB_FW_VERSION_MAJOR 0 51 51 #define DMUB_FW_VERSION_MINOR 0 52 - #define DMUB_FW_VERSION_REVISION 88 52 + #define DMUB_FW_VERSION_REVISION 90 53 53 #define DMUB_FW_VERSION_TEST 0 54 54 #define DMUB_FW_VERSION_VBIOS 0 55 55 #define DMUB_FW_VERSION_HOTFIX 0 ··· 370 370 uint32_t z10_disable: 1; /**< 1 to disable z10 */ 371 371 uint32_t enable_dpia: 1; /**< 1 if DPIA should be enabled */ 372 372 uint32_t invalid_vbios_data: 1; /**< 1 if VBIOS data table is invalid */ 373 - uint32_t reserved_unreleased2: 1; /**< reserved for an unreleased feature */ 374 - uint32_t reserved : 22; /**< reserved */ 373 + uint32_t dpia_supported: 1; /**< 1 if DPIA is supported on this platform */ 374 + uint32_t sel_mux_phy_c_d_phy_f_g: 1; /**< 1 if PHYF/PHYG should be enabled */ 375 + /**< 1 if all root clock gating is enabled and low power memory is enabled*/ 376 + uint32_t power_optimization: 1; 377 + uint32_t diag_env: 1; /* 1 if diagnostic environment */ 378 + 379 + uint32_t reserved : 19; /**< reserved */ 375 380 } bits; /**< boot bits */ 376 381 uint32_t all; /**< 32-bit access to bits */ 377 382 }; ··· 697 692 enum dmub_cmd_dpia_type { 698 693 DMUB_CMD__DPIA_DIG1_DPIA_CONTROL = 0, 699 694 DMUB_CMD__DPIA_SET_CONFIG_ACCESS = 1, 695 + DMUB_CMD__DPIA_MST_ALLOC_SLOTS = 2, 700 696 }; 701 697 702 698 #pragma pack(push, 1) ··· 1073 1067 }; 1074 1068 1075 1069 /** 1070 + * Data passed from driver to FW in a DMUB_CMD__DPIA_MST_ALLOC_SLOTS command. 1071 + */ 1072 + struct dmub_cmd_mst_alloc_slots_control_data { 1073 + uint8_t mst_alloc_slots; /* mst slots to be allotted */ 1074 + uint8_t instance; /* DPIA instance */ 1075 + uint8_t immed_status; /* Immediate status returned as there is no outbox msg posted */ 1076 + uint8_t mst_slots_in_use; /* returns slots in use for error cases */ 1077 + }; 1078 + 1079 + /** 1080 + * DMUB command structure for SET_ command. 1081 + */ 1082 + struct dmub_rb_cmd_set_mst_alloc_slots { 1083 + struct dmub_cmd_header header; /* header */ 1084 + struct dmub_cmd_mst_alloc_slots_control_data mst_slots_control; /* mst slots control */ 1085 + }; 1086 + 1087 + /** 1076 1088 * struct dmub_rb_cmd_dpphy_init - DPPHY init. 1077 1089 */ 1078 1090 struct dmub_rb_cmd_dpphy_init { ··· 1402 1378 * Forces PSR enabled until an explicit PSR disable call. 1403 1379 */ 1404 1380 DMUB_CMD__PSR_FORCE_STATIC = 5, 1381 + /** 1382 + * Set PSR power option 1383 + */ 1384 + DMUB_CMD__SET_PSR_POWER_OPT = 7, 1405 1385 }; 1406 1386 1407 1387 /** ··· 1701 1673 * Data passed from driver to FW in a DMUB_CMD__PSR_FORCE_STATIC command. 1702 1674 */ 1703 1675 struct dmub_cmd_psr_force_static_data psr_force_static_data; 1676 + }; 1677 + 1678 + /** 1679 + * Data passed from driver to FW in a DMUB_CMD__SET_PSR_POWER_OPT command. 1680 + */ 1681 + struct dmub_cmd_psr_set_power_opt_data { 1682 + /** 1683 + * PSR control version. 1684 + */ 1685 + uint8_t cmd_version; 1686 + /** 1687 + * Panel Instance. 1688 + * Panel isntance to identify which psr_state to use 1689 + * Currently the support is only for 0 or 1 1690 + */ 1691 + uint8_t panel_inst; 1692 + /** 1693 + * Explicit padding to 4 byte boundary. 1694 + */ 1695 + uint8_t pad[2]; 1696 + /** 1697 + * PSR power option 1698 + */ 1699 + uint32_t power_opt; 1700 + }; 1701 + 1702 + /** 1703 + * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command. 1704 + */ 1705 + struct dmub_rb_cmd_psr_set_power_opt { 1706 + /** 1707 + * Command header. 1708 + */ 1709 + struct dmub_cmd_header header; 1710 + /** 1711 + * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command. 1712 + */ 1713 + struct dmub_cmd_psr_set_power_opt_data psr_set_power_opt_data; 1704 1714 }; 1705 1715 1706 1716 /** ··· 2525 2459 */ 2526 2460 struct dmub_rb_cmd_psr_force_static psr_force_static; 2527 2461 /** 2462 + * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command. 2463 + */ 2464 + struct dmub_rb_cmd_psr_set_power_opt psr_set_power_opt; 2465 + /** 2528 2466 * Definition of a DMUB_CMD__PLAT_54186_WA command. 2529 2467 */ 2530 2468 struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa; ··· 2612 2542 * Definition of a DMUB_CMD__DPIA_SET_CONFIG_ACCESS command. 2613 2543 */ 2614 2544 struct dmub_rb_cmd_set_config_access set_config_access; 2545 + /** 2546 + * Definition of a DMUB_CMD__DPIA_MST_ALLOC_SLOTS command. 2547 + */ 2548 + struct dmub_rb_cmd_set_mst_alloc_slots set_mst_alloc_slots; 2615 2549 /** 2616 2550 * Definition of a DMUB_CMD__EDID_CEA command. 2617 2551 */
+3
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
··· 338 338 union dmub_fw_boot_options boot_options = {0}; 339 339 340 340 boot_options.bits.z10_disable = params->disable_z10; 341 + boot_options.bits.dpia_supported = params->dpia_supported; 341 342 boot_options.bits.enable_dpia = params->disable_dpia ? 0 : 1; 343 + 344 + boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0; 342 345 343 346 REG_WRITE(DMCUB_SCRATCH14, boot_options.all); 344 347 }
+1
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
··· 208 208 break; 209 209 210 210 case DMUB_ASIC_DCN31: 211 + case DMUB_ASIC_DCN31B: 211 212 dmub->regs_dcn31 = &dmub_srv_dcn31_regs; 212 213 funcs->reset = dmub_dcn31_reset; 213 214 funcs->reset_release = dmub_dcn31_reset_release;
+1
drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
··· 328 328 329 329 uint8_t gu_id[NUMBER_OF_UCHAR_FOR_GUID]; 330 330 uint8_t checksum; 331 + uint8_t fixdpvoltageswing; 331 332 } ext_disp_conn_info; /* exiting long long time */ 332 333 333 334 struct available_s_clk_list {
+3
drivers/gpu/drm/amd/display/include/i2caux_interface.h
··· 41 41 * reset it to read data */ 42 42 bool write; 43 43 bool mot; 44 + bool write_status_update; 45 + 44 46 uint32_t address; 45 47 uint32_t length; 46 48 uint8_t *data; ··· 55 53 * zero means "use default value" 56 54 */ 57 55 uint32_t defer_delay; 56 + 58 57 }; 59 58 60 59 struct aux_command {
+12 -3
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
··· 155 155 if (duration_in_us > vrr->max_duration_in_us) 156 156 duration_in_us = vrr->max_duration_in_us; 157 157 158 - v_total = div64_u64(div64_u64(((unsigned long long)( 159 - duration_in_us) * (stream->timing.pix_clk_100hz / 10)), 160 - stream->timing.h_total), 1000); 158 + if (dc_is_hdmi_signal(stream->signal)) { 159 + uint32_t h_total_up_scaled; 160 + 161 + h_total_up_scaled = stream->timing.h_total * 10000; 162 + v_total = div_u64((unsigned long long)duration_in_us 163 + * stream->timing.pix_clk_100hz + (h_total_up_scaled - 1), 164 + h_total_up_scaled); 165 + } else { 166 + v_total = div64_u64(div64_u64(((unsigned long long)( 167 + duration_in_us) * (stream->timing.pix_clk_100hz / 10)), 168 + stream->timing.h_total), 1000); 169 + } 161 170 162 171 /* v_total cannot be less than nominal */ 163 172 if (v_total < stream->timing.v_total) {
+2 -4
drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
··· 105 105 dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; 106 106 107 107 psp_dtm_invoke(psp, dtm_cmd->cmd_id); 108 + mutex_unlock(&psp->dtm_context.mutex); 108 109 109 110 if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) { 110 111 status = remove_display_from_topology_v2(hdcp, index); ··· 115 114 display->state = MOD_HDCP_DISPLAY_ACTIVE; 116 115 HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index); 117 116 } 118 - 119 - mutex_unlock(&psp->dtm_context.mutex); 120 117 121 118 return status; 122 119 } ··· 204 205 dtm_cmd->dtm_in_message.topology_update_v3.link_hdcp_cap = link->hdcp_supported_informational; 205 206 206 207 psp_dtm_invoke(psp, dtm_cmd->cmd_id); 208 + mutex_unlock(&psp->dtm_context.mutex); 207 209 208 210 if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) { 209 211 status = add_display_to_topology_v2(hdcp, display); ··· 213 213 } else { 214 214 HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index); 215 215 } 216 - 217 - mutex_unlock(&psp->dtm_context.mutex); 218 216 219 217 return status; 220 218 }
+2
drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
··· 249 249 uint8_t ddc_line; 250 250 uint8_t link_enc_idx; 251 251 uint8_t phy_idx; 252 + uint8_t dio_output_type; 253 + uint8_t dio_output_id; 252 254 uint8_t hdcp_supported_informational; 253 255 union { 254 256 struct mod_hdcp_displayport dp;
+3 -1
drivers/gpu/drm/amd/pm/amdgpu_pm.c
··· 310 310 struct amdgpu_device *adev = drm_to_adev(ddev); 311 311 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; 312 312 enum amd_dpm_forced_level level; 313 - enum amd_dpm_forced_level current_level = 0xff; 313 + enum amd_dpm_forced_level current_level; 314 314 int ret = 0; 315 315 316 316 if (amdgpu_in_reset(adev)) ··· 350 350 351 351 if (pp_funcs->get_performance_level) 352 352 current_level = amdgpu_dpm_get_performance_level(adev); 353 + else 354 + current_level = adev->pm.dpm.forced_level; 353 355 354 356 if (current_level == level) { 355 357 pm_runtime_mark_last_busy(ddev->dev);
+6 -7
include/uapi/drm/amdgpu_drm.h
··· 786 786 #define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F 787 787 /* query ras mask of enabled features*/ 788 788 #define AMDGPU_INFO_RAS_ENABLED_FEATURES 0x20 789 - /* query video encode/decode caps */ 790 - #define AMDGPU_INFO_VIDEO_CAPS 0x21 791 - /* Subquery id: Decode */ 792 - #define AMDGPU_INFO_VIDEO_CAPS_DECODE 0 793 - /* Subquery id: Encode */ 794 - #define AMDGPU_INFO_VIDEO_CAPS_ENCODE 1 795 - 796 789 /* RAS MASK: UMC (VRAM) */ 797 790 #define AMDGPU_INFO_RAS_ENABLED_UMC (1 << 0) 798 791 /* RAS MASK: SDMA */ ··· 814 821 #define AMDGPU_INFO_RAS_ENABLED_MP1 (1 << 12) 815 822 /* RAS MASK: FUSE */ 816 823 #define AMDGPU_INFO_RAS_ENABLED_FUSE (1 << 13) 824 + /* query video encode/decode caps */ 825 + #define AMDGPU_INFO_VIDEO_CAPS 0x21 826 + /* Subquery id: Decode */ 827 + #define AMDGPU_INFO_VIDEO_CAPS_DECODE 0 828 + /* Subquery id: Encode */ 829 + #define AMDGPU_INFO_VIDEO_CAPS_ENCODE 1 817 830 818 831 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 819 832 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff