From: Ed Schofield <ed@aicharmers.com>
To: amd-gfx@lists.freedesktop.org
Cc: "Kenneth Feng" <kenneth.feng@amd.com>,
"Alex Deucher" <alexander.deucher@amd.com>,
"Atharva Tiwari" <atharvatiwarilinuxdev@gmail.com>,
"Christian König" <christian.koenig@amd.com>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
"Ed Schofield" <ed@aicharmers.com>
Subject: [PATCH v4] drm/amd/pm: defer UCLK DPM on selected Apple Navi GPUs
Date: Wed, 16 Sep 2026 14:40:14 +0000 [thread overview]
Message-ID: <20260916144014.879355-1-ed@aicharmers.com> (raw)
From: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Some Apple Navi GPUs intermittently time out during SMU initialization
when EnableAllSmuFeatures includes UCLK DPM. Leave UCLK out of that early
request and enable it from Navi post-init, after display hardware init
and before the UMC workaround and UMD clock setup.
Read back the enabled features before rebuilding the memory clock table
and sustainable clock limits. Also check the PPT memory states used by
display initialization before late enablement. Keep memory-voltage DPM
and respect the user's memory-DPM setting and the secure Navi 10 exclusion.
Limit this workaround to Apple 7340/0218 revision 41, 7340/0219, and
731b/021a revision 40. Revisions and PCI IDs here are hexadecimal. The
underlying initialization dependency behind the timing sensitivity is
still unknown.
This builds on Atharva Tiwari's submitted 0219 delayed-UCLK patch
and Guna's diagnosis. Ed Schofield moved the enable point into the
Navi callback, added state validation and clock-table refresh, and
extended the board matching.
Independent tests of the related T2 implementation support improved boot
reliability on 0219 and 021a; those are not tests of this exact AMD patch.
Link: https://lore.kernel.org/amd-gfx/20260824190409.1724-1-atharvatiwarilinuxdev@gmail.com/
Link: https://github.com/t2linux/linux-t2-patches/pull/61#issuecomment-5637976466
Link: https://github.com/t2linux/linux-t2-patches/pull/61#issuecomment-5645652752
Assisted-by: Codex:GPT-6
Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Co-developed-by: Ed Schofield <ed@aicharmers.com>
Signed-off-by: Ed Schofield <ed@aicharmers.com>
---
Hi Alex, hi Atharva,
Here is v4 of the delayed-UCLK workaround. Atharva is credited as the
author in `From:`, with my rework credited through `Co-developed-by:`.
The local development history starts from Atharva's original 0219
submission [1], followed by my move to the Navi post-init callback,
state validation, clock-table refresh and additional board support. This
export is a single replacement patch against AMD staging at `8a4e96cf2`;
it is not an incremental patch to apply on top of v2 or Atharva's
original patch. (V3 was a local revision that I didn't submit to this
list.)
Atharva, I agree that display initialization may explain the timing
dependency. This patch already enables UCLK after display hardware
initialization on the normal probe path. It is intended as a targeted
workaround for the reported boot failures; it does not establish the
underlying cause or address native 5K support. Could you share the exact
initialization-ordering diff, kernel version and GPU IDs from your
experiment? In the AMD staging tree used for this patch,
`dce_v10_0_early_init()` handles Tonga/Fiji, while these Navi boards use
the DCN path.
My goal is to stop the intermittent boot failures on my iMac (0218) and
other affected machines. Testing of my related T2 candidate in PR 61
[2], which was based on my local v3, is encouraging:
- Matt Olney's report on 021a [3] records internal-display boot success
improving from 2/10 to 10/10, with mixed restart types.
External-display results were 4/10 versus 4/5, with uncertain kernel
selection on the failed candidate attempt.
- Vivek Chauhan's report on 0219 [4] records boot success improving from
1/5 to 3/3.
These results are from the T2 implementation, not this exact AMD v4
export. The T2 patch stack also includes a separate correction to its
existing fixed allowed-feature mask on 0219, which clean AMD does not
need and this patch does not contain. The results support improved boot
reliability on these machines, but do not establish full performance or
reliability across all display configurations.
Compared with public v2, v4 adds 731b/021a revision 40, preserves the
existing secure-Navi-10 exclusion and generalizes the helper names. It
retains 7340/0218 revision 41 and 7340/0219. All IDs and revisions here
are hexadecimal.
Compared with my local v3 / T2 Linux PR #61, v4 excludes 020f: 3v3nFloW
reported that initialization completed but the machine subsequently hung
under load [5]. Their follow-up testing with a fixed memory-clock level
[6] suggests that memory-clock changes cause the hang, but doesn't
establish whether GPU load or display activity triggers it. I've also
excluded 021b from this version, which we don't yet have testing results
for.
Local build and host checks pass. I am currently travelling without my
iMac and have no new v4 hardware results, but I am submitting this
version for merging, with the workaround limited to the three board
matches supported by the existing evidence from the volunteer testers
mentioned above.
Alex, this patch replaces v2 and applies directly to the AMD staging
commit identified above.
Thanks,
Ed
[1] https://lore.kernel.org/amd-gfx/20260824190409.1724-1-atharvatiwarilinuxdev@gmail.com/
[2] https://github.com/t2linux/linux-t2-patches/pull/61
[3] https://github.com/t2linux/linux-t2-patches/pull/61#issuecomment-5637976466
[4] https://github.com/t2linux/linux-t2-patches/pull/61#issuecomment-5645652752
[5] https://github.com/t2linux/linux-t2-patches/pull/61#issuecomment-5646139127
[6] https://github.com/t2linux/linux-t2-patches/pull/61#issuecomment-5646438512
v3 was local, not submitted. Since public v2: add the tested 021a/40
match, retain the secure-Navi-10 exclusion, and generalize helper names.
Since local v3: remove 020f (load hangs) and 021b (no testing evidence).
Base: 8a4e96cf2acd1e0340581df100b559f77ad7d855 (AMD staging).
This is a full replacement, not a patch to apply on top of v2.
.../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 100 ++++++++++++++++++
1 file changed, 100 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..3ac2a074c 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,37 @@
static int navi10_init_ppt_limits(struct smu_context *smu);
+static bool is_asic_secure(struct smu_context *smu);
+
+static bool navi10_apple_needs_late_uclk(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
+ struct pci_dev *pdev = adev->pdev;
+
+ if (pdev->vendor != PCI_VENDOR_ID_ATI ||
+ pdev->subsystem_vendor != PCI_VENDOR_ID_APPLE ||
+ !(adev->pm.pp_feature & PP_MCLK_DPM_MASK))
+ return false;
+
+ /* Preserve the existing secure Navi 10 memory-DPM exclusion. */
+ if (is_asic_secure(smu) &&
+ amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 0) &&
+ adev->rev_id == 0)
+ return false;
+
+ switch (pdev->device) {
+ case 0x7340:
+ return (pdev->subsystem_device == 0x0218 &&
+ pdev->revision == 0x41) ||
+ pdev->subsystem_device == 0x0219;
+ case 0x731b:
+ return pdev->subsystem_device == 0x021a &&
+ pdev->revision == 0x40;
+ default:
+ return false;
+ }
+}
+
static const struct smu_feature_bits navi10_dpm_features = {
.bits = {
SMU_FEATURE_BIT_INIT(FEATURE_DPM_PREFETCHER_BIT),
@@ -356,6 +387,11 @@ navi10_init_allowed_features(struct smu_context *smu)
smu_feature_list_set_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_MEM_MVDD_SCALING_BIT);
}
+ /* Defer UCLK on the selected Apple boards until IP late init. */
+ if (navi10_apple_needs_late_uclk(smu))
+ 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 +506,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 navi10_apple_check_uclk_states(struct smu_context *smu)
+{
+ PPTable_t *ppt = smu->smu_table.driver_pptable;
+ unsigned int count, i;
+
+ if (!navi10_apple_needs_late_uclk(smu))
+ 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 +545,10 @@ static int navi10_setup_pptable(struct smu_context *smu)
if (ret)
return ret;
+ ret = navi10_apple_check_uclk_states(smu);
+ if (ret)
+ return ret;
+
return navi10_init_ppt_limits(smu);
}
@@ -3219,6 +3278,41 @@ static int navi10_enable_mgpu_fan_boost(struct smu_context *smu)
NULL);
}
+/* IP late init follows display hw_init; refresh clocks before UMC/UMD setup. */
+static int navi10_apple_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 (!navi10_apple_needs_late_uclk(smu))
+ 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 +3321,12 @@ static int navi10_post_smu_init(struct smu_context *smu)
if (amdgpu_sriov_vf(adev))
return 0;
+ ret = navi10_apple_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");
--
2.43.0
reply other threads:[~2026-09-16 14:42 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260916144014.879355-1-ed@aicharmers.com \
--to=ed@aicharmers.com \
--cc=airlied@gmail.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=atharvatiwarilinuxdev@gmail.com \
--cc=christian.koenig@amd.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=kenneth.feng@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=simona@ffwll.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®