AMD General Reviewed-by: Kenneth Feng <[email protected]>
-----Original Message----- From: Ed Schofield <[email protected]> Sent: Wednesday, September 9, 2026 8:35 PM To: Feng, Kenneth <[email protected]> Cc: [email protected]; [email protected]; [email protected]; Deucher, Alexander <[email protected]>; Koenig, Christian <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected] Subject: [PATCH v2] drm/amd/pm: defer UCLK DPM enablement on Apple Navi 14 Apple Navi 14 boards 1002:7340/106b:0218 (revision 0x41) and 1002:7340/106b:0219 can time out when EnableAllSmuFeatures includes UCLK DPM, leaving amdgpu without a DRM device. Exclude only UCLK DPM from the initial allowed features and enable it separately in the Navi post-init callback. On 0218, enabling UCLK just after EnableAllSmuFeatures or at the start of default DPM table setup still timed out. The earlier 0218-only patch passed ten warm boots with UCLK enabled in post-init. The earliest safe point remains unknown. Check the enabled firmware bit, update the supported-feature bit and rebuild the memory DPM table and sustainable clock limits before the UMC workaround and UMD clock setup. Validate the PPT memory states that DCN20 consumes before post-init. Preserve both memory-voltage features and honor PP_MCLK_DPM_MASK. Combine Atharva Tiwari's delayed-UCLK proposal for 0219 with the Navi post-init implementation for 0218. Retain the revision restriction for 0218 and the revision-independent 0219 match from Atharva's proposal. The combined patch passed ten warm boots on 0218, with rendering and H.264 video decoding checks on every boot. Testing on 0219 is still pending. Link: https://www.mail-archive.com/[email protected]/msg149770.html Link: https://github.com/t2linux/kernel/issues/19#issuecomment-5537823876 Assisted-by: Codex:GPT-6 Signed-off-by: Ed Schofield <[email protected]> --- Changes since the 0218-only RFC: - Add the 0219 board match from Atharva's proposal, without a revision restriction. Keep the 0218 match limited to revision 0x41. - Keep the Navi post-init implementation and clock-state updates from the RFC. Atharva's proposal enabled UCLK at the end of smu_late_init(). - Record the failed tests at the start of default DPM table setup and ten successful warm boots of the combined patch on 0218. .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index f8ca5eb9a..d7cc41a5d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -60,6 +60,19 @@ static int navi10_init_ppt_limits(struct smu_context *smu); +static bool navi14_needs_late_uclk(struct amdgpu_device *adev) { + struct pci_dev *pdev = adev->pdev; + + return pdev->vendor == PCI_VENDOR_ID_ATI && + pdev->device == 0x7340 && + pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE && + ((pdev->subsystem_device == 0x0218 && + pdev->revision == 0x41) || + pdev->subsystem_device == 0x0219) && + (adev->pm.pp_feature & PP_MCLK_DPM_MASK); } + static const struct smu_feature_bits navi10_dpm_features = { .bits = { SMU_FEATURE_BIT_INIT(FEATURE_DPM_PREFETCHER_BIT), @@ -356,6 +369,11 @@ navi10_init_allowed_features(struct smu_context *smu) smu_feature_list_set_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_MEM_MVDD_SCALING_BIT); } + /* These boards time out if EnableAllSmuFeatures includes UCLK DPM. */ + if (navi14_needs_late_uclk(adev)) + smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, + FEATURE_DPM_UCLK_BIT); + if (is_asic_secure(smu) && (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 0)) && (adev->rev_id == 0)) @@ -470,6 +488,25 @@ static int navi10_store_powerplay_table(struct smu_context *smu) return 0; } +/* DCN20 consumes these PPT states before the post-init UCLK enable. */ +static int navi14_imac_check_uclk_states(struct smu_context *smu) { + PPTable_t *ppt = smu->smu_table.driver_pptable; + unsigned int count, i; + + if (!navi14_needs_late_uclk(smu->adev)) + return 0; + + count = ppt->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels; + if (!count || count > ARRAY_SIZE(ppt->FreqTableUclk)) + return -EINVAL; + for (i = 0; i < count; i++) { + if (!ppt->FreqTableUclk[i]) + return -EINVAL; + } + return 0; +} + static int navi10_setup_pptable(struct smu_context *smu) { int ret = 0; @@ -490,6 +527,10 @@ static int navi10_setup_pptable(struct smu_context *smu) if (ret) return ret; + ret = navi14_imac_check_uclk_states(smu); + if (ret) + return ret; + return navi10_init_ppt_limits(smu); } @@ -3219,6 +3260,41 @@ static int navi10_enable_mgpu_fan_boost(struct smu_context *smu) NULL); } +/* Rebuild memory clocks before the UMC workaround and UMD clock setup. +*/ static int navi14_imac_late_uclk_enable(struct smu_context *smu) { + struct smu_11_0_dpm_context *dpm = smu->smu_dpm.dpm_context; + struct smu_dpm_table *table = &dpm->dpm_tables.uclk_table; + PPTable_t *ppt = smu->smu_table.driver_pptable; + struct smu_feature_bits enabled; + int ret; + + if (!navi14_needs_late_uclk(smu->adev)) + return 0; + + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT, true); + if (ret) + return ret; + ret = smu_cmn_get_enabled_mask(smu, &enabled); + if (ret) + return ret; + if (!smu_feature_bits_is_set(&enabled, FEATURE_DPM_UCLK_BIT)) + return -EIO; + + smu_feature_list_set_bit(smu, SMU_FEATURE_LIST_SUPPORTED, + FEATURE_DPM_UCLK_BIT); + table->clk_type = SMU_UCLK; + ret = smu_v11_0_set_single_dpm_table(smu, SMU_UCLK, table); + if (ret) + return ret; + if (!table->count) + return -EINVAL; + if (!ppt->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete) + table->flags |= SMU_DPM_TABLE_FINE_GRAINED; + + return smu_v11_0_init_max_sustainable_clocks(smu); +} + static int navi10_post_smu_init(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -3227,6 +3303,12 @@ static int navi10_post_smu_init(struct smu_context *smu) if (amdgpu_sriov_vf(adev)) return 0; + ret = navi14_imac_late_uclk_enable(smu); + if (ret) { + dev_err(adev->dev, "Failed to enable late UCLK DPM: %d\n", ret); + return ret; + } + ret = navi10_run_umc_cdr_workaround(smu); if (ret) dev_err(adev->dev, "Failed to apply umc cdr workaround!\n"); base-commit: c22f9a61e288580824edbbc3ae5a29c9a338594f -- 2.55.0
