Repository navigation
drm/apple: T6041 (M4 Pro/Max) displays on desktop 26.6 firmware (carries #445) - #446
Conversation
The register sequence tables of the T6050 fixed DisplayPort PHY, taken alone from 440f79f ("phy: apple: Add T6050 fixed DP and four-clock crossbar support"). The T6041 DisplayPort mode of the T6040 PHY uses the same sequences. The driver and crossbar parts of that commit build on the APIF series and are not included here. Signed-off-by: Dj <hey@djdev.me> (cherry picked from commit 440f79f) Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
…ed DP PHY
The T6040 Type-C PHY also carries DisplayPort: the PHY of a USB-C port as
the alt mode switch of its connector (mode-switch), and the PHY of an HDMI
converter as a fixed DisplayPort link. The fixed instance has no USB
controller behind it, so no PIPE interface ("pipehandler" region), no reset
line and no connector port. Describe the DP phy type, the mode switch and
the ten-region variant, and require #reset-cells only where the PIPE
interface exists.
Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
Add PHY_TYPE_DP to the T6040 Type-C PHY: PHY mode 3 of the paired
AppleT6040TypeCPhy driver, DisplayPort on all four lanes, for a Type-C port
whose controller selected DP alt mode with pin assignment C or E, and for
the fixed DP PHY of an HDMI converter, a node without the PIPE interface
and the DWC3 reset line, which now probes too.
Bring-up follows the paired driver's mode 3: wake the CFG block, apply the
generic ADT tunables and the DPTX tunables, set the lane crossbar to DP,
hold the common block and both TX lanes on by override (the PHY
coprocessor does not run in this mode), release the reset, then set the
lane mode and the AUX block. On a Type-C port the USB3 side is shut down
first. The per-rate link sequences (RBR to HBR3) and the drive-setting
presets are the T6050 fixed-DP tables, whose PHY the T6050 ADT marks as
T6040-compatible ("atc-phy,t6050", "atc-phy,t6040"); the T6050 clock shim
steps are replaced by the T6040 DP clock switch of the CFG window, run
after the lane program as the paired driver does. Pin assignment D (two DP
lanes next to USB3) is not supported.
The Type-C mode switch latches whether the port is in DP alt mode;
apple_t6040_phy_dp_alt() (include/linux/soc/apple/dp-tunnel.h) exposes it
for a DCP that lists several Type-C DP PHYs and routes to the one with a
sink plugged.
Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
The IOMFB template keys its H17 (A18 Pro, M5) wire changes on DCP_FW_VER >= 26.0. The desktop firmware of the M4 Pro/Max DCP (T6041) also reports 26.x, but continues the 14.7 IOMFB. Mark a desktop instance's version with DCP_FW_DESKTOP and key the H17 branches on DCP_FW_H17(). No functional change: the 12.3, 13.3, 14.7 and H17P template objects are unchanged. Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
The 26.6 firmware of the M4 Pro/Max DCP (T6041) continues the 14.7 IOMFB rather than the H17 protocol: most method numbers match H17P, but the records and the start, power and mode-set flows are those of 14.7 with extensions. Add it as a template instance, iomfb_v26_6_desktop.c, with firmware compatibility value DCP_FIRMWARE_V_26_6_DESKTOP. Nothing selects it yet. The instance carries this firmware's wire layout: a 0x588-byte swap record with presents_surface, has_completion and the panel level in nits as a binary64, a 0x1bd8-byte swap_submit with six surf2 entries, swap_start with an opaque client cookie, set_power_state with four transition flags, and the padded abort_swaps, read_edt_data, hotplug, swap intent and frame_sync records. DCP_FW_LAYOUT_14_7() covers the desktop 26.x versions, and static assertions pin the record sizes. Power-on is A414, first_client_open, A474, is_main_display and set_power_state(1), then set_display_device; power-off clears the swap and sets power state 0. A mode set selects the timing through get_mode_info (A364) before set_digital_out_mode. A pipe without a live mode is bootstrapped through the timing's best virtual color element, which the parser now records. GAMMA_LUT is composed with the firmware's gamma table (A420/A421). VRR timings are not offered. The per-DCP desktop state is allocated only for this firmware, so other instances keep their struct apple_dcp size and the 12.3, 13.3, 14.7 and H17P template objects are unchanged. Co-developed-by: Niklas Sheth <hi@niklassheth.com> Signed-off-by: Niklas Sheth <hi@niklassheth.com> Co-developed-by: Josh Rodd <josh@rodd.us> Signed-off-by: Josh Rodd <josh@rodd.us> Co-developed-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
The desktop 26.6 firmware of the T6041 DCP speaks a compact EPIC on its system and auxiliary endpoints: an 8-byte transport header (sequence, flags, interface, total length), the timestamp, an 8-byte sub-header and the payload. Messages longer than 1028 bytes arrive in fragments that repeat the header. Services announce themselves with type 0x11 and are opened with type 0x12; commands, replies and calls carry a status/length descriptor. On DCP_FIRMWARE_V_26_6_DESKTOP endpoints, switch to it on the first compact message: reassemble fragments, register and open announced services, answer calls, deliver reports and match replies to pending commands. Send commands and replies the same way, fragmented when needed, waiting for ring space with WAIT_FOR_SPACE, and answer the firmware's WAIT_FOR_SPACE after draining the receive ring. Call replies are sent from a separate workqueue so that a full transmit ring cannot stall reception. Ring pointers read from shared memory are validated before use; a send that fails part-way fails the commands in flight without shutting the endpoint down. Other firmware never takes these paths. Co-developed-by: Niklas Sheth <hi@niklassheth.com> Signed-off-by: Niklas Sheth <hi@niklassheth.com> Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
Match apple,t6041-dcp and apple,t6041-dcpext and drive the internal DCP of the M4 Pro/Max (J616s) through the desktop 26.6 IOMFB instance. Probe accepts a T6041 processor only with apple,firmware-version and apple,firmware-compat both 26.6.2, and the internal one only if its register windows, iommus, mboxes and piodma match the ADT. The clock is optional there, and without apple,max-brightness the backlight maximum defaults to the panel's 600 nits. The firmware does not tolerate being left running with its endpoints unserviced, so bind sets the coprocessor running and dcp_start() wakes RTKit once every handler is in place. It starts the system endpoint, the IOMFB transport and the auxiliary endpoints the firmware advertises, routes their messages, and binds the IOMFB shared memory last. An auxiliary endpoint that fails to start is skipped. Before the boot framebuffer is evicted, the panel goes through a takeover trial: DCP ready, modes known, panel connected, power-on and one mode set, boot-like mode first. If it fails, the DCP is left running, the DRM device is kept, shutdown and resume leave the DCP alone and suspend is refused, and the boot framebuffer keeps the screen. The T6041 external processors stay out of the DRM device unless t6041_dcpext=1, and then as unusable pipes. Co-developed-by: Cody Ho <codyho@stanford.edu> Signed-off-by: Cody Ho <codyho@stanford.edu> Co-developed-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
The T6041 external display processors publish their DPTX port services as dcpdptx-port-epic:0 and :1 in compact EPIC on EPIC2C (0x2c). Bind them by unit, open port 0 last, and follow the firmware's own client where the compact ABI differs: - set_hpd returns an IOReturn status in its first word; - GET_SUPPORTS_HPD and GET_VIRTUAL_DEVICE_MODE are answered with 0; - GET_MAX_LINK_RATE offers HBR3; - the crossbar link is taken down before a link configuration change and brought up after it; - group 1 calls 3 and 4 keep the first 32 bytes of their record and clear the result word. The DPAVSERV EDID request asks for 2 KiB there, as a 32 KiB inline request does not fit the compact ring, and dcpdp-service-epic is not opened. Co-developed-by: Niklas Sheth <hi@niklassheth.com> Signed-off-by: Niklas Sheth <hi@niklassheth.com> Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
The two external display processors of the M4 Pro/Max (J616s) join the panel's DRM device as further pipelines; t6041_dcpext=0 leaves them alone. dcpext0 drives the HDMI port through its fixed route (atcphy3 and its crossbar), dcpext1 the USB-C ports through a route chosen at connect from the PHY that entered DP alt mode. - probe powers the fixed route's DP PHY and lists the dynamic routes (dp-phyN, dp-xbarN, apple,dptx-phys, apple,dptx-mux-index); - start brings up the advertised auxiliary endpoints, the DPTX port services, DPAVSERV, EXPERT and EPIC25, and connects DPTX port 0; - a connect asserts HPD after the display request and does not fail when no display is attached; - an HDMI hotplug on a connected port pulses HPD, so the firmware exports the modes of a display plugged in after boot; - a USB-C hotplug selects and releases the route through the connector's out-of-band hotplug under hpd_mutex; a failed connect and unbind release it; - a CRTC kept active across a replug is powered on and set up again on its next flush. A dcpext that is absent or fails to probe or bind is kept as an unusable pipe and never holds up the panel. apple_t6040_phy_dp_alt() gets a stub, and DRM_APPLE cannot be built in with the T6040 USB2 PHY as a module. Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
The desktop 26.x DPTX path called apple_dpxbar_link_up/down() and apple_t6040_phy_dp_alt() directly. That made appledrm.ko depend on the crossbar and T6040 PHY modules on every SoC, and DRM_APPLE=y with the crossbar built as a module failed to link. The PHY dependency was also expressed as "depends on PHY_APPLE_T6040_USB2 || !PHY_APPLE_T6040_USB2", which silently demotes DRM_APPLE=y to m wherever the PHY is a module. Use the existing symbol_get() based dcp_dpxbar_link() for the crossbar, look the PHY helper up the same way, and drop the Kconfig dependency. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
When a USB3 tunable fails to parse, t6040_usb3_probe() falls back to USB2 only but leaves the ERR_PTR in tphy->tunables[]. The node is then treated as DP only, and t6040_dp_probe() skips an absent property without touching that slot. A later DP power on hands the error pointer to apple_tunable_apply(), which only checks for NULL. Clear the slot on the USB3 failure path and on the DP skip path, so an unparsed tunable is always NULL and simply not applied. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
The T6041 display series added DCP_FIRMWARE_V_26_6_DESKTOP, the fw_compat and desktop checks it implies, the DCP_FW_H17() lineage test, compact EPIC in the AFK sender, receive worker and quiesce, a VRR filter and a gamma size check in the extracted functions. The fixtures lacked the matching mock fields, defines and helpers, and the lookup_mode() extraction matched a new call site instead of the definition, so nine units no longer compiled. Add them so every scenario stays off the desktop path (fw_compat not desktop, desktop NULL, compact false, no colour-management change), with stubs that assert if it is reached, so the existing paths are checked exactly as before. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Resolve the conflict with #395 in apple_drm_uninit(): withdraw the T6030 display publication first, then keep the T6041 rule that an aborted takeover leaves its DCPs running. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
|
Thanks for carrying this. The Type-C routes of the T6041 DCP still use the private dynamic route from the original series. fbalazsy:j616s/display-t6041-fabric is #446 plus three commits: the first moves them onto the display fabric (typec-routes, as T602x/T6030/J700) and drops apple_t6040_phy_dp_alt(); the other two are the callback size check and the USB3-after-DP fix from your review notes. Tested on a J616s with a USB-C display (attach at boot, port controller rebind, device suspend); it builds with W=1 for DRM_APPLE=m and =y. I can open it as a PR once #446 is in, or you can pull it. |
|
Opened as #451 (stacked on this one, the top three commits). |
|
Follow-up from testing the merged desktop path on our J616s (issues are off on this repo, so posting here). On the J616s (M4 Pro, DCP firmware 26.6.2), the internal panel offers 120, 60, 59.94, 50, 48 and 47.95 Hz at 3456x2160 with the T6041 desktop path (#446, with #452 for the handoff). Setting 120 or 60 Hz works, and modetest's vsync page flip test measures 120.00 and 60.00 Hz. Setting 50, 59.94 or 48 Hz doesn't. Each of those modesets logs and the page flips that follow complete at about 199 Hz, so they aren't paced by the panel. On a build with the display polish series on top, the same sequence ended in a WARN in dcp_push() (iomfb.c:188, called from iomfb_modeset_v26_6_desktop()) and then "DCP has crashed". Reproduce, with the session stopped so modetest owns the display. The stdin pipe keeps modetest's flip loop running: D202 isn't in the desktop 26.6 callback table. Handling it, or not offering these timings until it is, would be the place to start. Until then, GNOME or any compositor that picks one of these rates will hit the timeout. |
|
D202 and D454 are handled in #454. D202 (unmap_piodma) arrives as a 24-byte record with the DVA at offset 12, not the layout the older firmware sends, and D454 (release_mem_desc) wants a 32-bit result. With only D454 answered the DCP crashes; with both, 50, 59.94, 48, 47.95, 60 and 120 Hz all apply on the J616s internal panel, including 48 changes in a row. |
…e callbacks Setting 50, 59.94 or 48 Hz on the J616s internal panel logged "received unknown callback D202 (24, 0)" and timed out in set_digital_out_mode (reported on #446). A mode change makes the desktop 26.6 firmware retire the piodma buffers it mapped for the change with unmap_piodma (D202), then their descriptors with release_mem_desc (D454). The desktop callback table had neither, so the first stayed unanswered and every later modeset timed out. D202 is not the record the older firmware sends: the buffer id and the id again, then the DVA unaligned at offset 12, then one word. Reading it as struct dcp_unmap_buf_resp makes the DVA check fail and leaves the piodma translation standing. Decode it and unmap that. D454 carries a 32-bit descriptor id and takes a 32-bit result back (the older firmware returned a byte); run the existing release handler and return its result as 32 bits. D454 alone, with the piodma buffers still mapped, made the firmware crash ("RTKit: co-processor has crashed"); with D202 unmapping first, both together run clean. Signed-off-by: František Balázsy <frantisekbalazsy@gmail.com>
This carries František Balázsy's T6041 display series from #445 with three small fixes on top, so it can land tonight. His eight commits keep his authorship, his sign-off and the co-developer credit (Niklas Sheth, Cody Ho, Josh Rodd, Jonathan Goyvaerts) unchanged. Thanks for all the work on this one!
What differs from #445:
Gates
On integration/aurora 653c489 with #394, #435, #436, this branch, #427 and #428 merged (test tree 4582b72703d5):
Hardware
On the MacBook Pro 16" M4 Pro (J616s) with 26.6.2 firmware:
Follow-ups, not in this PR
Supersedes #445.