display: Avoid placing FBs at IOVA 0

Also search harder for a matching dcp/disp iova, in case it matters.

Fixes: #391
Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2024-05-17 10:17:40 +09:00
parent 1841d88dcd
commit dfffdf6609

View file

@ -191,7 +191,7 @@ static uintptr_t display_map_fb(uintptr_t iova, u64 paddr, u64 size)
u64 iova_dcp = 0; u64 iova_dcp = 0;
// start scanning for free iova space on vm-base // start scanning for free iova space on vm-base
iova_dcp = dart_find_iova(dcp->dart_dcp, dart_vm_base(dcp->dart_dcp), size); iova_dcp = dart_find_iova(dcp->dart_dcp, dart_vm_base(dcp->dart_dcp) + SZ_16K, size);
if (DART_IS_ERR(iova_dcp)) { if (DART_IS_ERR(iova_dcp)) {
printf("display: failed to find IOVA for fb of %06zx bytes (dcp)\n", size); printf("display: failed to find IOVA for fb of %06zx bytes (dcp)\n", size);
return iova_dcp; return iova_dcp;
@ -204,6 +204,15 @@ static uintptr_t display_map_fb(uintptr_t iova, u64 paddr, u64 size)
return iova_disp0; return iova_disp0;
} }
// try to find the same IOVA on DCP again
if (iova_disp0 != iova_dcp) {
iova_dcp = dart_find_iova(dcp->dart_dcp, iova_disp0, size);
if (DART_IS_ERR(iova_dcp)) {
printf("display: failed to find IOVA for fb of %06zx bytes (dcp)\n", size);
return iova_dcp;
}
}
// assume this results in the same IOVA, not sure if this is required but matches what iboot // assume this results in the same IOVA, not sure if this is required but matches what iboot
// does on other models. // does on other models.
if (iova_disp0 != iova_dcp) { if (iova_disp0 != iova_dcp) {
@ -276,7 +285,7 @@ int display_start_dcp(void)
// Find the framebuffer DVA // Find the framebuffer DVA
fb_dva = dart_search(dcp->dart_disp, (void *)cur_boot_args.video.base); fb_dva = dart_search(dcp->dart_disp, (void *)cur_boot_args.video.base);
// framebuffer is not mapped on the M1 Ultra Mac Studio // framebuffer is not mapped on the M1 Ultra Mac Studio
if (DART_IS_ERR(fb_dva)) if (DART_IS_ERR(fb_dva) || !fb_dva)
fb_dva = display_map_fb(0, pa, size); fb_dva = display_map_fb(0, pa, size);
if (DART_IS_ERR(fb_dva)) { if (DART_IS_ERR(fb_dva)) {
printf("display: failed to find display DVA\n"); printf("display: failed to find display DVA\n");