* [PATCH] drm/amdgpu/gmc_v8_0: restore the FB location after a re-POST
@ 2026-09-24 13:29 Francisco Beltrán Millalén
2026-09-24 14:55 ` Christian König
0 siblings, 1 reply; 6+ messages in thread
From: Francisco Beltrán Millalén @ 2026-09-24 13:29 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, amd-gfx
Cc: airlied, simona, dri-devel, linux-kernel
On a MacBookPro14,3 (Radeon Pro 560, POLARIS11) amdgpu has never recovered
from an ASIC reset: five attempts recorded, zero successes. Since suspend
to RAM goes through a reset, S3 fails the same way, and as the internal
panel hangs off the AMD GPU the machine comes back blind.
The failure looks like VRAM going write-only-dead: writes are silently
dropped while reads still work, the driver reports success at every step,
and then it hands the SMU a pointer to a table that was never written:
amdgpu_device_asic_init() -> 0 (reports success)
gmc_v8_0_hw_init() -> 0 (reports success)
memcpy_toio() (write silently discarded)
send_msg(0x251, ...) (SMU parses garbage)
smu7_check_fw_load_finish() -> -EINVAL -> black screen
It is not VRAM dying. It is the framebuffer moving.
On this machine the Apple firmware places VRAM at MC address 0 on a cold
boot, and gmc_v8_0_vram_gtt_location() reads MC_VM_FB_LOCATION once, at
init, to derive vram_start. A re-POST -- which is what an ASIC reset and
an S3 resume both trigger -- lets the VBIOS put the framebuffer back at
its own default instead, 0xf400_0000 here:
cold boot: MC_VM_FB_LOCATION = 0x007f0000
after reset: MC_VM_FB_LOCATION = 0xf47ff400
gmc_v8_0_mc_program() programs the system aperture from the stale
vram_start, but only writes MC_VM_FB_LOCATION and HDP_NONSURFACE_BASE
under SR-IOV; on bare metal it trusts whatever the VBIOS left behind.
While the MC is still in pass-through everything appears to work, so the
mismatch goes unnoticed. Then gmc_v8_0_gart_enable() sets ENABLE_L1_TLB,
SYSTEM_ACCESS_MODE=3 and ENABLE_ADVANCED_DRIVER_MODEL, the MC starts
checking the system aperture, and every access lands outside it -- which
is why reads return data written before the reset, from a different
physical place than the writes are going to.
Write the framebuffer location back when it does not match the one the
driver is working with, which is what the SR-IOV path already does. The
comparison keeps this a no-op on machines where the VBIOS restores the
same location, so nothing changes for them.
This runs after the VGA aperture has been locked out and with the display
suspended, so the MC does not need to be stopped; only CPU access through
the BAR could land while the FB and HDP bases disagree, so BIF_FB_EN is
cleared around the update and re-enabled below.
With this the GPU survives resets and S3: the machine has since completed
twelve suspend/resume cycles in a single boot without a failure, and the
restore is visible on each resume:
amdgpu 0000:01:00.0: amdgpu: FB location 0xf47ff400 does not match
vram_start, restoring 0x007f0000
To be precise about what those cycles prove: the kernel they were run on
also carries unrelated local patches for this machine's Thunderbolt
controller, which fails separately. This patch is the one that brings the
display back -- without it the GPU never recovered from a reset at all.
Tested on 6.18.49 on a MacBookPro14,3. I have no other smu7 hardware, so
this is only known to matter on machines whose firmware boots the GPU at a
different framebuffer location than the VBIOS default; elsewhere the new
branch does nothing.
Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>
---
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -472,14 +472,42 @@
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
adev->mem_scratch.gpu_addr >> 12);
+ tmp = ((adev->gmc.vram_end >> 24) & 0xFFFF) << 16;
+ tmp |= ((adev->gmc.vram_start >> 24) & 0xFFFF);
+
if (amdgpu_sriov_vf(adev)) {
- tmp = ((adev->gmc.vram_end >> 24) & 0xFFFF) << 16;
- tmp |= ((adev->gmc.vram_start >> 24) & 0xFFFF);
WREG32(mmMC_VM_FB_LOCATION, tmp);
/* XXX double check these! */
WREG32(mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8));
WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
+ } else {
+ u32 fb_loc = RREG32(mmMC_VM_FB_LOCATION);
+
+ /*
+ * On bare metal vram_start is the FB base found at init (see
+ * gmc_v8_0_vram_gtt_location()). Normally the VBIOS put it
+ * there and a later re-POST puts it back in the same place.
+ * On MacBookPros with switchable graphics VRAM is at 0 at boot
+ * instead, and a re-POST (S3 resume, ASIC reset) moves it to
+ * the VBIOS default, away from the addresses the driver
+ * already uses. Move it back.
+ *
+ * This only happens after a re-POST: the display is suspended
+ * and the VGA aperture has been locked out above, so there is
+ * no need to stop the MC. Only CPU access through the BAR
+ * could land while the FB and HDP bases disagree, so block it
+ * here; BIF_FB_EN is enabled again below.
+ */
+ if (REG_GET_FIELD(fb_loc, MC_VM_FB_LOCATION, FB_BASE) !=
+ REG_GET_FIELD(tmp, MC_VM_FB_LOCATION, FB_BASE)) {
+ dev_info(adev->dev,
+ "FB location 0x%08x does not match vram_start, restoring 0x%08x\n",
+ fb_loc, tmp);
+ WREG32(mmBIF_FB_EN, 0);
+ WREG32(mmMC_VM_FB_LOCATION, tmp);
+ WREG32(mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8));
+ }
}
WREG32(mmMC_VM_AGP_BASE, 0);
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] drm/amdgpu/gmc_v8_0: restore the FB location after a re-POST
2026-09-24 13:29 [PATCH] drm/amdgpu/gmc_v8_0: restore the FB location after a re-POST Francisco Beltrán Millalén
@ 2026-09-24 14:55 ` Christian König
2026-09-24 15:21 ` Alex Deucher
0 siblings, 1 reply; 6+ messages in thread
From: Christian König @ 2026-09-24 14:55 UTC (permalink / raw)
To: Francisco Beltrán Millalén, alexander.deucher, amd-gfx
Cc: airlied, simona, dri-devel, linux-kernel
On 9/24/26 15:29, Francisco Beltrán Millalén wrote:
> On a MacBookPro14,3 (Radeon Pro 560, POLARIS11) amdgpu has never recovered
> from an ASIC reset: five attempts recorded, zero successes. Since suspend
> to RAM goes through a reset, S3 fails the same way, and as the internal
> panel hangs off the AMD GPU the machine comes back blind.
>
> The failure looks like VRAM going write-only-dead: writes are silently
> dropped while reads still work, the driver reports success at every step,
> and then it hands the SMU a pointer to a table that was never written:
>
> amdgpu_device_asic_init() -> 0 (reports success)
> gmc_v8_0_hw_init() -> 0 (reports success)
> memcpy_toio() (write silently discarded)
> send_msg(0x251, ...) (SMU parses garbage)
> smu7_check_fw_load_finish() -> -EINVAL -> black screen
>
> It is not VRAM dying. It is the framebuffer moving.
>
> On this machine the Apple firmware places VRAM at MC address 0 on a cold
> boot, and gmc_v8_0_vram_gtt_location() reads MC_VM_FB_LOCATION once, at
> init, to derive vram_start. A re-POST -- which is what an ASIC reset and
> an S3 resume both trigger -- lets the VBIOS put the framebuffer back at
> its own default instead, 0xf400_0000 here:
>
> cold boot: MC_VM_FB_LOCATION = 0x007f0000
> after reset: MC_VM_FB_LOCATION = 0xf47ff400
Mhm, interesting I'm really wondering where those values come from.
>
> gmc_v8_0_mc_program() programs the system aperture from the stale
> vram_start, but only writes MC_VM_FB_LOCATION and HDP_NONSURFACE_BASE
> under SR-IOV; on bare metal it trusts whatever the VBIOS left behind.
> While the MC is still in pass-through everything appears to work, so the
> mismatch goes unnoticed. Then gmc_v8_0_gart_enable() sets ENABLE_L1_TLB,
> SYSTEM_ACCESS_MODE=3 and ENABLE_ADVANCED_DRIVER_MODEL, the MC starts
> checking the system aperture, and every access lands outside it -- which
> is why reads return data written before the reset, from a different
> physical place than the writes are going to.
>
> Write the framebuffer location back when it does not match the one the
> driver is working with, which is what the SR-IOV path already does. The
> comparison keeps this a no-op on machines where the VBIOS restores the
> same location, so nothing changes for them.
That is still a rather bad idea for multiple reasons.
You often run into suspend/resume and random memory corruption issues when stuff like that is done and we never fully implemented blocking VRAM access during a runtime ASIC reset.
I think the more defensive approach is to do an ASIC reset on driver load and use the values the AtomBIOS init function comes up with.
@Alex what's your take here?
Regards,
Christian.
>
> This runs after the VGA aperture has been locked out and with the display
> suspended, so the MC does not need to be stopped; only CPU access through
> the BAR could land while the FB and HDP bases disagree, so BIF_FB_EN is
> cleared around the update and re-enabled below.
>
> With this the GPU survives resets and S3: the machine has since completed
> twelve suspend/resume cycles in a single boot without a failure, and the
> restore is visible on each resume:
>
> amdgpu 0000:01:00.0: amdgpu: FB location 0xf47ff400 does not match
> vram_start, restoring 0x007f0000
>
> To be precise about what those cycles prove: the kernel they were run on
> also carries unrelated local patches for this machine's Thunderbolt
> controller, which fails separately. This patch is the one that brings the
> display back -- without it the GPU never recovered from a reset at all.
>
> Tested on 6.18.49 on a MacBookPro14,3. I have no other smu7 hardware, so
> this is only known to matter on machines whose firmware boots the GPU at a
> different framebuffer location than the VBIOS default; elsewhere the new
> branch does nothing.
>
> Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>
> ---
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> @@ -472,14 +472,42 @@
> WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
> adev->mem_scratch.gpu_addr >> 12);
>
> + tmp = ((adev->gmc.vram_end >> 24) & 0xFFFF) << 16;
> + tmp |= ((adev->gmc.vram_start >> 24) & 0xFFFF);
> +
> if (amdgpu_sriov_vf(adev)) {
> - tmp = ((adev->gmc.vram_end >> 24) & 0xFFFF) << 16;
> - tmp |= ((adev->gmc.vram_start >> 24) & 0xFFFF);
> WREG32(mmMC_VM_FB_LOCATION, tmp);
> /* XXX double check these! */
> WREG32(mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8));
> WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
> WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
> + } else {
> + u32 fb_loc = RREG32(mmMC_VM_FB_LOCATION);
> +
> + /*
> + * On bare metal vram_start is the FB base found at init (see
> + * gmc_v8_0_vram_gtt_location()). Normally the VBIOS put it
> + * there and a later re-POST puts it back in the same place.
> + * On MacBookPros with switchable graphics VRAM is at 0 at boot
> + * instead, and a re-POST (S3 resume, ASIC reset) moves it to
> + * the VBIOS default, away from the addresses the driver
> + * already uses. Move it back.
> + *
> + * This only happens after a re-POST: the display is suspended
> + * and the VGA aperture has been locked out above, so there is
> + * no need to stop the MC. Only CPU access through the BAR
> + * could land while the FB and HDP bases disagree, so block it
> + * here; BIF_FB_EN is enabled again below.
> + */
> + if (REG_GET_FIELD(fb_loc, MC_VM_FB_LOCATION, FB_BASE) !=
> + REG_GET_FIELD(tmp, MC_VM_FB_LOCATION, FB_BASE)) {
> + dev_info(adev->dev,
> + "FB location 0x%08x does not match vram_start, restoring 0x%08x\n",
> + fb_loc, tmp);
> + WREG32(mmBIF_FB_EN, 0);
> + WREG32(mmMC_VM_FB_LOCATION, tmp);
> + WREG32(mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8));
> + }
> }
>
> WREG32(mmMC_VM_AGP_BASE, 0);
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] drm/amdgpu/gmc_v8_0: restore the FB location after a re-POST
2026-09-24 14:55 ` Christian König
@ 2026-09-24 15:21 ` Alex Deucher
2026-09-24 21:04 ` Francisco Beltrán Millalén
2026-09-24 21:05 ` [PATCH v2] drm/amdgpu: reset VI ASIC on MacBookPro14,3 Francisco Beltrán Millalén
0 siblings, 2 replies; 6+ messages in thread
From: Alex Deucher @ 2026-09-24 15:21 UTC (permalink / raw)
To: Christian König
Cc: Francisco Beltrán Millalén, alexander.deucher, amd-gfx,
airlied, simona, dri-devel, linux-kernel
On Thu, Sep 24, 2026 at 11:06 AM Christian König
<christian.koenig@amd.com> wrote:
>
> On 9/24/26 15:29, Francisco Beltrán Millalén wrote:
> > On a MacBookPro14,3 (Radeon Pro 560, POLARIS11) amdgpu has never recovered
> > from an ASIC reset: five attempts recorded, zero successes. Since suspend
> > to RAM goes through a reset, S3 fails the same way, and as the internal
> > panel hangs off the AMD GPU the machine comes back blind.
> >
> > The failure looks like VRAM going write-only-dead: writes are silently
> > dropped while reads still work, the driver reports success at every step,
> > and then it hands the SMU a pointer to a table that was never written:
> >
> > amdgpu_device_asic_init() -> 0 (reports success)
> > gmc_v8_0_hw_init() -> 0 (reports success)
> > memcpy_toio() (write silently discarded)
> > send_msg(0x251, ...) (SMU parses garbage)
> > smu7_check_fw_load_finish() -> -EINVAL -> black screen
> >
> > It is not VRAM dying. It is the framebuffer moving.
> >
> > On this machine the Apple firmware places VRAM at MC address 0 on a cold
> > boot, and gmc_v8_0_vram_gtt_location() reads MC_VM_FB_LOCATION once, at
> > init, to derive vram_start. A re-POST -- which is what an ASIC reset and
> > an S3 resume both trigger -- lets the VBIOS put the framebuffer back at
> > its own default instead, 0xf400_0000 here:
> >
> > cold boot: MC_VM_FB_LOCATION = 0x007f0000
> > after reset: MC_VM_FB_LOCATION = 0xf47ff400
>
> Mhm, interesting I'm really wondering where those values come from.
>
> >
> > gmc_v8_0_mc_program() programs the system aperture from the stale
> > vram_start, but only writes MC_VM_FB_LOCATION and HDP_NONSURFACE_BASE
> > under SR-IOV; on bare metal it trusts whatever the VBIOS left behind.
> > While the MC is still in pass-through everything appears to work, so the
> > mismatch goes unnoticed. Then gmc_v8_0_gart_enable() sets ENABLE_L1_TLB,
> > SYSTEM_ACCESS_MODE=3 and ENABLE_ADVANCED_DRIVER_MODEL, the MC starts
> > checking the system aperture, and every access lands outside it -- which
> > is why reads return data written before the reset, from a different
> > physical place than the writes are going to.
> >
> > Write the framebuffer location back when it does not match the one the
> > driver is working with, which is what the SR-IOV path already does. The
> > comparison keeps this a no-op on machines where the VBIOS restores the
> > same location, so nothing changes for them.
>
> That is still a rather bad idea for multiple reasons.
>
> You often run into suspend/resume and random memory corruption issues when stuff like that is done and we never fully implemented blocking VRAM access during a runtime ASIC reset.
>
> I think the more defensive approach is to do an ASIC reset on driver load and use the values the AtomBIOS init function comes up with.
>
> @Alex what's your take here?
Sounds like crazy Mac specific behavior. The asic_init bios table has
to reprogram the FB aperture otherwise the pre-OS environment won't
work. Moreover, at some point, these registers became privileged such
that only firmware can program them. I agree that running asic_init
on boot for Macs would make sense. I think we already have a similar
workaround for some other mac models, probably to work around a
similar issue:
https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a5be7ad8f5f0e067613e9197638f216f46252946
Maybe add your device to that existing quirk or make the quirk generic
for all VI boards with apple ssids?
Alex
>
> Regards,
> Christian.
>
> >
> > This runs after the VGA aperture has been locked out and with the display
> > suspended, so the MC does not need to be stopped; only CPU access through
> > the BAR could land while the FB and HDP bases disagree, so BIF_FB_EN is
> > cleared around the update and re-enabled below.
> >
> > With this the GPU survives resets and S3: the machine has since completed
> > twelve suspend/resume cycles in a single boot without a failure, and the
> > restore is visible on each resume:
> >
> > amdgpu 0000:01:00.0: amdgpu: FB location 0xf47ff400 does not match
> > vram_start, restoring 0x007f0000
> >
> > To be precise about what those cycles prove: the kernel they were run on
> > also carries unrelated local patches for this machine's Thunderbolt
> > controller, which fails separately. This patch is the one that brings the
> > display back -- without it the GPU never recovered from a reset at all.
> >
> > Tested on 6.18.49 on a MacBookPro14,3. I have no other smu7 hardware, so
> > this is only known to matter on machines whose firmware boots the GPU at a
> > different framebuffer location than the VBIOS default; elsewhere the new
> > branch does nothing.
> >
> > Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>
> > ---
> > --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> > @@ -472,14 +472,42 @@
> > WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
> > adev->mem_scratch.gpu_addr >> 12);
> >
> > + tmp = ((adev->gmc.vram_end >> 24) & 0xFFFF) << 16;
> > + tmp |= ((adev->gmc.vram_start >> 24) & 0xFFFF);
> > +
> > if (amdgpu_sriov_vf(adev)) {
> > - tmp = ((adev->gmc.vram_end >> 24) & 0xFFFF) << 16;
> > - tmp |= ((adev->gmc.vram_start >> 24) & 0xFFFF);
> > WREG32(mmMC_VM_FB_LOCATION, tmp);
> > /* XXX double check these! */
> > WREG32(mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8));
> > WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
> > WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
> > + } else {
> > + u32 fb_loc = RREG32(mmMC_VM_FB_LOCATION);
> > +
> > + /*
> > + * On bare metal vram_start is the FB base found at init (see
> > + * gmc_v8_0_vram_gtt_location()). Normally the VBIOS put it
> > + * there and a later re-POST puts it back in the same place.
> > + * On MacBookPros with switchable graphics VRAM is at 0 at boot
> > + * instead, and a re-POST (S3 resume, ASIC reset) moves it to
> > + * the VBIOS default, away from the addresses the driver
> > + * already uses. Move it back.
> > + *
> > + * This only happens after a re-POST: the display is suspended
> > + * and the VGA aperture has been locked out above, so there is
> > + * no need to stop the MC. Only CPU access through the BAR
> > + * could land while the FB and HDP bases disagree, so block it
> > + * here; BIF_FB_EN is enabled again below.
> > + */
> > + if (REG_GET_FIELD(fb_loc, MC_VM_FB_LOCATION, FB_BASE) !=
> > + REG_GET_FIELD(tmp, MC_VM_FB_LOCATION, FB_BASE)) {
> > + dev_info(adev->dev,
> > + "FB location 0x%08x does not match vram_start, restoring 0x%08x\n",
> > + fb_loc, tmp);
> > + WREG32(mmBIF_FB_EN, 0);
> > + WREG32(mmMC_VM_FB_LOCATION, tmp);
> > + WREG32(mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8));
> > + }
> > }
> >
> > WREG32(mmMC_VM_AGP_BASE, 0);
>
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] drm/amdgpu/gmc_v8_0: restore the FB location after a re-POST
2026-09-24 15:21 ` Alex Deucher
@ 2026-09-24 21:04 ` Francisco Beltrán Millalén
2026-09-24 21:05 ` [PATCH v2] drm/amdgpu: reset VI ASIC on MacBookPro14,3 Francisco Beltrán Millalén
1 sibling, 0 replies; 6+ messages in thread
From: Francisco Beltrán Millalén @ 2026-09-24 21:04 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, amd-gfx
Cc: alexdeucher, airlied, simona, dri-devel, linux-kernel
On Thu, Sep 24, 2026 at 11:21 AM Alex Deucher <alexdeucher@gmail.com> wrote:
> On Thu, Sep 24, 2026 at 11:06 AM Christian König
> <christian.koenig@amd.com> wrote:
>> On 9/24/26 15:29, Francisco Beltrán Millalén wrote:
>>> cold boot: MC_VM_FB_LOCATION = 0x007f0000
>>> after reset: MC_VM_FB_LOCATION = 0xf47ff400
>>
>> Mhm, interesting I'm really wondering where those values come from.
0x007f0000 is what amdgpu finds when it loads after a cold boot, with
HDP_NONSURFACE_BASE = 0: the framebuffer at MC address 0. That is what
the platform hands over; I have no trace of who writes it before the
kernel runs, so I can only say it comes from the Apple side.
0xf47ff400, with HDP_NONSURFACE_BASE = 0xf4000000, is written by the
VBIOS ASIC_Init table that amdgpu runs on resume and after a GPU reset.
I traced the register writes across that call. As far as I know it
is the usual 0xF4_0000_0000 placement of Polaris boards elsewhere.
(The "0xf400_0000" in my commit message was wrong: the MC address is
0xF4_0000_0000.)
>> I think the more defensive approach is to do an ASIC reset on driver
>> load and use the values the AtomBIOS init function comes up with.
[...]
> I agree that running asic_init
> on boot for Macs would make sense. I think we already have a similar
> workaround for some other mac models, probably to work around a
> similar issue:
> https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a5be7ad8f5f0e067613e9197638f216f46252946
> Maybe add your device to that existing quirk or make the quirk generic
> for all VI boards with apple ssids?
That works, thank you both. I backported a5be7ad8f5f0 to 6.18.49,
added this board (106b:017a rev c7) and dropped my gmc_v8_0 patch:
- On load: "PCI CONFIG reset", "GPU posting now...", then
"VRAM: 2048M 0x000000F400000000 - 0x000000F47FFFFFFF", after both a
cold and a warm boot. With a debug print just before the reset,
MC_VM_FB_LOCATION reads 0x007f0000 before it and 0xf47ff400 after.
- S3: 9 suspend/resume cycles (lid close and rtcwake, one of them with
the lid closed for about 7.5 minutes and a USB-C disk attached), each
followed by a few minutes of 3D load. MC_VM_FB_LOCATION stays at
0xf47ff400 and no ring timeouts or VM faults were reported. In 4 of
them my old patch was still in as a detector and never fired; the
other 5 ran without it. The kernel also carries my unrelated PCI and
ACPI patches for this machine.
- Cost: the reset and post take 20-35 ms, and amdgpu init up to fbdev
takes about 0.23 s longer than before.
So please consider the gmc_v8_0 patch withdrawn. I'll send the one-line
quirk as v2 in reply to this thread.
Two things in case you prefer the generic version:
- The GPU here is a Radeon Pro 555 (2 GB), not the 560 I wrote. The
MacBookPro14,3 was also sold with a Pro 560. pci.ids lists 106b:0179
as a Radeon Pro 560 and 106b:0160, 0166 and 0167 as the Pro 460, 455
and 450 (the GPUs of the 2016 MacBookPro13,3), all 1002:67ef. I have
not checked those IDs on real machines, and I only have this one, so
I only added 017a/c7.
- From reading the code, on VI the reset on load is always a PCI
config reset: the BACO capability is only known once the PowerPlay
table is parsed in hw_init, after the reset. That is also what
happens here.
Thanks,
Francisco
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2] drm/amdgpu: reset VI ASIC on MacBookPro14,3
2026-09-24 15:21 ` Alex Deucher
2026-09-24 21:04 ` Francisco Beltrán Millalén
@ 2026-09-24 21:05 ` Francisco Beltrán Millalén
2026-09-24 21:54 ` Alex Deucher
1 sibling, 1 reply; 6+ messages in thread
From: Francisco Beltrán Millalén @ 2026-09-24 21:05 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, amd-gfx
Cc: alexdeucher, airlied, simona, dri-devel, linux-kernel
On a MacBookPro14,3 with a Radeon Pro 555 (Polaris11), the framebuffer
is at MC address 0 when amdgpu loads after a cold boot, as the firmware
leaves it (MC_VM_FB_LOCATION = 0x007f0000), while the VBIOS ASIC_Init
table places it at 0xF4_0000_0000 (0xf47ff400). amdgpu reads the
location once, at init, so after a re-POST (S3 resume or GPU reset)
the framebuffer has moved and the driver keeps programming the old
one: the SMU is handed a table that was never written and the GPU
does not come back, which leaves the internal panel black.
Resetting the ASIC on load makes ASIC_Init run before the driver reads
the location, so the driver uses the VBIOS placement from the start and
every later re-POST puts the framebuffer back where it already is.
Add the Radeon Pro 555 used in this machine to the existing VI reset
quirk table.
Tested on a MacBookPro14,3 on 6.18.49 with the quirk table backported
(the kernel also carries unrelated local PCI and ACPI patches for this
machine). The framebuffer is at 0x000000F400000000 after both cold and
warm boot, and the GPU survived 9 S3 cycles (lid close and rtcwake, one
of them with the lid closed for about 7.5 minutes and a USB-C disk
attached), each followed by a few minutes of 3D load; no ring timeouts
or VM faults were reported. The reset adds about 0.23 s to amdgpu init.
Suggested-by: Christian König <christian.koenig@amd.com>
Suggested-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/all/20260924132952.25054-1-fbeltranmillalen@gmail.com/
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>
---
v2: new approach, as suggested by Christian and Alex: instead of
rewriting MC_VM_FB_LOCATION after every re-POST in gmc_v8_0
(v1, withdrawn), reset the ASIC on load through the existing
vi_reset_quirks table.
v1: https://lore.kernel.org/all/20260924132952.25054-1-fbeltranmillalen@gmail.com/
drivers/gpu/drm/amd/amdgpu/vi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 2cd6d7d77..a0435fd55 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1397,6 +1397,7 @@ struct vi_reset_quirk {
static const struct vi_reset_quirk vi_reset_quirks[] = {
{ 0x67ef, PCI_VENDOR_ID_APPLE, 0x0190, 0xe3 }, /* Radeon Pro 555X */
{ 0x67ef, PCI_VENDOR_ID_APPLE, 0x018f, 0xc2 }, /* Radeon Pro 560X */
+ { 0x67ef, PCI_VENDOR_ID_APPLE, 0x017a, 0xc7 }, /* Radeon Pro 555 */
};
static bool vi_need_reset_on_init(struct amdgpu_device *adev)
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v2] drm/amdgpu: reset VI ASIC on MacBookPro14,3
2026-09-24 21:05 ` [PATCH v2] drm/amdgpu: reset VI ASIC on MacBookPro14,3 Francisco Beltrán Millalén
@ 2026-09-24 21:54 ` Alex Deucher
0 siblings, 0 replies; 6+ messages in thread
From: Alex Deucher @ 2026-09-24 21:54 UTC (permalink / raw)
To: Francisco Beltrán Millalén
Cc: alexander.deucher, christian.koenig, amd-gfx, airlied, simona,
dri-devel, linux-kernel
Applied. Thanks!
Alex
On Thu, Sep 24, 2026 at 5:05 PM Francisco Beltrán Millalén
<fbeltranmillalen@gmail.com> wrote:
>
> On a MacBookPro14,3 with a Radeon Pro 555 (Polaris11), the framebuffer
> is at MC address 0 when amdgpu loads after a cold boot, as the firmware
> leaves it (MC_VM_FB_LOCATION = 0x007f0000), while the VBIOS ASIC_Init
> table places it at 0xF4_0000_0000 (0xf47ff400). amdgpu reads the
> location once, at init, so after a re-POST (S3 resume or GPU reset)
> the framebuffer has moved and the driver keeps programming the old
> one: the SMU is handed a table that was never written and the GPU
> does not come back, which leaves the internal panel black.
>
> Resetting the ASIC on load makes ASIC_Init run before the driver reads
> the location, so the driver uses the VBIOS placement from the start and
> every later re-POST puts the framebuffer back where it already is.
>
> Add the Radeon Pro 555 used in this machine to the existing VI reset
> quirk table.
>
> Tested on a MacBookPro14,3 on 6.18.49 with the quirk table backported
> (the kernel also carries unrelated local PCI and ACPI patches for this
> machine). The framebuffer is at 0x000000F400000000 after both cold and
> warm boot, and the GPU survived 9 S3 cycles (lid close and rtcwake, one
> of them with the lid closed for about 7.5 minutes and a USB-C disk
> attached), each followed by a few minutes of 3D load; no ring timeouts
> or VM faults were reported. The reset adds about 0.23 s to amdgpu init.
>
> Suggested-by: Christian König <christian.koenig@amd.com>
> Suggested-by: Alex Deucher <alexander.deucher@amd.com>
> Link: https://lore.kernel.org/all/20260924132952.25054-1-fbeltranmillalen@gmail.com/
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>
> ---
> v2: new approach, as suggested by Christian and Alex: instead of
> rewriting MC_VM_FB_LOCATION after every re-POST in gmc_v8_0
> (v1, withdrawn), reset the ASIC on load through the existing
> vi_reset_quirks table.
> v1: https://lore.kernel.org/all/20260924132952.25054-1-fbeltranmillalen@gmail.com/
>
> drivers/gpu/drm/amd/amdgpu/vi.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
> index 2cd6d7d77..a0435fd55 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vi.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vi.c
> @@ -1397,6 +1397,7 @@ struct vi_reset_quirk {
> static const struct vi_reset_quirk vi_reset_quirks[] = {
> { 0x67ef, PCI_VENDOR_ID_APPLE, 0x0190, 0xe3 }, /* Radeon Pro 555X */
> { 0x67ef, PCI_VENDOR_ID_APPLE, 0x018f, 0xc2 }, /* Radeon Pro 560X */
> + { 0x67ef, PCI_VENDOR_ID_APPLE, 0x017a, 0xc7 }, /* Radeon Pro 555 */
> };
>
> static bool vi_need_reset_on_init(struct amdgpu_device *adev)
> --
> 2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-24 21:54 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-24 13:29 [PATCH] drm/amdgpu/gmc_v8_0: restore the FB location after a re-POST Francisco Beltrán Millalén
2026-09-24 14:55 ` Christian König
2026-09-24 15:21 ` Alex Deucher
2026-09-24 21:04 ` Francisco Beltrán Millalén
2026-09-24 21:05 ` [PATCH v2] drm/amdgpu: reset VI ASIC on MacBookPro14,3 Francisco Beltrán Millalén
2026-09-24 21:54 ` Alex Deucher
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®