From patchwork Fri Oct 11 11:31:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13832435 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22B13197A9A for ; Fri, 11 Oct 2024 11:31:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728646298; cv=none; b=IDYsYnnY/VL8M0iyhSaRqWW+UoTwdDKBhYP4C7kwnE5lh+x/93Vc9HHQnRcHCv2zKpca4aIe3oa3jHVsjxOytpPuntDweunKbPDhYe9SUn/Y3ltfrjHaNpwOTw7DtkwCukZ6TuhhrQDofc5U5HkbHtBn9AMUn+6w+ed8N/YZdTc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728646298; c=relaxed/simple; bh=vOXRHFlSNnSPmjDmWUoS/vuYOGol88R+dQjIRs6ZWJg=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=iS6BPtH2sH6jYrtomgQsSWxTFPt7/ry+tpACbvw48IezDYt1L9nfnfqYFbYMogtpb6ws89Y9w0pSiFCtoV2TC98EMOlkmHPg3/9MVekqNqXpRUWIyCTSc7eZHVF3h3n207+4i5KAVwX0jE+CASBZnGVHmABmvg5Xs52NFY/ezEY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=lvaRei8A; arc=none smtp.client-ip=192.198.163.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="lvaRei8A" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728646297; x=1760182297; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=vOXRHFlSNnSPmjDmWUoS/vuYOGol88R+dQjIRs6ZWJg=; b=lvaRei8AXLtXiDHsZAFQs+XwU5Wfhnv9K72hbQlkuXO1gMYfkCdFC4Zn RbrX2tVAF1vipByTWHsXS9LXujjYEMDJNncm3b/XagpilMfyv5+TpeppX Y7ssRQJNn2KQIosaLgizPoM4DHnPhDhbJlLEbR+8of7l+lVBpfmHEA6DK 7HGuV9Y+tflLQGEAxBDU6X+YWDBl2IxzEsfxStejbgqAj6m/nlHN4yYCA x2TyerR+CLtLpsVu7XHxVrSRpny6NaygtHaT0KWiySe9Z4rmvzh0VYdik shAYFesrgH9fXPOgWbRzwYcG9pKs4U48zVL7w9MEWVlXFy4POPh0/wZe1 Q==; X-CSE-ConnectionGUID: 47tAm14QSrmLzuVWg26NuQ== X-CSE-MsgGUID: MjRcQwGBRxqIBSSExYdHIw== X-IronPort-AV: E=McAfee;i="6700,10204,11221"; a="15666041" X-IronPort-AV: E=Sophos;i="6.11,195,1725346800"; d="scan'208";a="15666041" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Oct 2024 04:31:36 -0700 X-CSE-ConnectionGUID: 0DWIk1yWRnKecmV0pdMokA== X-CSE-MsgGUID: ZE5RQReOSC+FXX3e/R5toA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,195,1725346800"; d="scan'208";a="80896936" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa003.fm.intel.com with ESMTP; 11 Oct 2024 04:31:34 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 2BA70184; Fri, 11 Oct 2024 14:31:33 +0300 (EEST) From: Mika Westerberg To: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever Cc: Gil Fine , linux-usb@vger.kernel.org, Mika Westerberg Subject: [PATCH] thunderbolt: Honor TMU requirements in the domain when setting TMU mode Date: Fri, 11 Oct 2024 14:31:33 +0300 Message-ID: <20241011113133.3286723-1-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Gil Fine 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 --- drivers/thunderbolt/tb.c | 48 +++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 10e719dd837c..4f777788e917 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -288,6 +288,24 @@ static void tb_increase_tmu_accuracy(struct tb_tunnel *tunnel) 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; @@ -302,12 +320,30 @@ static int tb_enable_tmu(struct tb_switch *sw) 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;