mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-10 09:44:13 +00:00
display: Map the framebuffer if it is not mapped
iboot on Mac Studio (M1 Ultra) does not map the framebuffer("/vram") for dcp and disp0. Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
parent
0104abbea7
commit
1b5dee2496
1 changed files with 82 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include "display.h"
|
||||
#include "adt.h"
|
||||
#include "assert.h"
|
||||
#include "dcp.h"
|
||||
#include "dcp_iboot.h"
|
||||
|
@ -68,6 +69,84 @@ static void display_choose_color_mode(dcp_color_mode_t *modes, int cnt, dcp_colo
|
|||
best->colorimetry, best->eotf, best->encoding, best->bpp);
|
||||
}
|
||||
|
||||
static int display_map_fb(uintptr_t iova, void *paddr, size_t size)
|
||||
{
|
||||
int ret = dart_map(dcp->dart_disp, iova, paddr, size);
|
||||
if (ret < 0) {
|
||||
printf("display: failed to map fb to dart-disp0\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dart_map(dcp->dart_dcp, iova, paddr, size);
|
||||
if (ret < 0) {
|
||||
printf("display: failed to map fb to dart-dcp\n");
|
||||
dart_unmap(dcp->dart_disp, iova, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uintptr_t display_map_vram(void)
|
||||
{
|
||||
int ret = 0;
|
||||
u64 paddr, size;
|
||||
int adt_path[4];
|
||||
int node = adt_path_offset_trace(adt, "/vram", adt_path);
|
||||
|
||||
if (node < 0) {
|
||||
printf("display: '/vram' not found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pp = 0;
|
||||
while (adt_path[pp])
|
||||
pp++;
|
||||
adt_path[pp + 1] = 0;
|
||||
|
||||
ret = adt_get_reg(adt, adt_path, "reg", 0, &paddr, &size);
|
||||
if (ret < 0) {
|
||||
printf("display: failed to read /vram/reg\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (paddr != cur_boot_args.video.base) {
|
||||
printf("display: vram does not match boot_args.video.base\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
s64 iova_disp0 = 0;
|
||||
s64 iova_dcp = 0;
|
||||
|
||||
iova_dcp = dart_find_iova(dcp->dart_dcp, iova_dcp, size);
|
||||
if (iova_dcp < 0) {
|
||||
printf("display: failed to find IOVA for fb of %06zx bytes (dcp)\n", size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// try to map the fb to the same IOVA on disp0
|
||||
iova_disp0 = dart_find_iova(dcp->dart_dcp, iova_dcp, size);
|
||||
if (iova_disp0 < 0) {
|
||||
printf("display: failed to find IOVA for fb of %06zx bytes (disp0)\n", size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// assume this results in the same IOVA, not sure if this is required but matches what iboot
|
||||
// does on other models.
|
||||
if (iova_disp0 != iova_dcp) {
|
||||
printf("display: IOVA mismatch for fb between dcp (%08lx) and disp0 (%08lx)\n",
|
||||
(u64)iova_dcp, (u64)iova_disp0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t iova = iova_dcp;
|
||||
ret = display_map_fb(iova, (void *)paddr, size);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
return iova;
|
||||
}
|
||||
|
||||
static int display_start_dcp(void)
|
||||
{
|
||||
if (iboot)
|
||||
|
@ -81,6 +160,9 @@ static int display_start_dcp(void)
|
|||
|
||||
// Find the framebuffer DVA
|
||||
fb_dva = dart_search(dcp->dart_disp, (void *)cur_boot_args.video.base);
|
||||
// framebuffer is not mapped on the M1 Ultra Mac Studio
|
||||
if (!fb_dva)
|
||||
fb_dva = display_map_vram();
|
||||
if (!fb_dva) {
|
||||
printf("display: failed to find display DVA\n");
|
||||
dcp_shutdown(dcp);
|
||||
|
|
Loading…
Reference in a new issue