From da83e551d4032b2df121a9b5ad98554fb3f074c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Bal=C3=A1zsy?= Date: Sun, 25 Oct 2026 21:09:56 +0100 Subject: [PATCH] drm/apple: answer the desktop 26.6 piodma unmap and descriptor release callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- drivers/gpu/drm/apple/iomfb_v26_6_desktop.c | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/gpu/drm/apple/iomfb_v26_6_desktop.c b/drivers/gpu/drm/apple/iomfb_v26_6_desktop.c index 98a3504a9a5f0..05417d2c2b2cb 100644 --- a/drivers/gpu/drm/apple/iomfb_v26_6_desktop.c +++ b/drivers/gpu/drm/apple/iomfb_v26_6_desktop.c @@ -91,6 +91,48 @@ static bool trampoline_passthrough_dict_v26_6(struct apple_dcp *dcp, int tag, return true; } +/* + * unmap_piodma (D202): the buffer id, the id again, the DVA (unaligned) and a + * trailing word. The older firmware sends the DVA after a virtual address. + */ +struct dcp_unmap_buf_req_v26_6 { + __le64 buffer; + __le32 id; + __le64 dva; + __le32 unk; +} __packed; +static_assert(sizeof(struct dcp_unmap_buf_req_v26_6) == 24); + +static bool trampoline_unmap_piodma_v26_6(struct apple_dcp *dcp, int tag, + void *out, void *in) +{ + const struct dcp_unmap_buf_req_v26_6 *wire = in; + struct dcp_unmap_buf_resp request = { + .buffer = get_unaligned_le64(&wire->buffer), + .dva = get_unaligned_le64(&wire->dva), + }; + + trace_iomfb_callback(dcp, tag, "dcpep_cb_unmap_piodma"); + dcpep_unmap_piodma(dcp, &request); + + return true; +} + +/* + * release_mem_desc (D454): the firmware sends the 32-bit descriptor id and + * wants a 32-bit result, where the older firmware took a byte. + */ +static bool trampoline_release_mem_desc_v26_6(struct apple_dcp *dcp, int tag, + void *out, void *in) +{ + u32 id = get_unaligned_le32(in); + + trace_iomfb_callback(dcp, tag, "dcpep_cb_release_mem_desc"); + put_unaligned_le32(dcpep_cb_release_mem_desc(dcp, &id), out); + + return true; +} + static const iomfb_cb_handler cb_handlers[IOMFB_MAX_CB] = { [0] = trampoline_true, /* did_boot_signal */ [1] = trampoline_true, /* did_power_on_signal */ @@ -120,6 +162,8 @@ static const iomfb_cb_handler cb_handlers[IOMFB_MAX_CB] = { [129] = trampoline_prop_end, [134] = trampoline_zero, [201] = trampoline_map_piodma, + /* a mode change retires its piodma buffers, then their descriptors */ + [202] = trampoline_unmap_piodma_v26_6, [206] = iomfbep_cb_match_pmu_service_2, [207] = iomfbep_cb_match_backlight_service, [208] = trampoline_nop, /* update_backlight_factor_prop */ @@ -134,6 +178,7 @@ static const iomfb_cb_handler cb_handlers[IOMFB_MAX_CB] = { [414] = trampoline_sr_set_property_int, [415] = trampoline_true, /* sr_set_property_bool */ [451] = trampoline_allocate_buffer, + [454] = trampoline_release_mem_desc_v26_6, [552] = trampoline_true, /* set_property_dict_0 */ [561] = trampoline_true, /* set_property_dict */ [563] = trampoline_true, /* set_property_int */