Skip to content

Commit 1b5dee2

Browse files
jannaumarcan
authored andcommitted
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 <[email protected]>
1 parent 0104abb commit 1b5dee2

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

src/display.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* SPDX-License-Identifier: MIT */
22

33
#include "display.h"
4+
#include "adt.h"
45
#include "assert.h"
56
#include "dcp.h"
67
#include "dcp_iboot.h"
@@ -68,6 +69,84 @@ static void display_choose_color_mode(dcp_color_mode_t *modes, int cnt, dcp_colo
6869
best->colorimetry, best->eotf, best->encoding, best->bpp);
6970
}
7071

72+
static int display_map_fb(uintptr_t iova, void *paddr, size_t size)
73+
{
74+
int ret = dart_map(dcp->dart_disp, iova, paddr, size);
75+
if (ret < 0) {
76+
printf("display: failed to map fb to dart-disp0\n");
77+
return -1;
78+
}
79+
80+
ret = dart_map(dcp->dart_dcp, iova, paddr, size);
81+
if (ret < 0) {
82+
printf("display: failed to map fb to dart-dcp\n");
83+
dart_unmap(dcp->dart_disp, iova, size);
84+
return -1;
85+
}
86+
87+
return 0;
88+
}
89+
90+
static uintptr_t display_map_vram(void)
91+
{
92+
int ret = 0;
93+
u64 paddr, size;
94+
int adt_path[4];
95+
int node = adt_path_offset_trace(adt, "/vram", adt_path);
96+
97+
if (node < 0) {
98+
printf("display: '/vram' not found\n");
99+
return 0;
100+
}
101+
102+
int pp = 0;
103+
while (adt_path[pp])
104+
pp++;
105+
adt_path[pp + 1] = 0;
106+
107+
ret = adt_get_reg(adt, adt_path, "reg", 0, &paddr, &size);
108+
if (ret < 0) {
109+
printf("display: failed to read /vram/reg\n");
110+
return 0;
111+
}
112+
113+
if (paddr != cur_boot_args.video.base) {
114+
printf("display: vram does not match boot_args.video.base\n");
115+
return 0;
116+
}
117+
118+
s64 iova_disp0 = 0;
119+
s64 iova_dcp = 0;
120+
121+
iova_dcp = dart_find_iova(dcp->dart_dcp, iova_dcp, size);
122+
if (iova_dcp < 0) {
123+
printf("display: failed to find IOVA for fb of %06zx bytes (dcp)\n", size);
124+
return 0;
125+
}
126+
127+
// try to map the fb to the same IOVA on disp0
128+
iova_disp0 = dart_find_iova(dcp->dart_dcp, iova_dcp, size);
129+
if (iova_disp0 < 0) {
130+
printf("display: failed to find IOVA for fb of %06zx bytes (disp0)\n", size);
131+
return 0;
132+
}
133+
134+
// assume this results in the same IOVA, not sure if this is required but matches what iboot
135+
// does on other models.
136+
if (iova_disp0 != iova_dcp) {
137+
printf("display: IOVA mismatch for fb between dcp (%08lx) and disp0 (%08lx)\n",
138+
(u64)iova_dcp, (u64)iova_disp0);
139+
return 0;
140+
}
141+
142+
uintptr_t iova = iova_dcp;
143+
ret = display_map_fb(iova, (void *)paddr, size);
144+
if (ret < 0)
145+
return 0;
146+
147+
return iova;
148+
}
149+
71150
static int display_start_dcp(void)
72151
{
73152
if (iboot)
@@ -81,6 +160,9 @@ static int display_start_dcp(void)
81160

82161
// Find the framebuffer DVA
83162
fb_dva = dart_search(dcp->dart_disp, (void *)cur_boot_args.video.base);
163+
// framebuffer is not mapped on the M1 Ultra Mac Studio
164+
if (!fb_dva)
165+
fb_dva = display_map_vram();
84166
if (!fb_dva) {
85167
printf("display: failed to find display DVA\n");
86168
dcp_shutdown(dcp);

0 commit comments

Comments
 (0)