m1n1: Mac mini 12+ DCP initialization fails with some monitors
I have two monitors: An iiyama ProLite E2473HDS (1080p) and a Philips 279P1 (4K). They do not work with m1n1 from a 12.1 Mac mini (connected over HDMI). When m1n1 starts, the 1080p monitor wakes up from sleep (power LED turns blue), and a few seconds later displays “No signal” and goes back to sleep. m1n1 logs (including the DCP syslog messages) indicate nothing out of the ordinary; the display is correctly recognized at the correct resolution/refresh rate. In fact, the log is identical to the one produced when the mini is connected to a 1080p capture card. The 4K monitor does not seem to even wake up.
I’ve messed with m1n1’s display init code (mostly with the 1080p monitor since it’s not my primary display) and found out the following:
- The monitor wakes up from sleep when
dcp_ib_swap_begin
is called. - Calling
dcp_ib_set_mode
afterdcp_ib_swap_begin
does not change anything at that point. - Calling
dcp_ib_get_hpd
in a loop afterdcp_ib_swap_begin
shows thatconnected
goes back to0
after 1-2 seconds, then goes back to1
after ~400ms. - Calling
dcp_ib_set_mode
afterconnected
is back to1
, then completing the swap (dcp_ib_swap_set_layer
/dcp_ib_swap_end
) makes the monitor work correctly; it will actually show m1n1 logo/console. It still takes a couple of seconds after completing the swap for the image to actually appear. - When rebooting, the situation is messier; after the call to
dcp_ib_swap_begin
, the monitor will still disconnect/reconnect, but after 5-6 seconds, not 1-2 seconds. It is, however, not necessary to wait for the disconnection: callingdcp_ib_set_mode
a couple of seconds afterdcp_ib_swap_begin
seems to prevent the disconnection, and the monitor works afterwards.
I managed to make both my monitors work by making these changes: wait up to 5 seconds for the display to disconnect; if it does, wait for it to reconnect and call dcp_ib_set_mode
; if it doesn’t, call dcp_ib_set_mode
anyway.
This has the obvious issue of slowing down startup by at least 5 seconds on all monitors; it also seems very fragile and timing-dependent. I’m guessing there must be a better solution, since the monitors work (most of the time) in m1n1 with 11.6 iBoot, and it doesn’t seem to wait 5 seconds for the monitor to disconnect/reconnect… (I’ve tried to measure the time iBoot takes before starting m1n1, and it seems 11.6 is only slower than 12.1 by 900ms)
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 3
- Comments: 45 (21 by maintainers)
Commits related to this issue
- display: Add wait option to handle monitor disconnection Some monitors disconnect when getting out of sleep mode; they rely on the OS hotplug support to work properly. To make them work properly in m... — committed to VinDuv/m1n1 by VinDuv 2 years ago
- display: Add wait option to handle monitor disconnection Some monitors disconnect when getting out of sleep mode; they rely on the OS hotplug support to work properly. Since stage1 m1n1 initializes ... — committed to VinDuv/m1n1 by VinDuv 2 years ago
- display: Add wait option to handle monitor disconnection Some monitors disconnect when getting out of sleep mode; they rely on the OS hotplug support to work properly. Since stage1 m1n1 initializes ... — committed to VinDuv/m1n1 by VinDuv 2 years ago
coughs it works for me
None of these displays “work” under macOS because Apple disabled iBoot display output entirely since 12.0 😉
There is no display output until the OS driver loads, which means no verbose boot, no iBoot messages, no Apple logo and no progress bar until the kernel is half booted, etc. In fact, you get those features back if you chainload macOS under m1n1 and the display was initialized properly.
Once Linux has a real display driver it will work like macOS. The problem we’re trying to solve in this bug is bootloader display output, which is handicapped by the iBoot-mode interface that Apple provides for it. That’s why we’re having so much trouble with modes and timeouts and such.
@patlux Don’t reinstall! This is normal behavior. The
boot.bin
file I provided doesn’t include the U-Boot payload, so once m1n1 is started it waits for a payload to be sent over serial (from another computer). I’ll try to build a full version later; in the meantime, you can restore your originalboot.bin
from macOS.Okay, for the folks with issues: please make a backup of
/boot/efi/m1n1/boot.bin
(in the same folder) and replace it with this one: https://mrcn.st/t/boot_display-test.bin (make sure to rename it to boot.bin).Let me know if that improves things by default, for folks with no display output at all. Then, if you want to set the mode:
echo display=1920x1080 >> /boot/efi/m1n1/boot.bin
You can also use 1920x1080@60 to set the rate, or even 1920x1080@59.94 for fractional rates (but the parser is really dumb, always use two decimals).
You can also do:
echo display=auto >> /boot/efi/m1n1/boot.bin
And that will re-invoke the mode autoconfig logic (@pat42smith this should help with your 4K issue).
Obviously only do the
echo
once. For each time m1n1 finds thedisplay=
line it’ll set the mode, so if you append it multiple times you’ll wind up with the mode changing repeatedly.By the way, the framebuffer size is limited and currently unchecked, so 4K modes may not work / may make everything crash. You’ve been warned. You can restore the boot.bin from macOS if this breaks things, as long as you backed up boot.bin inside /boot/efi, since macOS can access that FAT32 partition.
@patlux can you try boot_display_wait.bin? It should wait for the monitor to come up and then boot Linux. @tpwrules I followed your suggestion of adding a way to control the wait delay; you can test it by downloading either
m1n1.bin
orboot.bin
from https://vincent.duvert.net/dropbox/ and append adisplay=...
line to them. The format is:display=auto
display=1280x1024
display=wait
display=wait,auto
display=wait:6
display=wait:6,auto
display=wait,1280x1024
display=wait:6,1280x1024
@Skirmisher if you’re interested, you can download m1n1_1280_modes.bin that will dump all the timing modes that the DCP thinks are supported by the monitor (after setting it to 1280x1024). On my monitor it detects some resolutions that are probably not supported (3840x2160 on a 1080p monitor…), and I guess it’s the same in your case…