summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/thunderbolt/tb.c13
-rw-r--r--drivers/thunderbolt/tb.h2
-rw-r--r--drivers/thunderbolt/tmu.c29
3 files changed, 44 insertions, 0 deletions
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 8e9fdc4e0650..9853f6c7e81d 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -118,6 +118,13 @@ static void tb_switch_discover_tunnels(struct tb_switch *sw,
switch (port->config.type) {
case TB_TYPE_DP_HDMI_IN:
tunnel = tb_tunnel_discover_dp(tb, port, alloc_hopids);
+ /*
+ * In case of DP tunnel exists, change host router's
+ * 1st children TMU mode to HiFi for CL0s to work.
+ */
+ if (tunnel)
+ tb_switch_enable_tmu_1st_child(tb->root_switch,
+ TB_SWITCH_TMU_RATE_HIFI);
break;
case TB_TYPE_PCIE_DOWN:
@@ -979,6 +986,12 @@ static void tb_tunnel_dp(struct tb *tb)
list_add_tail(&tunnel->list, &tcm->tunnel_list);
tb_reclaim_usb3_bandwidth(tb, in, out);
+ /*
+ * In case of DP tunnel exists, change host router's 1st children
+ * TMU mode to HiFi for CL0s to work.
+ */
+ tb_switch_enable_tmu_1st_child(tb->root_switch, TB_SWITCH_TMU_RATE_HIFI);
+
return;
err_free:
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 3882b6eb9f51..e2f50fd90ba9 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -934,6 +934,8 @@ int tb_switch_tmu_enable(struct tb_switch *sw);
void tb_switch_tmu_configure(struct tb_switch *sw,
enum tb_switch_tmu_rate rate,
bool unidirectional);
+void tb_switch_enable_tmu_1st_child(struct tb_switch *sw,
+ enum tb_switch_tmu_rate rate);
/**
* tb_switch_tmu_is_enabled() - Checks if the specified TMU mode is enabled
* @sw: Router whose TMU mode to check
diff --git a/drivers/thunderbolt/tmu.c b/drivers/thunderbolt/tmu.c
index e822ab90338b..626aca3124b1 100644
--- a/drivers/thunderbolt/tmu.c
+++ b/drivers/thunderbolt/tmu.c
@@ -742,3 +742,32 @@ void tb_switch_tmu_configure(struct tb_switch *sw,
sw->tmu.unidirectional_request = unidirectional;
sw->tmu.rate_request = rate;
}
+
+static int tb_switch_tmu_config_enable(struct device *dev, void *rate)
+{
+ if (tb_is_switch(dev)) {
+ struct tb_switch *sw = tb_to_switch(dev);
+
+ tb_switch_tmu_configure(sw, *(enum tb_switch_tmu_rate *)rate,
+ tb_switch_is_clx_enabled(sw, TB_CL1));
+ if (tb_switch_tmu_enable(sw))
+ tb_sw_dbg(sw, "fail switching TMU mode for 1st depth router\n");
+ }
+
+ return 0;
+}
+
+/**
+ * tb_switch_enable_tmu_1st_child - Configure and enable TMU for 1st chidren
+ * @sw: The router to configure and enable it's children TMU
+ * @rate: Rate of the TMU to configure the router's chidren to
+ *
+ * Configures and enables the TMU mode of 1st depth children of the specified
+ * router to the specified rate.
+ */
+void tb_switch_enable_tmu_1st_child(struct tb_switch *sw,
+ enum tb_switch_tmu_rate rate)
+{
+ device_for_each_child(&sw->dev, &rate,
+ tb_switch_tmu_config_enable);
+}