* [PATCH v2 00/12] Fixes for apple-gmux and runtime support @ 2026-11-14 16:03 Atharva Tiwari 2026-11-14 16:03 ` [PATCH v2 01/12] platform/apple-gmux: Fix power for MMIO systems Atharva Tiwari 2026-11-14 16:03 ` [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices Atharva Tiwari 0 siblings, 2 replies; 5+ messages in thread From: Atharva Tiwari @ 2026-11-14 16:03 UTC (permalink / raw) Cc: Atharva Tiwari, Bjorn Helgaas, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, Alex Deucher, Christian König, David Airlie, Simona Vetter, Harry Wentland, Leo Li, Rodrigo Siqueira, Kenneth Feng, Hans de Goede, Ilpo Järvinen, Andre Eikmeyer, open list:PCI SUBSYSTEM, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), open list:RADEON and AMDGPU DRM DRIVERS, open list:DRM DRIVERS, open list:X86 PLATFORM DRIVERS This series fixes apple-gmux on T2 Macs (2018-2020): - Fix interrupt handling - Automatically turn on dGPU when a external monitor connects. - Fix base register read/write - Fix power handling - Improve documentation - New module parameter to toggle boot GPU. It also adds vga_switcheroo runtime power management for T2 Macs, built on gmux power control, so the dGPU is powered off automatically when idle and users no longer need to toggle it manually. Changes in v2: - Check the discrete pdev config before GFX0 restore (01/13) - Don't save bridges state when state is VGA_SWITCHEROO_OFF (01/13) - Fixes discrete_pdev initialization (01/13) - Used PWRD on 15,1 and 15,3 aswell - Add quirk to 0x7360 PCI id aswell (02/13) - Add 15,1 and 15,3 and its gpu's aswell - Removed ignore_access code (02/13) - Initialized val in read functions (03/13) - Fixed permanent mutex block on failure (03/13) - Only resumed when pm_runtime is available (skipping on iMacs) (04/13) - Corrected ordering of interrupt_work (04/13) - Notified drm about hotplug change (04/13) - Checked if EFI_RT_SUPPORTED_SET_VARIABLE is available before writing gpu-active (05/13) - Wrote gpu-active on shutdown aswell (05/13) - Dropped boot-gpu parameter (06/13) - Checked if vga_switcheroo has been initialized (09/13) - Added additional pci_is_thunderbolt_attached check to amdgpu_device_supports_gmux (09/13) - Removed duplicate check (10/13) - Renamed gmux_off to runpm_active - Checked if adev->dev exists in dm_dp_aux_transfer to fix null ptr deref (11/13) - Removed GMUX specific code (12/13) - Initialized edp_sink_present in testing code (13/13) Link to v1: https://lore.kernel.org/all/20261025040046.1602-1-atharvatiwarilinuxdev@gmail.com/ Andre Eikmeyer (6): platform/apple-gmux: Write switch state to EFI on MMIO devices drm/amdgpu: Add Apple GMUX runtime PM support drm/amdgpu: Catch register access while GMUX keeps the GPU off drm/amd/display: Refuse DP AUX while GMUX keeps the GPU off drm/amdgpu: Skip AC/DC notification while the GPU is runtime suspended drm/amd/display: Skip panel power savings on eDP links without a panel Atharva Tiwari (6): platform/apple-gmux: Fix power for MMIO systems PCI: Disable pcie port on specific amd devices platform/apple-gmux: Fix MMIO interface platform/apple-gmux: Fix Interrupts for MMIO systems platform/apple-gmux: Add check to detect FSS platform/apple-gmux: Add documentation about iMacs arch/x86/pci/fixup.c | 43 +++ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 61 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 48 ++- .../gpu/drm/amd/amdgpu/amdgpu_reg_access.c | 24 ++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 + .../display/amdgpu_dm/amdgpu_dm_backlight.c | 3 + .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 19 +- .../tests/amdgpu_dm_backlight_test.c | 1 + drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 19 +- drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 1 + drivers/pci/pcie/portdrv.c | 2 +- drivers/platform/x86/Kconfig | 1 + drivers/platform/x86/apple-gmux.c | 365 +++++++++++++++--- include/linux/apple-gmux.h | 1 + include/linux/pci.h | 1 + 16 files changed, 534 insertions(+), 72 deletions(-) -- 2.55.0 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 01/12] platform/apple-gmux: Fix power for MMIO systems 2026-11-14 16:03 [PATCH v2 00/12] Fixes for apple-gmux and runtime support Atharva Tiwari @ 2026-11-14 16:03 ` Atharva Tiwari 2026-11-14 16:03 ` [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices Atharva Tiwari 1 sibling, 0 replies; 5+ messages in thread From: Atharva Tiwari @ 2026-11-14 16:03 UTC (permalink / raw) Cc: Atharva Tiwari, Sebastian Zygadlo, Yossef Osman, Andre Eikmeyer, Bjorn Helgaas, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, Alex Deucher, Christian König, David Airlie, Simona Vetter, Harry Wentland, Leo Li, Rodrigo Siqueira, Kenneth Feng, Hans de Goede, Ilpo Järvinen, open list:PCI SUBSYSTEM, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), open list:RADEON and AMDGPU DRM DRIVERS, open list:DRM DRIVERS, open list:X86 PLATFORM DRIVERS Currently The dGPU on MMIO Systems, dies when we write the gmux values to turn off the gpu. On MMIO macs Using only gmux dosent work, instead we have to use PWRD method + GMUX, which turns off the entire bridge, and completely messes the pci config, so we can't use pci to traverse through it. we save the entire bridge using ACPI addresses then we run PWRD(1) to turn off the bridge, then we write gmux states, and resume we do the vice versa, but here we dont need to retrain the link and write the MMIO variable. Tested-by: Sebastian Zygadlo <szgit@icloud.com> Tested-by: Yossef Osman <yossef.osman@proton.me> Co-developed-by: Andre Eikmeyer <dev@deq.rocks> Signed-off-by: Andre Eikmeyer <dev@deq.rocks> Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> --- drivers/platform/x86/apple-gmux.c | 159 ++++++++++++++++++++++++++++-- 1 file changed, 152 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 9c728ac4e..34e94f2b2 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -65,6 +65,10 @@ struct apple_gmux_data { struct backlight_device *bdev; + /* power handling data */ + struct pci_dev *discrete_pdev; + enum apple_gmux_type type; + /* switcheroo data */ acpi_handle dhandle; int gpe; @@ -502,23 +506,158 @@ static int gmux_switch_ddc(enum vga_switcheroo_client_id id) /** * DOC: Power control * - * gmux is able to cut power to the discrete GPU. It automatically takes care + * gmux is able to cut power to the discrete GPU. On most + * Systems the gmux automatically takes care * of the correct sequence to tear down and bring up the power rails for * core voltage, VRAM and PCIe. + * + * But on MMIO systems, the standard gmux writes does not work instead we + * have to use a combination of ACPI and GMUX, + * and Using PWRD (the method that used in macOS to turn on/off the dGPU and its bridges), + * which turns off the entire bridge and messes up the PCI config, + * so we can't use pci_upstream_bridge to traverse + * through the bridge, so we use ACPI addresses to save/restore bridges. + * + * NOTE: Communication to these bridges (not the dGPU/HDA) in any form + * when the bridge is off, will result in CPU CATERR. */ +static int gmux_save_restore_pci(acpi_handle parent_handle, const char *name, + bool save, acpi_handle *out_handle) +{ + acpi_status status; + acpi_handle handle; + struct acpi_device *adev; + struct device *dev; + struct pci_dev *pdev; + + if (name) { + status = acpi_get_handle(parent_handle, name, &handle); + if (ACPI_FAILURE(status)) + return -EIO; + + if (out_handle) + *out_handle = handle; + } else + handle = parent_handle; + + adev = acpi_fetch_acpi_dev(handle); + if (!adev) + return -EIO; + + dev = acpi_get_first_physical_node(adev); + if (!dev || !dev_is_pci(dev)) + return -EIO; + + pdev = to_pci_dev(dev); + + if (save) { + pci_save_state(pdev); + pdev->current_state = PCI_D3cold; + } else { + pdev->current_state = PCI_D0; + pci_restore_state(pdev); + } + return 0; +} + static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data, enum vga_switcheroo_state state) { reinit_completion(&gmux_data->powerchange_done); + acpi_handle discrete_handle; + acpi_status status; + unsigned long long result; + + if (!gmux_data->discrete_pdev) + return -ENODEV; + + discrete_handle = ACPI_HANDLE(&gmux_data->discrete_pdev->dev); + if (!discrete_handle) + return -ENODEV; if (state == VGA_SWITCHEROO_ON) { - gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); - gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3); + if (gmux_data->type == APPLE_GMUX_TYPE_MMIO) { + acpi_handle handle; + u16 vendor; + int i; + + gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 2); + msleep(100); + gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3); + + status = acpi_execute_simple_method(discrete_handle, "PWRD", 0); + if (ACPI_FAILURE(status)) + return -EIO; + msleep(20); + + if (gmux_save_restore_pci(NULL, "\\_SB_.PCI0.PEG0", 0, &handle)) + return -EIO; + + if (gmux_save_restore_pci(handle, "EGP0", 0, &handle)) + return -EIO; + + if (gmux_save_restore_pci(handle, "EGP1", 0, &handle)) + return -EIO; + + for (i = 0; i < 1000; i++) { + pci_read_config_word(gmux_data->discrete_pdev, + PCI_VENDOR_ID, &vendor); + if (vendor != 0xffff) + break; + msleep(1); + } + if (vendor == 0xffff) + return -ETIMEDOUT; + + if (gmux_save_restore_pci(handle, "GFX0", 0, NULL)) + return -EIO; + + if (gmux_save_restore_pci(handle, "HDAU", 0, NULL)) + return -EIO; + } else { + gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); + gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3); + } pr_debug("Discrete card powered up\n"); } else { - gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); - gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0); + if (gmux_data->type == APPLE_GMUX_TYPE_MMIO) { + acpi_handle parent_handle = discrete_handle; + bool saved_hda = false; + + /* If the power state was OFF, then we only do + * PWRD and we do not save registers, as the + * registers are already saved + */ + if (gmux_data->power_state == VGA_SWITCHEROO_OFF) + goto do_pwrd; + + while (ACPI_SUCCESS(acpi_get_parent(parent_handle, + &parent_handle))) { + if (!saved_hda) { + if (!gmux_save_restore_pci(parent_handle, + "HDAU", true, NULL)) { + saved_hda = true; + pci_save_state(gmux_data->discrete_pdev); + gmux_data->discrete_pdev->current_state = + PCI_D3cold; + } + } + if (gmux_save_restore_pci(parent_handle, NULL, true, NULL)) + break; + } +do_pwrd: + status = acpi_execute_simple_method(discrete_handle, "PWRD", 1); + if (ACPI_FAILURE(status)) + return -EIO; + msleep(20); + gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); + mdelay(10); + gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0); + } else { + gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); + gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0); + } pr_debug("Discrete card powered down\n"); } @@ -552,10 +691,14 @@ static enum vga_switcheroo_client_id gmux_get_client_id(struct pci_dev *pdev) else if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && pdev->device == 0x0863) return VGA_SWITCHEROO_IGD; - else + else { + if (!apple_gmux_data->discrete_pdev) + apple_gmux_data->discrete_pdev = pci_dev_get(pdev); + return VGA_SWITCHEROO_DIS; -} + } +} static const struct vga_switcheroo_handler gmux_handler_no_ddc = { .switchto = gmux_switchto, .power_state = gmux_set_power_state, @@ -803,6 +946,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) if (!gmux_data) return -ENOMEM; pnp_set_drvdata(pnp, gmux_data); + gmux_data->type = type; switch (type) { case APPLE_GMUX_TYPE_MMIO: @@ -993,6 +1137,7 @@ static void gmux_remove(struct pnp_dev *pnp) gmux_fini_debugfs(gmux_data); vga_switcheroo_unregister_handler(); + pci_dev_put(gmux_data->discrete_pdev); gmux_disable_interrupts(gmux_data); if (gmux_data->gpe >= 0) { acpi_disable_gpe(NULL, gmux_data->gpe); -- 2.55.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices 2026-11-14 16:03 [PATCH v2 00/12] Fixes for apple-gmux and runtime support Atharva Tiwari 2026-11-14 16:03 ` [PATCH v2 01/12] platform/apple-gmux: Fix power for MMIO systems Atharva Tiwari @ 2026-11-14 16:03 ` Atharva Tiwari 1 sibling, 0 replies; 5+ messages in thread From: Atharva Tiwari @ 2026-11-14 16:03 UTC (permalink / raw) Cc: Atharva Tiwari, Sebastian Zygadlo, Yossef Osman, Bjorn Helgaas, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, Alex Deucher, Christian König, David Airlie, Simona Vetter, Harry Wentland, Leo Li, Rodrigo Siqueira, Kenneth Feng, Hans de Goede, Ilpo Järvinen, Andre Eikmeyer, open list:PCI SUBSYSTEM, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), open list:RADEON and AMDGPU DRM DRIVERS, open list:DRM DRIVERS, open list:X86 PLATFORM DRIVERS As mentioned in the previous commit, PWRD turns off the entire bridge, and if we read/write anything to the config space or the PCIE space when the bridge is dead, the CPU CATERR's, so to avoid interaction when the bridge is dead, we remove pcieport support for the bridges.. Tested-by: Sebastian Zygadlo <szgit@icloud.com> Tested-by: Yossef Osman <yossef.osman@proton.me> Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> --- arch/x86/pci/fixup.c | 43 ++++++++++++++++++++++++++++++++++++++ drivers/pci/pcie/portdrv.c | 2 +- include/linux/pci.h | 1 + 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 795d81c7a..b1697cc4a 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -1094,6 +1094,48 @@ static void asus_disable_nvme_d3cold(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold); +static const struct dmi_system_id quirk_disable_pcie_port_dmi_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro15,1"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro15,3"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,1"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,4"), + }, + }, + {} +}; + +static void quirk_disable_pcie_port(struct pci_dev *pdev) +{ + struct pci_dev *upstream = pdev; + + if (dmi_check_system(quirk_disable_pcie_port_dmi_table)) { + while ((upstream = pci_upstream_bridge(upstream))) + upstream->no_pcie_port = 1; + } +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x67ef, quirk_disable_pcie_port); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x69af, quirk_disable_pcie_port); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7340, quirk_disable_pcie_port); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7360, quirk_disable_pcie_port); + #ifdef CONFIG_SUSPEND /* * Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but @@ -1179,4 +1221,5 @@ static void quirk_tuxeo_rp_d3(struct pci_dev *pdev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1502, quirk_tuxeo_rp_d3); + #endif /* CONFIG_SUSPEND */ diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index a9cbfc1d2..d2f19e566 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -688,7 +688,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev, int type = pci_pcie_type(dev); int status; - if (!pci_is_pcie(dev) || + if (!pci_is_pcie(dev) || dev->no_pcie_port || ((type != PCI_EXP_TYPE_ROOT_PORT) && (type != PCI_EXP_TYPE_UPSTREAM) && (type != PCI_EXP_TYPE_DOWNSTREAM) && diff --git a/include/linux/pci.h b/include/linux/pci.h index d31a8d107..fcb4f5893 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -420,6 +420,7 @@ struct pci_dev { unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ unsigned int no_d3cold:1; /* D3cold is forbidden */ unsigned int bridge_d3:1; /* Allow D3 for bridge */ + unsigned int no_pcie_port:1; /* PCIE Port driver is forbidden */ unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ unsigned int mmio_always_on:1; /* Disallow turning off io/mem decoding during BAR sizing */ -- 2.55.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 00/12] Fixes for apple-gmux and runtime support @ 2026-11-14 16:06 Atharva Tiwari 2026-11-14 16:06 ` [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices Atharva Tiwari 0 siblings, 1 reply; 5+ messages in thread From: Atharva Tiwari @ 2026-11-14 16:06 UTC (permalink / raw) Cc: Atharva Tiwari, Bjorn Helgaas, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, Alex Deucher, Christian König, David Airlie, Simona Vetter, Harry Wentland, Leo Li, Rodrigo Siqueira, Kenneth Feng, Hans de Goede, Ilpo Järvinen, Andre Eikmeyer, open list:PCI SUBSYSTEM, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), open list:RADEON and AMDGPU DRM DRIVERS, open list:DRM DRIVERS, open list:X86 PLATFORM DRIVERS This series fixes apple-gmux on T2 Macs (2018-2020): - Fix interrupt handling - Automatically turn on dGPU when a external monitor connects. - Fix base register read/write - Fix power handling - Improve documentation - New module parameter to toggle boot GPU. It also adds vga_switcheroo runtime power management for T2 Macs, built on gmux power control, so the dGPU is powered off automatically when idle and users no longer need to toggle it manually. Changes in v2: - Check the discrete pdev config before GFX0 restore (01/13) - Don't save bridges state when state is VGA_SWITCHEROO_OFF (01/13) - Fixes discrete_pdev initialization (01/13) - Used PWRD on 15,1 and 15,3 aswell - Add quirk to 0x7360 PCI id aswell (02/13) - Add 15,1 and 15,3 and its gpu's aswell - Removed ignore_access code (02/13) - Initialized val in read functions (03/13) - Fixed permanent mutex block on failure (03/13) - Only resumed when pm_runtime is available (skipping on iMacs) (04/13) - Corrected ordering of interrupt_work (04/13) - Notified drm about hotplug change (04/13) - Checked if EFI_RT_SUPPORTED_SET_VARIABLE is available before writing gpu-active (05/13) - Wrote gpu-active on shutdown aswell (05/13) - Dropped boot-gpu parameter (06/13) - Checked if vga_switcheroo has been initialized (09/13) - Added additional pci_is_thunderbolt_attached check to amdgpu_device_supports_gmux (09/13) - Removed duplicate check (10/13) - Renamed gmux_off to runpm_active - Checked if adev->dev exists in dm_dp_aux_transfer to fix null ptr deref (11/13) - Removed GMUX specific code (12/13) - Initialized edp_sink_present in testing code (13/13) Link to v1: https://lore.kernel.org/all/20261025040046.1602-1-atharvatiwarilinuxdev@gmail.com/ Andre Eikmeyer (6): platform/apple-gmux: Write switch state to EFI on MMIO devices drm/amdgpu: Add Apple GMUX runtime PM support drm/amdgpu: Catch register access while GMUX keeps the GPU off drm/amd/display: Refuse DP AUX while GMUX keeps the GPU off drm/amdgpu: Skip AC/DC notification while the GPU is runtime suspended drm/amd/display: Skip panel power savings on eDP links without a panel Atharva Tiwari (6): platform/apple-gmux: Fix power for MMIO systems PCI: Disable pcie port on specific amd devices platform/apple-gmux: Fix MMIO interface platform/apple-gmux: Fix Interrupts for MMIO systems platform/apple-gmux: Add check to detect FSS platform/apple-gmux: Add documentation about iMacs arch/x86/pci/fixup.c | 43 +++ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 61 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 48 ++- .../gpu/drm/amd/amdgpu/amdgpu_reg_access.c | 24 ++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 + .../display/amdgpu_dm/amdgpu_dm_backlight.c | 3 + .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 19 +- .../tests/amdgpu_dm_backlight_test.c | 1 + drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 19 +- drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 1 + drivers/pci/pcie/portdrv.c | 2 +- drivers/platform/x86/Kconfig | 1 + drivers/platform/x86/apple-gmux.c | 365 +++++++++++++++--- include/linux/apple-gmux.h | 1 + include/linux/pci.h | 1 + 16 files changed, 534 insertions(+), 72 deletions(-) -- 2.55.0 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices 2026-11-14 16:06 [PATCH v2 00/12] Fixes for apple-gmux and runtime support Atharva Tiwari @ 2026-11-14 16:06 ` Atharva Tiwari 2026-11-14 16:34 ` sashiko-bot 0 siblings, 1 reply; 5+ messages in thread From: Atharva Tiwari @ 2026-11-14 16:06 UTC (permalink / raw) Cc: Atharva Tiwari, Sebastian Zygadlo, Yossef Osman, Bjorn Helgaas, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, Alex Deucher, Christian König, David Airlie, Simona Vetter, Harry Wentland, Leo Li, Rodrigo Siqueira, Kenneth Feng, Hans de Goede, Ilpo Järvinen, Andre Eikmeyer, open list:PCI SUBSYSTEM, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), open list:RADEON and AMDGPU DRM DRIVERS, open list:DRM DRIVERS, open list:X86 PLATFORM DRIVERS As mentioned in the previous commit, PWRD turns off the entire bridge, and if we read/write anything to the config space or the PCIE space when the bridge is dead, the CPU CATERR's, so to avoid interaction when the bridge is dead, we remove pcieport support for the bridges.. Tested-by: Sebastian Zygadlo <szgit@icloud.com> Tested-by: Yossef Osman <yossef.osman@proton.me> Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> --- arch/x86/pci/fixup.c | 43 ++++++++++++++++++++++++++++++++++++++ drivers/pci/pcie/portdrv.c | 2 +- include/linux/pci.h | 1 + 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 795d81c7a..b1697cc4a 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -1094,6 +1094,48 @@ static void asus_disable_nvme_d3cold(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold); +static const struct dmi_system_id quirk_disable_pcie_port_dmi_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro15,1"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro15,3"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,1"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,4"), + }, + }, + {} +}; + +static void quirk_disable_pcie_port(struct pci_dev *pdev) +{ + struct pci_dev *upstream = pdev; + + if (dmi_check_system(quirk_disable_pcie_port_dmi_table)) { + while ((upstream = pci_upstream_bridge(upstream))) + upstream->no_pcie_port = 1; + } +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x67ef, quirk_disable_pcie_port); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x69af, quirk_disable_pcie_port); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7340, quirk_disable_pcie_port); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7360, quirk_disable_pcie_port); + #ifdef CONFIG_SUSPEND /* * Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but @@ -1179,4 +1221,5 @@ static void quirk_tuxeo_rp_d3(struct pci_dev *pdev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1502, quirk_tuxeo_rp_d3); + #endif /* CONFIG_SUSPEND */ diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index a9cbfc1d2..d2f19e566 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -688,7 +688,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev, int type = pci_pcie_type(dev); int status; - if (!pci_is_pcie(dev) || + if (!pci_is_pcie(dev) || dev->no_pcie_port || ((type != PCI_EXP_TYPE_ROOT_PORT) && (type != PCI_EXP_TYPE_UPSTREAM) && (type != PCI_EXP_TYPE_DOWNSTREAM) && diff --git a/include/linux/pci.h b/include/linux/pci.h index d31a8d107..fcb4f5893 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -420,6 +420,7 @@ struct pci_dev { unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ unsigned int no_d3cold:1; /* D3cold is forbidden */ unsigned int bridge_d3:1; /* Allow D3 for bridge */ + unsigned int no_pcie_port:1; /* PCIE Port driver is forbidden */ unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ unsigned int mmio_always_on:1; /* Disallow turning off io/mem decoding during BAR sizing */ -- 2.55.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices 2026-11-14 16:06 ` [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices Atharva Tiwari @ 2026-11-14 16:34 ` sashiko-bot 0 siblings, 0 replies; 5+ messages in thread From: sashiko-bot @ 2026-11-14 16:34 UTC (permalink / raw) To: Atharva Tiwari Cc: open list:PCI SUBSYSTEM, open list:RADEON and AMDGPU DRM DRIVERS, open list:DRM DRIVERS Thank you for your contribution! Sashiko AI review found 2 potential issues to consider: - [High] PCI: no_pcie_port leaves D3cold bridges exposed in suspend and sysfs - [Medium] x86/PCI: quirk_disable_pcie_port() disables pcieport on Thunderbolt eGPUs -- commit ceffb6c4c39f628d202fdc8e2a5f341d822f54ff Author: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> PCI: Disable pcie port on specific amd devices This commit adds a no_pcie_port flag to struct pci_dev and sets it via an early PCI fixup on the upstream bridges of certain AMD GPUs on Apple MacBookPro models so pcie_portdrv does not bind to them. > diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c > index 795d81c7a4de4..b1697cc4aed56 100644 > --- a/arch/x86/pci/fixup.c > +++ b/arch/x86/pci/fixup.c > @@ -1094,6 +1094,48 @@ static void asus_disable_nvme_d3cold(struct pci_dev *pdev) > } > DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold); > > +static const struct dmi_system_id quirk_disable_pcie_port_dmi_table[] = { > + { > + .matches = { > + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), > + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro15,1"), > + }, > + }, > + { > + .matches = { > + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), > + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro15,3"), > + }, > + }, > + { > + .matches = { > + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), > + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,1"), > + }, > + }, > + { > + .matches = { > + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), > + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,4"), > + }, > + }, > + {} > +}; > + > +static void quirk_disable_pcie_port(struct pci_dev *pdev) > +{ > + struct pci_dev *upstream = pdev; > + > + if (dmi_check_system(quirk_disable_pcie_port_dmi_table)) { > + while ((upstream = pci_upstream_bridge(upstream))) > + upstream->no_pcie_port = 1; > + } > +} > +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x67ef, quirk_disable_pcie_port); > +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x69af, quirk_disable_pcie_port); > +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7340, quirk_disable_pcie_port); > +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7360, quirk_disable_pcie_port); [Severity: Medium] Can quirk_disable_pcie_port() also disable pcieport on a Thunderbolt hierarchy when an external GPU with one of these retail AMD PCI device IDs (such as Radeon RX 460/560 0x67ef or Radeon RX 5500 XT 0x7340) is attached? Walking every upstream bridge without checking !pci_is_thunderbolt_attached(pdev) sets no_pcie_port = 1 on the Thunderbolt Root Port and switch bridges, breaking pciehp, PME, AER, and bridge runtime D3 across that hierarchy. > diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c > index a9cbfc1d2bc75..d2f19e5666022 100644 > --- a/drivers/pci/pcie/portdrv.c > +++ b/drivers/pci/pcie/portdrv.c > @@ -688,7 +688,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev, > int type = pci_pcie_type(dev); > int status; > > - if (!pci_is_pcie(dev) || > + if (!pci_is_pcie(dev) || dev->no_pcie_port || > ((type != PCI_EXP_TYPE_ROOT_PORT) && > (type != PCI_EXP_TYPE_UPSTREAM) && > (type != PCI_EXP_TYPE_DOWNSTREAM) && [Severity: High] Does returning -ENODEV here leave the upstream bridges exposed to config space accesses while powered off by apple-gmux via PWRD(1)? Without pcie_portdrv bound, each upstream bridge has dev->driver == NULL (so pm == NULL) and remains in RPM_ACTIVE with runtime PM forbidden. When apple-gmux powers off the discrete GPU in gmux_set_discrete_state(), it saves state, sets pdev->current_state = PCI_D3cold on the bridges, and cuts power via PWRD(1). During system suspend while the bridges are off, pci_pm_prepare() sees !pm_runtime_suspended(dev) and skips direct_complete, and then pci_pm_suspend_noirq() accesses the dead bridge directly: drivers/pci/pci-driver.c:pci_pm_suspend_noirq() { ... if (!pm) { pci_save_state(pci_dev); goto set_unknown; } ... } pci_pm_resume_noirq() similarly accesses config space and PCIe capabilities on the dead bridges before gmux_resume() restores power. At runtime, any userspace read of /sys/bus/pci/devices/.../config (such as lspci) calls pci_read_config() -> pci_config_pm_runtime_get(), where pm_runtime_resume(dev) is a no-op because the unbound bridge is still in RPM_ACTIVE, so pci_user_read_config_*() reads directly from the powered-off bridge and triggers a CPU CATERR. -- Sashiko AI review · https://sashiko.dev/#/patchset/20261114160731.3756-1-atharvatiwarilinuxdev@gmail.com?part=2 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-14 16:34 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-14 16:03 [PATCH v2 00/12] Fixes for apple-gmux and runtime support Atharva Tiwari 2026-11-14 16:03 ` [PATCH v2 01/12] platform/apple-gmux: Fix power for MMIO systems Atharva Tiwari 2026-11-14 16:03 ` [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices Atharva Tiwari -- strict thread matches above, loose matches on Subject: below -- 2026-11-14 16:06 [PATCH v2 00/12] Fixes for apple-gmux and runtime support Atharva Tiwari 2026-11-14 16:06 ` [PATCH v2 02/12] PCI: Disable pcie port on specific amd devices Atharva Tiwari 2026-11-14 16:34 ` sashiko-bot
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.