Skip to content

Commit 5006e08

Browse files
jannaumarcan
authored andcommitted
display: Use dcpext0 for HDMI out on t8112/t6020/t6021
dcpext0 behaves like dcp on M1* devices and can sleep after display init. This has the advantage of not breaking macOS when starting with an initialized display. dcpext* are according to Apple's tech specs slightly more powerful than dcp. They are advertised as 6K at 60Hz while dcp seems to be limited to 5K at 60Hz. Signed-off-by: Janne Grunau <[email protected]>
1 parent 5245fc6 commit 5006e08

5 files changed

Lines changed: 41 additions & 29 deletions

File tree

src/dcp.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,7 @@ dcp_dev_t *dcp_init(const display_config_t *cfg)
204204

205205
int dcp_shutdown(dcp_dev_t *dcp, bool sleep)
206206
{
207-
if (dcp->dptx_ep) {
208-
if (sleep) {
209-
printf("DCP: dcp_shutdown(sleep=true) is broken with dptx-port, quiesce instead\n");
210-
sleep = false;
211-
}
212-
}
207+
/* dcp/dcp0 on desktop M2 and M2 Pro/Max devices do not wake from sleep */
213208
dcp_system_shutdown(dcp->system_ep);
214209
dcp_dptx_shutdown(dcp->dptx_ep);
215210
dcp_dpav_shutdown(dcp->dpav_ep);

src/dcp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef struct {
1919
const char dptx_phy[24];
2020
const char dp2hdmi_gpio[24];
2121
const char pmgr_dev[24];
22+
const char dcp_alias[8];
2223
u32 dcp_index;
2324
u8 num_dptxports;
2425
u8 die;

src/display.c

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,41 +37,49 @@ static const display_config_t display_config_m1 = {
3737
.dcp_dart = "/arm-io/dart-dcp",
3838
.disp_dart = "/arm-io/dart-disp0",
3939
.pmgr_dev = "DISP0_CPU0",
40+
.dcp_alias = "dcp",
4041
};
4142

43+
#define USE_DCPEXT 1
44+
4245
static const display_config_t display_config_m2 = {
46+
#if USE_DCPEXT
47+
.dcp = "/arm-io/dcpext",
48+
.dcp_dart = "/arm-io/dart-dcpext",
49+
.disp_dart = "/arm-io/dart-dispext0",
50+
.pmgr_dev = "DISPEXT_CPU0",
51+
.dcp_alias = "dcpext",
52+
.dcp_index = 1,
53+
#else
4354
.dcp = "/arm-io/dcp",
4455
.dcp_dart = "/arm-io/dart-dcp",
4556
.disp_dart = "/arm-io/dart-disp0",
4657
.dp2hdmi_gpio = "/arm-io/dp2hdmi-gpio",
4758
.dptx_phy = "/arm-io/dptx-phy",
4859
.pmgr_dev = "DISP0_CPU0",
60+
.dcp_alias = "dcp",
4961
.dcp_index = 0,
62+
#endif
63+
.dp2hdmi_gpio = "/arm-io/dp2hdmi-gpio",
64+
.dptx_phy = "/arm-io/dptx-phy",
5065
.num_dptxports = 2,
5166
};
5267

53-
#define T6020_T6021_USE_DCPEXT 255
54-
5568
static const display_config_t display_config_m2_pro_max = {
56-
#if T6020_T6021_USE_DCPEXT == 0
69+
#if USE_DCPEXT
5770
.dcp = "/arm-io/dcpext0",
5871
.dcp_dart = "/arm-io/dart-dcpext0",
5972
.disp_dart = "/arm-io/dart-dispext0",
6073
.pmgr_dev = "DISPEXT0_CPU0",
74+
.dcp_alias = "dcpext0",
6175
.dcp_index = 1,
6276
.num_dptxports = 2,
63-
#elif T6020_T6021_USE_DCPEXT == 1
64-
.dcp = "/arm-io/dcpext1",
65-
.dcp_dart = "/arm-io/dart-dcpext1",
66-
.disp_dart = "/arm-io/dart-dispext1",
67-
.pmgr_dev = "DISPEXT1_CPU0",
68-
.dcp_index = 2,
69-
.num_dptxports = 2,
7077
#else
7178
.dcp = "/arm-io/dcp0",
7279
.dcp_dart = "/arm-io/dart-dcp0",
7380
.disp_dart = "/arm-io/dart-disp0",
7481
.pmgr_dev = "DISP0_CPU0",
82+
.dcp_alias = "dcp",
7583
.dcp_index = 0,
7684
.num_dptxports = 1,
7785
#endif
@@ -86,6 +94,7 @@ static const display_config_t display_config_m2_ultra = {
8694
.dp2hdmi_gpio = "/arm-io/dp2hdmi-gpio1",
8795
.dptx_phy = "/arm-io/lpdptx-phy1",
8896
.pmgr_dev = "DISPEXT4_CPU0",
97+
.dcp_alias = "dcpext4",
8998
.dcp_index = 1,
9099
.num_dptxports = 2,
91100
.die = 1,
@@ -222,6 +231,18 @@ static uintptr_t display_map_fb(uintptr_t iova, u64 paddr, u64 size)
222231
return iova;
223232
}
224233

234+
const display_config_t *display_get_config(void)
235+
{
236+
if (adt_is_compatible(adt, 0, "J473AP"))
237+
return &display_config_m2;
238+
else if (adt_is_compatible(adt, 0, "J474sAP") || adt_is_compatible(adt, 0, "J475cAP"))
239+
return &display_config_m2_pro_max;
240+
else if (adt_is_compatible(adt, 0, "J180dAP") || adt_is_compatible(adt, 0, "J475dAP"))
241+
return &display_config_m2_ultra;
242+
else
243+
return &display_config_m1;
244+
}
245+
225246
int display_start_dcp(void)
226247
{
227248
if (iboot)
@@ -232,14 +253,7 @@ int display_start_dcp(void)
232253
return 0;
233254
#endif
234255

235-
const display_config_t *disp_cfg = &display_config_m1;
236-
237-
if (adt_is_compatible(adt, 0, "J473AP"))
238-
disp_cfg = &display_config_m2;
239-
else if (adt_is_compatible(adt, 0, "J474sAP") || adt_is_compatible(adt, 0, "J475cAP"))
240-
disp_cfg = &display_config_m2_pro_max;
241-
else if (adt_is_compatible(adt, 0, "J180dAP") || adt_is_compatible(adt, 0, "J475dAP"))
242-
disp_cfg = &display_config_m2_ultra;
256+
const display_config_t *disp_cfg = display_get_config();
243257

244258
display_is_dptx = !!disp_cfg->dptx_phy[0];
245259

src/display.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#ifndef DISPLAY_H
44
#define DISPLAY_H
55

6+
#include "dcp.h"
67
#include "types.h"
78

89
typedef enum _dcp_shutdown_mode {
@@ -17,5 +18,6 @@ int display_init(void);
1718
int display_start_dcp(void);
1819
int display_configure(const char *config);
1920
void display_shutdown(dcp_shutdown_mode mode);
21+
const display_config_t *display_get_config(void);
2022

2123
#endif

src/kboot.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "clk.h"
99
#include "dapf.h"
1010
#include "devicetree.h"
11+
#include "display.h"
1112
#include "exception.h"
1213
#include "firmware.h"
1314
#include "isp.h"
@@ -1774,7 +1775,6 @@ static int dt_set_display(void)
17741775
* they are missing. */
17751776

17761777
int ret = 0;
1777-
char dcp_alias[8] = "dcp";
17781778

17791779
if (!fdt_node_check_compatible(dt, 0, "apple,t8103")) {
17801780
ret = dt_carveout_reserved_regions("dcp", "disp0", "disp0_piodma",
@@ -1818,9 +1818,7 @@ static int dt_set_display(void)
18181818
if (ret)
18191819
return ret;
18201820
} else if (!fdt_node_check_compatible(dt, 0, "apple,t6022")) {
1821-
// Set dcp_alias to "dcpext4" on M2 Ultra, cmp. display.c
1822-
strncpy(dcp_alias, "dcpext4", sizeof(dcp_alias));
1823-
dcp_alias[sizeof(dcp_alias) - 1] = '\0';
1821+
/* noop */
18241822
} else {
18251823
printf("FDT: unknown compatible, skip display reserved-memory setup\n");
18261824
return 0;
@@ -1838,7 +1836,9 @@ static int dt_set_display(void)
18381836
!fdt_node_check_compatible(dt, 0, "apple,t6022"))
18391837
dt_reserve_dcpext_firmware();
18401838

1841-
return dt_vram_reserved_region(dcp_alias, "disp0");
1839+
const display_config_t *disp_cfg = display_get_config();
1840+
1841+
return dt_vram_reserved_region(disp_cfg->dcp_alias, "disp0");
18421842
}
18431843

18441844
static int dt_set_sio_fwdata(void)

0 commit comments

Comments
 (0)