From 7e63b87b0ed10a4a7b06cb1ea07d03bac5103096 Mon Sep 17 00:00:00 2001 From: Sasha Finkelstein Date: Tue, 7 Apr 2026 13:33:46 +0200 Subject: [PATCH 01/14] Bluetooth: Add Broadcom channel priority commands Certain Broadcom bluetooth chips (bcm4377/bcm4378/bcm438) need ACL streams carrying audio to be set as "high priority" using a vendor specific command to prevent 10-ish second-long dropouts whenever something does a device scan. This patch sends the command when the socket priority is set to TC_PRIO_INTERACTIVE, as BlueZ does for audio. Signed-off-by: Sasha Finkelstein --- MAINTAINERS | 2 ++ drivers/bluetooth/hci_bcm4377.c | 2 ++ include/net/bluetooth/bluetooth.h | 4 ++++ include/net/bluetooth/hci_core.h | 11 +++++++++++ net/bluetooth/Kconfig | 7 +++++++ net/bluetooth/Makefile | 1 + net/bluetooth/brcm.c | 29 +++++++++++++++++++++++++++++ net/bluetooth/brcm.h | 17 +++++++++++++++++ net/bluetooth/hci_conn.c | 27 +++++++++++++++++++++++++++ net/bluetooth/l2cap_sock.c | 13 +++++++++++++ 10 files changed, 113 insertions(+) create mode 100644 net/bluetooth/brcm.c create mode 100644 net/bluetooth/brcm.h diff --git a/MAINTAINERS b/MAINTAINERS index 13241dc0aecafe..f20aebb9bf2d5a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2595,6 +2595,8 @@ F: include/dt-bindings/pinctrl/apple.h F: include/linux/mfd/macsmc.h F: include/linux/soc/apple/* F: include/uapi/drm/asahi_drm.h +F: net/bluetooth/brcm.c +F: net/bluetooth/brcm.h ARM/ARTPEC MACHINE SUPPORT M: Jesper Nilsson diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c index 925d0a6359453e..5f79920c030681 100644 --- a/drivers/bluetooth/hci_bcm4377.c +++ b/drivers/bluetooth/hci_bcm4377.c @@ -2397,6 +2397,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (bcm4377->hw->broken_le_ext_adv_report_phy) hci_set_quirk(hdev, HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY); + hci_set_brcm_capable(hdev); + pci_set_drvdata(pdev, bcm4377); hci_set_drvdata(hdev, bcm4377); SET_HCIDEV_DEV(hdev, &pdev->dev); diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 3faea66b19799a..5d82944370e427 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -458,6 +458,7 @@ struct l2cap_ctrl { }; struct hci_dev; +struct hci_conn; typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode); typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status, @@ -470,6 +471,9 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, int hci_ethtool_ts_info(unsigned int index, int sk_proto, struct kernel_ethtool_ts_info *ts_info); +int hci_conn_setsockopt(struct hci_conn *conn, struct sock *sk, int level, + int optname, sockptr_t optval, unsigned int optlen); + #define HCI_REQ_START BIT(0) #define HCI_REQ_SKB BIT(1) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 2c15c9d8dbf74d..eb721509c0ab88 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -642,6 +642,10 @@ struct hci_dev { bool aosp_quality_report; #endif +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + bool brcm_capable; +#endif + int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); @@ -1794,6 +1798,13 @@ static inline void hci_set_aosp_capable(struct hci_dev *hdev) #endif } +static inline void hci_set_brcm_capable(struct hci_dev *hdev) +{ +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + hdev->brcm_capable = true; +#endif +} + static inline void hci_devcd_setup(struct hci_dev *hdev) { #ifdef CONFIG_DEV_COREDUMP diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index ee6457d1a5eed3..b611942c7b8ffd 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -107,6 +107,13 @@ config BT_AOSPEXT This options enables support for the Android Open Source Project defined HCI vendor extensions. +config BT_BRCMEXT + bool "Enable Broadcom extensions" + depends on BT + help + This option enables support for the Broadcom defined HCI + vendor extensions. + config BT_DEBUGFS bool "Export Bluetooth internals in debugfs" depends on BT && DEBUG_FS diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 41049b280887db..d402645dfb7da0 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -23,5 +23,6 @@ bluetooth-$(CONFIG_BT_LE) += iso.o bluetooth-$(CONFIG_BT_LEDS) += leds.o bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o +bluetooth-$(CONFIG_BT_BRCMEXT) += brcm.o bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o diff --git a/net/bluetooth/brcm.c b/net/bluetooth/brcm.c new file mode 100644 index 00000000000000..9aa0a265ab3d6b --- /dev/null +++ b/net/bluetooth/brcm.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 The Asahi Linux Contributors + */ + +#include +#include + +#include "brcm.h" + +int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable) +{ + struct sk_buff *skb; + u8 cmd[3]; + + if (!hdev->brcm_capable) + return 0; + + cmd[0] = handle; + cmd[1] = handle >> 8; + cmd[2] = !!enable; + + skb = hci_cmd_sync(hdev, 0xfc57, sizeof(cmd), cmd, HCI_CMD_TIMEOUT); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + kfree_skb(skb); + return 0; +} diff --git a/net/bluetooth/brcm.h b/net/bluetooth/brcm.h new file mode 100644 index 00000000000000..fdaee63bd1d23c --- /dev/null +++ b/net/bluetooth/brcm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 The Asahi Linux Contributors + */ + +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + +int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable); + +#else + +static inline int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable) +{ + return 0; +} + +#endif diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index fb96d019cf8568..636c36ff077673 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -35,6 +35,7 @@ #include #include +#include "brcm.h" #include "smp.h" #include "eir.h" @@ -3158,6 +3159,32 @@ int hci_conn_set_phy(struct hci_conn *conn, u32 phys) } } +int hci_conn_setsockopt(struct hci_conn *conn, struct sock *sk, int level, + int optname, sockptr_t optval, unsigned int optlen) { + int val; + bool old_high, new_high, changed; + + if (level != SOL_SOCKET) + return 0; + + if (optname != SO_PRIORITY) + return 0; + + if (optlen < sizeof(int)) + return -EINVAL; + + if (copy_from_sockptr(&val, optval, sizeof(val))) + return -EFAULT; + + old_high = sk->sk_priority >= TC_PRIO_INTERACTIVE; + new_high = val >= TC_PRIO_INTERACTIVE; + changed = old_high != new_high; + if (!changed) + return 0; + + return brcm_set_high_priority(conn->hdev, conn->handle, new_high); +} + static int abort_conn_sync(struct hci_dev *hdev, void *data) { struct hci_conn *conn = data; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index d8cbe278443779..0c86be41622e2b 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -897,6 +897,16 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, BT_DBG("sk %p", sk); + if (level == SOL_SOCKET) { + conn = chan->conn; + if (conn) + err = hci_conn_setsockopt(conn->hcon, sock->sk, level, + optname, optval, optlen); + if (err) + return err; + return sock_setsockopt(sock, level, optname, optval, optlen); + } + if (level == SOL_L2CAP) return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); @@ -1976,6 +1986,9 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, INIT_LIST_HEAD(&l2cap_pi(sk)->rx_busy); + if (sock) + set_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags); + /* The sock takes ownership of the caller's reference on chan. */ l2cap_pi(sk)->chan = chan; From 0a27beeb1a9eceb73a492d581766337c72948963 Mon Sep 17 00:00:00 2001 From: Sasha Finkelstein Date: Thu, 21 May 2026 10:30:50 +0200 Subject: [PATCH 02/14] Fail the build on RUST=y and RUST_IS_AVAILABLE=n The current approach of silently disabling all rust drivers if the toolchain is missing results in users that try to compile their own kernels getting a "successful" build and then being confused about where did their drivers go. In comparison, missing openssl results in a build failure, not a disappearance of everything that depends on it. This also means that allyesconfig will depend on rust, but since the rust experiment concluded with "rust is here to stay", i believe that allyesconfig should be building rust drivers too. Signed-off-by: Sasha Finkelstein --- Documentation/rust/quick-start.rst | 6 +++--- init/Kconfig | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index a6ec3fa94d3307..764c81d0dd5926 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -321,9 +321,9 @@ Configuration ------------- ``Rust support`` (``CONFIG_RUST``) needs to be enabled in the ``General setup`` -menu. The option is only shown if a suitable Rust toolchain is found (see -above), as long as the other requirements are met. In turn, this will make -visible the rest of options that depend on Rust. +menu. In turn, this will make visible the rest of options that depend on Rust. +You can check the value of ``RUST_IS_AVAILABLE`` to determine if your toolchain +is configured correctly. Afterwards, go to:: diff --git a/init/Kconfig b/init/Kconfig index d78a6e616311e8..dbc6d709068f42 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2193,7 +2193,6 @@ config PROFILING config RUST bool "Rust support" depends on HAVE_RUST - depends on RUST_IS_AVAILABLE select EXTENDED_MODVERSIONS if MODVERSIONS depends on !MODVERSIONS || GENDWARFKSYMS depends on !GCC_PLUGIN_RANDSTRUCT From 097b56319e37cb7399ccd1dfefdf5700f8291827 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 9 May 2026 11:58:52 +0200 Subject: [PATCH 03/14] driver-core: Add error message to device_links_missing_supplier WARN() Signed-off-by: Janne Grunau --- drivers/base/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index 3ee92a5b88c3a0..a9df82e5f6b5d9 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1076,6 +1076,7 @@ static void device_links_missing_supplier(struct device *dev) if (link->supplier->links.status == DL_DEV_DRIVER_BOUND) { WRITE_ONCE(link->status, DL_STATE_AVAILABLE); } else { + dev_err(dev, "devices misses supplier %s\n", dev_name(link->supplier)); WARN_ON(!device_link_test(link, DL_FLAG_SYNC_STATE_ONLY)); WRITE_ONCE(link->status, DL_STATE_DORMANT); } From d78ca86e55bea2e4906025beca56a968142737fb Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 30 May 2026 12:16:44 +0200 Subject: [PATCH 04/14] dt-bindings: gpio: apple,smc: Add compatible for 'gp00' keys Apple M3 Pro and Max devices are using 'gp00' keys for GPIO in addition to 'gP00' keys. Add a second compatible to handle this keys with an additional macsmc-gpio instance. Signed-off-by: Janne Grunau --- Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml b/Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml index 42b1bc0a10c97a..b4063a9dd1248c 100644 --- a/Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml @@ -14,7 +14,9 @@ description: properties: compatible: - const: apple,smc-gpio + enum: + - apple,smc-gpio + - apple,smc-low-gpio gpio-controller: true From c8a3899d6716296f175c14726422acd622442745 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 29 May 2026 20:54:16 +0200 Subject: [PATCH 05/14] gpio: gpio-macsmc: Support 'gp00' GPIO keys Add support for SMC GPIO keys with a lower letter 'p' via the "apple,smc-low-gpio" compatible. This adds support for a second macsmc-gpio controller using 'gp00' keys. These keys are used on Apple M3 Pro and Max MacBooks in the controller for keyboard and trackpad and for the built-in DisplayPort to HDMI converter. Signed-off-by: Janne Grunau --- drivers/gpio/gpio-macsmc.c | 45 +++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpio-macsmc.c b/drivers/gpio/gpio-macsmc.c index b0952d066a9dd0..c3ca445a85ac9d 100644 --- a/drivers/gpio/gpio-macsmc.c +++ b/drivers/gpio/gpio-macsmc.c @@ -75,6 +75,7 @@ struct macsmc_gpio { struct gpio_chip gc; int first_index; + smc_key base_key; }; static int macsmc_gpio_nr(smc_key key) @@ -88,15 +89,15 @@ static int macsmc_gpio_nr(smc_key key) return low | (high << 4); } -static int macsmc_gpio_key(unsigned int offset) +static int macsmc_gpio_key(smc_key base_key, unsigned int offset) { - return _SMC_KEY("gP\0\0") | hex_asc_hi(offset) << 8 | hex_asc_lo(offset); + return base_key | hex_asc_hi(offset) << 8 | hex_asc_lo(offset); } static int macsmc_gpio_find_first_gpio_index(struct macsmc_gpio *smcgp) { struct apple_smc *smc = smcgp->smc; - smc_key key = macsmc_gpio_key(0); + smc_key key = macsmc_gpio_key(smcgp->base_key, 0); smc_key first_key, last_key; int start, count, ret; @@ -143,7 +144,7 @@ static int macsmc_gpio_find_first_gpio_index(struct macsmc_gpio *smcgp) static int macsmc_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) { struct macsmc_gpio *smcgp = gpiochip_get_data(gc); - smc_key key = macsmc_gpio_key(offset); + smc_key key = macsmc_gpio_key(smcgp->base_key, offset); u32 val; int ret; @@ -163,7 +164,7 @@ static int macsmc_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) static int macsmc_gpio_get(struct gpio_chip *gc, unsigned int offset) { struct macsmc_gpio *smcgp = gpiochip_get_data(gc); - smc_key key = macsmc_gpio_key(offset); + smc_key key = macsmc_gpio_key(smcgp->base_key, offset); u32 cmd, val; int ret; @@ -186,7 +187,7 @@ static int macsmc_gpio_get(struct gpio_chip *gc, unsigned int offset) static int macsmc_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) { struct macsmc_gpio *smcgp = gpiochip_get_data(gc); - smc_key key = macsmc_gpio_key(offset); + smc_key key = macsmc_gpio_key(smcgp->base_key, offset); int ret; value |= CMD_OUTPUT; @@ -217,7 +218,7 @@ static int macsmc_gpio_init_valid_mask(struct gpio_chip *gc, if (ret < 0) return ret; - if (key > SMC_KEY(gPff)) + if (key > macsmc_gpio_key(smcgp->base_key, MAX_GPIO - 1)) break; gpio_nr = macsmc_gpio_nr(key); @@ -232,10 +233,15 @@ static int macsmc_gpio_init_valid_mask(struct gpio_chip *gc, return 0; } +struct macsmc_gpio_of_match_data { + smc_key base_key; +}; + static int macsmc_gpio_probe(struct platform_device *pdev) { struct macsmc_gpio *smcgp; struct apple_smc *smc = dev_get_drvdata(pdev->dev.parent); + const struct macsmc_gpio_of_match_data *data = of_device_get_match_data(&pdev->dev); smc_key key; int ret; @@ -245,6 +251,7 @@ static int macsmc_gpio_probe(struct platform_device *pdev) smcgp->dev = &pdev->dev; smcgp->smc = smc; + smcgp->base_key = data ? data->base_key : _SMC_KEY("gP\0\0"); smcgp->first_index = macsmc_gpio_find_first_gpio_index(smcgp); if (smcgp->first_index < 0) @@ -254,12 +261,15 @@ static int macsmc_gpio_probe(struct platform_device *pdev) if (ret < 0) return ret; - if (key > macsmc_gpio_key(MAX_GPIO - 1)) + if (key > macsmc_gpio_key(smcgp->base_key, MAX_GPIO - 1)) return -ENODEV; dev_info(smcgp->dev, "First GPIO key: %p4ch\n", &key); - smcgp->gc.label = "macsmc-pmu-gpio"; + if (device_is_compatible(&pdev->dev, "apple,smc-low-gpio")) + smcgp->gc.label = "macsmc-pmu-low-gpio"; + else + smcgp->gc.label = "macsmc-pmu-gpio"; smcgp->gc.owner = THIS_MODULE; smcgp->gc.get = macsmc_gpio_get; smcgp->gc.set = macsmc_gpio_set; @@ -273,8 +283,23 @@ static int macsmc_gpio_probe(struct platform_device *pdev) return devm_gpiochip_add_data(&pdev->dev, &smcgp->gc, smcgp); } +static const struct macsmc_gpio_of_match_data macsmc_gpio_up_data = { + .base_key = _SMC_KEY("gP\0\0"), +}; + +static const struct macsmc_gpio_of_match_data macsmc_gpio_low_data = { + .base_key = _SMC_KEY("gp\0\0"), +}; + static const struct of_device_id macsmc_gpio_of_table[] = { - { .compatible = "apple,smc-gpio", }, + { + .compatible = "apple,smc-gpio", + .data = &macsmc_gpio_up_data, + }, + { + .compatible = "apple,smc-low-gpio", + .data = &macsmc_gpio_low_data, + }, {} }; MODULE_DEVICE_TABLE(of, macsmc_gpio_of_table); From 96fa2b9c825bd42c3ea4dc8c8adb6182e5016f51 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 30 May 2026 12:20:39 +0200 Subject: [PATCH 06/14] mfd: macsmc: Add second gpio subdevice for 'gp00' keys Apple M3 Pro and Max devices are using 'gp00' keys for GPIO in addition to 'gP00' keys. These keys are handled by an additional macsmc-gpio instance using the "apple,smc-low-gpio" compatible. Signed-off-by: Janne Grunau --- drivers/mfd/macsmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/macsmc.c b/drivers/mfd/macsmc.c index 514cba7dc897ae..31540f67ddbd8a 100644 --- a/drivers/mfd/macsmc.c +++ b/drivers/mfd/macsmc.c @@ -48,6 +48,7 @@ static const struct mfd_cell apple_smc_devs[] = { MFD_CELL_NAME("macsmc-input"), MFD_CELL_NAME("macsmc-power"), MFD_CELL_OF("macsmc-gpio", NULL, NULL, 0, 0, "apple,smc-gpio"), + MFD_CELL_OF("macsmc-low-gpio", NULL, NULL, 0, 0, "apple,smc-low-gpio"), MFD_CELL_OF("macsmc-hwmon", NULL, NULL, 0, 0, "apple,smc-hwmon"), MFD_CELL_OF("macsmc-reboot", NULL, NULL, 0, 0, "apple,smc-reboot"), MFD_CELL_OF("macsmc-rtc", NULL, NULL, 0, 0, "apple,smc-rtc"), From 0b28a2cacc675d04f51ca8ab7417faef66e0d362 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 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 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 | 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 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 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 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 906ef0929851139860fa9bd3234a2691b13e112b 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 df5345589e368be05ae267217302af116099d6f7 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 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 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 | 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 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;