Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 203 additions & 0 deletions arch/arm64/boot/dts/apple/t6034-dcpext.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
* T6034 external display processor dcpext0.
*
* The J516M ADT places dcpext0 exactly 0x8000_0000 below the panel's DCP
* block: coprocessor 0x3_06c0_0000, mailbox 0x3_06c0_8000, firmware DART
* 0x3_0530_c000 and display DART 0x3_0530_4000 (both on interrupt 1047),
* display pipe 0x3_0400_0000. Its preloaded 14.7 firmware is the panel's
* image (F493F03E-...), and its nub has the T6030 dcpext segment layout, so
* it runs on the T6030 dcpext handoff protocol: compatible falls back to
* apple,t6030-dcpext.
*
* Power: as for the panel, dispext0_fe is the child of dispext0_cpu on
* T6031/T6034, so the processor holds the front end (and with it all three
* states); its DART and mailbox hold dispext0_cpu, which is what m1n1's
* display DART handoff and the display gate check.
*
* Every node stays disabled. m1n1 describes the firmware memory and the
* display DART only with chosen asahi,t6034-dcpext=1 / asahi,t6034-dispext=1,
* and the display gate enables the nodes only when those markers are there.
*/

/ {
aliases {
dcpext0 = &dcpext;
};
};

&soc {
dcpext_dart: iommu@30530c000 {
compatible = "apple,t6031-dart", "apple,t8110-dart";
reg = <0x3 0x0530c000 0x0 0x4000>;
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 0 1047 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
apple,dma-range = <0x100 0x0 0x10 0x0>;
power-domains = <&ps_dispext0_cpu>;
status = "disabled";
};

dcpext_mbox: mailbox@306c08000 {
compatible = "apple,t6031-asc-mailbox", "apple,asc-mailbox-v4";
reg = <0x3 0x06c08000 0x0 0x4000>;
interrupt-parent = <&aic>;
/* ADT order 1069 1068 1071 1070, as the panel's 1030 1029 1032 1031 */
interrupts = <AIC_IRQ 0 1068 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 0 1069 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 0 1070 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 0 1071 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "send-empty", "send-not-empty",
"recv-empty", "recv-not-empty";
#mbox-cells = <0>;
power-domains = <&ps_dispext0_cpu>;
resets = <&ps_dispext0_cpu>;
status = "disabled";
};

/* ADT atcN-dpxbar (compatible atc-dpxbar,t602x), one per Type-C port. */
atcphy0_xbar: mux@70304c000 {
compatible = "apple,t6031-display-crossbar",
"apple,t6020-display-crossbar";
reg = <0x7 0x0304c000 0x0 0x4000>;
#mux-control-cells = <1>;
power-domains = <&ps_atc0_usb>;
};

atcphy1_xbar: mux@b0304c000 {
compatible = "apple,t6031-display-crossbar",
"apple,t6020-display-crossbar";
reg = <0xb 0x0304c000 0x0 0x4000>;
#mux-control-cells = <1>;
power-domains = <&ps_atc1_usb>;
};

atcphy2_xbar: mux@f0304c000 {
compatible = "apple,t6031-display-crossbar",
"apple,t6020-display-crossbar";
reg = <0xf 0x0304c000 0x0 0x4000>;
#mux-control-cells = <1>;
power-domains = <&ps_atc2_usb>;
};

dcpext: dcp@306c00000 {
compatible = "apple,t6034-dcpext", "apple,t6030-dcpext",
"apple,dcpext";
reg = <0x3 0x06c00000 0x0 0x4000>;
reg-names = "coproc";
mboxes = <&dcpext_mbox>;
mbox-names = "mbox";
iommus = <&dcpext_dart 5>;
power-domains = <&ps_dispext0_fe>;
resets = <&ps_dispext0_cpu>;
/*
* The gate sets this too; naming it here gives the entry the
* phandle the gate requires (dtc emits one only if referenced).
*/
apple,pmp-report = <&pmp_report_dispext0>;
phys = <&atcphy0 PHY_TYPE_DP>, <&atcphy1 PHY_TYPE_DP>,
<&atcphy2 PHY_TYPE_DP>;
phy-names = "typec0", "typec1", "typec2";
mux-controls = <&atcphy0_xbar 0>, <&atcphy1_xbar 0>,
<&atcphy2_xbar 0>,
<&atcphy0_xbar 1>, <&atcphy0_xbar 2>,
<&atcphy1_xbar 1>, <&atcphy1_xbar 2>,
<&atcphy2_xbar 1>, <&atcphy2_xbar 2>;
mux-control-names = "typec0", "typec1", "typec2",
"typec0-dpin0", "typec0-dpin1",
"typec1-dpin0", "typec1-dpin1",
"typec2-dpin0", "typec2-dpin1";
apple,connector-type = "USB-C";
/* display-crossbar0 upstream port: dispext0 */
apple,dcp-index = <1>;
apple,typec-dptx-phys = <0 1 2>;
apple,typec-mux-indices = <0 0 0>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
status = "disabled";

/* Enabled together with the processor by the display gate. */
typec-routes {
#address-cells = <1>;
#size-cells = <0>;

route@0 {
reg = <0>;
mode-switch;
status = "disabled";

port {
dcpext_typec0: endpoint {
remote-endpoint = <&typec0_dcpext>;
};
};
};

route@1 {
reg = <1>;
mode-switch;
status = "disabled";

port {
dcpext_typec1: endpoint {
remote-endpoint = <&typec1_dcpext>;
};
};
};

route@2 {
reg = <2>;
mode-switch;
status = "disabled";

port {
dcpext_typec2: endpoint {
remote-endpoint = <&typec2_dcpext>;
};
};
};
};
};
};

