From b81eac581a326dc92862813d984fa8fb7de21840 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 19 Jun 2026 20:20:35 +1000 Subject: [PATCH 01/14] drm: apple: Handle differences in surface positions between SoCs DCP is an interesting little bit of hardware. Each variant has quite different scanout capabilities, including which hardware planes are actually present. The firmware interface will always accept four IOSurface structs, however the hardware will fail in weird and wonderful ways if the firmware then tries to program the corresponding scanout planes when they do not actually work. We need a way to declare to KMS which hardware planes actually work on which SoCs. Add an array to the Devicetree node representing the working hardware surfaces (relative to the four possible IOSurfaces), and use this to decide which KMS planes get created at driver init. Since we now guarantee that every instantiated DRM plane corresponds to a valid hardware surface, we can remove some superfluous sanity checks in crtc_atomic_check too. Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/apple_drv.c | 36 +++++++++++--------------- drivers/gpu/drm/apple/dcp-internal.h | 2 ++ drivers/gpu/drm/apple/dcp.c | 21 ++++----------- drivers/gpu/drm/apple/iomfb.h | 2 -- drivers/gpu/drm/apple/iomfb_template.c | 33 +++++++---------------- drivers/gpu/drm/apple/plane.c | 8 ++---- drivers/gpu/drm/apple/plane.h | 9 ++++++- 7 files changed, 42 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/apple/apple_drv.c b/drivers/gpu/drm/apple/apple_drv.c index 0f36dad6f96351..f4a1a06a98f622 100644 --- a/drivers/gpu/drm/apple/apple_drv.c +++ b/drivers/gpu/drm/apple/apple_drv.c @@ -272,31 +272,25 @@ static int apple_probe_per_dcp(struct device *dev, struct apple_crtc *crtc; struct apple_connector *connector; struct apple_encoder *enc; - struct drm_plane *planes[DCP_MAX_PLANES]; + struct apple_plane *planes[DCP_MAX_PLANES]; + struct apple_dcp *drv = platform_get_drvdata(dcp); int ret, i; - int immutable_zpos = 0; + int zpos = 0; bool supports_l10r = !dcp_fw_compat_is_12_x(dcp); - planes[0] = apple_plane_init(drm, 1U << num, supports_l10r, - DRM_PLANE_TYPE_PRIMARY); - if (IS_ERR(planes[0])) - return PTR_ERR(planes[0]); - ret = drm_plane_create_zpos_immutable_property(planes[0], immutable_zpos); - if (ret) { - return ret; - } + for (i = 0; i < DCP_MAX_PLANES; i++) { + if (drv->iomfb_surfaces[i]) { + planes[zpos] = apple_plane_init(drm, 1U << num, supports_l10r, + zpos ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY); + if (IS_ERR(planes[zpos])) + return PTR_ERR(planes[zpos]); + ret = drm_plane_create_zpos_immutable_property(&planes[zpos]->base, zpos); + if (ret) + return ret; - /* Set up our other planes */ - for (i = 1; i < DCP_MAX_PLANES; i++) { - planes[i] = apple_plane_init(drm, 1U << num, supports_l10r, - DRM_PLANE_TYPE_OVERLAY); - if (IS_ERR(planes[i])) - return PTR_ERR(planes[i]); - immutable_zpos++; - ret = drm_plane_create_zpos_immutable_property(planes[i], immutable_zpos); - if (ret) { - return ret; + planes[zpos]->iomfb_surf = i; + zpos++; } } @@ -307,7 +301,7 @@ static int apple_probe_per_dcp(struct device *dev, * knows what to do with overlays. */ crtc = kzalloc(sizeof(*crtc), GFP_KERNEL); - ret = drm_crtc_init_with_planes(drm, &crtc->base, planes[0], NULL, + ret = drm_crtc_init_with_planes(drm, &crtc->base, &planes[0]->base, NULL, &apple_crtc_funcs, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/apple/dcp-internal.h b/drivers/gpu/drm/apple/dcp-internal.h index f2eb2483c9a880..04ec57bd570fb2 100644 --- a/drivers/gpu/drm/apple/dcp-internal.h +++ b/drivers/gpu/drm/apple/dcp-internal.h @@ -138,6 +138,8 @@ struct apple_dcp { * sense to keep some of the members in apple_dcp. * **********************************************************************/ + u32 iomfb_surfaces[DCP_MAX_PLANES]; + /* clock rate request by dcp in */ struct clk *clk; diff --git a/drivers/gpu/drm/apple/dcp.c b/drivers/gpu/drm/apple/dcp.c index 9dfc3fd002f530..27a544a3ce3519 100644 --- a/drivers/gpu/drm/apple/dcp.c +++ b/drivers/gpu/drm/apple/dcp.c @@ -331,10 +331,7 @@ int dcp_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { struct platform_device *pdev = to_apple_crtc(crtc)->dcp; struct apple_dcp *dcp = platform_get_drvdata(pdev); - struct drm_plane_state *new_state; - struct drm_plane *plane; struct drm_crtc_state *crtc_state; - int plane_idx, plane_count = 0; bool needs_modeset; if (dcp->crashed) @@ -348,19 +345,6 @@ int dcp_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) return -EINVAL; } - for_each_new_plane_in_state(state, plane, new_state, plane_idx) { - /* skip planes not for this crtc */ - if (new_state->crtc != crtc) - continue; - - plane_count += 1; - } - - if (plane_count > DCP_MAX_PLANES) { - dev_err(dcp->dev, "crtc_atomic_check: Blend supports only 2 layers!\n"); - return -EINVAL; - } - return 0; } @@ -1194,6 +1178,11 @@ static int dcp_platform_probe(struct platform_device *pdev) dev_err(dev, "Failed to get dp-phy: %ld\n", PTR_ERR(dcp->phy)); return PTR_ERR(dcp->phy); } + + if (of_property_read_u32_array(dev->of_node, "apple,iomfb-surfaces", + (u32 *)&dcp->iomfb_surfaces, DCP_MAX_PLANES)) + dcp->iomfb_surfaces[0] = 1; + if (dcp->phy) { int ret; /* diff --git a/drivers/gpu/drm/apple/iomfb.h b/drivers/gpu/drm/apple/iomfb.h index 8a871db0b94a70..7903fad4040677 100644 --- a/drivers/gpu/drm/apple/iomfb.h +++ b/drivers/gpu/drm/apple/iomfb.h @@ -86,8 +86,6 @@ enum iomfb_property_id { /* Structures used in v12.0 firmware */ #define SWAP_SURFACES 4 -/* We have 4 surfaces, but we can only ever blend two */ -#define MAX_BLEND_SURFACES 2 struct dcp_iouserclient { /* Handle for the IOUserClient. macOS sets this to a kernel VA. */ diff --git a/drivers/gpu/drm/apple/iomfb_template.c b/drivers/gpu/drm/apple/iomfb_template.c index 553134aad80c9c..61d8b0c4e8c2b5 100644 --- a/drivers/gpu/drm/apple/iomfb_template.c +++ b/drivers/gpu/drm/apple/iomfb_template.c @@ -1311,26 +1311,13 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru for_each_oldnew_plane_in_state(state, plane, old_state, new_state, plane_idx) { struct apple_plane_state *apple_state = to_apple_plane_state(new_state); + struct apple_plane *apl_plane = to_apple_plane(plane); /* skip planes not for this crtc */ if (old_state->crtc != crtc && new_state->crtc != crtc) continue; - /* - * Plane order is nondeterministic for this iterator. DCP will - * almost always crash at some point if the z order of planes - * flip-flops around. Make sure we are always blending them - * in the correct order. - * - * Despite having 4 surfaces, we can only blend two. Surface 0 is - * also unusable on some machines, so ignore it. - */ - - l = MAX_BLEND_SURFACES - new_state->normalized_zpos; - - WARN_ON(l > MAX_BLEND_SURFACES); - - req->swap.swap_enabled |= BIT(l); + req->swap.swap_enabled |= BIT(apl_plane->iomfb_surf); if (old_state->fb && new_state->fb != old_state->fb) { /* @@ -1356,17 +1343,17 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru if (!new_state->fb || !new_state->visible) { continue; } - req->surf_null[l] = false; + req->surf_null[apl_plane->iomfb_surf] = false; has_surface = 1; - req->swap.src_rect[l] = apple_state->src_rect; - req->swap.dst_rect[l] = apple_state->dst_rect; + req->swap.src_rect[apl_plane->iomfb_surf] = apple_state->src_rect; + req->swap.dst_rect[apl_plane->iomfb_surf] = apple_state->dst_rect; if (dcp->notch_height > 0) - req->swap.dst_rect[l].y += dcp->notch_height; + req->swap.dst_rect[apl_plane->iomfb_surf].y += dcp->notch_height; - req->surf_iova[l] = apple_state->iova; - req->surf[l].base = apple_state->surf; + req->surf_iova[apl_plane->iomfb_surf] = apple_state->iova; + req->surf[apl_plane->iomfb_surf].base = apple_state->surf; /* Use sRGB colorspace only for internal panels. External * displays are expected to have EDID and user space can use @@ -1374,8 +1361,8 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru * colors. */ if (dcp->connector_type == DRM_MODE_CONNECTOR_eDP && - req->surf[l].base.colorspace == DCP_COLORSPACE_BG_SRGB) - req->surf[l].base.colorspace = DCP_COLORSPACE_NATIVE; + req->surf[apl_plane->iomfb_surf].base.colorspace == DCP_COLORSPACE_BG_SRGB) + req->surf[apl_plane->iomfb_surf].base.colorspace = DCP_COLORSPACE_NATIVE; } if (!has_surface && !crtc_state->color_mgmt_changed) { diff --git a/drivers/gpu/drm/apple/plane.c b/drivers/gpu/drm/apple/plane.c index 2f0b76ad84ad65..8654532f4afa30 100644 --- a/drivers/gpu/drm/apple/plane.c +++ b/drivers/gpu/drm/apple/plane.c @@ -430,11 +430,7 @@ u64 apple_format_modifiers[] = { DRM_FORMAT_MOD_INVALID }; -struct apple_plane { - struct drm_plane base; -}; - -struct drm_plane *apple_plane_init(struct drm_device *dev, +struct apple_plane *apple_plane_init(struct drm_device *dev, unsigned long possible_crtcs, bool supports_l10r, enum drm_plane_type type) @@ -487,5 +483,5 @@ struct drm_plane *apple_plane_init(struct drm_device *dev, else drm_plane_helper_add(&plane->base, &apple_plane_helper_funcs); - return &plane->base; + return plane; } diff --git a/drivers/gpu/drm/apple/plane.h b/drivers/gpu/drm/apple/plane.h index 67d15938cf0dcb..c0c28627a61042 100644 --- a/drivers/gpu/drm/apple/plane.h +++ b/drivers/gpu/drm/apple/plane.h @@ -12,6 +12,13 @@ #include "iomfb_plane.h" +struct apple_plane { + struct drm_plane base; + u8 iomfb_surf; +}; + +#define to_apple_plane(x) container_of(x, struct apple_plane, base) + struct apple_plane_state { struct drm_plane_state base; struct dcp_surface surf; @@ -22,7 +29,7 @@ struct apple_plane_state { #define to_apple_plane_state(x) container_of(x, struct apple_plane_state, base) -struct drm_plane *apple_plane_init(struct drm_device *dev, +struct apple_plane *apple_plane_init(struct drm_device *dev, unsigned long possible_crtcs, bool supports_l10r, enum drm_plane_type type); From c0cf891f4f01ac5997d860d03852a70b07b52dc9 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 19 Jun 2026 20:27:17 +1000 Subject: [PATCH 02/14] arm64: dts: apple: t602x: add apple,iomfb-surfaces to DCP nodes All T602x DCPs support simultaneous scanout on surfaces 0, 1, and 3. Signed-off-by: James Calligeros --- arch/arm64/boot/dts/apple/t602x-die0.dtsi | 1 + arch/arm64/boot/dts/apple/t602x-dieX.dtsi | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t602x-die0.dtsi b/arch/arm64/boot/dts/apple/t602x-die0.dtsi index 8938dd90693c4d..852b33a88b8136 100644 --- a/arch/arm64/boot/dts/apple/t602x-die0.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-die0.dtsi @@ -624,6 +624,7 @@ <0x3 0x89344000 0x0 0x4000>, <0x3 0x89800000 0x0 0x800000>; apple,bw-scratch = <&pmgr_dcp 0 4 0x1208>; + apple,iomfb-surfaces = <1 1 0 1>; #ifdef APPLE_USE_PMP power-domains = <&pmp_report_disp0>; #else diff --git a/arch/arm64/boot/dts/apple/t602x-dieX.dtsi b/arch/arm64/boot/dts/apple/t602x-dieX.dtsi index d916c0b106d109..13eb09067c4109 100644 --- a/arch/arm64/boot/dts/apple/t602x-dieX.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-dieX.dtsi @@ -102,6 +102,7 @@ <0x2 0x89344000 0x0 0x4000>, <0x2 0x89800000 0x0 0x800000>; apple,bw-scratch = <&pmgr_dcp 0 4 0x1210>; + apple,iomfb-surfaces = <1 1 0 1>; #ifdef APPLE_USE_PMP power-domains = <&DIE_NODE(pmp_report_dispext0)>; #else @@ -254,6 +255,7 @@ <0x3 0x15344000 0x0 0x4000>, <0x3 0x15800000 0x0 0x800000>; apple,bw-scratch = <&pmgr_dcp 0 4 0x1218>; + apple,iomfb-surfaces = <1 1 0 1>; #ifdef APPLE_USE_PMP power-domains = <&DIE_NODE(pmp_report_dispext1)>; #else From 73039e40392d47009e38cf0a6e1a4c14cf16a5c1 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 19 Jun 2026 20:30:08 +1000 Subject: [PATCH 03/14] arm64: dts: apple: t600x: Add apple,iomfb-surfaces to DCP nodes All T600x DCPs support simultaneous scanout on surfaces 0 and 1. Signed-off-by: James Calligeros --- arch/arm64/boot/dts/apple/t600x-die0.dtsi | 1 + arch/arm64/boot/dts/apple/t600x-dieX.dtsi | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi index 637e052e5db3c3..1be41d6ff5fca7 100644 --- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi @@ -525,6 +525,7 @@ <0x3 0x8b344000 0x0 0x4000>, <0x3 0x8b800000 0x0 0x800000>; apple,bw-scratch = <&pmgr_dcp 0 4 0x988>; + apple,iomfb-surfaces = <1 1 0 0>; #ifdef APPLE_USE_PMP power-domains = <&pmp_report_disp0>; #else diff --git a/arch/arm64/boot/dts/apple/t600x-dieX.dtsi b/arch/arm64/boot/dts/apple/t600x-dieX.dtsi index e222d63b37d320..e48065b70e0b97 100644 --- a/arch/arm64/boot/dts/apple/t600x-dieX.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-dieX.dtsi @@ -103,6 +103,7 @@ <0x2 0x89344000 0x0 0x4000>, <0x2 0x89800000 0x0 0x800000>; apple,bw-scratch = <&pmgr_dcp 0 4 0x990>; + apple,iomfb-surfaces = <1 1 0 0>; #ifdef APPLE_USE_PMP power-domains = <&DIE_NODE(pmp_report_dispext0)>; #else @@ -184,6 +185,7 @@ <0x2 0x8c344000 0x0 0x4000>, <0x2 0x8c800000 0x0 0x800000>; apple,bw-scratch = <&pmgr_dcp 0 4 0x998>; + apple,iomfb-surfaces = <1 1 0 0>; #ifdef APPLE_USE_PMP power-domains = <&DIE_NODE(pmp_report_dispext1)>; #else From 9676892099472e5e5710a7667db34149f95f5123 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 19 Jun 2026 20:32:02 +1000 Subject: [PATCH 04/14] arm64: dts: apple: t8103: Add apple,iomfb-surfaces to DCP nodes All T8103 DCPs support simultaneous scanout on surfaces 0 and 1. Signed-off-by: James Calligeros --- arch/arm64/boot/dts/apple/t8103.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi index dfb5f737a420b3..58c59075f2d2b7 100644 --- a/arch/arm64/boot/dts/apple/t8103.dtsi +++ b/arch/arm64/boot/dts/apple/t8103.dtsi @@ -659,6 +659,7 @@ <0x2 0x3b3d0000 0x0 0x4000>; apple,bw-scratch = <&pmgr_dcp 0 5 0x14>; apple,bw-doorbell = <&pmgr_dcp 1 6>; + apple,iomfb-surfaces = <1 1 0 0>; power-domains = <&ps_disp0_cpu0>; resets = <&ps_disp0_cpu0>; clocks = <&clk_disp0>; @@ -1485,6 +1486,7 @@ <0x2 0x3b3d0000 0x0 0x4000>; apple,bw-scratch = <&pmgr_dcp 0 5 0x18>; apple,bw-doorbell = <&pmgr_dcp 1 6>; + apple,iomfb-surfaces = <1 1 0 0>; power-domains = <&ps_dispext_cpu0>; resets = <&ps_dispext_cpu0>; clocks = <&clk_dispext0>; From 6cb0f44c91e8acbc5172f0a7b4e8039733554acb Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 19 Jun 2026 20:33:31 +1000 Subject: [PATCH 05/14] arm64: dts: apple: t8112: Add apple,iomfb-surfaces to DCP nodes All T8112 DCPs support simultaneous scanout on surfaces 0, 1, and 3. Signed-off-by: James Calligeros --- arch/arm64/boot/dts/apple/t8112.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8112.dtsi b/arch/arm64/boot/dts/apple/t8112.dtsi index b19b94305e47c1..1215de82221d5d 100644 --- a/arch/arm64/boot/dts/apple/t8112.dtsi +++ b/arch/arm64/boot/dts/apple/t8112.dtsi @@ -748,6 +748,7 @@ <0x2 0x31344000 0x0 0x4000>, <0x2 0x31800000 0x0 0x800000>; apple,bw-scratch = <&pmgr_dcp 0 4 0x5d8>; + apple,iomfb-surfaces = <1 1 0 1>; #ifdef APPLE_USE_PMP power-domains = <&pmp_report_disp0>; #else @@ -1745,6 +1746,7 @@ <0x2 0x71344000 0x0 0x4000>, <0x2 0x71800000 0x0 0x800000>; apple,bw-scratch = <&pmgr_dcp 0 4 0x5e0>; + apple,iomfb-surfaces = <1 1 0 1>; #ifdef APPLE_USE_PMP power-domains = <&pmp_report_dispext>; #else From ace6f64f7f0193a3b7487a0f958c72d90cab9e3a Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 19 Jun 2026 20:34:19 +1000 Subject: [PATCH 06/14] drm: apple: Max out DCP_MAX_PLANES Now that we can safely declare the working hardware surfaces on each SoC, let the driver test all possible positions for a working surface. Signed-off-by: James Calligeros --- drivers/gpu/drm/apple/dcp-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/apple/dcp-internal.h b/drivers/gpu/drm/apple/dcp-internal.h index 04ec57bd570fb2..c3f8eb77797b7c 100644 --- a/drivers/gpu/drm/apple/dcp-internal.h +++ b/drivers/gpu/drm/apple/dcp-internal.h @@ -20,7 +20,7 @@ #include "iomfb_v13_3.h" #include "epic/dpavservep.h" -#define DCP_MAX_PLANES 2 +#define DCP_MAX_PLANES 4 struct apple_dcp; struct apple_dcp_afkep; From c96950ab8ea7780e46c739362269643b4ff48f02 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 10 Jul 2026 17:47:46 +1000 Subject: [PATCH 07/14] 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 c3f8eb77797b7c..6df99e7d65d954 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 5caee694a182f4f226fc962073f6ea91f0583a7e Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Fri, 10 Jul 2026 17:55:37 +1000 Subject: [PATCH 08/14] 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 | 3 +- 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(+), 233 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 f4a1a06a98f622..eed346368c1972 100644 --- a/drivers/gpu/drm/apple/apple_drv.c +++ b/drivers/gpu/drm/apple/apple_drv.c @@ -276,11 +276,10 @@ static int apple_probe_per_dcp(struct device *dev, struct apple_dcp *drv = platform_get_drvdata(dcp); int ret, i; int zpos = 0; - bool supports_l10r = !dcp_fw_compat_is_12_x(dcp); for (i = 0; i < DCP_MAX_PLANES; i++) { if (drv->iomfb_surfaces[i]) { - planes[zpos] = apple_plane_init(drm, 1U << num, supports_l10r, + planes[zpos] = apple_plane_init(drm, 1U << num, zpos ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY); 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 6df99e7d65d954..1458928fc1813f 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 27a544a3ce3519..89a5ef883fa257 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; -} - int dcp_start(struct platform_device *pdev) { struct apple_dcp *dcp = platform_get_drvdata(pdev); @@ -568,9 +560,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; @@ -627,9 +616,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; @@ -652,9 +638,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; @@ -943,8 +926,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 bd20876847e0c3..ce18fa49e4da39 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); void dcp_link(struct platform_device *pdev, struct apple_crtc *apple, struct apple_connector *connector); int dcp_start(struct platform_device *pdev); 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 8654532f4afa30..ac84d5d91abe48 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 @@ -432,38 +401,23 @@ u64 apple_format_modifiers[] = { struct apple_plane *apple_plane_init(struct drm_device *dev, unsigned long possible_crtcs, - 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 c0c28627a61042..131a1c6e98f907 100644 --- a/drivers/gpu/drm/apple/plane.h +++ b/drivers/gpu/drm/apple/plane.h @@ -31,7 +31,6 @@ struct apple_plane_state { struct apple_plane *apple_plane_init(struct drm_device *dev, unsigned long possible_crtcs, - 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 eced014697087e821a7eb2bf978591c8c50f6a3c Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 12 Jul 2026 23:40:24 +1000 Subject: [PATCH 09/14] 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. 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 1458928fc1813f..9b7ca273c1e6b1 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 89a5ef883fa257..8ce6b7d403e822 100644 --- a/drivers/gpu/drm/apple/dcp.c +++ b/drivers/gpu/drm/apple/dcp.c @@ -563,6 +563,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; @@ -619,6 +622,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; @@ -641,6 +647,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; @@ -938,6 +947,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 61d8b0c4e8c2b5..bf1dbf8f15795e 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; } @@ -1393,7 +1398,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 0c2356de5271bf1122ddd5953747096216da450f Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 19 Jul 2026 20:24:58 +1000 Subject: [PATCH 10/14] 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 1305d599b6e52629750e16f98ee8b1de3ad499a1 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 26 Jul 2026 09:06:39 +1000 Subject: [PATCH 11/14] 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 0d5fd8ea0a0d47d4824e9b20a8bb386bbaf4a922 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 26 Jul 2026 09:09:52 +1000 Subject: [PATCH 12/14] 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 bf1dbf8f15795e..c4efa41a16926e 100644 --- a/drivers/gpu/drm/apple/iomfb_template.c +++ b/drivers/gpu/drm/apple/iomfb_template.c @@ -1354,6 +1354,8 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru req->swap.src_rect[apl_plane->iomfb_surf] = apple_state->src_rect; req->swap.dst_rect[apl_plane->iomfb_surf] = apple_state->dst_rect; + req->swap.surf_ids[apl_plane->iomfb_surf] = plane->base.id; + if (dcp->notch_height > 0) req->swap.dst_rect[apl_plane->iomfb_surf].y += dcp->notch_height; diff --git a/drivers/gpu/drm/apple/plane.c b/drivers/gpu/drm/apple/plane.c index ac84d5d91abe48..28cb6c96a991d5 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 239f1c9069c40e1a269664de22e20dcbcc1ba0bb Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sun, 26 Jul 2026 20:04:50 +1000 Subject: [PATCH 13/14] 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 | 44 +++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/apple/iomfb_template.c b/drivers/gpu/drm/apple/iomfb_template.c index c4efa41a16926e..252f1310870b53 100644 --- a/drivers/gpu/drm/apple/iomfb_template.c +++ b/drivers/gpu/drm/apple/iomfb_template.c @@ -739,17 +739,17 @@ static void dcp_swap_cleared(struct apple_dcp *dcp, void *data, void *cookie) return; } - while (!list_empty(&dcp->swapped_out_fbs)) { - struct dcp_fb_reference *entry; - entry = list_first_entry(&dcp->swapped_out_fbs, - struct dcp_fb_reference, head); - if (entry->swap_id == dcp->last_swap_id) - break; - if (entry->fb) - drm_framebuffer_put(entry->fb); - list_del(&entry->head); - kfree(entry); - } + // while (!list_empty(&dcp->swapped_out_fbs)) { + // struct dcp_fb_reference *entry; + // entry = list_first_entry(&dcp->swapped_out_fbs, + // struct dcp_fb_reference, head); + // if (entry->swap_id == dcp->last_swap_id) + // break; + // if (entry->fb) + // drm_framebuffer_put(entry->fb); + // list_del(&entry->head); + // kfree(entry); + // } } static void dcp_swap_clear_started(struct apple_dcp *dcp, void *data, @@ -1150,17 +1150,17 @@ static void dcp_swapped(struct apple_dcp *dcp, void *data, void *cookie) } dcp->swap_start = ktime_get(); - while (!list_empty(&dcp->swapped_out_fbs)) { - struct dcp_fb_reference *entry; - entry = list_first_entry(&dcp->swapped_out_fbs, - struct dcp_fb_reference, head); - if (entry->swap_id == dcp->last_swap_id) - break; - if (entry->fb) - drm_framebuffer_put(entry->fb); - list_del(&entry->head); - kfree(entry); - } + // while (!list_empty(&dcp->swapped_out_fbs)) { + // struct dcp_fb_reference *entry; + // entry = list_first_entry(&dcp->swapped_out_fbs, + // struct dcp_fb_reference, head); + // if (entry->swap_id == dcp->last_swap_id) + // break; + // if (entry->fb) + // drm_framebuffer_put(entry->fb); + // list_del(&entry->head); + // kfree(entry); + // } } static void dcp_swap_started(struct apple_dcp *dcp, void *data, void *cookie) From 31c49fc33b753580723458f8d9bc5ea3489d3ffe Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Sat, 1 Aug 2026 23:34:22 +1000 Subject: [PATCH 14/14] 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;