Skip to content

Commit

Permalink
display: Use dcpext0 for HDMI out on t8112/t6020/t6021
Browse files Browse the repository at this point in the history
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 <j@jannau.net>
  • Loading branch information
jannau authored and marcan committed Nov 27, 2023
1 parent 5245fc6 commit 5006e08
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 29 deletions.
7 changes: 1 addition & 6 deletions src/dcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,7 @@ dcp_dev_t *dcp_init(const display_config_t *cfg)

int dcp_shutdown(dcp_dev_t *dcp, bool sleep)
{
if (dcp->dptx_ep) {
if (sleep) {
printf("DCP: dcp_shutdown(sleep=true) is broken with dptx-port, quiesce instead\n");
sleep = false;
}
}
/* dcp/dcp0 on desktop M2 and M2 Pro/Max devices do not wake from sleep */
dcp_system_shutdown(dcp->system_ep);
dcp_dptx_shutdown(dcp->dptx_ep);
dcp_dpav_shutdown(dcp->dpav_ep);
Expand Down
1 change: 1 addition & 0 deletions src/dcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ typedef struct {
const char dptx_phy[24];
const char dp2hdmi_gpio[24];
const char pmgr_dev[24];
const char dcp_alias[8];
u32 dcp_index;
u8 num_dptxports;
u8 die;
Expand Down
50 changes: 32 additions & 18 deletions src/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,41 +37,49 @@ static const display_config_t display_config_m1 = {
.dcp_dart = "/arm-io/dart-dcp",
.disp_dart = "/arm-io/dart-disp0",
.pmgr_dev = "DISP0_CPU0",
.dcp_alias = "dcp",
};

#define USE_DCPEXT 1

static const display_config_t display_config_m2 = {
#if USE_DCPEXT
.dcp = "/arm-io/dcpext",
.dcp_dart = "/arm-io/dart-dcpext",
.disp_dart = "/arm-io/dart-dispext0",
.pmgr_dev = "DISPEXT_CPU0",
.dcp_alias = "dcpext",
.dcp_index = 1,
#else
.dcp = "/arm-io/dcp",
.dcp_dart = "/arm-io/dart-dcp",
.disp_dart = "/arm-io/dart-disp0",
.dp2hdmi_gpio = "/arm-io/dp2hdmi-gpio",
.dptx_phy = "/arm-io/dptx-phy",
.pmgr_dev = "DISP0_CPU0",
.dcp_alias = "dcp",
.dcp_index = 0,
#endif
.dp2hdmi_gpio = "/arm-io/dp2hdmi-gpio",
.dptx_phy = "/arm-io/dptx-phy",
.num_dptxports = 2,
};

#define T6020_T6021_USE_DCPEXT 255

static const display_config_t display_config_m2_pro_max = {
#if T6020_T6021_USE_DCPEXT == 0
#if USE_DCPEXT
.dcp = "/arm-io/dcpext0",
.dcp_dart = "/arm-io/dart-dcpext0",
.disp_dart = "/arm-io/dart-dispext0",
.pmgr_dev = "DISPEXT0_CPU0",
.dcp_alias = "dcpext0",
.dcp_index = 1,
.num_dptxports = 2,
#elif T6020_T6021_USE_DCPEXT == 1
.dcp = "/arm-io/dcpext1",
.dcp_dart = "/arm-io/dart-dcpext1",
.disp_dart = "/arm-io/dart-dispext1",
.pmgr_dev = "DISPEXT1_CPU0",
.dcp_index = 2,
.num_dptxports = 2,
#else
.dcp = "/arm-io/dcp0",
.dcp_dart = "/arm-io/dart-dcp0",
.disp_dart = "/arm-io/dart-disp0",
.pmgr_dev = "DISP0_CPU0",
.dcp_alias = "dcp",
.dcp_index = 0,
.num_dptxports = 1,
#endif
Expand All @@ -86,6 +94,7 @@ static const display_config_t display_config_m2_ultra = {
.dp2hdmi_gpio = "/arm-io/dp2hdmi-gpio1",
.dptx_phy = "/arm-io/lpdptx-phy1",
.pmgr_dev = "DISPEXT4_CPU0",
.dcp_alias = "dcpext4",
.dcp_index = 1,
.num_dptxports = 2,
.die = 1,
Expand Down Expand Up @@ -222,6 +231,18 @@ static uintptr_t display_map_fb(uintptr_t iova, u64 paddr, u64 size)
return iova;
}

const display_config_t *display_get_config(void)
{
if (adt_is_compatible(adt, 0, "J473AP"))
return &display_config_m2;
else if (adt_is_compatible(adt, 0, "J474sAP") || adt_is_compatible(adt, 0, "J475cAP"))
return &display_config_m2_pro_max;
else if (adt_is_compatible(adt, 0, "J180dAP") || adt_is_compatible(adt, 0, "J475dAP"))
return &display_config_m2_ultra;
else
return &display_config_m1;
}

int display_start_dcp(void)
{
if (iboot)
Expand All @@ -232,14 +253,7 @@ int display_start_dcp(void)
return 0;
#endif

const display_config_t *disp_cfg = &display_config_m1;

if (adt_is_compatible(adt, 0, "J473AP"))
disp_cfg = &display_config_m2;
else if (adt_is_compatible(adt, 0, "J474sAP") || adt_is_compatible(adt, 0, "J475cAP"))
disp_cfg = &display_config_m2_pro_max;
else if (adt_is_compatible(adt, 0, "J180dAP") || adt_is_compatible(adt, 0, "J475dAP"))
disp_cfg = &display_config_m2_ultra;
const display_config_t *disp_cfg = display_get_config();

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

Expand Down
2 changes: 2 additions & 0 deletions src/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#ifndef DISPLAY_H
#define DISPLAY_H

#include "dcp.h"
#include "types.h"

typedef enum _dcp_shutdown_mode {
Expand All @@ -17,5 +18,6 @@ int display_init(void);
int display_start_dcp(void);
int display_configure(const char *config);
void display_shutdown(dcp_shutdown_mode mode);
const display_config_t *display_get_config(void);

#endif
10 changes: 5 additions & 5 deletions src/kboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "clk.h"
#include "dapf.h"
#include "devicetree.h"
#include "display.h"
#include "exception.h"
#include "firmware.h"
#include "isp.h"
Expand Down Expand Up @@ -1774,7 +1775,6 @@ static int dt_set_display(void)
* they are missing. */

int ret = 0;
char dcp_alias[8] = "dcp";

if (!fdt_node_check_compatible(dt, 0, "apple,t8103")) {
ret = dt_carveout_reserved_regions("dcp", "disp0", "disp0_piodma",
Expand Down Expand Up @@ -1818,9 +1818,7 @@ static int dt_set_display(void)
if (ret)
return ret;
} else if (!fdt_node_check_compatible(dt, 0, "apple,t6022")) {
// Set dcp_alias to "dcpext4" on M2 Ultra, cmp. display.c
strncpy(dcp_alias, "dcpext4", sizeof(dcp_alias));
dcp_alias[sizeof(dcp_alias) - 1] = '\0';
/* noop */
} else {
printf("FDT: unknown compatible, skip display reserved-memory setup\n");
return 0;
Expand All @@ -1838,7 +1836,9 @@ static int dt_set_display(void)
!fdt_node_check_compatible(dt, 0, "apple,t6022"))
dt_reserve_dcpext_firmware();

return dt_vram_reserved_region(dcp_alias, "disp0");
const display_config_t *disp_cfg = display_get_config();

return dt_vram_reserved_region(disp_cfg->dcp_alias, "disp0");
}

static int dt_set_sio_fwdata(void)
Expand Down

0 comments on commit 5006e08

Please sign in to comment.