/* The driver waits for the PMP to acknowledge this request before RUN. */
&pmp_report_dispext0 {
apple,always-on;
};

&typec0 {
ports {
port@3 {
reg = <3>;

typec0_dcpext: endpoint {
remote-endpoint = <&dcpext_typec0>;
};
};
};
};

&typec1 {
ports {
port@3 {
reg = <3>;

typec1_dcpext: endpoint {
remote-endpoint = <&dcpext_typec1>;
};
};
};
};

&typec2 {
ports {
port@3 {
reg = <3>;

typec2_dcpext: endpoint {
remote-endpoint = <&dcpext_typec2>;
};
};
};
};
13 changes: 13 additions & 0 deletions arch/arm64/boot/dts/apple/t6034-j516m.dts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
/dts-v1/;

#include "t6034.dtsi"
#include "t6034-dcp.dtsi"
#include "t603x-j514-j516.dtsi"
#include "t6034-dcpext.dtsi"

/ {
compatible = "apple,j516m", "apple,t6034", "apple,arm-platform";
Expand All @@ -29,6 +31,17 @@
brcm,board-type = "apple,jura";
};

/* J516 panel dimensions, as on the J516C (same 16-inch chassis and panel). */
&dcp {
panel {
compatible = "apple,panel-j516", "apple,panel-mini-led", "apple,panel";
width-mm = <346>;
height-mm = <223>;
adj-height-mm = <216>;
apple,max-brightness = <500>;
};
};

