From 6622fd388875f39738d9fadc2ea0125cb94dc00d Mon Sep 17 00:00:00 2001 From: Satya Benson Date: Thu, 5 Nov 2026 23:39:01 -0500 Subject: [PATCH] drm/apple: av: start the DP audio service of DCP firmware 27 T6050's external display processors run DCP firmware 27, which avep_init() refused ("Audio not supported for firmware"), so neither the HDMI port nor DisplayPort on USB-C had any audio on the M5 Max Studio. Firmware 27 publishes the audio interface (DCPAVAudioInterface, dcpav-audio-interface-epic) on endpoint 0x2b, not 0x29: in the J775c IORegistry (macOS 27, a DELL S2725QS on dcpext0) it sits on RTBuddy Endpoint12, Endpoint13 being the dcpdptx-port-epic that Linux already talks to on 0x2c; firmware 27's 0x29 is dcpav-device-epic and 0x2a dcpav-service-epic. Its EP client is the link-data one of the T6030 14.7 external role: the firmware's method names run PrepareLinkWithData, StartLinkWithData, DidStartLinkWithData, WillStopLinkWithData, StopLinkWithData, CompleteLinkWithData, GetLinkData, GetLinkStatus, GetTransport, GetPortID, CopyElements, CopyChannelLayoutElements, CopyProductAttributes, the 13.5/14.7 numbering (prepare 6 ... complete 11, elements 16, product attributes 18), and macOS logs a StartLink with 32-byte link data (LinearPCM, 2 channels, 24 bit, 48 kHz) on it. So drive firmware 27 as the 14.7 external role: the native link lifecycle, the 32-byte link data and the large element catalog, the Terminate report, open and close around the PCM. The interface is published only for a sink the firmware drives, so no power check is added for it. Its Open reply is not known to carry the "opened" Boolean where 14.7's does; only its status decides there. Look the AV endpoint up by its own number, and start it, and the sound card on top of it, on firmware 27 without the hdmi_audio opt-in: a DCP whose port@0 links no DisplayPort audio interface in the DT starts nothing, so the DT is the opt-in there. All of it needs CONFIG_DRM_APPLE_DCP_T6030_AUDIO, which builds the link-data protocol; without it firmware 27 is refused as before. Signed-off-by: Satya Benson Co-Authored-By: Claude Opus 5.5 Adapted from 9d375903520c2148d1df0df38560a696df7da5f8: retain integration's compact desktop protocol, dynamic endpoint routing, native-link lifecycle and default-on audio policy. Only extend the native-role and firmware gates, select endpoint 0x2b, and accept firmware 27 Open without the 14.7 Boolean. No device-tree change is needed on #1619. --- drivers/gpu/drm/apple/av.c | 15 ++++++++++----- drivers/gpu/drm/apple/dcp-internal.h | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/apple/av.c b/drivers/gpu/drm/apple/av.c index 6b350cb0b9414..6fd15850000dd 100644 --- a/drivers/gpu/drm/apple/av.c +++ b/drivers/gpu/drm/apple/av.c @@ -288,7 +288,8 @@ bool dcp_audiosrv_native_link(struct device *dev) { struct apple_dcp *dcp = dev_get_drvdata(dev); - return dcp_is_v14_7_external(dcp) || av_desktop_audio_role(dcp); + return dcp_is_v14_7_external(dcp) || av_desktop_audio_role(dcp) || + dcp->fw_compat == DCP_FIRMWARE_V_27_0; } /* The 14.7 external role's audio service calls; KUnit stubs them. */ @@ -365,7 +366,10 @@ int dcp_audiosrv_open(struct device *dev) /* Open: a zero body; status at +0, the opened Boolean at +16. */ memset(reply, 0, sizeof(reply)); ret = av_audiosrv_call(srv, asrv->cmds.open, NULL, 0, 32, reply, sizeof(reply)); - if (!ret && (get_unaligned_le32(reply) || !get_unaligned_le64(reply + 16))) { + /* Firmware 27 does not require the 14.7 opened Boolean at +16. */ + if (!ret && (get_unaligned_le32(reply) || + (dcp->fw_compat != DCP_FIRMWARE_V_27_0 && + !get_unaligned_le64(reply + 16)))) { dev_err(dev, "audiosrv: open answered %#x, opened %llu\n", get_unaligned_le32(reply), get_unaligned_le64(reply + 16)); ret = -EIO; @@ -1232,7 +1236,8 @@ int avep_init(struct apple_dcp *dcp) struct device *dev = dcp->dev; struct device_node *endpoint, *audio_node = NULL; const struct apple_epic_service_ops *ops = avep_ops; - u32 av_endpoint = AV_ENDPOINT; + u32 av_endpoint = dcp->fw_compat == DCP_FIRMWARE_V_27_0 ? + AV_ENDPOINT_V27 : AV_ENDPOINT; int ret; if (dcp->fw_compat == DCP_FIRMWARE_V_26_6_DESKTOP || @@ -1290,11 +1295,11 @@ int avep_init(struct apple_dcp *dcp) default: #if IS_ENABLED(CONFIG_DRM_APPLE_DCP_T6030_AUDIO) /* - * The 14.7 external role (T6030 external processor) numbers its + * The 14.7 external role and firmware 27 number their * methods as 13.5 does: open 4, close 5, prepare 6, start 7, * stop 10, complete 11, elements 1/16, product attributes 1/18. */ - if (dcp_is_v14_7_external(dcp)) { + if (dcp_is_v14_7_external(dcp) || dcp->fw_compat == DCP_FIRMWARE_V_27_0) { audiosrv_data->cmds = dcp_av_audio_cmds_v13_5; break; } diff --git a/drivers/gpu/drm/apple/dcp-internal.h b/drivers/gpu/drm/apple/dcp-internal.h index 872789ba534c4..534573e27ba67 100644 --- a/drivers/gpu/drm/apple/dcp-internal.h +++ b/drivers/gpu/drm/apple/dcp-internal.h @@ -104,6 +104,8 @@ enum { DPAVSERV_ENDPOINT = 0x28, DPAVSERV_ENDPOINT_V2 = 0x2a, AV_ENDPOINT = 0x29, + /* Firmware 27 publishes DCPAVAudioInterface on 0x2b. */ + AV_ENDPOINT_V27 = 0x2b, /* Desktop 26.x separates the audio service from AV device control. */ AV_AUDIO_ENDPOINT_DESKTOP = 0x2b, DPTX_ENDPOINT = 0x2a,