From 7d59054ee22a5a187868453c93bd065da6e3990c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 5 Nov 2024 17:46:02 +0100 Subject: [PATCH] 6.6-stable patches added patches: thunderbolt-honor-tmu-requirements-in-the-domain-when-setting-tmu-mode.patch --- queue-6.6/series | 1 + ...-in-the-domain-when-setting-tmu-mode.patch | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 queue-6.6/thunderbolt-honor-tmu-requirements-in-the-domain-when-setting-tmu-mode.patch diff --git a/queue-6.6/series b/queue-6.6/series index ccef71bb3ea..b20cefd262f 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -102,3 +102,4 @@ nilfs2-fix-potential-deadlock-with-newly-created-symlinks.patch risc-v-acpi-fix-early_ioremap-to-early_memremap.patch mm-shmem-fix-data-race-in-shmem_getattr.patch tools-mm-werror-fixes-in-page-types-slabinfo.patch +thunderbolt-honor-tmu-requirements-in-the-domain-when-setting-tmu-mode.patch diff --git a/queue-6.6/thunderbolt-honor-tmu-requirements-in-the-domain-when-setting-tmu-mode.patch b/queue-6.6/thunderbolt-honor-tmu-requirements-in-the-domain-when-setting-tmu-mode.patch new file mode 100644 index 00000000000..75a7c649dfe --- /dev/null +++ b/queue-6.6/thunderbolt-honor-tmu-requirements-in-the-domain-when-setting-tmu-mode.patch @@ -0,0 +1,117 @@ +From 3cea8af2d1a9ae5869b47c3dabe3b20f331f3bbd Mon Sep 17 00:00:00 2001 +From: Gil Fine +Date: Thu, 10 Oct 2024 17:29:42 +0300 +Subject: thunderbolt: Honor TMU requirements in the domain when setting TMU mode + +From: Gil Fine + +commit 3cea8af2d1a9ae5869b47c3dabe3b20f331f3bbd upstream. + +Currently, when configuring TMU (Time Management Unit) mode of a given +router, we take into account only its own TMU requirements ignoring +other routers in the domain. This is problematic if the router we are +configuring has lower TMU requirements than what is already configured +in the domain. + +In the scenario below, we have a host router with two USB4 ports: A and +B. Port A connected to device router #1 (which supports CL states) and +existing DisplayPort tunnel, thus, the TMU mode is HiFi uni-directional. + +1. Initial topology + + [Host] + A/ + / + [Device #1] + / +Monitor + +2. Plug in device #2 (that supports CL states) to downstream port B of + the host router + + [Host] + A/ B\ + / \ + [Device #1] [Device #2] + / +Monitor + +The TMU mode on port B and port A will be configured to LowRes which is +not what we want and will cause monitor to start flickering. + +To address this we first scan the domain and search for any router +configured to HiFi uni-directional mode, and if found, configure TMU +mode of the given router to HiFi uni-directional as well. + +Cc: stable@vger.kernel.org +Signed-off-by: Gil Fine +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/tb.c | 48 +++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 42 insertions(+), 6 deletions(-) + +--- a/drivers/thunderbolt/tb.c ++++ b/drivers/thunderbolt/tb.c +@@ -383,6 +383,24 @@ static void tb_increase_tmu_accuracy(str + device_for_each_child(&sw->dev, NULL, tb_increase_switch_tmu_accuracy); + } + ++static int tb_switch_tmu_hifi_uni_required(struct device *dev, void *not_used) ++{ ++ struct tb_switch *sw = tb_to_switch(dev); ++ ++ if (sw && tb_switch_tmu_is_enabled(sw) && ++ tb_switch_tmu_is_configured(sw, TB_SWITCH_TMU_MODE_HIFI_UNI)) ++ return 1; ++ ++ return device_for_each_child(dev, NULL, ++ tb_switch_tmu_hifi_uni_required); ++} ++ ++static bool tb_tmu_hifi_uni_required(struct tb *tb) ++{ ++ return device_for_each_child(&tb->dev, NULL, ++ tb_switch_tmu_hifi_uni_required) == 1; ++} ++ + static int tb_enable_tmu(struct tb_switch *sw) + { + int ret; +@@ -397,12 +415,30 @@ static int tb_enable_tmu(struct tb_switc + ret = tb_switch_tmu_configure(sw, + TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI); + if (ret == -EOPNOTSUPP) { +- if (tb_switch_clx_is_enabled(sw, TB_CL1)) +- ret = tb_switch_tmu_configure(sw, +- TB_SWITCH_TMU_MODE_LOWRES); +- else +- ret = tb_switch_tmu_configure(sw, +- TB_SWITCH_TMU_MODE_HIFI_BI); ++ if (tb_switch_clx_is_enabled(sw, TB_CL1)) { ++ /* ++ * Figure out uni-directional HiFi TMU requirements ++ * currently in the domain. If there are no ++ * uni-directional HiFi requirements we can put the TMU ++ * into LowRes mode. ++ * ++ * Deliberately skip bi-directional HiFi links ++ * as these work independently of other links ++ * (and they do not allow any CL states anyway). ++ */ ++ if (tb_tmu_hifi_uni_required(sw->tb)) ++ ret = tb_switch_tmu_configure(sw, ++ TB_SWITCH_TMU_MODE_HIFI_UNI); ++ else ++ ret = tb_switch_tmu_configure(sw, ++ TB_SWITCH_TMU_MODE_LOWRES); ++ } else { ++ ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI); ++ } ++ ++ /* If not supported, fallback to bi-directional HiFi */ ++ if (ret == -EOPNOTSUPP) ++ ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI); + } + if (ret) + return ret; -- 2.47.3