Skip to content

Studio Display: DCP firmware sends unhandled DPTX_APCALL_INACTIVE_SINK_DETECTED (call 20); driver acks blindly and link tears down (fairydust) #579

Description

@pulsebrowser

Summary

On the fairydust experimental branch, plugging an Apple Studio Display into a
MacBook Pro (13-inch, M2, 2022) brings up the whole display path — Type-C PHY
mode switch, OOB hotplug delivery to dcpext, DPTX bring-up — until the DCP
firmware issues AP call 20 (DPTX_APCALL_INACTIVE_SINK_DETECTED). The
constant is defined in dptxep.h but dptxport_call() has no case for it, so
it falls into the default "ack and hope for the best" branch
(dptxep.c:558). Immediately after the blind ack the firmware gives up and
the driver logs dcp_dptx_disconnect(port=0); the DP-1 connector never
leaves disconnected.

The Studio Display presumably needs a sink wake/activation sequence at this
point (its internal computer is still asleep), which explains why displays
without such a sink-side processor work while the Studio Display does not.

Environment

Machine Apple MacBook Pro (13-inch, M2, 2022) — apple,j493 / apple,t8112
Kernel linux-asahi-fairydust 7.1.6.fairydust.g96775a0 (AsahiLinux/linux commit 96775a0e72995e79e13b93755d456cb128dcdc81)
uname 7.1.9-1-1-ARCH #1 SMP PREEMPT_DYNAMIC aarch64
Display Apple Studio Display (USB hub 05ac:101d, bcdDevice 52.12)
Distro Arch Linux ARM (Omarchy), GRUB boot, Hyprland/Wayland desktop

Steps to reproduce

  1. Boot the fairydust kernel. card3-DP-1 (dcpext) appears, disconnected.
  2. modprobe typec_thunderbolt (see note 1 below — it does not autoload).
  3. Plug an Apple Studio Display into either Type-C port.

Result

The same terminal sequence on both ports (each attempt, no retraining):

kernel: #### oob_hotplug status:0x2 ####
kernel: apple-dcp 271c00000.dcp: DPTXPort: acking unhandled call 20
kernel: apple-dcp 271c00000.dcp: dcp_dptx_disconnect(port=0)

/sys/class/drm/card3-DP-1/status stays disconnected; no modes are ever
reported (dcp_hotplug() connected:0 valid_mode:0 nr_modes:0 at boot, no
hotplug event after plugging).

Port-specific detail:

  • Port at 503000000.phy: clean run of the sequence above, twice per
    plug, no other errors. The display's internal USB hub enumerates fine
    beforehand ("Apple USB2 Hub", 4 ports), then xhci tears down for the mode
    switch as expected.

  • Port at 383000000.phy: the same unhandled call 20dptx disconnect sequence, followed ~3 s later by:

    kernel: phy-apple-atc 383000000.phy: Pipehandler lock not acked.
    kernel: phy-apple-atc 383000000.phy: Failed to lock pipehandler
    

    This looks like fallout of the aborted DPTX bring-up rather than an
    independent failure, since the call-20 sequence precedes it.

Analysis

In drivers/gpu/drm/apple/dptxep.h:

DPTX_APCALL_INACTIVE_SINK_DETECTED = 20,

In drivers/gpu/drm/apple/dptxport_call() (dptxep.c), call 20 has no case
and lands in:

default:
        /* just try to ACK and hope for the best... */
        dev_info(service->ep->dcp->dev, "DPTXPort: acking unhandled call %u\n", idx);
        fallthrough;

The zeroed-retcode ack is apparently not what the firmware expects for an
inactive sink: it disconnects the DPTX port right after. I'd guess the
expected response involves waking/activating the sink (the Studio Display's
internal SoC) before link training can proceed, but I don't have m1n1 traces
of what macOS does at this point.

Happy to test patches, capture fuller logs, or run instrumented builds — the
machine and display are available.

Notes

  1. typec_thunderbolt.ko is built but does not autoload on this
    configuration; without it the plug event only ever enumerates the
    display's USB2 hub and no mode switch is attempted. If that is not
    expected I can file it separately.
  2. Full dmesg of the boot and both plug attempts available on request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions