From 497ef5b9f682ee6607f3eb667d8cf404ea5b2c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Bal=C3=A1zsy?= Date: Sun, 25 Oct 2026 01:25:45 +0200 Subject: [PATCH 1/2] dt-bindings: mux: apple,display-crossbar: add the T6041 per-ATC crossbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit T6040/T6041 (M4 Pro/Max) carry one display crossbar per Type-C or HDMI PHY (ADT atcN-dpxbar, "atc-dpxbar,t604x"), 0x4000 bytes each, which routes the DISPEXT pipes and the DP IN ports of that ATC. Add the compatible. Signed-off-by: František Balázsy --- .../devicetree/bindings/mux/apple,display-crossbar.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mux/apple,display-crossbar.yaml b/Documentation/devicetree/bindings/mux/apple,display-crossbar.yaml index eb80cf382a188..fcb65f7913670 100644 --- a/Documentation/devicetree/bindings/mux/apple,display-crossbar.yaml +++ b/Documentation/devicetree/bindings/mux/apple,display-crossbar.yaml @@ -24,6 +24,7 @@ properties: - apple,t8112-display-crossbar - apple,t6000-display-crossbar - apple,t6020-display-crossbar + - apple,t6041-display-crossbar reg: maxItems: 1 From 730ffa5971745643e81fd79a1966fecbd16c0ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Bal=C3=A1zsy?= Date: Sun, 25 Oct 2026 01:25:45 +0200 Subject: [PATCH 2/2] mux: apple-display-crossbar: support the T6041 per-ATC crossbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit T6040/T6041 (M4 Pro/Max) have one 0x4000-byte display crossbar per ATC instead of the single SoC crossbar of T6020. The block follows the T6030 compact register map and flow: the status words at 0x804/0x810/0x81c mirror 0x004/0x014/0x024 and 0x808/0x818 mirror 0x00c/0x020, while the T8142/T6050-layout writes to 0x34/0x38/0x3c do not hold (register dumps on a J616s). It has no tunable register. Select the T6030 flow from the match data instead of the machine compatible, skip the UNK_TUNABLE write for this block and describe the nine UFP endpoints the ADT lists (dispext0-3, scodec0 and the DP IN ports). Tested on a MacBook Pro M4 Pro (J616s): HDMI through the ATC3 crossbar (dcpext0, 3840x2160@60) and USB-C DisplayPort through the ATC0-2 crossbars (dcpext1, 5120x1440@120 and 3840x2160@120 with DSC over HBR3), including replug and switching between the three Type-C ports. Signed-off-by: František Balázsy --- drivers/mux/apple-display-crossbar.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/mux/apple-display-crossbar.c b/drivers/mux/apple-display-crossbar.c index a02b8d9fe8a30..e5270f2f51088 100644 --- a/drivers/mux/apple-display-crossbar.c +++ b/drivers/mux/apple-display-crossbar.c @@ -95,6 +95,10 @@ struct apple_dpxbar_hw { const struct mux_control_ops *ops; /* DP IN runs without the FIFO_RD_PCLK1 cycle-slip toggle (t600x) */ bool dpin_no_cycle_slip; + /* T6030 flow (route on select, clocks on link up) regardless of the machine */ + bool t6030_flow; + /* no UNK_TUNABLE write at probe */ + bool no_tunable; }; struct apple_dpxbar { @@ -1003,12 +1007,13 @@ static int apple_dpxbar_probe(struct platform_device *pdev) spin_lock_init(&dpxbar->lock); dpxbar->dev = dev; - dpxbar->t6030_dpin = of_machine_is_compatible("apple,t6030"); + dpxbar->t6030_dpin = hw->t6030_flow || of_machine_is_compatible("apple,t6030"); dpxbar->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(dpxbar->regs)) return PTR_ERR(dpxbar->regs); - if (!of_device_is_compatible(dev->of_node, "apple,t6020-display-crossbar")) { + if (!hw->no_tunable && + !of_device_is_compatible(dev->of_node, "apple,t6020-display-crossbar")) { readl(dpxbar->regs + UNK_TUNABLE); writel(hw->tunable, dpxbar->regs + UNK_TUNABLE); readl(dpxbar->regs + UNK_TUNABLE); @@ -1102,6 +1107,20 @@ static const struct apple_dpxbar_hw apple_dpxbar_hw_t6020 = { .ops = &apple_dpxbar_t602x_ops, }; +/* + * T6040/T6041 (M4 Pro/Max): one crossbar per ATC (ADT atcN-dpxbar, + * "atc-dpxbar,t604x"), 0x4000 bytes, no tunable. The block uses the T6030 + * compact register map and flow: the status mirrors at 0x804/0x810/0x81c + * follow 0x004/0x014/0x024 and 0x808/0x818 follow 0x00c/0x020, as on T6030. + * The ADT lists nine UFP endpoints (dispext0-3, scodec0 and the DP IN ports). + */ +static const struct apple_dpxbar_hw apple_dpxbar_hw_t6041 = { + .n_ufp = 9, + .ops = &apple_dpxbar_t602x_ops, + .t6030_flow = true, + .no_tunable = true, +}; + static const struct of_device_id apple_dpxbar_ids[] = { { .compatible = "apple,t8103-display-crossbar", @@ -1119,6 +1138,10 @@ static const struct of_device_id apple_dpxbar_ids[] = { .compatible = "apple,t6020-display-crossbar", .data = &apple_dpxbar_hw_t6020, }, + { + .compatible = "apple,t6041-display-crossbar", + .data = &apple_dpxbar_hw_t6041, + }, {} }; MODULE_DEVICE_TABLE(of, apple_dpxbar_ids);