From 0b28a2cacc675d04f51ca8ab7417faef66e0d362 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 10 Jul 2026 17:47:46 +1000 Subject: [PATCH 1/8] drm: apple: move fw version enum to version_utils.h Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/dcp-internal.h | 7 +------ drivers/gpu/drm/apple/version_utils.h | 6 ++++++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/apple/dcp-internal.h b/drivers/gpu/drm/apple/dcp-internal.h index 57832487d9a4ab..6042750f16019f 100644 --- a/drivers/gpu/drm/apple/dcp-internal.h +++ b/drivers/gpu/drm/apple/dcp-internal.h @@ -19,6 +19,7 @@ #include "iomfb_v12_3.h" #include "iomfb_v13_3.h" #include "epic/dpavservep.h" +#include "version_utils.h" #define DCP_MAX_PLANES 4 @@ -27,12 +28,6 @@ struct apple_dcp_afkep; struct dcpav_service_epic; -enum dcp_firmware_version { - DCP_FIRMWARE_UNKNOWN, - DCP_FIRMWARE_V_12_3, - DCP_FIRMWARE_V_13_5, -}; - enum { SYSTEM_ENDPOINT = 0x20, TEST_ENDPOINT = 0x21, diff --git a/drivers/gpu/drm/apple/version_utils.h b/drivers/gpu/drm/apple/version_utils.h index 5a33ce1db61c47..35f82e6ad56c01 100644 --- a/drivers/gpu/drm/apple/version_utils.h +++ b/drivers/gpu/drm/apple/version_utils.h @@ -12,4 +12,10 @@ #define DCP_FW_NAME(name) CONCATENATE(name, DCP_FW_SUFFIX) #define DCP_FW_VERSION(x, y, z) ( ((x) << 16) | ((y) << 8) | (z) ) +enum dcp_firmware_version { + DCP_FIRMWARE_UNKNOWN, + DCP_FIRMWARE_V_12_3, + DCP_FIRMWARE_V_13_5, +}; + #endif /*__APPLE_VERSION_UTILS_H__*/ From 8dc5189a995534069d92bc398ac78848e44dcd64 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 10 Jul 2026 17:55:37 +1000 Subject: [PATCH 2/8] drm: apple: Remove support for firmware version 12.3 This firmware version was only ever used for extremely early alpha installs based on ALARM (so basically just for developers testing things). Remove support for it to make way for a new target ABI for M3 machines. Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/Makefile | 1 - drivers/gpu/drm/apple/apple_drv.c | 4 +- drivers/gpu/drm/apple/av.c | 14 ---- drivers/gpu/drm/apple/dcp-internal.h | 2 - drivers/gpu/drm/apple/dcp.c | 19 ----- drivers/gpu/drm/apple/dcp.h | 1 - drivers/gpu/drm/apple/iomfb.c | 12 --- drivers/gpu/drm/apple/iomfb_v12_3.c | 108 -------------------------- drivers/gpu/drm/apple/iomfb_v12_3.h | 17 ---- drivers/gpu/drm/apple/iomfb_v13_3.c | 1 - drivers/gpu/drm/apple/plane.c | 62 ++------------- drivers/gpu/drm/apple/plane.h | 1 - drivers/gpu/drm/apple/version_utils.h | 1 - 13 files changed, 9 insertions(+), 234 deletions(-) delete mode 100644 drivers/gpu/drm/apple/iomfb_v12_3.c delete mode 100644 drivers/gpu/drm/apple/iomfb_v12_3.h diff --git a/drivers/gpu/drm/apple/Makefile b/drivers/gpu/drm/apple/Makefile index b22839bdd611a7..a050e1292186ec 100644 --- a/drivers/gpu/drm/apple/Makefile +++ b/drivers/gpu/drm/apple/Makefile @@ -8,7 +8,6 @@ appledrm-$(CONFIG_DRM_APPLE_AUDIO) += audio.o appledrm-$(CONFIG_DRM_APPLE_AUDIO) += av.o appledrm-y += connector.o appledrm-y += ibootep.o -appledrm-y += iomfb_v12_3.o appledrm-y += iomfb_v13_3.o appledrm-y += epic/dpavservep.o appledrm-y += plane.o diff --git a/drivers/gpu/drm/apple/apple_drv.c b/drivers/gpu/drm/apple/apple_drv.c index 17b59033f12dae..63ea549ba4e37c 100644 --- a/drivers/gpu/drm/apple/apple_drv.c +++ b/drivers/gpu/drm/apple/apple_drv.c @@ -277,13 +277,11 @@ static int apple_probe_per_dcp(struct device *dev, int ret; u32 surf; int zpos = 0; - bool supports_l10r = !dcp_fw_compat_is_12_x(dcp); enum drm_plane_type plane_type; for_each_set_bit(surf, iomfb_surfaces, DCP_MAX_PLANES) { plane_type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; - planes[zpos] = apple_plane_init(drm, 1U << num, surf, - supports_l10r, plane_type); + planes[zpos] = apple_plane_init(drm, 1U << num, surf, plane_type); if (IS_ERR(planes[zpos])) return PTR_ERR(planes[zpos]); diff --git a/drivers/gpu/drm/apple/av.c b/drivers/gpu/drm/apple/av.c index 0d3c752f62d5f5..2734cdf8a6cb1d 100644 --- a/drivers/gpu/drm/apple/av.c +++ b/drivers/gpu/drm/apple/av.c @@ -30,17 +30,6 @@ struct dcp_av_audio_cmds { u32 get_product_attrs; }; -static const struct dcp_av_audio_cmds dcp_av_audio_cmds_v12_3 = { - .open = 6, - .close = 7, - .prepare = 8, - .start_link = 9, - .stop_link = 12, - .unprepare = 13, - .get_elements = 18, - .get_product_attrs = 20, -}; - static const struct dcp_av_audio_cmds dcp_av_audio_cmds_v13_5 = { .open = 4, .close = 5, @@ -389,9 +378,6 @@ int avep_init(struct apple_dcp *dcp) mutex_init(&audiosrv_data->plug_lock); switch (dcp->fw_compat) { - case DCP_FIRMWARE_V_12_3: - audiosrv_data->cmds = dcp_av_audio_cmds_v12_3; - break; case DCP_FIRMWARE_V_13_5: 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 6042750f16019f..fbf40aac06e52d 100644 --- a/drivers/gpu/drm/apple/dcp-internal.h +++ b/drivers/gpu/drm/apple/dcp-internal.h @@ -16,7 +16,6 @@ #include "dptxep.h" #include "iomfb.h" -#include "iomfb_v12_3.h" #include "iomfb_v13_3.h" #include "epic/dpavservep.h" #include "version_utils.h" @@ -171,7 +170,6 @@ struct apple_dcp { /* Queued swap. Owned by the DCP to avoid per-swap memory allocation */ union { - struct dcp_swap_submit_req_v12_3 v12_3; struct dcp_swap_submit_req_v13_3 v13_3; } swap; diff --git a/drivers/gpu/drm/apple/dcp.c b/drivers/gpu/drm/apple/dcp.c index 272d1cef38e661..fef8a802f07709 100644 --- a/drivers/gpu/drm/apple/dcp.c +++ b/drivers/gpu/drm/apple/dcp.c @@ -485,14 +485,6 @@ void dcp_link(struct platform_device *pdev, struct apple_crtc *crtc, dcp->connector = connector; } - -bool dcp_fw_compat_is_12_x(struct platform_device *pdev) -{ - struct apple_dcp *dcp = platform_get_drvdata(pdev); - - return dcp->fw_compat == DCP_FIRMWARE_V_12_3; -} - unsigned long* dcp_get_iomfb_surfaces(struct platform_device *pdev) { struct apple_dcp *dcp = platform_get_drvdata(pdev); @@ -575,9 +567,6 @@ int dcp_start(struct platform_device *pdev) static void _dcp_poweroff(struct apple_dcp *dcp) { switch (dcp->fw_compat) { - case DCP_FIRMWARE_V_12_3: - iomfb_poweroff_v12_3(dcp); - break; case DCP_FIRMWARE_V_13_5: iomfb_poweroff_v13_3(dcp); break; @@ -634,9 +623,6 @@ int dcp_wait_ready(struct platform_device *pdev, u64 timeout) static void __maybe_unused dcp_sleep(struct apple_dcp *dcp) { switch (dcp->fw_compat) { - case DCP_FIRMWARE_V_12_3: - iomfb_sleep_v12_3(dcp); - break; case DCP_FIRMWARE_V_13_5: iomfb_sleep_v13_3(dcp); break; @@ -659,9 +645,6 @@ void dcp_poweron(struct platform_device *pdev) } switch (dcp->fw_compat) { - case DCP_FIRMWARE_V_12_3: - iomfb_poweron_v12_3(dcp); - break; case DCP_FIRMWARE_V_13_5: iomfb_poweron_v13_3(dcp); break; @@ -950,8 +933,6 @@ static enum dcp_firmware_version dcp_check_firmware_version(struct device *dev) return DCP_FIRMWARE_UNKNOWN; } - if (strncmp(compat_str, "12.3.0", sizeof(compat_str)) == 0) - return DCP_FIRMWARE_V_12_3; /* * m1n1 reports firmware version 13.5 as compatible with 13.3. This is * only true for the iomfb endpoint. The interface for the dptx-port diff --git a/drivers/gpu/drm/apple/dcp.h b/drivers/gpu/drm/apple/dcp.h index 2b421772bf5d57..7607aa06f3b035 100644 --- a/drivers/gpu/drm/apple/dcp.h +++ b/drivers/gpu/drm/apple/dcp.h @@ -34,7 +34,6 @@ void dcp_poweron(struct platform_device *pdev); int dcp_set_crc(struct drm_crtc *crtc, bool enabled); int dcp_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state); int dcp_get_connector_type(struct platform_device *pdev); -bool dcp_fw_compat_is_12_x(struct platform_device *pdev); unsigned long* dcp_get_iomfb_surfaces(struct platform_device *pdev); void dcp_link(struct platform_device *pdev, struct apple_crtc *apple, struct apple_connector *connector); diff --git a/drivers/gpu/drm/apple/iomfb.c b/drivers/gpu/drm/apple/iomfb.c index 1d9448f0f4dc47..18a35cd7077065 100644 --- a/drivers/gpu/drm/apple/iomfb.c +++ b/drivers/gpu/drm/apple/iomfb.c @@ -430,9 +430,6 @@ int dcp_crtc_atomic_modeset(struct drm_crtc *crtc, return 0; switch (dcp->fw_compat) { - case DCP_FIRMWARE_V_12_3: - ret = iomfb_modeset_v12_3(dcp, crtc_state); - break; case DCP_FIRMWARE_V_13_5: ret = iomfb_modeset_v13_3(dcp, crtc_state); break; @@ -479,9 +476,6 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) } switch (dcp->fw_compat) { - case DCP_FIRMWARE_V_12_3: - iomfb_flush_v12_3(dcp, crtc, state); - break; case DCP_FIRMWARE_V_13_5: iomfb_flush_v13_3(dcp, crtc, state); break; @@ -494,9 +488,6 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) static void iomfb_start(struct apple_dcp *dcp) { switch (dcp->fw_compat) { - case DCP_FIRMWARE_V_12_3: - iomfb_start_v12_3(dcp); - break; case DCP_FIRMWARE_V_13_5: iomfb_start_v13_3(dcp); break; @@ -545,9 +536,6 @@ void iomfb_shutdown(struct apple_dcp *dcp) dcp->valid_mode = false; switch (dcp->fw_compat) { - case DCP_FIRMWARE_V_12_3: - iomfb_shutdown_v12_3(dcp); - break; case DCP_FIRMWARE_V_13_5: iomfb_shutdown_v13_3(dcp); break; diff --git a/drivers/gpu/drm/apple/iomfb_v12_3.c b/drivers/gpu/drm/apple/iomfb_v12_3.c deleted file mode 100644 index 0fe08c42d64659..00000000000000 --- a/drivers/gpu/drm/apple/iomfb_v12_3.c +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only OR MIT -/* Copyright The Asahi Linux Contributors */ - -#include "iomfb_v12_3.h" -#include "iomfb_v13_3.h" -#include "version_utils.h" - -static const struct dcp_method_entry dcp_methods[dcpep_num_methods] = { - IOMFB_METHOD("A000", dcpep_late_init_signal), - IOMFB_METHOD("A029", dcpep_setup_video_limits), - IOMFB_METHOD("A131", iomfbep_a131_pmu_service_matched), - IOMFB_METHOD("A132", iomfbep_a132_backlight_service_matched), - IOMFB_METHOD("A357", dcpep_set_create_dfb), - IOMFB_METHOD("A358", iomfbep_a358_vi_set_temperature_hint), - IOMFB_METHOD("A401", dcpep_start_signal), - IOMFB_METHOD("A407", dcpep_swap_start), - IOMFB_METHOD("A408", dcpep_swap_submit), - IOMFB_METHOD("A410", dcpep_set_display_device), - IOMFB_METHOD("A411", dcpep_is_main_display), - IOMFB_METHOD("A412", dcpep_set_digital_out_mode), - IOMFB_METHOD("A422", iomfbep_set_matrix), - IOMFB_METHOD("A426", iomfbep_get_color_remap_mode), - IOMFB_METHOD("A439", dcpep_set_parameter_dcp), - IOMFB_METHOD("A443", dcpep_create_default_fb), - IOMFB_METHOD("A447", dcpep_enable_disable_video_power_savings), - IOMFB_METHOD("A454", dcpep_first_client_open), - IOMFB_METHOD("A455", iomfbep_last_client_close), - IOMFB_METHOD("A460", dcpep_set_display_refresh_properties), - IOMFB_METHOD("A463", dcpep_flush_supports_power), - IOMFB_METHOD("A464", iomfbep_abort_swaps_dcp), - IOMFB_METHOD("A468", dcpep_set_power_state), -}; - -#define DCP_FW v12_3 -#define DCP_FW_VER DCP_FW_VERSION(12, 3, 0) - -#include "iomfb_template.c" - -static const iomfb_cb_handler cb_handlers[IOMFB_MAX_CB] = { - [0] = trampoline_true, /* did_boot_signal */ - [1] = trampoline_true, /* did_power_on_signal */ - [2] = trampoline_nop, /* will_power_off_signal */ - [3] = trampoline_rt_bandwidth, - [100] = iomfbep_cb_match_pmu_service, - [101] = trampoline_zero, /* get_display_default_stride */ - [102] = trampoline_nop, /* set_number_property */ - [103] = trampoline_nop, /* set_boolean_property */ - [106] = trampoline_nop, /* remove_property */ - [107] = trampoline_true, /* create_provider_service */ - [108] = trampoline_true, /* create_product_service */ - [109] = trampoline_true, /* create_pmu_service */ - [110] = trampoline_true, /* create_iomfb_service */ - [111] = trampoline_create_backlight_service, - [116] = dcpep_cb_boot_1, - [117] = trampoline_false, /* is_dark_boot */ - [118] = trampoline_false, /* is_dark_boot / is_waking_from_hibernate*/ - [120] = trampoline_read_edt_data, - [122] = trampoline_prop_start, - [123] = trampoline_prop_chunk, - [124] = trampoline_prop_end, - [201] = trampoline_map_piodma, - [202] = trampoline_unmap_piodma, - [206] = iomfbep_cb_match_pmu_service_2, - [207] = iomfbep_cb_match_backlight_service, - [208] = trampoline_get_time, - [211] = trampoline_nop, /* update_backlight_factor_prop */ - [300] = trampoline_pr_publish, - [401] = trampoline_get_uint_prop, - [404] = trampoline_nop, /* sr_set_uint_prop */ - [406] = trampoline_set_fx_prop, - [408] = trampoline_get_frequency, - [411] = trampoline_map_reg, - [413] = trampoline_true, /* sr_set_property_dict */ - [414] = trampoline_sr_set_property_int, - [415] = trampoline_true, /* sr_set_property_bool */ - [451] = trampoline_allocate_buffer, - [452] = trampoline_map_physical, - [456] = trampoline_release_mem_desc, - [552] = trampoline_true, /* set_property_dict_0 */ - [561] = trampoline_true, /* set_property_dict */ - [563] = trampoline_true, /* set_property_int */ - [565] = trampoline_true, /* set_property_bool */ - [567] = trampoline_true, /* set_property_str */ - [574] = trampoline_zero, /* power_up_dart */ - [576] = trampoline_hotplug, - [577] = trampoline_nop, /* powerstate_notify */ - [582] = trampoline_true, /* create_default_fb_surface */ - [584] = trampoline_nop, /* IOMobileFramebufferAP::clear_default_surface */ - [588] = trampoline_nop, /* resize_default_fb_surface_gated */ - [589] = trampoline_swap_complete, - [591] = trampoline_swap_complete_intent_gated, - [592] = trampoline_abort_swap_ap_gated, - [593] = trampoline_enable_backlight_message_ap_gated, - [594] = trampoline_nop, /* IOMobileFramebufferAP::setSystemConsoleMode */ - [596] = trampoline_false, /* IOMobileFramebufferAP::isDFBAllocated */ - [597] = trampoline_false, /* IOMobileFramebufferAP::preserveContents */ - [598] = trampoline_nop, /* find_swap_function_gated */ -}; - -void DCP_FW_NAME(iomfb_start)(struct apple_dcp *dcp) -{ - dcp->cb_handlers = cb_handlers; - - dcp_start_signal(dcp, false, dcp_started, NULL); -} - -#undef DCP_FW_VER -#undef DCP_FW diff --git a/drivers/gpu/drm/apple/iomfb_v12_3.h b/drivers/gpu/drm/apple/iomfb_v12_3.h deleted file mode 100644 index 7359685d981fe5..00000000000000 --- a/drivers/gpu/drm/apple/iomfb_v12_3.h +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only OR MIT -/* Copyright The Asahi Linux Contributors */ - -#ifndef __APPLE_IOMFB_V12_3_H__ -#define __APPLE_IOMFB_V12_3_H__ - -#include "version_utils.h" - -#define DCP_FW v12_3 -#define DCP_FW_VER DCP_FW_VERSION(12, 3, 0) - -#include "iomfb_template.h" - -#undef DCP_FW_VER -#undef DCP_FW - -#endif /* __APPLE_IOMFB_V12_3_H__ */ diff --git a/drivers/gpu/drm/apple/iomfb_v13_3.c b/drivers/gpu/drm/apple/iomfb_v13_3.c index 0ac869d24eb01b..ceac3fe03bbb0c 100644 --- a/drivers/gpu/drm/apple/iomfb_v13_3.c +++ b/drivers/gpu/drm/apple/iomfb_v13_3.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only OR MIT /* Copyright The Asahi Linux Contributors */ -#include "iomfb_v12_3.h" #include "iomfb_v13_3.h" #include "version_utils.h" diff --git a/drivers/gpu/drm/apple/plane.c b/drivers/gpu/drm/apple/plane.c index 51a6c2dbd7a399..ea9af780dc1c09 100644 --- a/drivers/gpu/drm/apple/plane.c +++ b/drivers/gpu/drm/apple/plane.c @@ -394,37 +394,6 @@ static const u32 dcp_overlay_formats[] = { #endif }; -/* - * Formats for the 12.x firmware which does not support "l10r" / ARGB2101010 - */ -static const u32 dcp_primary_formats_12_x[] = { - DRM_FORMAT_XRGB8888, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_XBGR8888, - DRM_FORMAT_ABGR8888, - DRM_FORMAT_NV12, - DRM_FORMAT_NV16, - DRM_FORMAT_NV24, - DRM_FORMAT_P010, - DRM_FORMAT_P210, -#if defined(DRM_FORMAT_P410) - DRM_FORMAT_P410, -#endif -}; - -static const u32 dcp_overlay_formats_12_x[] = { - DRM_FORMAT_ARGB8888, - DRM_FORMAT_ABGR8888, - DRM_FORMAT_NV12, - DRM_FORMAT_NV16, - DRM_FORMAT_NV24, - DRM_FORMAT_P010, - DRM_FORMAT_P210, -#if defined(DRM_FORMAT_P410) - DRM_FORMAT_P410, -#endif -}; - u64 apple_format_modifiers[] = { DRM_FORMAT_MOD_LINEAR, DRM_FORMAT_MOD_INVALID @@ -433,38 +402,23 @@ u64 apple_format_modifiers[] = { struct drm_plane *apple_plane_init(struct drm_device *dev, unsigned long possible_crtcs, u32 iomfb_surf, - bool supports_l10r, enum drm_plane_type type) { struct apple_plane *plane; - const u32 *fmts; - u32 num_fmts; switch (type) { case DRM_PLANE_TYPE_PRIMARY: - if (supports_l10r) { - fmts = dcp_primary_formats; - num_fmts = ARRAY_SIZE(dcp_primary_formats); - } else { - fmts = dcp_primary_formats_12_x; - num_fmts = ARRAY_SIZE(dcp_primary_formats_12_x); - } - plane = drmm_universal_plane_alloc(dev, struct apple_plane, base, possible_crtcs, - &apple_plane_funcs, fmts, num_fmts, - apple_format_modifiers, type, NULL); + plane = drmm_universal_plane_alloc(dev, struct apple_plane, base, + possible_crtcs, &apple_plane_funcs, + dcp_primary_formats, ARRAY_SIZE(dcp_primary_formats), + apple_format_modifiers, type, NULL); break; case DRM_PLANE_TYPE_OVERLAY: case DRM_PLANE_TYPE_CURSOR: - if (supports_l10r) { - fmts = dcp_overlay_formats; - num_fmts = ARRAY_SIZE(dcp_overlay_formats); - } else { - fmts = dcp_overlay_formats_12_x; - num_fmts = ARRAY_SIZE(dcp_overlay_formats_12_x); - } - plane = drmm_universal_plane_alloc(dev, struct apple_plane, base, possible_crtcs, - &apple_plane_funcs, fmts, num_fmts, - apple_format_modifiers, type, NULL); + plane = drmm_universal_plane_alloc(dev, struct apple_plane, base, + possible_crtcs, &apple_plane_funcs, + dcp_overlay_formats, ARRAY_SIZE(dcp_overlay_formats), + apple_format_modifiers, type, NULL); break; default: return ERR_PTR(-EINVAL); diff --git a/drivers/gpu/drm/apple/plane.h b/drivers/gpu/drm/apple/plane.h index c5db78144d1f87..618cc95c5b8ffc 100644 --- a/drivers/gpu/drm/apple/plane.h +++ b/drivers/gpu/drm/apple/plane.h @@ -32,7 +32,6 @@ struct apple_plane_state { struct drm_plane *apple_plane_init(struct drm_device *dev, unsigned long possible_crtcs, u32 iomfb_surf, - bool supports_l10r, enum drm_plane_type type); #endif /* __APPLE_PLANE_H__ */ diff --git a/drivers/gpu/drm/apple/version_utils.h b/drivers/gpu/drm/apple/version_utils.h index 35f82e6ad56c01..dfa4fff589a269 100644 --- a/drivers/gpu/drm/apple/version_utils.h +++ b/drivers/gpu/drm/apple/version_utils.h @@ -14,7 +14,6 @@ enum dcp_firmware_version { DCP_FIRMWARE_UNKNOWN, - DCP_FIRMWARE_V_12_3, DCP_FIRMWARE_V_13_5, }; From fe010eb40fb950de0d2ea24bb9efc20f79f4e44e Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 12 Jul 2026 23:40:24 +1000 Subject: [PATCH 3/8] WIP: drm: apple: Add 14.7 FW ABI Asahi Linux will target the firmware ABI from macOS 14.8.3 for i/mBoot-loaded firmware on M3 series machines. This version identifies itself as v14.7, so add it as such to the DCP driver. Most things are working, except for EDID retrieval for external displays and audio over HDMI/DisplayPort. There is also an issue where DCP will try to read destroyed/invisible framebuffers for some reason or another, causing IOVA faults. We will need to figure out how to get the new firmware to clear surfaces and stop reading the nonexistent framebuffers at the very least before shipping. Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/Makefile | 1 + drivers/gpu/drm/apple/av.c | 1 + drivers/gpu/drm/apple/dcp-internal.h | 2 + drivers/gpu/drm/apple/dcp.c | 12 +++ drivers/gpu/drm/apple/iomfb.c | 12 +++ drivers/gpu/drm/apple/iomfb.h | 3 +- drivers/gpu/drm/apple/iomfb_template.c | 11 ++- drivers/gpu/drm/apple/iomfb_template.h | 30 ++++++- drivers/gpu/drm/apple/iomfb_v13_3.c | 1 + drivers/gpu/drm/apple/iomfb_v14_7.c | 116 +++++++++++++++++++++++++ drivers/gpu/drm/apple/iomfb_v14_7.h | 17 ++++ drivers/gpu/drm/apple/version_utils.h | 1 + 12 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 drivers/gpu/drm/apple/iomfb_v14_7.c create mode 100644 drivers/gpu/drm/apple/iomfb_v14_7.h diff --git a/drivers/gpu/drm/apple/Makefile b/drivers/gpu/drm/apple/Makefile index a050e1292186ec..578c0ce1c1f192 100644 --- a/drivers/gpu/drm/apple/Makefile +++ b/drivers/gpu/drm/apple/Makefile @@ -9,6 +9,7 @@ appledrm-$(CONFIG_DRM_APPLE_AUDIO) += av.o appledrm-y += connector.o appledrm-y += ibootep.o appledrm-y += iomfb_v13_3.o +appledrm-y += iomfb_v14_7.o appledrm-y += epic/dpavservep.o appledrm-y += plane.o diff --git a/drivers/gpu/drm/apple/av.c b/drivers/gpu/drm/apple/av.c index 2734cdf8a6cb1d..4a951d5800d708 100644 --- a/drivers/gpu/drm/apple/av.c +++ b/drivers/gpu/drm/apple/av.c @@ -379,6 +379,7 @@ int avep_init(struct apple_dcp *dcp) switch (dcp->fw_compat) { case DCP_FIRMWARE_V_13_5: + case DCP_FIRMWARE_V_14_7: audiosrv_data->cmds = dcp_av_audio_cmds_v13_5; break; default: diff --git a/drivers/gpu/drm/apple/dcp-internal.h b/drivers/gpu/drm/apple/dcp-internal.h index fbf40aac06e52d..09da3dbe62fc31 100644 --- a/drivers/gpu/drm/apple/dcp-internal.h +++ b/drivers/gpu/drm/apple/dcp-internal.h @@ -17,6 +17,7 @@ #include "dptxep.h" #include "iomfb.h" #include "iomfb_v13_3.h" +#include "iomfb_v14_7.h" #include "epic/dpavservep.h" #include "version_utils.h" @@ -171,6 +172,7 @@ struct apple_dcp { /* Queued swap. Owned by the DCP to avoid per-swap memory allocation */ union { struct dcp_swap_submit_req_v13_3 v13_3; + struct dcp_swap_submit_req_v14_7_0 v14_7_0; } swap; /* swap id of the last completed swap */ diff --git a/drivers/gpu/drm/apple/dcp.c b/drivers/gpu/drm/apple/dcp.c index fef8a802f07709..f6f1835b92ae2c 100644 --- a/drivers/gpu/drm/apple/dcp.c +++ b/drivers/gpu/drm/apple/dcp.c @@ -570,6 +570,9 @@ static void _dcp_poweroff(struct apple_dcp *dcp) case DCP_FIRMWARE_V_13_5: iomfb_poweroff_v13_3(dcp); break; + case DCP_FIRMWARE_V_14_7: + iomfb_poweroff_v14_7_0(dcp); + break; default: WARN_ONCE(true, "Unexpected firmware version: %u\n", dcp->fw_compat); break; @@ -626,6 +629,9 @@ static void __maybe_unused dcp_sleep(struct apple_dcp *dcp) case DCP_FIRMWARE_V_13_5: iomfb_sleep_v13_3(dcp); break; + case DCP_FIRMWARE_V_14_7: + iomfb_sleep_v14_7_0(dcp); + break; default: WARN_ONCE(true, "Unexpected firmware version: %u\n", dcp->fw_compat); break; @@ -648,6 +654,9 @@ void dcp_poweron(struct platform_device *pdev) case DCP_FIRMWARE_V_13_5: iomfb_poweron_v13_3(dcp); break; + case DCP_FIRMWARE_V_14_7: + iomfb_poweron_v14_7_0(dcp); + break; default: WARN_ONCE(true, "Unexpected firmware version: %u\n", dcp->fw_compat); break; @@ -945,6 +954,9 @@ static enum dcp_firmware_version dcp_check_firmware_version(struct device *dev) return DCP_FIRMWARE_V_13_5; else if (strncmp(compat_str, "13.5.0", sizeof(compat_str)) == 0) return DCP_FIRMWARE_V_13_5; + else if (strncmp(compat_str, "14.7.0", sizeof(compat_str)) == 0 && + (strncmp(fw_str, "14.7.0", sizeof(compat_str)) == 0)) + return DCP_FIRMWARE_V_14_7; dev_err(dev, "DCP firmware-compat %s (FW: %s) is not supported\n", compat_str, fw_str); diff --git a/drivers/gpu/drm/apple/iomfb.c b/drivers/gpu/drm/apple/iomfb.c index 18a35cd7077065..1eb71c1d85eaaf 100644 --- a/drivers/gpu/drm/apple/iomfb.c +++ b/drivers/gpu/drm/apple/iomfb.c @@ -433,6 +433,9 @@ int dcp_crtc_atomic_modeset(struct drm_crtc *crtc, case DCP_FIRMWARE_V_13_5: ret = iomfb_modeset_v13_3(dcp, crtc_state); break; + case DCP_FIRMWARE_V_14_7: + ret = iomfb_modeset_v14_7_0(dcp, crtc_state); + break; default: WARN_ONCE(true, "Unexpected firmware version: %u\n", dcp->fw_compat); @@ -479,6 +482,9 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) case DCP_FIRMWARE_V_13_5: iomfb_flush_v13_3(dcp, crtc, state); break; + case DCP_FIRMWARE_V_14_7: + iomfb_flush_v14_7_0(dcp, crtc, state); + break; default: WARN_ONCE(true, "Unexpected firmware version: %u\n", dcp->fw_compat); break; @@ -491,6 +497,9 @@ static void iomfb_start(struct apple_dcp *dcp) case DCP_FIRMWARE_V_13_5: iomfb_start_v13_3(dcp); break; + case DCP_FIRMWARE_V_14_7: + iomfb_start_v14_7_0(dcp); + break; default: WARN_ONCE(true, "Unexpected firmware version: %u\n", dcp->fw_compat); break; @@ -539,6 +548,9 @@ void iomfb_shutdown(struct apple_dcp *dcp) case DCP_FIRMWARE_V_13_5: iomfb_shutdown_v13_3(dcp); break; + case DCP_FIRMWARE_V_14_7: + iomfb_shutdown_v14_7_0(dcp); + break; default: WARN_ONCE(true, "Unexpected firmware version: %u\n", dcp->fw_compat); break; diff --git a/drivers/gpu/drm/apple/iomfb.h b/drivers/gpu/drm/apple/iomfb.h index 7903fad4040677..531089dab63134 100644 --- a/drivers/gpu/drm/apple/iomfb.h +++ b/drivers/gpu/drm/apple/iomfb.h @@ -78,7 +78,8 @@ struct dcp_packet_header { #define DCP_PACKET_ALIGNMENT (0x40) enum iomfb_property_id { - IOMFB_PROPERTY_NITS = 15, // divide by Brightness_Scale + IOMFB_PROPERTY_NITS_V13_3 = 15, // divide by Brightness_Scale + IOMFB_PROPERTY_NITS_V14_7 = 19, }; #define IOMFB_BRIGHTNESS_MIN 0x10000000 diff --git a/drivers/gpu/drm/apple/iomfb_template.c b/drivers/gpu/drm/apple/iomfb_template.c index cf40e273a2f43c..6721311f55ac23 100644 --- a/drivers/gpu/drm/apple/iomfb_template.c +++ b/drivers/gpu/drm/apple/iomfb_template.c @@ -200,7 +200,8 @@ static bool iomfbep_cb_match_backlight_service(struct apple_dcp *dcp, int tag, v static void iomfb_cb_pr_publish(struct apple_dcp *dcp, struct iomfb_property *prop) { switch (prop->id) { - case IOMFB_PROPERTY_NITS: + case IOMFB_PROPERTY_NITS_V13_3: + case IOMFB_PROPERTY_NITS_V14_7: { if (dcp_has_panel(dcp)) { dcp->brightness.nits = prop->value / dcp->brightness.scale; @@ -909,7 +910,11 @@ void DCP_FW_NAME(iomfb_poweroff)(struct apple_dcp *dcp) * brightness. */ if (dcp_has_panel(dcp)) { +#if DCP_FW_VER < DCP_FW_VERSION(14, 7, 0) swap->swap.bl_unk = 1; +#else + swap->swap.bl_update = 1; +#endif swap->swap.bl_value = 0; swap->swap.bl_power = 0; } @@ -1394,7 +1399,11 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru /* update brightness if changed */ if (dcp_has_panel(dcp) && dcp->brightness.update) { +#if DCP_FW_VER >= DCP_FW_VERSION(14, 7, 0) + req->swap.bl_update = 1; +#else req->swap.bl_unk = 1; +#endif req->swap.bl_value = dcp->brightness.dac; req->swap.bl_power = 0x40; dcp->brightness.update = false; diff --git a/drivers/gpu/drm/apple/iomfb_template.h b/drivers/gpu/drm/apple/iomfb_template.h index 8efab49cc53d08..49bab7c53c6e23 100644 --- a/drivers/gpu/drm/apple/iomfb_template.h +++ b/drivers/gpu/drm/apple/iomfb_template.h @@ -30,7 +30,9 @@ struct DCP_FW_NAME(dcp_swap) { u64 flags1; u64 flags2; - +#if DCP_FW_VER >= DCP_FW_VERSION(14, 7, 0) + u8 unk_v14_7[0x48]; +#endif u32 swap_id; u32 surf_ids[SWAP_SURFACES]; @@ -42,22 +44,39 @@ struct DCP_FW_NAME(dcp_swap) { u32 swap_completed; u32 bg_color; - u8 unk_110[0x1b8]; + u8 unk_110[0x30]; + u32 active_region_en[SWAP_SURFACES]; + struct dcp_rect active_regions[SWAP_SURFACES]; + u8 unk_190[0x138]; u32 unk_2c8; +#if DCP_FW_VER < DCP_FW_VERSION(14, 7, 0) u8 unk_2cc[0x14]; +#else + u8 unk_2cc[0x40]; +#endif +#if DCP_FW_VER < DCP_FW_VERSION(14, 7, 0) u32 unk_2e0; +#else + u32 bl_update; +#endif #if DCP_FW_VER < DCP_FW_VERSION(13, 2, 0) u16 unk_2e2; #else u8 unk_2e2[3]; #endif +#if DCP_FW_VER < DCP_FW_VERSION(14, 7 ,0) u64 bl_unk; +#else + u32 bl_unk; +#endif u32 bl_value; // min value is 0x10000000 u8 bl_power; // constant 0x40 for on u8 unk_2f3[0x2d]; #if DCP_FW_VER >= DCP_FW_VERSION(13, 2, 0) - u8 unk_320[0x13f]; - u64 unk_1; + u8 unk_320[0x147]; +#if DCP_FW_VER >= DCP_FW_VERSION(14, 7, 0) + u8 unk_14_7_2[0x30]; +#endif #endif } __packed; @@ -103,6 +122,9 @@ struct DCP_FW_NAME(dcp_swap_submit_req) { u8 unkU32out_null; #endif u8 padding[1]; +#if DCP_FW_VER >= DCP_FW_VERSION(14, 7, 0) + u8 padding_14_7[0x234]; +#endif } __packed; struct DCP_FW_NAME(dcp_swap_submit_resp) { diff --git a/drivers/gpu/drm/apple/iomfb_v13_3.c b/drivers/gpu/drm/apple/iomfb_v13_3.c index ceac3fe03bbb0c..24eac902173f75 100644 --- a/drivers/gpu/drm/apple/iomfb_v13_3.c +++ b/drivers/gpu/drm/apple/iomfb_v13_3.c @@ -2,6 +2,7 @@ /* Copyright The Asahi Linux Contributors */ #include "iomfb_v13_3.h" +#include "iomfb_v14_7.h" #include "version_utils.h" static const struct dcp_method_entry dcp_methods[dcpep_num_methods] = { diff --git a/drivers/gpu/drm/apple/iomfb_v14_7.c b/drivers/gpu/drm/apple/iomfb_v14_7.c new file mode 100644 index 00000000000000..6d26622036fdbb --- /dev/null +++ b/drivers/gpu/drm/apple/iomfb_v14_7.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* Copyright The Asahi Linux Contributors */ + +#include "iomfb_v13_3.h" +#include "iomfb_v14_7.h" +#include "version_utils.h" + +static const struct dcp_method_entry dcp_methods[dcpep_num_methods] = { + IOMFB_METHOD("A000", dcpep_late_init_signal), + IOMFB_METHOD("A029", dcpep_setup_video_limits), + IOMFB_METHOD("A131", iomfbep_a131_pmu_service_matched), + IOMFB_METHOD("A132", iomfbep_a132_backlight_service_matched), + IOMFB_METHOD("A377", dcpep_set_create_dfb), + IOMFB_METHOD("A378", iomfbep_a358_vi_set_temperature_hint), + IOMFB_METHOD("A401", dcpep_start_signal), + IOMFB_METHOD("A406", dcpep_swap_start), + IOMFB_METHOD("A407", dcpep_swap_submit), + IOMFB_METHOD("A409", dcpep_set_display_device), + IOMFB_METHOD("A410", dcpep_is_main_display), + IOMFB_METHOD("A411", dcpep_set_digital_out_mode), + IOMFB_METHOD("A421", iomfbep_set_matrix), + IOMFB_METHOD("A425", iomfbep_get_color_remap_mode), + IOMFB_METHOD("A440", dcpep_set_parameter_dcp), + IOMFB_METHOD("A444", dcpep_create_default_fb), + IOMFB_METHOD("A443", dcpep_enable_disable_video_power_savings), + IOMFB_METHOD("A455", dcpep_first_client_open), + IOMFB_METHOD("A457", iomfbep_last_client_close), + IOMFB_METHOD("A463", dcpep_set_display_refresh_properties), + IOMFB_METHOD("A466", dcpep_flush_supports_power), + IOMFB_METHOD("A467", iomfbep_abort_swaps_dcp), + //IOMFB_METHOD("A471", dcpep_update_dfb_surface), + IOMFB_METHOD("A472", dcpep_set_power_state), +}; + +#define DCP_FW v14_7_0 +#define DCP_FW_VER DCP_FW_VERSION(14, 7, 0) + +#include "iomfb_template.c" + +static const iomfb_cb_handler cb_handlers[IOMFB_MAX_CB] = { + [0] = trampoline_true, /* did_boot_signal */ + [1] = trampoline_true, /* did_power_on_signal */ + [2] = trampoline_nop, /* will_power_off_signal */ + [3] = trampoline_rt_bandwidth, + // [6] = trampoline_set_frame_sync_props, + [6] = trampoline_nop, + [100] = iomfbep_cb_match_pmu_service, + [101] = trampoline_zero, /* get_display_default_stride */ + [102] = trampoline_nop, /* set_number_property */ + [103] = trampoline_nop, /* trigger_user_cal_loader */ + [104] = trampoline_nop, /* set_boolean_property */ + [107] = trampoline_nop, /* remove_property */ + [108] = trampoline_true, /* create_provider_service */ + [109] = trampoline_true, /* create_product_service */ + [110] = trampoline_true, /* create_pmu_service */ + [111] = trampoline_true, /* create_iomfb_service */ + [112] = trampoline_create_backlight_service, + [113] = trampoline_true, /* create_nvram_service? */ + //[114] = trampoline_get_tiling_state, + //[115] = trampoline_false, /* set_tiling_state */ + [121] = dcpep_cb_boot_1, /* is_dark_boot */ + [122] = trampoline_false, /* is_dark_boot / is_waking_from_hibernate*/ + [123] = trampoline_false, + [125] = trampoline_read_edt_data, + [127] = trampoline_prop_start, + [128] = trampoline_prop_chunk, + [129] = trampoline_prop_end, + // [129] = trampoline_allocate_bandwidth, + [201] = trampoline_map_piodma, + [202] = trampoline_unmap_piodma, + [206] = iomfbep_cb_match_pmu_service_2, + [207] = iomfbep_cb_match_backlight_service, + [208] = trampoline_nop, /* update_backlight_factor_prop */ + [209] = trampoline_get_time, + [300] = trampoline_pr_publish, + [401] = trampoline_get_uint_prop, + [404] = trampoline_nop, /* sr_set_uint_prop */ + [406] = trampoline_set_fx_prop, + [408] = trampoline_get_frequency, + [411] = trampoline_map_reg, + [413] = trampoline_true, /* sr_set_property_dict */ + [414] = trampoline_sr_set_property_int, + [415] = trampoline_true, /* sr_set_property_bool */ + [451] = trampoline_allocate_buffer, + [452] = trampoline_map_physical, + [454] = trampoline_release_mem_desc, + [552] = trampoline_true, /* set_property_dict_0 */ + [561] = trampoline_true, /* set_property_dict */ + [563] = trampoline_true, /* set_property_int */ + [565] = trampoline_true, /* set_property_bool */ + [567] = trampoline_true, /* set_property_str */ + [574] = trampoline_zero, /* power_up_dart */ + [576] = trampoline_hotplug, + [577] = trampoline_nop, /* powerstate_notify */ + //[582] = trampoline_create_dfb_surface, /* create_default_fb_surface */ + [582] = trampoline_true, + [584] = trampoline_nop, /* IOMobileFramebufferAP::clear_default_surface */ + [588] = trampoline_nop, /* resize_default_fb_surface_gated */ + [589] = trampoline_swap_complete, + [591] = trampoline_swap_complete_intent_gated, + [592] = trampoline_abort_swap_ap_gated, + [593] = trampoline_enable_backlight_message_ap_gated, + [594] = trampoline_nop, /* IOMobileFramebufferAP::setSystemConsoleMode */ + [596] = trampoline_false, /* IOMobileFramebufferAP::isDFBAllocated */ + [597] = trampoline_false, /* IOMobileFramebufferAP::preserveContents */ + [598] = trampoline_nop, /* find_swap_function_gated */ +}; +void DCP_FW_NAME(iomfb_start)(struct apple_dcp *dcp) +{ + dcp->cb_handlers = cb_handlers; + + dcp_start_signal(dcp, false, dcp_started, NULL); +} + +#undef DCP_FW_VER +#undef DCP_FW diff --git a/drivers/gpu/drm/apple/iomfb_v14_7.h b/drivers/gpu/drm/apple/iomfb_v14_7.h new file mode 100644 index 00000000000000..7fd9b47fd372bc --- /dev/null +++ b/drivers/gpu/drm/apple/iomfb_v14_7.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* Copyright The Asahi Linux Contributors */ + +#ifndef __APPLE_IOMFB_V14_7_H__ +#define __APPLE_IOMFB_V14_7_H__ + +#include "version_utils.h" + +#define DCP_FW v14_7_0 +#define DCP_FW_VER DCP_FW_VERSION(14, 7, 0) + +#include "iomfb_template.h" + +#undef DCP_FW_VER +#undef DCP_FW + +#endif /* __APPLE_IOMFB_V14_7_H__ */ diff --git a/drivers/gpu/drm/apple/version_utils.h b/drivers/gpu/drm/apple/version_utils.h index dfa4fff589a269..542a5e9570866b 100644 --- a/drivers/gpu/drm/apple/version_utils.h +++ b/drivers/gpu/drm/apple/version_utils.h @@ -15,6 +15,7 @@ enum dcp_firmware_version { DCP_FIRMWARE_UNKNOWN, DCP_FIRMWARE_V_13_5, + DCP_FIRMWARE_V_14_7, }; #endif /*__APPLE_VERSION_UTILS_H__*/ From 08fca0bd992c0bc1e3112931b73cdfd67ee25086 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 19 Jul 2026 20:24:58 +1000 Subject: [PATCH 4/8] drm: apple: properly define plane and compression parameters Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/iomfb_plane.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/apple/iomfb_plane.h b/drivers/gpu/drm/apple/iomfb_plane.h index 0701978200311a..73f104059d29cc 100644 --- a/drivers/gpu/drm/apple/iomfb_plane.h +++ b/drivers/gpu/drm/apple/iomfb_plane.h @@ -67,7 +67,9 @@ struct dcp_plane_info { u16 tile_size; u8 tile_w; u8 tile_h; - u32 unk[13]; + u8 unk[0xd]; + u8 unk2; + u8 unk3[0x26]; } __packed; struct dcp_component_types { @@ -75,6 +77,23 @@ struct dcp_component_types { u8 types[7]; } __packed; +struct dcp_compression_info { + u32 tile_w; + u32 tile_h; + u32 metadata_offset; + u32 data_offset; + u32 meta_bytes; + u32 tiles_w; + u32 tiles_h; + u32 unk_1; + u32 compression_type; + u32 unk3; + u8 padding[3]; + u32 tile_bytes; + u32 row_stride; + u8 pad2; +} __packed; + /* Information describing a surface */ struct dcp_surface { u8 is_tiled; @@ -100,7 +119,7 @@ struct dcp_surface { u64 has_comp; struct dcp_plane_info planes[DCP_SURF_MAX_PLANES]; u64 has_planes; - u32 compression_info[DCP_SURF_MAX_PLANES][13]; + struct dcp_compression_info compression_info[DCP_SURF_MAX_PLANES]; u64 has_compr_info; u32 unk_num; u32 unk_denom; From 906ef0929851139860fa9bd3234a2691b13e112b Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 26 Jul 2026 09:06:39 +1000 Subject: [PATCH 5/8] drm: apple: Expose two flag fields at the end of IOMFBSwapRec Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/iomfb_template.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/apple/iomfb_template.h b/drivers/gpu/drm/apple/iomfb_template.h index 49bab7c53c6e23..c08d31b177c822 100644 --- a/drivers/gpu/drm/apple/iomfb_template.h +++ b/drivers/gpu/drm/apple/iomfb_template.h @@ -73,10 +73,12 @@ struct DCP_FW_NAME(dcp_swap) { u8 bl_power; // constant 0x40 for on u8 unk_2f3[0x2d]; #if DCP_FW_VER >= DCP_FW_VERSION(13, 2, 0) - u8 unk_320[0x147]; + u8 unk_320[0x13f]; #if DCP_FW_VER >= DCP_FW_VERSION(14, 7, 0) u8 unk_14_7_2[0x30]; #endif + u32 unk_flags; + u32 unk_flags2; #endif } __packed; From df5345589e368be05ae267217302af116099d6f7 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 26 Jul 2026 09:09:52 +1000 Subject: [PATCH 6/8] drm: apple: Pass plane ID as IOSurface ID Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/iomfb_template.c | 2 ++ drivers/gpu/drm/apple/plane.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/apple/iomfb_template.c b/drivers/gpu/drm/apple/iomfb_template.c index 6721311f55ac23..1fb8d838526eec 100644 --- a/drivers/gpu/drm/apple/iomfb_template.c +++ b/drivers/gpu/drm/apple/iomfb_template.c @@ -1355,6 +1355,8 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru req->swap.src_rect[l] = apple_state->src_rect; req->swap.dst_rect[l] = apple_state->dst_rect; + req->swap.surf_ids[apl_plane->iomfb_surf] = plane->base.id; + if (dcp->notch_height > 0) req->swap.dst_rect[l].y += dcp->notch_height; diff --git a/drivers/gpu/drm/apple/plane.c b/drivers/gpu/drm/apple/plane.c index ea9af780dc1c09..a6d7205bba5850 100644 --- a/drivers/gpu/drm/apple/plane.c +++ b/drivers/gpu/drm/apple/plane.c @@ -249,7 +249,7 @@ static void apple_plane_atomic_update(struct drm_plane *plane, .width = fb->width, .height = fb->height, .buf_size = fb->height * fb->pitches[0], - // .surface_id = req->swap.surf_ids[l], + .surface_id = plane->base.id, /* Only used for compressed or multiplanar surfaces */ .pix_size = 1, From 8e8473088b1bc28fb9aaf665e6954da033c5d4cc Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 26 Jul 2026 20:04:50 +1000 Subject: [PATCH 7/8] HACK: drm: apple: do not destroy stale framebuffer references Because we have not yet figured out how to clear surfaces, freeing old framebuffer references crashes DCP with IOVA errors. Don't destroy them for now so that we can continue working. Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/iomfb_template.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/apple/iomfb_template.c b/drivers/gpu/drm/apple/iomfb_template.c index 1fb8d838526eec..74386d0d213793 100644 --- a/drivers/gpu/drm/apple/iomfb_template.c +++ b/drivers/gpu/drm/apple/iomfb_template.c @@ -739,6 +739,8 @@ static void dcp_swap_cleared(struct apple_dcp *dcp, void *data, void *cookie) return; } + /* TODO: Figure out how to clear surfaces for 14.x */ +#if DCP_FW_VER < DCP_FW_VERSION(14, 7, 0) while (!list_empty(&dcp->swapped_out_fbs)) { struct dcp_fb_reference *entry; entry = list_first_entry(&dcp->swapped_out_fbs, @@ -750,6 +752,7 @@ static void dcp_swap_cleared(struct apple_dcp *dcp, void *data, void *cookie) list_del(&entry->head); kfree(entry); } +#endif } static void dcp_swap_clear_started(struct apple_dcp *dcp, void *data, @@ -1150,6 +1153,8 @@ static void dcp_swapped(struct apple_dcp *dcp, void *data, void *cookie) } dcp->swap_start = ktime_get(); + /* TODO: Figure out how to clear surfaces on 14.x */ +#if DCP_FW_VER < DCP_FW_VERSION(14, 7, 0) while (!list_empty(&dcp->swapped_out_fbs)) { struct dcp_fb_reference *entry; entry = list_first_entry(&dcp->swapped_out_fbs, @@ -1161,6 +1166,7 @@ static void dcp_swapped(struct apple_dcp *dcp, void *data, void *cookie) list_del(&entry->head); kfree(entry); } +#endif } static void dcp_swap_started(struct apple_dcp *dcp, void *data, void *cookie) From ab2252fab98dc5c68bbef4891109d13d0400a496 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sat, 1 Aug 2026 23:34:22 +1000 Subject: [PATCH 8/8] drm: apple: split out unknown 14.7 region Some of this is 0xaa padding, some of it is zeroes, and there is a conspicuous empty byte at the end. Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/iomfb_template.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/apple/iomfb_template.h b/drivers/gpu/drm/apple/iomfb_template.h index c08d31b177c822..87204bc43b1e4e 100644 --- a/drivers/gpu/drm/apple/iomfb_template.h +++ b/drivers/gpu/drm/apple/iomfb_template.h @@ -125,7 +125,10 @@ struct DCP_FW_NAME(dcp_swap_submit_req) { #endif u8 padding[1]; #if DCP_FW_VER >= DCP_FW_VERSION(14, 7, 0) - u8 padding_14_7[0x234]; + u8 padding_14_7[0x1e9]; + u8 unk_14_7_zero[0x46]; + u32 unk_14_7_u32; + u8 unk_bool; #endif } __packed;