* [PATCH] drm/i915/ddi: add DDI A force 4 lanes quirk for Apple MacBookPro11,5
@ 2026-09-12 9:18 Theo Andersen Carton
2026-09-14 10:01 ` Jani Nikula
0 siblings, 1 reply; 5+ messages in thread
From: Theo Andersen Carton @ 2026-09-12 9:18 UTC (permalink / raw)
To: jani.nikula, rodrigo.vivi
Cc: joonas.lahtinen, tursulin, airlied, simona, intel-gfx, intel-xe,
dri-devel, linux-kernel, Theo Andersen Carton
On dual-GPU Retina MacBooks the internal panel is muxed to the discrete
GPU at boot, so Apple's firmware never lights up eDP on the Intel side.
As a result it never sets DDI_A_4_LANES, and intel_ddi_max_lanes() reads
back a source maximum of two lanes for port A.
intel_dp_max_common_lane_count() then takes min3(source_max = 2,
sink_max = 4, ...) = 2, giving 2 x 2.7 Gbps x 8/10 = 4.32 Gbps of link
bandwidth. The panel's native 2880x1800@60 8bpc mode needs 8.1 Gbps, so
every mode is rejected with MODE_CLOCK_HIGH and the connector comes up
with no usable modes at all -- the panel stays dark whenever i915 is
made to drive it, which looks like a hardware limitation but is not.
The lanes are physically there. Reading the panel's DPCD from the AMD
side, where amdgpu drives it correctly, reports MAX_LANE_COUNT = 0x84,
i.e. 4 lanes, and amdgpu's own link_settings shows it running the panel
at 4 lanes / HBR. macOS likewise drives this panel from the iGPU at its
native resolution, so all four lanes are routed through the gmux to
DDI A. Only the register bit is unset.
intel_ddi_a_force_4_lanes() already exists for exactly this situation --
its neighbouring comment notes that "Some BIOS might fail to set this
bit on port A if eDP wasn't lit up at boot" -- but it only covers
Broxton and Geminilake. Extend it with a DMI quirk so affected Macs get
the correct lane count too.
The DMI match is deliberately narrow. Other dual-GPU models in the same
family are very likely affected identically, but they are untested, so
widen the match only as reports come in.
Tested on a MacBookPro11,5 (Broadwell, Iris Pro + Radeon R9 M370X):
with the quirk, DDI A comes up as 4 lanes, link training passes at
link rate 270000 / lane count 4, and i915 drives the internal panel at
its native 2880x1800.
Signed-off-by: Theo Andersen Carton <andersen.theo@gmail.com>
---
drivers/gpu/drm/i915/display/intel_ddi.c | 7 +++++
drivers/gpu/drm/i915/display/intel_quirks.c | 34 +++++++++++++++++++++
drivers/gpu/drm/i915/display/intel_quirks.h | 1 +
3 files changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 02a53c9848e1..f746287830b3 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4976,6 +4976,13 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
if (display->platform.geminilake || display->platform.broxton)
return true;
+ /*
+ * Machines whose firmware leaves eDP dark on the Intel side never set
+ * the bit, so trust the quirk rather than the register.
+ */
+ if (intel_has_quirk(display, QUIRK_DDI_A_FORCE_4_LANES))
+ return true;
+
return false;
}
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
index 33245f44c0d5..feb28956a013 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -100,6 +100,20 @@ static void quirk_disable_psr2(struct intel_display *display)
drm_info(display->drm, "PSR2 support not currently available for this setup, applying disable PSR2 quirk\n");
}
+/*
+ * Dual-GPU Macs boot with the internal panel muxed to the discrete GPU, so
+ * the firmware never lights up eDP on the Intel side and consequently never
+ * sets DDI_A_4_LANES -- even though all four lanes are wired through the gmux
+ * to DDI A. Without the bit, port A is capped at two lanes, which is not
+ * enough bandwidth for the panel's native mode, leaving the connector with no
+ * usable modes at all.
+ */
+static void quirk_ddi_a_force_4_lanes(struct intel_display *display)
+{
+ intel_set_quirk(display, QUIRK_DDI_A_FORCE_4_LANES);
+ drm_info(display->drm, "Applying DDI A force 4 lanes quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -142,6 +156,13 @@ static int intel_dmi_no_pps_backlight(const struct dmi_system_id *id)
return 1;
}
+static int intel_dmi_ddi_a_force_4_lanes(const struct dmi_system_id *id)
+{
+ DRM_INFO("DDI A is 4 lanes despite firmware on %s\n", id->ident);
+
+ return 1;
+}
+
static const struct intel_dmi_quirk intel_dmi_quirks[] = {
{
.dmi_id_list = &(const struct dmi_system_id[]) {
@@ -188,6 +209,19 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = {
},
.hook = quirk_no_pps_backlight_power_hook,
},
+ {
+ .dmi_id_list = &(const struct dmi_system_id[]) {
+ {
+ .callback = intel_dmi_ddi_a_force_4_lanes,
+ .ident = "Apple MacBookPro11,5",
+ .matches = {DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MacBookPro11,5"),
+ },
+ },
+ { }
+ },
+ .hook = quirk_ddi_a_force_4_lanes,
+ },
};
static struct intel_quirk intel_quirks[] = {
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h
index 970a4fe52faf..d2b8e9183c62 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.h
+++ b/drivers/gpu/drm/i915/display/intel_quirks.h
@@ -23,6 +23,7 @@ enum intel_quirk_id {
QUIRK_EDP_LIMIT_RATE_HBR2,
QUIRK_DISABLE_EDP_PANEL_REPLAY,
QUIRK_DISABLE_PSR2,
+ QUIRK_DDI_A_FORCE_4_LANES,
};
void intel_init_quirks(struct intel_display *display);
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] drm/i915/ddi: add DDI A force 4 lanes quirk for Apple MacBookPro11,5
2026-09-12 9:18 [PATCH] drm/i915/ddi: add DDI A force 4 lanes quirk for Apple MacBookPro11,5 Theo Andersen Carton
@ 2026-09-14 10:01 ` Jani Nikula
2026-09-15 9:21 ` Jani Nikula
2026-09-17 18:50 ` Theo Andersen Carton
0 siblings, 2 replies; 5+ messages in thread
From: Jani Nikula @ 2026-09-14 10:01 UTC (permalink / raw)
To: Theo Andersen Carton, rodrigo.vivi
Cc: joonas.lahtinen, tursulin, airlied, simona, intel-gfx, intel-xe,
dri-devel, linux-kernel, Theo Andersen Carton
On Sat, 12 Sep 2026, Theo Andersen Carton <andersen.theo@gmail.com> wrote:
> On dual-GPU Retina MacBooks the internal panel is muxed to the discrete
> GPU at boot, so Apple's firmware never lights up eDP on the Intel side.
> As a result it never sets DDI_A_4_LANES, and intel_ddi_max_lanes() reads
> back a source maximum of two lanes for port A.
>
> intel_dp_max_common_lane_count() then takes min3(source_max = 2,
> sink_max = 4, ...) = 2, giving 2 x 2.7 Gbps x 8/10 = 4.32 Gbps of link
> bandwidth. The panel's native 2880x1800@60 8bpc mode needs 8.1 Gbps, so
> every mode is rejected with MODE_CLOCK_HIGH and the connector comes up
> with no usable modes at all -- the panel stays dark whenever i915 is
> made to drive it, which looks like a hardware limitation but is not.
>
> The lanes are physically there. Reading the panel's DPCD from the AMD
> side, where amdgpu drives it correctly, reports MAX_LANE_COUNT = 0x84,
> i.e. 4 lanes, and amdgpu's own link_settings shows it running the panel
> at 4 lanes / HBR. macOS likewise drives this panel from the iGPU at its
> native resolution, so all four lanes are routed through the gmux to
> DDI A. Only the register bit is unset.
>
> intel_ddi_a_force_4_lanes() already exists for exactly this situation --
> its neighbouring comment notes that "Some BIOS might fail to set this
> bit on port A if eDP wasn't lit up at boot" -- but it only covers
> Broxton and Geminilake. Extend it with a DMI quirk so affected Macs get
> the correct lane count too.
>
> The DMI match is deliberately narrow. Other dual-GPU models in the same
> family are very likely affected identically, but they are untested, so
> widen the match only as reports come in.
>
> Tested on a MacBookPro11,5 (Broadwell, Iris Pro + Radeon R9 M370X):
> with the quirk, DDI A comes up as 4 lanes, link training passes at
> link rate 270000 / lane count 4, and i915 drives the internal panel at
> its native 2880x1800.
>
> Signed-off-by: Theo Andersen Carton <andersen.theo@gmail.com>
I'm guessing this is v2 of [1], but I shouldn't have to guess.
For future reference, please indicate patch revision, and log the
differences between the revisions. See Documentation/process, other
messages on the mailing list and git log for plenty of examples.
Is there a bug report about this? Would be nice to see the logs in the
failing case. See [2].
BR,
Jani.
[1] https://lore.kernel.org/r/CANFnrspHiK7ii28XPdLkOMyhSZcJ9xz6CT-kNX+oiiF+8N-2Fg@mail.gmail.com
[2] https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html
> ---
> drivers/gpu/drm/i915/display/intel_ddi.c | 7 +++++
> drivers/gpu/drm/i915/display/intel_quirks.c | 34 +++++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_quirks.h | 1 +
> 3 files changed, 42 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 02a53c9848e1..f746287830b3 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4976,6 +4976,13 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
> if (display->platform.geminilake || display->platform.broxton)
> return true;
>
> + /*
> + * Machines whose firmware leaves eDP dark on the Intel side never set
> + * the bit, so trust the quirk rather than the register.
> + */
> + if (intel_has_quirk(display, QUIRK_DDI_A_FORCE_4_LANES))
> + return true;
> +
> return false;
> }
>
> diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
> index 33245f44c0d5..feb28956a013 100644
> --- a/drivers/gpu/drm/i915/display/intel_quirks.c
> +++ b/drivers/gpu/drm/i915/display/intel_quirks.c
> @@ -100,6 +100,20 @@ static void quirk_disable_psr2(struct intel_display *display)
> drm_info(display->drm, "PSR2 support not currently available for this setup, applying disable PSR2 quirk\n");
> }
>
> +/*
> + * Dual-GPU Macs boot with the internal panel muxed to the discrete GPU, so
> + * the firmware never lights up eDP on the Intel side and consequently never
> + * sets DDI_A_4_LANES -- even though all four lanes are wired through the gmux
> + * to DDI A. Without the bit, port A is capped at two lanes, which is not
> + * enough bandwidth for the panel's native mode, leaving the connector with no
> + * usable modes at all.
> + */
> +static void quirk_ddi_a_force_4_lanes(struct intel_display *display)
> +{
> + intel_set_quirk(display, QUIRK_DDI_A_FORCE_4_LANES);
> + drm_info(display->drm, "Applying DDI A force 4 lanes quirk\n");
> +}
> +
> struct intel_quirk {
> int device;
> int subsystem_vendor;
> @@ -142,6 +156,13 @@ static int intel_dmi_no_pps_backlight(const struct dmi_system_id *id)
> return 1;
> }
>
> +static int intel_dmi_ddi_a_force_4_lanes(const struct dmi_system_id *id)
> +{
> + DRM_INFO("DDI A is 4 lanes despite firmware on %s\n", id->ident);
> +
> + return 1;
> +}
> +
> static const struct intel_dmi_quirk intel_dmi_quirks[] = {
> {
> .dmi_id_list = &(const struct dmi_system_id[]) {
> @@ -188,6 +209,19 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = {
> },
> .hook = quirk_no_pps_backlight_power_hook,
> },
> + {
> + .dmi_id_list = &(const struct dmi_system_id[]) {
> + {
> + .callback = intel_dmi_ddi_a_force_4_lanes,
> + .ident = "Apple MacBookPro11,5",
> + .matches = {DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
> + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MacBookPro11,5"),
> + },
> + },
> + { }
> + },
> + .hook = quirk_ddi_a_force_4_lanes,
> + },
> };
>
> static struct intel_quirk intel_quirks[] = {
> diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h
> index 970a4fe52faf..d2b8e9183c62 100644
> --- a/drivers/gpu/drm/i915/display/intel_quirks.h
> +++ b/drivers/gpu/drm/i915/display/intel_quirks.h
> @@ -23,6 +23,7 @@ enum intel_quirk_id {
> QUIRK_EDP_LIMIT_RATE_HBR2,
> QUIRK_DISABLE_EDP_PANEL_REPLAY,
> QUIRK_DISABLE_PSR2,
> + QUIRK_DDI_A_FORCE_4_LANES,
> };
>
> void intel_init_quirks(struct intel_display *display);
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] drm/i915/ddi: add DDI A force 4 lanes quirk for Apple MacBookPro11,5
2026-09-14 10:01 ` Jani Nikula
@ 2026-09-15 9:21 ` Jani Nikula
2026-09-17 18:50 ` Theo Andersen Carton
1 sibling, 0 replies; 5+ messages in thread
From: Jani Nikula @ 2026-09-15 9:21 UTC (permalink / raw)
To: Theo Andersen Carton, rodrigo.vivi
Cc: joonas.lahtinen, tursulin, airlied, simona, intel-gfx, intel-xe,
dri-devel, linux-kernel, Theo Andersen Carton
On Mon, 14 Sep 2026, Jani Nikula <jani.nikula@linux.intel.com> wrote:
> On Sat, 12 Sep 2026, Theo Andersen Carton <andersen.theo@gmail.com> wrote:
>> On dual-GPU Retina MacBooks the internal panel is muxed to the discrete
>> GPU at boot, so Apple's firmware never lights up eDP on the Intel side.
>> As a result it never sets DDI_A_4_LANES, and intel_ddi_max_lanes() reads
>> back a source maximum of two lanes for port A.
>>
>> intel_dp_max_common_lane_count() then takes min3(source_max = 2,
>> sink_max = 4, ...) = 2, giving 2 x 2.7 Gbps x 8/10 = 4.32 Gbps of link
>> bandwidth. The panel's native 2880x1800@60 8bpc mode needs 8.1 Gbps, so
>> every mode is rejected with MODE_CLOCK_HIGH and the connector comes up
>> with no usable modes at all -- the panel stays dark whenever i915 is
>> made to drive it, which looks like a hardware limitation but is not.
>>
>> The lanes are physically there. Reading the panel's DPCD from the AMD
>> side, where amdgpu drives it correctly, reports MAX_LANE_COUNT = 0x84,
>> i.e. 4 lanes, and amdgpu's own link_settings shows it running the panel
>> at 4 lanes / HBR. macOS likewise drives this panel from the iGPU at its
>> native resolution, so all four lanes are routed through the gmux to
>> DDI A. Only the register bit is unset.
>>
>> intel_ddi_a_force_4_lanes() already exists for exactly this situation --
>> its neighbouring comment notes that "Some BIOS might fail to set this
>> bit on port A if eDP wasn't lit up at boot" -- but it only covers
>> Broxton and Geminilake. Extend it with a DMI quirk so affected Macs get
>> the correct lane count too.
>>
>> The DMI match is deliberately narrow. Other dual-GPU models in the same
>> family are very likely affected identically, but they are untested, so
>> widen the match only as reports come in.
>>
>> Tested on a MacBookPro11,5 (Broadwell, Iris Pro + Radeon R9 M370X):
>> with the quirk, DDI A comes up as 4 lanes, link training passes at
>> link rate 270000 / lane count 4, and i915 drives the internal panel at
>> its native 2880x1800.
>>
>> Signed-off-by: Theo Andersen Carton <andersen.theo@gmail.com>
>
> I'm guessing this is v2 of [1], but I shouldn't have to guess.
>
> For future reference, please indicate patch revision, and log the
> differences between the revisions. See Documentation/process, other
> messages on the mailing list and git log for plenty of examples.
>
> Is there a bug report about this? Would be nice to see the logs in the
> failing case. See [2].
i915_vbt from debugfs would also be interesting.
The patch itself looks sane.
BR,
Jani.
>
>
> BR,
> Jani.
>
>
> [1] https://lore.kernel.org/r/CANFnrspHiK7ii28XPdLkOMyhSZcJ9xz6CT-kNX+oiiF+8N-2Fg@mail.gmail.com
> [2] https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html
>
>
>> ---
>> drivers/gpu/drm/i915/display/intel_ddi.c | 7 +++++
>> drivers/gpu/drm/i915/display/intel_quirks.c | 34 +++++++++++++++++++++
>> drivers/gpu/drm/i915/display/intel_quirks.h | 1 +
>> 3 files changed, 42 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
>> index 02a53c9848e1..f746287830b3 100644
>> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
>> @@ -4976,6 +4976,13 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
>> if (display->platform.geminilake || display->platform.broxton)
>> return true;
>>
>> + /*
>> + * Machines whose firmware leaves eDP dark on the Intel side never set
>> + * the bit, so trust the quirk rather than the register.
>> + */
>> + if (intel_has_quirk(display, QUIRK_DDI_A_FORCE_4_LANES))
>> + return true;
>> +
>> return false;
>> }
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
>> index 33245f44c0d5..feb28956a013 100644
>> --- a/drivers/gpu/drm/i915/display/intel_quirks.c
>> +++ b/drivers/gpu/drm/i915/display/intel_quirks.c
>> @@ -100,6 +100,20 @@ static void quirk_disable_psr2(struct intel_display *display)
>> drm_info(display->drm, "PSR2 support not currently available for this setup, applying disable PSR2 quirk\n");
>> }
>>
>> +/*
>> + * Dual-GPU Macs boot with the internal panel muxed to the discrete GPU, so
>> + * the firmware never lights up eDP on the Intel side and consequently never
>> + * sets DDI_A_4_LANES -- even though all four lanes are wired through the gmux
>> + * to DDI A. Without the bit, port A is capped at two lanes, which is not
>> + * enough bandwidth for the panel's native mode, leaving the connector with no
>> + * usable modes at all.
>> + */
>> +static void quirk_ddi_a_force_4_lanes(struct intel_display *display)
>> +{
>> + intel_set_quirk(display, QUIRK_DDI_A_FORCE_4_LANES);
>> + drm_info(display->drm, "Applying DDI A force 4 lanes quirk\n");
>> +}
>> +
>> struct intel_quirk {
>> int device;
>> int subsystem_vendor;
>> @@ -142,6 +156,13 @@ static int intel_dmi_no_pps_backlight(const struct dmi_system_id *id)
>> return 1;
>> }
>>
>> +static int intel_dmi_ddi_a_force_4_lanes(const struct dmi_system_id *id)
>> +{
>> + DRM_INFO("DDI A is 4 lanes despite firmware on %s\n", id->ident);
>> +
>> + return 1;
>> +}
>> +
>> static const struct intel_dmi_quirk intel_dmi_quirks[] = {
>> {
>> .dmi_id_list = &(const struct dmi_system_id[]) {
>> @@ -188,6 +209,19 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = {
>> },
>> .hook = quirk_no_pps_backlight_power_hook,
>> },
>> + {
>> + .dmi_id_list = &(const struct dmi_system_id[]) {
>> + {
>> + .callback = intel_dmi_ddi_a_force_4_lanes,
>> + .ident = "Apple MacBookPro11,5",
>> + .matches = {DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
>> + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MacBookPro11,5"),
>> + },
>> + },
>> + { }
>> + },
>> + .hook = quirk_ddi_a_force_4_lanes,
>> + },
>> };
>>
>> static struct intel_quirk intel_quirks[] = {
>> diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h
>> index 970a4fe52faf..d2b8e9183c62 100644
>> --- a/drivers/gpu/drm/i915/display/intel_quirks.h
>> +++ b/drivers/gpu/drm/i915/display/intel_quirks.h
>> @@ -23,6 +23,7 @@ enum intel_quirk_id {
>> QUIRK_EDP_LIMIT_RATE_HBR2,
>> QUIRK_DISABLE_EDP_PANEL_REPLAY,
>> QUIRK_DISABLE_PSR2,
>> + QUIRK_DDI_A_FORCE_4_LANES,
>> };
>>
>> void intel_init_quirks(struct intel_display *display);
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] drm/i915/ddi: add DDI A force 4 lanes quirk for Apple MacBookPro11,5
2026-09-14 10:01 ` Jani Nikula
2026-09-15 9:21 ` Jani Nikula
@ 2026-09-17 18:50 ` Theo Andersen Carton
1 sibling, 0 replies; 5+ messages in thread
From: Theo Andersen Carton @ 2026-09-17 18:50 UTC (permalink / raw)
To: Jani Nikula
Cc: rodrigo.vivi, joonas.lahtinen, tursulin, airlied, simona,
intel-gfx, intel-xe, dri-devel, linux-kernel
> I'm guessing this is v2 of [1], but I shouldn't have to guess.
You're right, it is effectively v2 of [1] -- same patch, no functional
change. Sorry for not labelling it.
[1] was pasted into a mail client by hand, which hard-wrapped the
"diff --git" lines and turned the leading tabs into spaces. It did reach
the lists, but not as an applicable patch, so I resent it with
git send-email and didn't think of it as a revision. I'll use proper vN
and changelogs from here on.
> Is there a bug report about this? Would be nice to see the logs in the
> failing case. See [2].
There wasn't one -- I went straight to the list. Filed now:
https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/17087
It has the full failing-case log with drm debug enabled, on an unpatched
i915 with the panel muxed to the iGPU. AUX and EDID are fine, and then the
panel's only mode is pruned:
[drm:intel_dp_print_rates] sink rates: 162000, 270000
[drm:update_display_info] [CONNECTOR:93:eDP-1] Assigning EDID-1.4
digital sink color depth as 8 bpc.
[drm:drm_mode_prune_invalid] Rejected mode: "2880x1800": 60 337750
2880 2928 2960 3040 1800 1803 1809 1852 0x48 0x9 (CLOCK_HIGH)
because intel_ddi_max_lanes() reports a source maximum of 2 for port A.
The matching log with the quirk applied is attached too, where the same
link trains at lane count 4.
> i915_vbt from debugfs would also be interesting.
Attached to the bug as i915_vbt.bin, 6144 bytes -- a $VBT HASWELL block,
BIOS build 1215 dated 12/13/2012, on Apple firmware 427.140.8.0.0. Say the
word if you'd rather have a specific block dumped inline.
> The patch itself looks sane.
Thanks. One thing I got wrong in the commit message, which v3 fixes: I
wrote Broadwell, but the machine is Haswell Crystal Well -- i7-4980HQ,
8086:0d26, $VBT HASWELL, and i915 logs "Found haswell". Apple's ACPI DMAR
OEM string says BDW, which is what misled me. No code change; the quirk
matches on DMI model either way.
I'll send it as v3 rather than v2, to match the numbering you used
above -- neither earlier posting was labelled, and renumbering them now
would just recreate the ambiguity. It has that fix, a Closes: tag for the
bug, and a changelog spelling out what v1 and v2 were.
BR,
Theo
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] drm/i915/ddi: add DDI A force 4 lanes quirk for Apple MacBookPro11,5
@ 2026-09-12 8:59 Theo Andersen Carton
0 siblings, 0 replies; 5+ messages in thread
From: Theo Andersen Carton @ 2026-09-12 8:59 UTC (permalink / raw)
To: jani.nikula, rodrigo.vivi
Cc: joonas.lahtinen, tursulin, airlied, simona, intel-gfx, intel-xe,
dri-devel, linux-kernel
On dual-GPU Retina MacBooks (mid 2015 fx) the internal panel is muxed
to the discrete
GPU at boot, so Apple's firmware never lights up eDP on the Intel side.
As a result it never sets DDI_A_4_LANES, and intel_ddi_max_lanes() reads
back a source maximum of two lanes for port A.
intel_dp_max_common_lane_count() then takes min3(source_max = 2,
sink_max = 4, ...) = 2, giving 2 x 2.7 Gbps x 8/10 = 4.32 Gbps of link
bandwidth. The panel's native 2880x1800@60 8bpc mode needs 8.1 Gbps, so
every mode is rejected with MODE_CLOCK_HIGH and the connector comes up
with no usable modes at all -- the panel stays dark whenever i915 is
made to drive it, which looks like a hardware limitation but is not.
The lanes are physically there. Reading the panel's DPCD from the AMD
side, where amdgpu drives it correctly, reports MAX_LANE_COUNT = 0x84,
i.e. 4 lanes, and amdgpu's own link_settings shows it running the panel
at 4 lanes / HBR. macOS likewise drives this panel from the iGPU at its
native resolution, so all four lanes are routed through the gmux to
DDI A. Only the register bit is unset.
intel_ddi_a_force_4_lanes() already exists for exactly this situation --
its neighbouring comment notes that "Some BIOS might fail to set this
bit on port A if eDP wasn't lit up at boot" -- but it only covers
Broxton and Geminilake. Extend it with a DMI quirk so affected Macs get
the correct lane count too.
The DMI match is deliberately narrow. Other dual-GPU models in the same
family are very likely affected identically, but they are untested, so
widen the match only as reports come in.
Tested on a MacBookPro11,5 (Broadwell, Iris Pro + Radeon R9 M370X):
with the quirk, DDI A comes up as 4 lanes, link training passes at
link rate 270000 / lane count 4, and i915 drives the internal panel at
its native 2880x1800.
Signed-off-by: Theo Andersen Carton <andersen.theo@gmail.com>
---
drivers/gpu/drm/i915/display/intel_ddi.c | 7 +++++
drivers/gpu/drm/i915/display/intel_quirks.c | 34 +++++++++++++++++++++
drivers/gpu/drm/i915/display/intel_quirks.h | 1 +
3 files changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 02a53c9848e1..f746287830b3 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4976,6 +4976,13 @@ static bool intel_ddi_a_force_4_lanes(struct
intel_digital_port *dig_port)
if (display->platform.geminilake || display->platform.broxton)
return true;
+ /*
+ * Machines whose firmware leaves eDP dark on the Intel side never set
+ * the bit, so trust the quirk rather than the register.
+ */
+ if (intel_has_quirk(display, QUIRK_DDI_A_FORCE_4_LANES))
+ return true;
+
return false;
}
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c
b/drivers/gpu/drm/i915/display/intel_quirks.c
index 33245f44c0d5..feb28956a013 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -100,6 +100,20 @@ static void quirk_disable_psr2(struct
intel_display *display)
drm_info(display->drm, "PSR2 support not currently available for
this setup, applying disable PSR2 quirk\n");
}
+/*
+ * Dual-GPU Macs boot with the internal panel muxed to the discrete GPU, so
+ * the firmware never lights up eDP on the Intel side and consequently never
+ * sets DDI_A_4_LANES -- even though all four lanes are wired through the gmux
+ * to DDI A. Without the bit, port A is capped at two lanes, which is not
+ * enough bandwidth for the panel's native mode, leaving the connector with no
+ * usable modes at all.
+ */
+static void quirk_ddi_a_force_4_lanes(struct intel_display *display)
+{
+ intel_set_quirk(display, QUIRK_DDI_A_FORCE_4_LANES);
+ drm_info(display->drm, "Applying DDI A force 4 lanes quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -142,6 +156,13 @@ static int intel_dmi_no_pps_backlight(const
struct dmi_system_id *id)
return 1;
}
+static int intel_dmi_ddi_a_force_4_lanes(const struct dmi_system_id *id)
+{
+ DRM_INFO("DDI A is 4 lanes despite firmware on %s\n", id->ident);
+
+ return 1;
+}
+
static const struct intel_dmi_quirk intel_dmi_quirks[] = {
{
.dmi_id_list = &(const struct dmi_system_id[]) {
@@ -188,6 +209,19 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = {
},
.hook = quirk_no_pps_backlight_power_hook,
},
+ {
+ .dmi_id_list = &(const struct dmi_system_id[]) {
+ {
+ .callback = intel_dmi_ddi_a_force_4_lanes,
+ .ident = "Apple MacBookPro11,5",
+ .matches = {DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MacBookPro11,5"),
+ },
+ },
+ { }
+ },
+ .hook = quirk_ddi_a_force_4_lanes,
+ },
};
static struct intel_quirk intel_quirks[] = {
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h
b/drivers/gpu/drm/i915/display/intel_quirks.h
index 970a4fe52faf..d2b8e9183c62 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.h
+++ b/drivers/gpu/drm/i915/display/intel_quirks.h
@@ -23,6 +23,7 @@ enum intel_quirk_id {
QUIRK_EDP_LIMIT_RATE_HBR2,
QUIRK_DISABLE_EDP_PANEL_REPLAY,
QUIRK_DISABLE_PSR2,
+ QUIRK_DDI_A_FORCE_4_LANES,
};
void intel_init_quirks(struct intel_display *display);
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-17 18:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-12 9:18 [PATCH] drm/i915/ddi: add DDI A force 4 lanes quirk for Apple MacBookPro11,5 Theo Andersen Carton
2026-09-14 10:01 ` Jani Nikula
2026-09-15 9:21 ` Jani Nikula
2026-09-17 18:50 ` Theo Andersen Carton
-- strict thread matches above, loose matches on Subject: below --
2026-09-12 8:59 Theo Andersen Carton
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®