mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Francisco Beltrán Millalén" <fbeltranmillalen@gmail.com>
To: alexander.deucher@amd.com, christian.koenig@amd.com,
	amd-gfx@lists.freedesktop.org
Cc: airlied@gmail.com, simona@ffwll.ch,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: [PATCH] drm/amdgpu/gmc_v8_0: restore the FB location after a re-POST
Date: Thu, 24 Sep 2026 10:29:52 -0300	[thread overview]
Message-ID: <20260924132952.25054-1-fbeltranmillalen@gmail.com> (raw)

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);

             reply	other threads:[~2026-09-24 13:30 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-24 13:29 Francisco Beltrán Millalén [this message]
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

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=20260924132952.25054-1-fbeltranmillalen@gmail.com \
    --to=fbeltranmillalen@gmail.com \
    --cc=airlied@gmail.com \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --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®