&aop_audio {
apple,chassis-name = "J516";
apple,machine-kind = "MacBook Pro";
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/apple/apple_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ EXPORT_SYMBOL_GPL(apple_drm_t6031_link_device);

int apple_drm_t6034_link_device(struct device *consumer)
{
if (!of_machine_is_compatible("apple,j514m"))
if (!of_machine_is_compatible("apple,j514m") &&
!of_machine_is_compatible("apple,j516m"))
return -ENODEV;
return apple_g15_link_device(consumer, "apple,t6034", "apple,agx-t6034",
&apple_t6034_display);
Expand Down
12 changes: 6 additions & 6 deletions drivers/gpu/drm/apple/dcp-fabric.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ bool dcp_typec_dual_stream(void)
bool dcp_typec_ordered_dual_stream(void)
{
return dcp_fabric_ordered_dual_stream(dcp_typec_dual_stream(),
of_machine_is_compatible("apple,t6030"));
apple_dp_tunnel_m3_soc());
}

/*
Expand Down Expand Up @@ -257,7 +257,7 @@ static int dcp_route_clock_rate(struct apple_dcp_typec_route *route,
{
int ret;

if (of_machine_is_compatible("apple,t6030")) {
if (apple_dp_tunnel_m3_soc()) {
typeof(apple_atc_dp_tunnel_rate_source) *fn;

if (dcp_fabric_t6030_pclk(route->mux_index, dpin) < 0)
Expand Down Expand Up @@ -902,7 +902,7 @@ static void dcp_fabric_snapshot_port(struct apple_dcp_typec_port *port,
route->core.tunnel = route->tunnel;
route->core.dpin = route->tunnel_dpin;
route->core.tunnel_clock_blocked = dcp_fabric_tunnel_clock_blocked(
of_machine_is_compatible("apple,t6030"), route->mux_index);
apple_dp_tunnel_m3_soc(), route->mux_index);
*tail = &route->core;
tail = &route->core.next;
}
Expand Down Expand Up @@ -1763,7 +1763,7 @@ int dcp_direct_crossbar_link(struct apple_dcp *dcp, bool up)
struct mux_control *xbar = NULL;
int ret;

if (!of_machine_is_compatible("apple,t6030"))
if (!apple_dp_tunnel_m3_soc())
return 0;
guard(mutex)(&dcp->tb_lock);
route = dcp->active_typec_route;
Expand Down Expand Up @@ -1805,7 +1805,7 @@ int dcp_tunnel_set_rate(struct apple_dcp *dcp, struct phy *phy, u32 unit,
return -ENODEV;
if (!dcp_fabric_callback_valid(route->tunnel_generation, dcp->tb_generation))
return -ESTALE;
if (of_machine_is_compatible("apple,t6030") &&
if (apple_dp_tunnel_m3_soc() &&
(unit || dcp->dptx_dfp_port != 1 + route->tunnel_dpin ||
apple_dp_tunnel_t6030_pclk(route->mux_index,
route->tunnel_dpin) < 0))
Expand Down Expand Up @@ -1903,7 +1903,7 @@ static struct mux_control *
dcp_typec_tunnel_ctl(struct apple_dcp_typec_route *route, unsigned int dpin)
{
if (dpin > 1 ||
(dcp_fabric_tunnel_clock_blocked(of_machine_is_compatible("apple,t6030"),
(dcp_fabric_tunnel_clock_blocked(apple_dp_tunnel_m3_soc(),
route->mux_index) & BIT(dpin)))
return NULL;
if (route->dpin[dpin])
Expand Down
62 changes: 61 additions & 1 deletion drivers/gpu/drm/apple/dcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,66 @@ static int dcp_external_start_locked(struct apple_dcp *dcp)
* that DART, and stream 0 among the display subsystem's iommus, so that
* framebuffers are mapped for it as for the panel.
*/
/* Display subsystems an external processor on the T6030 handoff can join. */
static const struct of_device_id dcp_ext_display_ids[] = {
{ .compatible = "apple,t6030-display-subsystem" },
/* T6034: dcpext0 on the T6030 handoff protocol. */
{ .compatible = "apple,t6034-display-subsystem" },
{},
};

/*
* The external processor images the 14.7 external path speaks to: the
* T6030 image, and on T6034 the SoC's own image, which
* the panel's DCP already runs natively on the same 14.7 layouts.
*/
bool dcp_ext_firmware_admitted(const struct device_node *np)
{
const char *uuid;

if (of_property_read_string(np, "apple,firmware-uuid", &uuid))
return false;
if (!strcmp(uuid, "DDF38191-93B3-324A-BC8F-643006F5AC82"))
return true;
return of_machine_is_compatible("apple,t6034") &&
!strcmp(uuid, "F493F03E-CC40-3D89-9A08-5F259BA2B246");
}

static bool dcp_ext_domain_is(struct device_node *ps, const char *part)
{
const char *label;
size_t len, plen = strlen(part);

if (!ps || of_property_read_string(ps, "label", &label) ||
!strstarts(label, "dispext"))
return false;
len = strlen(label);
return len > plen && !strcmp(label + len - plen, part);
}

/*
* The CPU power domain of an external processor's pipe, dispext<N>_cpu,
* with a reference. T6030 names it first in the processor's power-domains;
* on T6031/T6034 the processor holds dispext<N>_fe, the
* child of dispext<N>_cpu there, as disp_fe is of disp_cpu.
*/
struct device_node *dcp_ext_cpu_domain(const struct device_node *np)
{
struct device_node *ps, *parent;

ps = of_parse_phandle(np, "power-domains", 0);
if (dcp_ext_domain_is(ps, "_fe")) {
parent = of_parse_phandle(ps, "power-domains", 0);
of_node_put(ps);
ps = parent;
}
if (!dcp_ext_domain_is(ps, "_cpu")) {
of_node_put(ps);
return NULL;
}
return ps;
}

bool dcp_t6030_ext_native(const struct device_node *np)
{
struct of_phandle_args dart, args;
Expand All @@ -1403,7 +1463,7 @@ bool dcp_t6030_ext_native(const struct device_node *np)
of_node_put(piodma);
if (dart.args_count != 1 || dart.args[0] != 4 || !of_device_is_available(dart.np))
goto out;
display = of_find_compatible_node(NULL, NULL, "apple,t6030-display-subsystem");
display = of_find_matching_node(NULL, dcp_ext_display_ids);
n = display && of_device_is_available(display) ?
of_count_phandle_with_args(display, "iommus", "#iommu-cells") : 0;
for (i = 0; i < n && !native; i++) {
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/apple/dcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ void dcp_send_message(struct apple_dcp *dcp, u8 endpoint, u64 message);

int dcp_dptx_connect_oob(struct platform_device *pdev, u32 port);
bool dcp_t6030_ext_native(const struct device_node *np);
bool dcp_ext_firmware_admitted(const struct device_node *np);
struct device_node *dcp_ext_cpu_domain(const struct device_node *np);
void dcp_external_ready(struct apple_dcp *dcp);
void dcp_external_retry(struct apple_dcp *dcp, const char *why, int error,
unsigned int base_ms);
Expand Down
Loading