thunderbolt: Change TMU mode to HiFi uni-directional once DisplayPort tunneled
authorGil Fine <gil.fine@intel.com>
Thu, 26 May 2022 10:59:21 +0000 (13:59 +0300)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Mon, 6 Jun 2022 09:24:56 +0000 (12:24 +0300)
Here we configure TMU mode to HiFi uni-directional once DP tunnel
is created. This is due to accuracy requirement for DP tunneling
as appears in CM guide 1.0, section 7.3.2.
Due to Intel hardware limitation, once we changed the TMU mode to HiFi
uni-directional (when DP tunnel exists), we don't change TMU mode back to
normal uni-directional, even if DP tunnel is torn down later.

Signed-off-by: Gil Fine <gil.fine@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
drivers/thunderbolt/tb.c
drivers/thunderbolt/tb.h
drivers/thunderbolt/tmu.c

index 8e9fdc4e065089b322675b75eba615f4602bba5e..9853f6c7e81d710156c833cb08ba4346219b305f 100644 (file)
@@ -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:
index 3882b6eb9f51eca3adb7af5dd410d2bcfd502d3d..e2f50fd90ba94a4b31c77bf556f03172e666fd4e 100644 (file)
@@ -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
index e822ab90338bad5aedfb41309620dad9668b022b..626aca3124b1c1fea877fb15ca7147b2a6de5a42 100644 (file)
@@ -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);
+}