Messages in this thread Patch in this message | | | Date | Tue, 3 Sep 2019 13:13:25 +0300 | From | Mika Westerberg <> | Subject | Re: Thunderbolt DP oddity on v5.2.9 on iMac 12,2 |
| |
Hi Brad,
On Thu, Aug 29, 2019 at 12:27:08AM +0800, Brad Campbell wrote: > It wouldn't surprise me if the firmware was doing something funky. It was > one of the first Thunderbolt equipped models and the support docs explicitly > say only one Thunderbolt display in Windows and two in later versions of > OSX. It almost needs a quirk to say "firmware does something we don't like, > reset the controller and re-discover from scratch". > > Anyway, I'm not in any hurry. It doesn't get rebooted often and it's not in > any way preventing me using the machine. In fact, upgrading the third head > from an old 24" 1920x1200 to the second Thunderbolt display has been > invaluable.
Can you apply the below patch and then boot with two monitors connected? Then send me the dmesg. It does not fix anything but should log a bit more.
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 1f7a9e1cc09c..28a72336558a 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -313,8 +313,10 @@ static struct tb_port *tb_find_unused_port(struct tb_switch *sw, continue; if (!sw->ports[i].cap_adap) continue; - if (tb_port_is_enabled(&sw->ports[i])) + if (tb_port_is_enabled(&sw->ports[i])) { + tb_port_dbg(&sw->ports[i], "this already enabled\n"); continue; + } return &sw->ports[i]; } return NULL; @@ -365,16 +367,25 @@ static int tb_tunnel_dp(struct tb *tb, struct tb_port *out) struct tb_tunnel *tunnel; struct tb_port *in; - if (tb_port_is_enabled(out)) + tb_port_dbg(out, "trying to tunnel DP\n"); + + if (tb_port_is_enabled(out)) { + tb_port_dbg(out, "DP OUT port already enabled\n"); return 0; + } + + tb_port_dbg(out, "finding free DP IN port\n"); do { sw = tb_to_switch(sw->dev.parent); if (!sw) return 0; + tb_sw_dbg(sw, "finding available DP IN\n"); in = tb_find_unused_port(sw, TB_TYPE_DP_HDMI_IN); } while (!in); + tb_port_dbg(in, "found DP IN\n"); + tunnel = tb_tunnel_alloc_dp(tb, in, out); if (!tunnel) { tb_port_dbg(out, "DP tunnel allocation failed\n"); diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 5a99234826e7..93c2c965bdde 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -351,9 +351,23 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in) struct tb_tunnel *tunnel; struct tb_port *port; struct tb_path *path; + u32 data[2]; + int ret; + + tb_port_dbg(in, "start DP discover\n"); - if (!tb_dp_port_is_enabled(in)) + if (!tb_dp_port_is_enabled(in)) { + tb_port_dbg(in, "DP port enabled\n"); return NULL; + } + + ret = tb_port_read(in, data, TB_CFG_PORT, in->cap_adap, + ARRAY_SIZE(data)); + if (ret) + return NULL; + + tb_port_dbg(in, "data[0]=0x%08x\n", data[0]); + tb_port_dbg(in, "data[1]=0x%08x\n", data[1]); tunnel = tb_tunnel_alloc(tb, 3, TB_TUNNEL_DP); if (!tunnel)
| |