thunderbolt: Improvements for Alpine and Titan Ridge devices
Subsystems (2)
cover thunderbolt: Improvements for Alpine and Titan Ridge devices
Hi all,
The first two patches implement flows that are needed to bring up the internal xHCI controller when there is USB device connected to the downstream Thunderbolt port of the the router. The last patch disables LTTPR (LT-tunable PHY Repeater, DisplayPort term) when Titan Ridge device router is connected to avoid tunneling issues.
Mika Westerberg (3):
thunderbolt: Add missing device ID to tb_switch_is_alpine_ridge()
thunderbolt: Add internal xHCI connect flows for Thunderbolt 3 devices
thunderbolt: Disable LTTPR on Intel Titan Ridge
drivers/thunderbolt/lc.c | 110 ++++++++++++++++++++++++++++++++++ drivers/thunderbolt/switch.c | 71 +++++++++++++++++++++- drivers/thunderbolt/tb.c | 11 ++++ drivers/thunderbolt/tb.h | 8 +++ drivers/thunderbolt/tb_regs.h | 9 +++ drivers/thunderbolt/tunnel.c | 10 ++++ 6 files changed, 218 insertions(+), 1 deletion(-)
Signature · 1 line
2.34.1
PATCH 1/3 thunderbolt: Add missing device ID to tb_switch_is_alpine_ridge()
tb_switch_is_alpine_ridge() is missing device ID for Intel Alpine Ridge dual port version so add this.
--- drivers/thunderbolt/tb.h | 1 + 1 file changed, 1 insertion(+)
drivers/thunderbolt/tb.h +1 -0
@@ -855,6 +855,7 @@ static inline bool tb_switch_is_alpine_ridge(const struct tb_switch *sw)if (sw->config.vendor_id ==PCI_VENDOR_ID_INTEL ) {switch (sw->config.device_id) {case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE : +case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE :case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_BRIDGE :case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE :case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE :
Signature · 1 line
2.34.1
PATCH 2/3 thunderbolt: Add internal xHCI connect flows for Thunderbolt 3 devices
In reply to Mika WesterbergBoth Alpine Ridge and Titan Ridge require special flows in order to activate the internal xHCI controller when there is USB device connected to the downstream type-C port. This implements the missing flows for both.
--- drivers/thunderbolt/lc.c | 110 ++++++++++++++++++++++++++++++++++ drivers/thunderbolt/switch.c | 71 +++++++++++++++++++++- drivers/thunderbolt/tb.c | 11 ++++ drivers/thunderbolt/tb.h | 7 +++ drivers/thunderbolt/tb_regs.h | 8 +++ 5 files changed, 206 insertions(+), 1 deletion(-)
drivers/thunderbolt/lc.c +110 -0
@@ -217,6 +217,116 @@ bool tb_lc_is_clx_supported(struct tb_port *port)return !!(val &TB_LC_LINK_ATTR_CPS ); } +/** +* tb_lc_is_usb_plugged() - Is there USB device connected to port +* @port: Device router lane 0 adapter +* +* Returns true if the @port has USB type-C device connected. +*/ +bool tb_lc_is_usb_plugged (struct tb_port *port) +{ +struct tb_switch *sw = port->sw; +int cap, ret; +u32 val; + +if (sw->generation !=3 ) +return false; + + cap =find_port_lc_cap (port); +if (cap <0 ) +return false; + + ret =tb_sw_read (sw, &val,TB_CFG_SWITCH , cap +TB_LC_CS_42 ,1 ); +if (ret) +return false; + +return !!(val &TB_LC_CS_42_USB_PLUGGED ); +} + +/** +* tb_lc_is_xhci_connected() - Is the internal xHCI connected +* @port: Device router lane 0 adapter +* +* Returns true if the internal xHCI has been connected to @port. +*/ +bool tb_lc_is_xhci_connected (struct tb_port *port) +{ +struct tb_switch *sw = port->sw; +int cap, ret; +u32 val; + +if (sw->generation !=3 ) +return false; + + cap =find_port_lc_cap (port); +if (cap <0 ) +return false; + + ret =tb_sw_read (sw, &val,TB_CFG_SWITCH , cap +TB_LC_LINK_REQ ,1 ); +if (ret) +return false; + +return !!(val &TB_LC_LINK_REQ_XHCI_CONNECT ); +} + +static int __tb_lc_xhci_connect (struct tb_port *port,bool connect) +{ +struct tb_switch *sw = port->sw; +int cap, ret; +u32 val; + +if (sw->generation !=3 ) +return -EINVAL ; + + cap =find_port_lc_cap (port); +if (cap <0 ) +return cap; + + ret =tb_sw_read (sw, &val,TB_CFG_SWITCH , cap +TB_LC_LINK_REQ ,1 ); +if (ret) +return ret; + +if (connect) + val |=TB_LC_LINK_REQ_XHCI_CONNECT ; +else + val &= ~TB_LC_LINK_REQ_XHCI_CONNECT ; + +return tb_sw_write (sw, &val,TB_CFG_SWITCH , cap +TB_LC_LINK_REQ ,1 ); +} + +/** +* tb_lc_xhci_connect() - Connect internal xHCI +* @port: Device router lane 0 adapter +* +* Tells LC to connect the internal xHCI to @port. Returns %0 in success +* and negative errno in case of failure. Can be called for Thunderbolt 3 +* routers only. +*/ +int tb_lc_xhci_connect (struct tb_port *port) +{ +int ret; + + ret =__tb_lc_xhci_connect (port, true); +if (ret) +return ret; + +tb_port_dbg (port,"xHCI connected\n" ); +return 0 ; +} + +/** +* tb_lc_xhci_disconnect() - Disconnect internal xHCI +* @port: Device router lane 0 adapter +* +* Tells LC to disconnect the internal xHCI from @port. Can be called +* for Thunderbolt 3 routers only. +*/ +void tb_lc_xhci_disconnect (struct tb_port *port) +{ +__tb_lc_xhci_connect (port, false); +tb_port_dbg (port,"xHCI disconnected\n" ); +} +static int tb_lc_set_wake_one (struct tb_switch *sw,unsigned int offset,unsigned int flags) {
drivers/thunderbolt/switch.c +70 -1
80 lines not on this page · raw message
drivers/thunderbolt/tb.c +11 -0
@@ -1054,6 +1054,8 @@ static int tb_disconnect_pci(struct tb *tb, struct tb_switch *sw)if (WARN_ON (!tunnel))return -ENODEV ; +tb_switch_xhci_disconnect (sw); +tb_tunnel_deactivate (tunnel);list_del (&tunnel->list);tb_tunnel_free (tunnel);
@@ -1099,6 +1101,9 @@ static int tb_tunnel_pci(struct tb *tb, struct tb_switch *sw)if (tb_switch_pcie_l1_enable (sw))tb_sw_warn (sw,"failed to enable PCIe L1 for Titan Ridge\n" ); +if (tb_switch_xhci_connect (sw)) +tb_sw_warn (sw,"failed to connect xHCI\n" ); +list_add_tail (&tunnel->list, &tcm->tunnel_list);return 0 ; }
@@ -1256,12 +1261,18 @@ static void tb_handle_hotplug(struct work_struct *work)tb_port_unconfigure_xdomain (port); }else if (tb_port_is_dpout (port) ||tb_port_is_dpin (port)) {tb_dp_resource_unavailable (tb, port); + }else if (!port->port) { +tb_sw_dbg (sw,"xHCI disconnect request\n" ); +tb_switch_xhci_disconnect (sw); }else {tb_port_dbg (port,"got unplug event for disconnected port, ignoring\n" ); } }else if (port->remote) {tb_port_dbg (port,"got plug event for connected port, ignoring\n" ); + }else if (!port->port && sw->authorized) { +tb_sw_dbg (sw,"xHCI connect request\n" ); +tb_switch_xhci_connect (sw); }else {if (tb_port_is_null (port)) {tb_port_dbg (port,"hotplug: scanning\n" );
drivers/thunderbolt/tb.h +7 -0
@@ -988,6 +988,9 @@ int tb_switch_mask_clx_objections(struct tb_switch *sw);int tb_switch_pcie_l1_enable (struct tb_switch *sw); +int tb_switch_xhci_connect (struct tb_switch *sw); +void tb_switch_xhci_disconnect (struct tb_switch *sw); +int tb_wait_for_port (struct tb_port *port,bool wait_if_unplugged);int tb_port_add_nfc_credits (struct tb_port *port,int credits);int tb_port_clear_counter (struct tb_port *port,int counter);
@@ -1082,6 +1085,10 @@ int tb_lc_configure_xdomain(struct tb_port *port);void tb_lc_unconfigure_xdomain (struct tb_port *port);int tb_lc_start_lane_initialization (struct tb_port *port);bool tb_lc_is_clx_supported (struct tb_port *port); +bool tb_lc_is_usb_plugged (struct tb_port *port); +bool tb_lc_is_xhci_connected (struct tb_port *port); +int tb_lc_xhci_connect (struct tb_port *port); +void tb_lc_xhci_disconnect (struct tb_port *port);int tb_lc_set_wake (struct tb_switch *sw,unsigned int flags);int tb_lc_set_sleep (struct tb_switch *sw);bool tb_lc_lane_bonding_possible (struct tb_switch *sw);
drivers/thunderbolt/tb_regs.h +8 -0
@@ -462,6 +462,8 @@ struct tb_regs_hop {#define TMU_ADP_CS_6_DISABLE_TMU_OBJ_CL2 BIT(3)/* Plug Events registers */ +#define TB_PLUG_EVENTS_USB_DISABLE BIT(2) +#define TB_PLUG_EVENTS_PCIE_WR_DATA 0x1b#define TB_PLUG_EVENTS_PCIE_CMD 0x1c#define TB_PLUG_EVENTS_PCIE_CMD_DW_OFFSET_MASK GENMASK(9, 0)
@@ -501,6 +503,9 @@ struct tb_regs_hop {#define TB_LC_POWER 0x740/* Link controller registers */ +#define TB_LC_CS_42 0x2a +#define TB_LC_CS_42_USB_PLUGGED BIT(31) +#define TB_LC_PORT_ATTR 0x8d#define TB_LC_PORT_ATTR_BE BIT(12)
@@ -521,4 +526,7 @@ struct tb_regs_hop {#define TB_LC_LINK_ATTR 0x97#define TB_LC_LINK_ATTR_CPS BIT(18) +#define TB_LC_LINK_REQ 0xad +#define TB_LC_LINK_REQ_XHCI_CONNECT BIT(31) +#endif
Signature · 1 line
2.34.1
Re: [PATCH 2/3] thunderbolt: Add internal xHCI connect flows for Thunderbolt 3 devices
Quoted 5 lines · Mika Westerberg
+/**
+ *tb_lc_xhci_connect()- Connect internal xHCI
+ * @port: Device router lane 0 adapter
+ *
+ * Tells LC to connect the internal xHCI to @port. Returns %0 in success
^^ on
Quoted 3 lines
+ * and negative errno in case of failure. Can be called for Thunderbolt 3
+ * routers only.
+ */
PATCH 3/3 thunderbolt: Disable LTTPR on Intel Titan Ridge
In reply to Mika WesterbergIntel Titan Ridge does not disable AUX timers when it gets SET_CONFIG with SET_LTTPR_MODE set which makes DP tunneling to fail. For this reason disable LTTPR on Titan Ridge device side.
--- drivers/thunderbolt/tb_regs.h | 1 + drivers/thunderbolt/tunnel.c | 10 ++++++++++ 2 files changed, 11 insertions(+)
drivers/thunderbolt/tb_regs.h +1 -0
@@ -389,6 +389,7 @@ struct tb_regs_port_header {#define DP_COMMON_CAP_1_LANE 0x0#define DP_COMMON_CAP_2_LANES 0x1#define DP_COMMON_CAP_4_LANES 0x2 +#define DP_COMMON_CAP_LTTPR_NS BIT(27)#define DP_COMMON_CAP_DPRX_DONE BIT(31)/* PCIe adapter registers */
drivers/thunderbolt/tunnel.c +10 -0
@@ -580,6 +580,16 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) out_dp_cap =tb_dp_cap_set_lanes (out_dp_cap, new_lanes); } +/* +* Titan Ridge does not disable AUX timers when it gets +* SET_CONFIG with SET_LTTPR_MODE set. This causes problems with +* DP tunneling. +*/ +if (tb_route (out->sw) &&tb_switch_is_titan_ridge (out->sw)) { + out_dp_cap |=DP_COMMON_CAP_LTTPR_NS ; +tb_port_dbg (out,"disabling LTTPR\n" ); + } +return tb_port_write (in, &out_dp_cap,TB_CFG_PORT , in->cap_adap +DP_REMOTE_CAP ,1 ); }
Signature · 1 line
2.34.1
Quoted 8 lines · Mika Westerberg
Hi all,
The first two patches implement flows that are needed to bring up the internal xHCI controller when there is USB device connected to the downstream Thunderbolt port of the the router. The last patch disables LTTPR (LT-tunable PHY Repeater, DisplayPort term) when Titan Ridge device router is connected to avoid tunneling issues.
Quoted 4 lines
Mika Westerberg (3):
thunderbolt: Add missing device ID totb_switch_is_alpine_ridge()
thunderbolt: Add internal xHCI connect flows for Thunderbolt 3 devices
thunderbolt: Disable LTTPR on Intel Titan Ridge
Fixed the typo pointed out by Lukas and applied to thunderbolt.git/next.