Skip to content

Commit 1b5741b

Browse files
committed
display: Work around macOS Sonoma firmware bugs
It appears that when macOS is set to non-ProMotion mode, DCP firmware <14.0 booted from DCP firmware 14.0+ needs a delay before modesetting to complete the modeset properly. The cases here are: - Older m1n1 stage1 will, as far as it's concerned, initialize the display properly, but it won't work. It also misses the retina flag, since this codepath was intended for external displays. Use the missing retina flag as a signal to trigger reconfig. - If installed as stage1, we reconfigure the display as usual, now with the extra delay. We also set the Retina flag now. The persistence mechanism for the ProMotion flag is unknown. It doesn't seem to be nvram. It also doesn't matter if we successfully modeset to 120Hz mode and then reboot, it breaks again, so it's not about the "current" mode sticking. Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent 33a7e35 commit 1b5741b

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

src/display.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ int display_configure(const char *config)
378378
return ret;
379379
}
380380

381+
// Sonoma bug workaround
382+
mdelay(100);
383+
381384
// Find best modes
382385
dcp_timing_mode_t *tmodes, tbest;
383386
if ((ret = dcp_ib_get_timing_modes(iboot, &tmodes)) < 0) {
@@ -475,6 +478,7 @@ int display_configure(const char *config)
475478

476479
printf("display: swapped! (swap_id=%d)\n", ret);
477480

481+
bool reinit = false;
478482
if (fb_pa != cur_boot_args.video.base || cur_boot_args.video.stride != stride ||
479483
cur_boot_args.video.width != tbest.width || cur_boot_args.video.height != tbest.height ||
480484
cur_boot_args.video.depth != 30) {
@@ -483,9 +487,17 @@ int display_configure(const char *config)
483487
cur_boot_args.video.width = tbest.width;
484488
cur_boot_args.video.height = tbest.height;
485489
cur_boot_args.video.depth = 30 | (opts.retina ? FB_DEPTH_FLAG_RETINA : 0);
486-
fb_reinit();
490+
reinit = true;
491+
}
492+
493+
if (!display_is_external && !(cur_boot_args.video.depth & FB_DEPTH_FLAG_RETINA)) {
494+
cur_boot_args.video.depth |= FB_DEPTH_FLAG_RETINA;
495+
reinit = true;
487496
}
488497

498+
if (reinit)
499+
fb_reinit();
500+
489501
/* Update for python / subsequent stages */
490502
memcpy((void *)boot_args_addr, &cur_boot_args, sizeof(cur_boot_args));
491503

@@ -528,6 +540,9 @@ int display_init(void)
528540
} else if (display_is_external) {
529541
printf("display: External display found, reconfiguring\n");
530542
return display_configure(NULL);
543+
} else if (!(cur_boot_args.video.depth & FB_DEPTH_FLAG_RETINA)) {
544+
printf("display: Internal display with non-retina flag, assuming Sonoma bug and reconfiguring\n");
545+
return display_configure(NULL);
531546
} else {
532547
printf("display: Display is already initialized (%ldx%ld)\n", cur_boot_args.video.width,
533548
cur_boot_args.video.height);

0 commit comments

Comments
 (0)