Re: [PATCH] drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery
From: Alex Deucher
Date: Fri Jun 26 2026 - 15:39:14 EST
On Fri, Jun 26, 2026 at 1:42 PM Mario Limonciello
<mario.limonciello@xxxxxxx> wrote:
>
>
>
> On 6/21/26 13:01, Oz Tiram wrote:
> > APUs (e.g. AMD Radeon 780M / HawkPoint, PCI 1002:1900) have no
> > dedicated VBIOS ROM chip. amdgpu_get_bios_apu() attempts four paths
> > before giving up:
> >
> > 1. ACPI VFCT table
> > 2. VRAM BAR read
> > 3. ROM BAR read
> > 4. platform BIOS
> >
> > On some systems all four fail:
>
> That's pretty odd to me. Isn't this a BIOS bug? Can you share more
> about why all of these are failing?
>
> Does the UEFI GOP driver work?
>
> >
> > - The VFCT table is absent or contains only the discrete GPU entry
> > (e.g. when a custom ACPI override is present for the dGPU only).
> > - The VRAM BAR is unmapped at probe time.
> > - The ROM BAR is zero (PCI firmware did not assign it; observed even
> > with pci=realloc,assign-busses).
> > - No platform BIOS mapping exists.
> >
> > The driver then prints "Unable to locate a BIOS ROM" and refuses to
> > bind, leaving the APU completely unusable under Linux even though the
> > hardware is functional.
> >
> > Add a fifth fallback: request a firmware file named
> > "amdgpu/<vendor>_<device>.bin" (e.g. "amdgpu/1002_1900.bin") via
> > request_firmware(). This allows a VBIOS image extracted from the
> > running hardware
>
> I thought you just said this didn't work. How did you extract it?
This is not likely to work which is why we don't generally support
this. On APUs, the base vbios image is updated by the sbios at boot
depending on the runtime configuration of the specific system (OEM
display configuration, etc.). Overriding these values with something
else can cause serious problems.
Alex
>
> > to be shipped as a firmware blob in /lib/firmware/ and
> > makes the binding succeed without any change to the ACPI tables.
> >
> > The fallback is only reached if all existing paths have already failed,
> > so there is no regression risk for boards where VFCT or ROM BAR work.
> >
> > Signed-off-by: Oz Tiram <oz@xxxxxxxxxxxxxxxxxx>
> > ---
> > v2: Validate the fetched firmware with check_atom_bios() before accepting
> > it, consistent with all other VBIOS discovery paths. Save fw->size
> > before release_firmware() so it remains valid for the size check.
> > Release the buffer via amdgpu_bios_release() if validation fails.
> >
> > drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 23 +++++++++++++++++++++++
> > 1 file changed, 23 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> > index aa039e148a5e..86064c753b09 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> > @@ -26,6 +26,7 @@
> > * Jerome Glisse
> > */
> >
> > +#include <linux/firmware.h>
> > #include "amdgpu.h"
> > #include "atom.h"
> >
> > @@ -457,6 +458,28 @@ static bool amdgpu_get_bios_apu(struct amdgpu_device *adev)
> > goto success;
> > }
> >
> > + {
> > + const struct firmware *fw;
> > + char fw_name[32];
> > + size_t fw_size;
> > +
> > + snprintf(fw_name, sizeof(fw_name), "amdgpu/%04x_%04x.bin",
> > + adev->pdev->vendor, adev->pdev->device);
> > + if (request_firmware(&fw, fw_name, adev->dev) == 0) {
> > + adev->bios = kmemdup(fw->data, fw->size, GFP_KERNEL);
> > + fw_size = fw->size;
> > + release_firmware(fw);
> > + if (!adev->bios || !check_atom_bios(adev, fw_size)) {
> > + amdgpu_bios_release(adev);
> > + } else {
> > + adev->bios_size = fw_size;
> > + dev_info(adev->dev, "Fetched VBIOS from firmware file %s\n",
> > + fw_name);
> > + goto success;
> > + }
> > + }
> > + }
> > +
> > dev_err(adev->dev, "Unable to locate a BIOS ROM\n");
> > return false;
> >
>