@@ -1335,6 +1335,29 @@ static int tb_port_clx_enable(struct tb_port *port, enum tb_clx clx)
return __tb_port_clx_set(port, clx, true);
}
+/**
+ * tb_port_is_clx_enabled() - Is given CL state enabled
+ * @port: USB4 port to check
+ * @clx: CL state to check
+ *
+ * Returns true if given CL state is enabled for @port.
+ */
+bool tb_port_is_clx_enabled(struct tb_port *port, enum tb_clx clx)
+{
+ u32 phy, mask = LANE_ADP_CS_1_CL0S_ENABLE | LANE_ADP_CS_1_CL1_ENABLE;
+ int ret;
+
+ if (!tb_port_clx_supported(port, clx))
+ return false;
+
+ ret = tb_port_read(port, &phy, TB_CFG_PORT,
+ port->cap_phy + LANE_ADP_CS_1, 1);
+ if (ret)
+ return false;
+
+ return (phy & mask) == mask;
+}
+
static int tb_port_start_lane_initialization(struct tb_port *port)
{
int ret;
@@ -1035,6 +1035,13 @@ void tb_port_lane_bonding_disable(struct tb_port *port);
int tb_port_wait_for_link_width(struct tb_port *port, int width,
int timeout_msec);
int tb_port_update_credits(struct tb_port *port);
+bool tb_port_is_clx_enabled(struct tb_port *port, enum tb_clx clx);
+
+static inline bool tb_port_are_clx_enabled(struct tb_port *port)
+{
+ return tb_port_is_clx_enabled(port, TB_CL1) ||
+ tb_port_is_clx_enabled(port, TB_CL2);
+}
int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec);
int tb_switch_find_cap(struct tb_switch *sw, enum tb_switch_cap cap);
We will need these when enabling lane margining support. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> --- drivers/thunderbolt/switch.c | 23 +++++++++++++++++++++++ drivers/thunderbolt/tb.h | 7 +++++++ 2 files changed, 30 insertions(+)