From patchwork Wed Oct 23 10:11:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 838052 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.13]) (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 596E91A0BE0 for ; Wed, 23 Oct 2024 10:11:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678278; cv=none; b=NP1lwIo50yPOQQzMLiiPAtedAt8bKilxdJm844LQDJ8pkoxLlvyfhXQD/hDzv+iJDGo8SvQZ/mTpMj5FgRgdmzFevZwwrgO4l69ptCpZuqIqJ7FDxBM/Gn1mvulW6r3B2EWreCtAiVlEzqfR3h4bHTh+3xQ8f0w0EycAn8IgE20= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678278; c=relaxed/simple; bh=cwrZYMyff+gycsnPDS3QFfLN8eDPTvJ6uNgN4Xcbn04=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Egir8smZoaHyQg7lsPVhr3APnthh4BizP2gnmz9Uyp/VunHAs01C8Qo+HPgf6LePcRRYdq9cGdo1COJeAFjssUlrfR06wTyBq5nXiP0kJTZSk8Q9Z68bwpUMakCzqtUHJ40xoLjI/O8btwc6KSshR5ekknAAfykfkHNMaQ8BrZc= 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=J0CcLpXY; arc=none smtp.client-ip=192.198.163.13 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="J0CcLpXY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729678277; x=1761214277; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cwrZYMyff+gycsnPDS3QFfLN8eDPTvJ6uNgN4Xcbn04=; b=J0CcLpXYl8e9aFGtslwPGV6p12y7uZ/533DRoRDUp8IOxonHBcLZpeau rFCJu78Vcow05iv6ruGTnFOGS0hVKF+g+BJ/9pYusxDW503JoYP6lhmIJ ZKfKseQbL0sepnHkpIgP5SeL+tyh+FMEQ58wwOa94KFJj3PSfzhpRANdH ZPr5U6hNcLyqqz/qrhI3RJAy69K1Hn77kYk4dLGk0p/cIuTzeyroVHbv9 fXTd21rvsRo4BKvPBQNn3R6YjIwD7KWtlMM8tZ5XScd6m+LkEGqk1E3o2 vxOIaOa3CkRT4bIeGGlK3r7+C+4ntTBzhFWw9rq87M3h3TxkoZVbDwRRg w==; X-CSE-ConnectionGUID: 7wKQwTAiTQCcyKFYlEh8Ng== X-CSE-MsgGUID: CwKitazWT1K2lZx2u70fyg== X-IronPort-AV: E=McAfee;i="6700,10204,11233"; a="32116757" X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="32116757" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Oct 2024 03:11:16 -0700 X-CSE-ConnectionGUID: MYn7MCycQ6yq9CB0lWaPkw== X-CSE-MsgGUID: MRFzJQ9OR36IoNojBK48eA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="80084195" Received: from black.fi.intel.com ([10.237.72.28]) by orviesa010.jf.intel.com with ESMTP; 23 Oct 2024 03:11:13 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 143E2301; Wed, 23 Oct 2024 13:11:12 +0300 (EEST) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Aapo Vienamo , Mika Westerberg Subject: [PATCH 1/8] thunderbolt: Don't hardcode margining capabilities size Date: Wed, 23 Oct 2024 13:11:04 +0300 Message-ID: <20241023101111.3418311-2-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> References: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Aapo Vienamo Use or pass ARRAY_SIZE() of the capabilities array instead of hardcoding it. USB4 Gen 4 introduces an additional data word, which requires expanding the capabilities array. Signed-off-by: Aapo Vienamo Signed-off-by: Mika Westerberg --- drivers/thunderbolt/debugfs.c | 13 ++++++------- drivers/thunderbolt/tb.h | 2 +- drivers/thunderbolt/usb4.c | 5 +++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 350310bd0fee..972f1948725f 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -7,6 +7,7 @@ * Mika Westerberg */ +#include #include #include #include @@ -570,16 +571,13 @@ static int margining_caps_show(struct seq_file *s, void *not_used) { struct tb_margining *margining = s->private; struct tb *tb = margining->port->sw->tb; - u32 cap0, cap1; if (mutex_lock_interruptible(&tb->lock)) return -ERESTARTSYS; /* Dump the raw caps first */ - cap0 = margining->caps[0]; - seq_printf(s, "0x%08x\n", cap0); - cap1 = margining->caps[1]; - seq_printf(s, "0x%08x\n", cap1); + for (int i = 0; i < ARRAY_SIZE(margining->caps); i++) + seq_printf(s, "0x%08x\n", margining->caps[i]); seq_printf(s, "# software margining: %s\n", supports_software(margining) ? "yes" : "no"); @@ -623,7 +621,7 @@ static int margining_caps_show(struct seq_file *s, void *not_used) if (supports_time(margining)) { seq_puts(s, "# time margining: yes\n"); seq_printf(s, "# time margining is destructive: %s\n", - cap1 & USB4_MARGIN_CAP_1_TIME_DESTR ? "yes" : "no"); + str_yes_no(margining->caps[1] & USB4_MARGIN_CAP_1_TIME_DESTR)); switch (independent_time_margins(margining)) { case USB4_MARGIN_CAP_1_TIME_MIN: @@ -1401,7 +1399,8 @@ static struct tb_margining *margining_alloc(struct tb_port *port, margining->index = index; margining->dev = dev; - ret = usb4_port_margining_caps(port, target, index, margining->caps); + ret = usb4_port_margining_caps(port, target, index, margining->caps, + ARRAY_SIZE(margining->caps)); if (ret) { kfree(margining); return NULL; diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 6737188f2581..fa7fc9bba70f 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1388,7 +1388,7 @@ struct usb4_port_margining_params { }; int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, - u8 index, u32 *caps); + u8 index, u32 *caps, size_t ncaps); int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, u8 index, const struct usb4_port_margining_params *params, u32 *results); diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 0a9b4aeb3fa1..1fb72ff1268e 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -1631,11 +1631,12 @@ int usb4_port_asym_start(struct tb_port *port) * @target: Sideband target * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER * @caps: Array with at least two elements to hold the results + * @ncaps: Number of elements in the caps array * * Reads the USB4 port lane margining capabilities into @caps. */ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, - u8 index, u32 *caps) + u8 index, u32 *caps, size_t ncaps) { int ret; @@ -1645,7 +1646,7 @@ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, return ret; return usb4_port_sb_read(port, target, index, USB4_SB_DATA, caps, - sizeof(*caps) * 2); + sizeof(*caps) * ncaps); } /** From patchwork Wed Oct 23 10:11:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 838051 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.13]) (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 251D21A2632 for ; Wed, 23 Oct 2024 10:11:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678280; cv=none; b=YJ5xq9VJlK+v8415cWd4Ro98JA7yX/h7sv+/6emPxAW2R8GhT/tSjXlBnzToXgx5mOvdc46P8VvuHtSrwvnNegQd0X7Fyu46BlqXvwOuDpz4056Qjy5e7o/Iheo5LcdUOVm1Dsyw5MKt4RjehJ/BUsa6tH7OtZp27VNajMXS6hM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678280; c=relaxed/simple; bh=kZ2tXljabZsX0pKzHnlb1jILEXpu8OB8wvuZ2v+TjOc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Kw4FKCreYtwKqTdhHdLtMEfgyyb/QHhL19m8Tu9VHUDcvhKSP0H+C8iJ6Pp30GY6wzWEjnoTyQxC+1YkX/fW8joNX/OHHVVESXv+6yMAlAphON5pxHCfc1jDBqKzBiZrAy4M35oN2VEZ/7/3DZVnWW1SsMiM2psRYdK7rOYX8tk= 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=QsVwmmRK; arc=none smtp.client-ip=192.198.163.13 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="QsVwmmRK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729678278; x=1761214278; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kZ2tXljabZsX0pKzHnlb1jILEXpu8OB8wvuZ2v+TjOc=; b=QsVwmmRKL6HQLAk/CHinTvUeRskzc3YS28bddWNBYCYRAF70gwLbAGSf WRGFzsTORLx0fuGmbhAcHtJjIXeBWoZD00qtuT2/dCJ5U2EV4VtobL5zJ kk43HFN3lhS7idHWNApS3jpuPwuHThI47auSCSMflCboxBlfcbOQm9/Av yMYWFyH75HZOChekr3vqlkOFxxRToFLoThyxhvL0z/48nsOLfsrbNO9En bhQML20cjnlrzmUleSAxbiefbi13cXsgiSsrgZH8ijPQjwyzMFYv+At+M oHDm7pafAxzIker19uZL1+r6rzR88RZ76RSyzLzLABOhYGP0iwdh/82tJ Q==; X-CSE-ConnectionGUID: 5H4ebyMkTl2/OftrIbBHnA== X-CSE-MsgGUID: DjiJQPuUTiaMmWHSoXY8/A== X-IronPort-AV: E=McAfee;i="6700,10204,11233"; a="32116762" X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="32116762" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Oct 2024 03:11:16 -0700 X-CSE-ConnectionGUID: dHpIBav5SXy97zDun1nhqA== X-CSE-MsgGUID: LW65pxT8QkGd9DAhqZbEzg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="80084197" Received: from black.fi.intel.com ([10.237.72.28]) by orviesa010.jf.intel.com with ESMTP; 23 Oct 2024 03:11:13 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 1E3E437D; Wed, 23 Oct 2024 13:11:12 +0300 (EEST) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Aapo Vienamo , Mika Westerberg Subject: [PATCH 2/8] thunderbolt: debugfs: Add USB4 Gen 4 margining capabilities Date: Wed, 23 Oct 2024 13:11:05 +0300 Message-ID: <20241023101111.3418311-3-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> References: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Aapo Vienamo Parse the Gen 4 specific capabilities. Change the return types of independent_voltage_margins() and independent_time_margins() to enums that distinguish between the Gen 2/3 and Gen 4 margins since they behave differently between generations. Signed-off-by: Aapo Vienamo Signed-off-by: Mika Westerberg --- drivers/thunderbolt/debugfs.c | 143 ++++++++++++++++++++++++++++------ drivers/thunderbolt/sb_regs.h | 11 +++ 2 files changed, 131 insertions(+), 23 deletions(-) diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 972f1948725f..83721ca069a5 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -44,6 +44,24 @@ #define MAX_DWELL_TIME 500 /* ms */ #define DWELL_SAMPLE_INTERVAL 10 +enum usb4_margin_cap_voltage_indp { + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_MIN, + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_HL, + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_BOTH, + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_MIN, + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_BOTH, + USB4_MARGIN_CAP_VOLTAGE_INDP_UNKNOWN, +}; + +enum usb4_margin_cap_time_indp { + USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_MIN, + USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_LR, + USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_BOTH, + USB4_MARGIN_CAP_TIME_INDP_GEN_4_MIN, + USB4_MARGIN_CAP_TIME_INDP_GEN_4_BOTH, + USB4_MARGIN_CAP_TIME_INDP_UNKNOWN, +}; + /* Sideband registers and their sizes as defined in the USB4 spec */ struct sb_reg { unsigned int reg; @@ -396,6 +414,7 @@ static ssize_t retimer_sb_regs_write(struct file *file, * @target: Sideband target * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER * @dev: Pointer to the device that is the target (USB4 port or retimer) + * @gen: Link generation * @caps: Port lane margining capabilities * @results: Last lane margining results * @lanes: %0, %1 or %7 (all) @@ -423,7 +442,8 @@ struct tb_margining { enum usb4_sb_target target; u8 index; struct device *dev; - u32 caps[2]; + unsigned int gen; + u32 caps[3]; u32 results[2]; unsigned int lanes; unsigned int min_ber_level; @@ -464,12 +484,16 @@ static int margining_modify_error_counter(struct tb_margining *margining, static bool supports_software(const struct tb_margining *margining) { - return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_SW; + if (margining->gen < 4) + return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_SW; + return margining->caps[2] & USB4_MARGIN_CAP_2_MODES_SW; } static bool supports_hardware(const struct tb_margining *margining) { - return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_HW; + if (margining->gen < 4) + return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_HW; + return margining->caps[2] & USB4_MARGIN_CAP_2_MODES_HW; } static bool both_lanes(const struct tb_margining *margining) @@ -477,22 +501,58 @@ static bool both_lanes(const struct tb_margining *margining) return margining->caps[0] & USB4_MARGIN_CAP_0_2_LANES; } -static unsigned int +static enum usb4_margin_cap_voltage_indp independent_voltage_margins(const struct tb_margining *margining) { - return FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK, margining->caps[0]); + if (margining->gen < 4) { + switch (FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK, margining->caps[0])) { + case USB4_MARGIN_CAP_0_VOLTAGE_MIN: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_MIN; + case USB4_MARGIN_CAP_0_VOLTAGE_HL: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_HL; + case USB4_MARGIN_CAP_1_TIME_BOTH: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_BOTH; + } + } else { + switch (FIELD_GET(USB4_MARGIN_CAP_2_VOLTAGE_INDP_MASK, margining->caps[2])) { + case USB4_MARGIN_CAP_2_VOLTAGE_MIN: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_MIN; + case USB4_MARGIN_CAP_2_VOLTAGE_BOTH: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_BOTH; + } + } + return USB4_MARGIN_CAP_VOLTAGE_INDP_UNKNOWN; } static bool supports_time(const struct tb_margining *margining) { - return margining->caps[0] & USB4_MARGIN_CAP_0_TIME; + if (margining->gen < 4) + return margining->caps[0] & USB4_MARGIN_CAP_0_TIME; + return margining->caps[2] & USB4_MARGIN_CAP_2_TIME; } /* Only applicable if supports_time() returns true */ -static unsigned int +static enum usb4_margin_cap_time_indp independent_time_margins(const struct tb_margining *margining) { - return FIELD_GET(USB4_MARGIN_CAP_1_TIME_INDP_MASK, margining->caps[1]); + if (margining->gen < 4) { + switch (FIELD_GET(USB4_MARGIN_CAP_1_TIME_INDP_MASK, margining->caps[1])) { + case USB4_MARGIN_CAP_1_TIME_MIN: + return USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_MIN; + case USB4_MARGIN_CAP_1_TIME_LR: + return USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_LR; + case USB4_MARGIN_CAP_1_TIME_BOTH: + return USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_BOTH; + } + } else { + switch (FIELD_GET(USB4_MARGIN_CAP_2_TIME_INDP_MASK, margining->caps[2])) { + case USB4_MARGIN_CAP_2_TIME_MIN: + return USB4_MARGIN_CAP_TIME_INDP_GEN_4_MIN; + case USB4_MARGIN_CAP_2_TIME_BOTH: + return USB4_MARGIN_CAP_TIME_INDP_GEN_4_BOTH; + } + } + return USB4_MARGIN_CAP_TIME_INDP_UNKNOWN; } static bool @@ -571,6 +631,7 @@ static int margining_caps_show(struct seq_file *s, void *not_used) { struct tb_margining *margining = s->private; struct tb *tb = margining->port->sw->tb; + int ret = 0; if (mutex_lock_interruptible(&tb->lock)) return -ERESTARTSYS; @@ -607,15 +668,26 @@ static int margining_caps_show(struct seq_file *s, void *not_used) } switch (independent_voltage_margins(margining)) { - case USB4_MARGIN_CAP_0_VOLTAGE_MIN: + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_MIN: seq_puts(s, "# returns minimum between high and low voltage margins\n"); break; - case USB4_MARGIN_CAP_0_VOLTAGE_HL: + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_HL: seq_puts(s, "# returns high or low voltage margin\n"); break; - case USB4_MARGIN_CAP_0_VOLTAGE_BOTH: + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_BOTH: seq_puts(s, "# returns both high and low margins\n"); break; + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_MIN: + seq_puts(s, "# returns minimum between high and low voltage margins in both lower and upper eye\n"); + break; + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_BOTH: + seq_puts(s, "# returns both high and low margins of both upper and lower eye\n"); + break; + case USB4_MARGIN_CAP_VOLTAGE_INDP_UNKNOWN: + tb_port_warn(margining->port, + "failed to parse independent voltage margining capabilities\n"); + ret = -EIO; + goto out; } if (supports_time(margining)) { @@ -624,15 +696,26 @@ static int margining_caps_show(struct seq_file *s, void *not_used) str_yes_no(margining->caps[1] & USB4_MARGIN_CAP_1_TIME_DESTR)); switch (independent_time_margins(margining)) { - case USB4_MARGIN_CAP_1_TIME_MIN: + case USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_MIN: seq_puts(s, "# returns minimum between left and right time margins\n"); break; - case USB4_MARGIN_CAP_1_TIME_LR: + case USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_LR: seq_puts(s, "# returns left or right margin\n"); break; - case USB4_MARGIN_CAP_1_TIME_BOTH: + case USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_BOTH: seq_puts(s, "# returns both left and right margins\n"); break; + case USB4_MARGIN_CAP_TIME_INDP_GEN_4_MIN: + seq_puts(s, "# returns minimum between left and right time margins in both lower and upper eye\n"); + break; + case USB4_MARGIN_CAP_TIME_INDP_GEN_4_BOTH: + seq_puts(s, "# returns both left and right margins of both upper and lower eye\n"); + break; + case USB4_MARGIN_CAP_TIME_INDP_UNKNOWN: + tb_port_warn(margining->port, + "failed to parse independent time margining capabilities\n"); + ret = -EIO; + goto out; } seq_printf(s, "# time margin steps: %u\n", @@ -643,8 +726,9 @@ static int margining_caps_show(struct seq_file *s, void *not_used) seq_puts(s, "# time margining: no\n"); } +out: mutex_unlock(&tb->lock); - return 0; + return ret; } DEBUGFS_ATTR_RO(margining_caps); @@ -1390,6 +1474,12 @@ static struct tb_margining *margining_alloc(struct tb_port *port, unsigned int val; int ret; + ret = tb_port_get_link_generation(port); + if (ret < 0) { + tb_port_warn(port, "failed to read link generation\n"); + return NULL; + } + margining = kzalloc(sizeof(*margining), GFP_KERNEL); if (!margining) return NULL; @@ -1398,6 +1488,7 @@ static struct tb_margining *margining_alloc(struct tb_port *port, margining->target = target; margining->index = index; margining->dev = dev; + margining->gen = ret; ret = usb4_port_margining_caps(port, target, index, margining->caps, ARRAY_SIZE(margining->caps)); @@ -1410,10 +1501,17 @@ static struct tb_margining *margining_alloc(struct tb_port *port, if (supports_software(margining)) margining->software = true; - val = FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_STEPS_MASK, margining->caps[0]); - margining->voltage_steps = val; - val = FIELD_GET(USB4_MARGIN_CAP_0_MAX_VOLTAGE_OFFSET_MASK, margining->caps[0]); - margining->max_voltage_offset = 74 + val * 2; + if (margining->gen < 4) { + val = FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_STEPS_MASK, margining->caps[0]); + margining->voltage_steps = val; + val = FIELD_GET(USB4_MARGIN_CAP_0_MAX_VOLTAGE_OFFSET_MASK, margining->caps[0]); + margining->max_voltage_offset = 74 + val * 2; + } else { + val = FIELD_GET(USB4_MARGIN_CAP_2_VOLTAGE_STEPS_MASK, margining->caps[2]); + margining->voltage_steps = val; + val = FIELD_GET(USB4_MARGIN_CAP_2_MAX_VOLTAGE_OFFSET_MASK, margining->caps[2]); + margining->max_voltage_offset = 74 + val * 2; + } if (supports_optional_voltage_offset_range(margining)) { val = FIELD_GET(USB4_MARGIN_CAP_0_VOLT_STEPS_OPT_MASK, @@ -1455,11 +1553,10 @@ static struct tb_margining *margining_alloc(struct tb_port *port, debugfs_create_file("results", 0600, dir, margining, &margining_results_fops); debugfs_create_file("test", 0600, dir, margining, &margining_test_fops); - if (independent_voltage_margins(margining) == USB4_MARGIN_CAP_0_VOLTAGE_HL || + if (independent_voltage_margins(margining) == USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_HL || (supports_time(margining) && - independent_time_margins(margining) == USB4_MARGIN_CAP_1_TIME_LR)) - debugfs_create_file("margin", 0600, dir, margining, - &margining_margin_fops); + independent_time_margins(margining) == USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_LR)) + debugfs_create_file("margin", 0600, dir, margining, &margining_margin_fops); margining->error_counter = USB4_MARGIN_SW_ERROR_COUNTER_CLEAR; margining->dwell_time = MIN_DWELL_TIME; diff --git a/drivers/thunderbolt/sb_regs.h b/drivers/thunderbolt/sb_regs.h index dbcad25ead50..f60b8d90a71a 100644 --- a/drivers/thunderbolt/sb_regs.h +++ b/drivers/thunderbolt/sb_regs.h @@ -69,6 +69,17 @@ enum usb4_sb_opcode { #define USB4_MARGIN_CAP_1_TIME_OFFSET_MASK GENMASK(20, 16) #define USB4_MARGIN_CAP_1_MIN_BER_MASK GENMASK(25, 21) #define USB4_MARGIN_CAP_1_MAX_BER_MASK GENMASK(30, 26) +#define USB4_MARGIN_CAP_2_MODES_HW BIT(0) +#define USB4_MARGIN_CAP_2_MODES_SW BIT(1) +#define USB4_MARGIN_CAP_2_TIME BIT(2) +#define USB4_MARGIN_CAP_2_MAX_VOLTAGE_OFFSET_MASK GENMASK(8, 3) +#define USB4_MARGIN_CAP_2_VOLTAGE_STEPS_MASK GENMASK(15, 9) +#define USB4_MARGIN_CAP_2_VOLTAGE_INDP_MASK GENMASK(17, 16) +#define USB4_MARGIN_CAP_2_VOLTAGE_MIN 0x0 +#define USB4_MARGIN_CAP_2_VOLTAGE_BOTH 0x1 +#define USB4_MARGIN_CAP_2_TIME_INDP_MASK GENMASK(19, 18) +#define USB4_MARGIN_CAP_2_TIME_MIN 0x0 +#define USB4_MARGIN_CAP_2_TIME_BOTH 0x1 /* USB4_SB_OPCODE_RUN_HW_LANE_MARGINING */ #define USB4_MARGIN_HW_TIME BIT(3) From patchwork Wed Oct 23 10:11:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 838738 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 B261A1A38E1 for ; Wed, 23 Oct 2024 10:11:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678282; cv=none; b=rK+GJM0SqxiVRUT+ZQ1A2u6Ho2Yddjh6oGsHJ1/KbCgKFqFLBaXszuQD05iusAuYKj0YHBit9m+ktTe4/ej1kPVLhUtebS9ihg/6vBGXERY6/c3ntmRLA1KUwoyJpv1wM8jkTkXoQlHy1GvnhwQOU5l8mQdGy3TjlDelDeboEvo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678282; c=relaxed/simple; bh=9Doqg0wIvyHKPq8p3KJV96nqP7oiy48VughLE2RwEJ8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mTaV9xe/SM+7I2E7XKlaXt1gM5pDQJZkfZi7pQ/O7LgQG6pPs9en4SjsZ7jVB+NedrzDzLCwWovzvefib3SpyGooyam3HD1yLdD1dPXAblu86jzgwZW/ffx0MsqPRAL+3pLtH8LfdWT5eB57A/xaHWeGiB9sqHeHbmfHSrLYC0M= 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=Okpt+xDp; arc=none smtp.client-ip=192.198.163.17 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="Okpt+xDp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729678280; x=1761214280; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9Doqg0wIvyHKPq8p3KJV96nqP7oiy48VughLE2RwEJ8=; b=Okpt+xDp5mRvGNX7NXvbrSOGsd0IbO3ySE9YxP90rKlvcijVixnjkTZc wsIX2ssL8mL5esSE6wYAJ/CamE8roy31ELBp4aXAXNAqqunM+RYfNrFOg nacP7JKGq2jZrsH0cGUDVcmR7TUjcCdtt1PBOhBVQZtWiwkx4a3rqZdZ3 sz0ElCqDaMZild9t+taPwpaHxIC6s60t8YgESZ2nm5aWUxfqyzTe1SQC9 VO0a7d8fYVZcPdBQxHmD6dEwBiYp16vRXCKI2LjU84m/njTKpl/vSTOPK LLQ4SMWm2nDI8m+2wze8+YwVkGQoXzkdqIoZI4/EvGNzZrdBmSvbKwyQG Q==; X-CSE-ConnectionGUID: nhfZecCcRaS34XjbP+si5A== X-CSE-MsgGUID: SP2C9tgDSJSOtQkIQGr7Cg== X-IronPort-AV: E=McAfee;i="6700,10204,11233"; a="29149608" X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="29149608" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Oct 2024 03:11:15 -0700 X-CSE-ConnectionGUID: JYmgvN0qQq6Ujlp7K+EM0A== X-CSE-MsgGUID: LnNb0yj7QKWFXKX2b+VFDA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="84954602" Received: from black.fi.intel.com ([10.237.72.28]) by orviesa005.jf.intel.com with ESMTP; 23 Oct 2024 03:11:14 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 286373F0; Wed, 23 Oct 2024 13:11:12 +0300 (EEST) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Aapo Vienamo , Mika Westerberg Subject: [PATCH 3/8] thunderbolt: debugfs: Implement Gen 4 margining eye selection Date: Wed, 23 Oct 2024 13:11:06 +0300 Message-ID: <20241023101111.3418311-4-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> References: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Aapo Vienamo Add a debugfs knob for USB4 Gen 4 margining eye selection. Gen 4 uses 3-level pulse amplitude modulation (PAM3) which changes how margining measurements are made because PAM3 has two eyes per lane from which the margins can be measured. Signed-off-by: Aapo Vienamo Signed-off-by: Mika Westerberg --- drivers/thunderbolt/debugfs.c | 58 +++++++++++++++++++++++++++++++++++ drivers/thunderbolt/sb_regs.h | 3 +- drivers/thunderbolt/tb.h | 1 + drivers/thunderbolt/usb4.c | 6 ++-- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 83721ca069a5..699e1632e3f5 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -436,6 +436,8 @@ static ssize_t retimer_sb_regs_write(struct file *file, * @time: %true if time margining is used instead of voltage * @right_high: %false if left/low margin test is performed, %true if * right/high + * @upper_eye: %false if the lower PAM3 eye is used, %true if the upper + * eye is used */ struct tb_margining { struct tb_port *port; @@ -462,6 +464,7 @@ struct tb_margining { bool software; bool time; bool right_high; + bool upper_eye; }; static int margining_modify_error_counter(struct tb_margining *margining, @@ -1162,6 +1165,7 @@ static int margining_run_write(void *data, u64 val) .time = margining->time, .voltage_time_offset = margining->voltage_time_offset, .right_high = margining->right_high, + .upper_eye = margining->upper_eye, .optional_voltage_offset_range = margining->optional_voltage_offset_range, }; @@ -1177,6 +1181,7 @@ static int margining_run_write(void *data, u64 val) .lanes = margining->lanes, .time = margining->time, .right_high = margining->right_high, + .upper_eye = margining->upper_eye, .optional_voltage_offset_range = margining->optional_voltage_offset_range, }; @@ -1464,6 +1469,55 @@ static int margining_margin_show(struct seq_file *s, void *not_used) } DEBUGFS_ATTR_RW(margining_margin); +static ssize_t margining_eye_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct tb_port *port = s->private; + struct usb4_port *usb4 = port->usb4; + struct tb *tb = port->sw->tb; + int ret = 0; + char *buf; + + buf = validate_and_copy_from_user(user_buf, &count); + if (IS_ERR(buf)) + return PTR_ERR(buf); + + buf[count - 1] = '\0'; + + scoped_cond_guard(mutex_intr, ret = -ERESTARTSYS, &tb->lock) { + if (!strcmp(buf, "lower")) + usb4->margining->upper_eye = false; + else if (!strcmp(buf, "upper")) + usb4->margining->upper_eye = true; + else + ret = -EINVAL; + } + + free_page((unsigned long)buf); + return ret ? ret : count; +} + +static int margining_eye_show(struct seq_file *s, void *not_used) +{ + struct tb_port *port = s->private; + struct usb4_port *usb4 = port->usb4; + struct tb *tb = port->sw->tb; + + scoped_guard(mutex_intr, &tb->lock) { + if (usb4->margining->upper_eye) + seq_puts(s, "lower [upper]\n"); + else + seq_puts(s, "[lower] upper\n"); + + return 0; + } + + return -ERESTARTSYS; +} +DEBUGFS_ATTR_RW(margining_eye); + static struct tb_margining *margining_alloc(struct tb_port *port, struct device *dev, enum usb4_sb_target target, @@ -1573,6 +1627,10 @@ static struct tb_margining *margining_alloc(struct tb_port *port, debugfs_create_file("dwell_time", DEBUGFS_MODE, dir, margining, &margining_dwell_time_fops); } + + if (margining->gen >= 4) + debugfs_create_file("eye", 0600, dir, port, &margining_eye_fops); + return margining; } diff --git a/drivers/thunderbolt/sb_regs.h b/drivers/thunderbolt/sb_regs.h index f60b8d90a71a..b7e91b99fefe 100644 --- a/drivers/thunderbolt/sb_regs.h +++ b/drivers/thunderbolt/sb_regs.h @@ -83,7 +83,7 @@ enum usb4_sb_opcode { /* USB4_SB_OPCODE_RUN_HW_LANE_MARGINING */ #define USB4_MARGIN_HW_TIME BIT(3) -#define USB4_MARGIN_HW_RH BIT(4) +#define USB4_MARGIN_HW_RHU BIT(4) #define USB4_MARGIN_HW_BER_MASK GENMASK(9, 5) #define USB4_MARGIN_HW_BER_SHIFT 5 #define USB4_MARGIN_HW_OPT_VOLTAGE BIT(10) @@ -106,6 +106,7 @@ enum usb4_sb_opcode { #define USB4_MARGIN_SW_OPT_VOLTAGE BIT(5) #define USB4_MARGIN_SW_VT_MASK GENMASK(12, 6) #define USB4_MARGIN_SW_COUNTER_MASK GENMASK(14, 13) +#define USB4_MARGIN_SW_UPPER_EYE BIT(15) #define USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK GENMASK(3, 0) #define USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK GENMASK(7, 4) diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index fa7fc9bba70f..ced9be271620 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1384,6 +1384,7 @@ struct usb4_port_margining_params { u32 voltage_time_offset; bool optional_voltage_offset_range; bool right_high; + bool upper_eye; bool time; }; diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 1fb72ff1268e..985f24b044b3 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -1673,8 +1673,8 @@ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, val = params->lanes; if (params->time) val |= USB4_MARGIN_HW_TIME; - if (params->right_high) - val |= USB4_MARGIN_HW_RH; + if (params->right_high || params->upper_eye) + val |= USB4_MARGIN_HW_RHU; if (params->ber_level) val |= FIELD_PREP(USB4_MARGIN_HW_BER_MASK, params->ber_level); if (params->optional_voltage_offset_range) @@ -1723,6 +1723,8 @@ int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target, val |= USB4_MARGIN_SW_OPT_VOLTAGE; if (params->right_high) val |= USB4_MARGIN_SW_RH; + if (params->upper_eye) + val |= USB4_MARGIN_SW_UPPER_EYE; val |= FIELD_PREP(USB4_MARGIN_SW_COUNTER_MASK, params->error_counter); val |= FIELD_PREP(USB4_MARGIN_SW_VT_MASK, params->voltage_time_offset); From patchwork Wed Oct 23 10:11:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 838741 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 7DB0519F438 for ; Wed, 23 Oct 2024 10:11:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678279; cv=none; b=AqVt9qh6i9igp5y+z2CoI4/6JhOPN1V9Mn92M1lVOZULpT0dHDfJjrKP2ZCq/1QJROPo6LKDFKcV+L06w+yGkXoSaGW3Q9dLteq6hwIREVyIBWS8tEfDp5liFjyHYTq+ibVtFCOUoPrseuddGVbKm4BeJVf9XWIL/cnNrJk1pjo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678279; c=relaxed/simple; bh=tqGAXK2Jg7SLUZO+dTZt1sfym7dfAI1q4koqUg2dC6I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SGeUUKHyAp+TXr/U9bgFp3CiGKtJoBWsqHF9oohIaqsBQ2Q8ezfVIz0SuEE2kj9bRVRkgN0hCitF+2oT+XHK+w+sWvbDGC/U4kgd3U4+c2BH0XJ1XgH32HiXMAFVAzUMflicYdkF9BRCJpzfC77jj60gAwR8QoxLnAV1E4ujXbc= 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=e6FiTYa9; arc=none smtp.client-ip=192.198.163.17 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="e6FiTYa9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729678278; x=1761214278; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tqGAXK2Jg7SLUZO+dTZt1sfym7dfAI1q4koqUg2dC6I=; b=e6FiTYa9TZmZh6/n50i9SQZKQudLlHD+dIFK2ebdLYb2tPuyLhxUd3kN jIN+OlTpf1CJqpyX6IVuvJWGDgo6y9bpNrmRBgxH/U/QWalMJenr28T/O m3uCN+saQph/6f8YBmCGfFfm+D2cqnycV7LBfIBhy0gxGMbgwb3PgDslV NzGewzd+3+qUTTd08PwajbvkyKDK6OV0WCyNeGw1IeImWQsOnHwEEL0pT +s2tx4KEF5Muu02ig4DROnfTGQ1feUOkyyRYUvjKmmsFXvhQ3XXW0hIqT AmZpA1/5CWISp/JzkbGfB3gVCIkxPlNBkSQWR5XfGBfCNSZadPjxnfSCl Q==; X-CSE-ConnectionGUID: z2VB6IFqR7mKOo87GlfscA== X-CSE-MsgGUID: GnI2X22hTfSCftvffqpZIQ== X-IronPort-AV: E=McAfee;i="6700,10204,11233"; a="29149605" X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="29149605" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Oct 2024 03:11:15 -0700 X-CSE-ConnectionGUID: UalW/7uTRx+Shxo4EQKCOA== X-CSE-MsgGUID: kSztRxHGTa6a4852/mb+Jg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="84954600" Received: from black.fi.intel.com ([10.237.72.28]) by orviesa005.jf.intel.com with ESMTP; 23 Oct 2024 03:11:14 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 364614FD; Wed, 23 Oct 2024 13:11:12 +0300 (EEST) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Aapo Vienamo , Mika Westerberg Subject: [PATCH 4/8] thunderbolt: debugfs: Replace "both lanes" with "all lanes" Date: Wed, 23 Oct 2024 13:11:07 +0300 Message-ID: <20241023101111.3418311-5-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> References: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Aapo Vienamo With USB4 Gen 4, the link can be configured into an asymmetric mode, where there are three receivers and only one transmitter. The USB4 specification also uses the "all lanes" nomenclature instead of "both lanes". Signed-off-by: Aapo Vienamo Signed-off-by: Mika Westerberg --- drivers/thunderbolt/debugfs.c | 12 ++++++------ drivers/thunderbolt/sb_regs.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 699e1632e3f5..5f9f8babeae2 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -499,9 +499,9 @@ static bool supports_hardware(const struct tb_margining *margining) return margining->caps[2] & USB4_MARGIN_CAP_2_MODES_HW; } -static bool both_lanes(const struct tb_margining *margining) +static bool all_lanes(const struct tb_margining *margining) { - return margining->caps[0] & USB4_MARGIN_CAP_0_2_LANES; + return margining->caps[0] & USB4_MARGIN_CAP_0_ALL_LANES; } static enum usb4_margin_cap_voltage_indp @@ -655,8 +655,8 @@ static int margining_caps_show(struct seq_file *s, void *not_used) seq_puts(s, "# hardware margining: no\n"); } - seq_printf(s, "# both lanes simultaneously: %s\n", - both_lanes(margining) ? "yes" : "no"); + seq_printf(s, "# all lanes simultaneously: %s\n", + str_yes_no(all_lanes(margining))); seq_printf(s, "# voltage margin steps: %u\n", margining->voltage_steps); seq_printf(s, "# maximum voltage offset: %u mV\n", @@ -762,7 +762,7 @@ margining_lanes_write(struct file *file, const char __user *user_buf, margining->lanes = 1; } else if (!strcmp(buf, "all")) { /* Needs to be supported */ - if (both_lanes(margining)) + if (all_lanes(margining)) margining->lanes = 7; else ret = -EINVAL; @@ -787,7 +787,7 @@ static int margining_lanes_show(struct seq_file *s, void *not_used) return -ERESTARTSYS; lanes = margining->lanes; - if (both_lanes(margining)) { + if (all_lanes(margining)) { if (!lanes) seq_puts(s, "[0] 1 all\n"); else if (lanes == 1) diff --git a/drivers/thunderbolt/sb_regs.h b/drivers/thunderbolt/sb_regs.h index b7e91b99fefe..a3652b9cb246 100644 --- a/drivers/thunderbolt/sb_regs.h +++ b/drivers/thunderbolt/sb_regs.h @@ -49,7 +49,7 @@ enum usb4_sb_opcode { /* USB4_SB_OPCODE_READ_LANE_MARGINING_CAP */ #define USB4_MARGIN_CAP_0_MODES_HW BIT(0) #define USB4_MARGIN_CAP_0_MODES_SW BIT(1) -#define USB4_MARGIN_CAP_0_2_LANES BIT(2) +#define USB4_MARGIN_CAP_0_ALL_LANES BIT(2) #define USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK GENMASK(4, 3) #define USB4_MARGIN_CAP_0_VOLTAGE_MIN 0x0 #define USB4_MARGIN_CAP_0_VOLTAGE_HL 0x1 From patchwork Wed Oct 23 10:11:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 838740 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 563651A2C29 for ; Wed, 23 Oct 2024 10:11:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678281; cv=none; b=Unj4+NDfho49S0OxQKOnCw8/KUWfuz7ts4z0iPM6a+c+3qEN4afwr6/QfHHyMUz1FAP1oJRVDvfyDubrOR0hwqlsJ3lFhamKye6q4jK7FLWxJECGHDDZMgKWtpy290a3TMbi1QtL+up0W/cJHoqUWt84SQARA+fxQM6Q8UbdXRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678281; c=relaxed/simple; bh=duEL0YiiFk7uKom6bDRLp7avASuvtmCBw1GfWXgIjxI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nIO6Tv57FEjyNOVfNh7+hvrxOJjAyGqEbUGnEFKnSMHFPpzw9nDWP/8swVAdG+Iw0C51ouw+BI8/6TFB97YDiAbs5bScByHunlY5syMUEU+nUiKAmGB9/KUabbVl/nSWgFW8ZmHcUhnmx5OgOlQkMlRhQcqmjcASj5CeP/tjKNY= 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=WQbskab9; arc=none smtp.client-ip=192.198.163.17 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="WQbskab9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729678279; x=1761214279; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=duEL0YiiFk7uKom6bDRLp7avASuvtmCBw1GfWXgIjxI=; b=WQbskab9rp+5qpPJutLCTT9LAvMoTCFQLup+s1AV8Z0jsEWY3BPuX6UQ 76OR6x6FEwXLuA5WyNrqQVg2AyJ2DQWAYam6GiPEOSUFBTW/21ZmxP/59 /EmLmTHfk3gDfULy3Hvrm/2v99D9lb+74KwQC+nOc2iygGdnYJnbjDDSt J0f+J23ZQ+uSTZR+Nx6cOMteKO2BuxrNP7lwSqYAKOddE52xaOdaWmRLj STaSR5MVoOqglXU3nA8NiipQWvRVaKFfN5ZaXT5s/1yuWManyYNoC8Grt SNx5OGoJEg/94BX9vw61X/E2oqahLYKqLcDb/sr4emO9hunM/YWPppYpt g==; X-CSE-ConnectionGUID: p8aFO5rlSr2s+WrAslJaKQ== X-CSE-MsgGUID: GGbMQWm+QjCUcXZ+NXc5KA== X-IronPort-AV: E=McAfee;i="6700,10204,11233"; a="29149614" X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="29149614" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Oct 2024 03:11:18 -0700 X-CSE-ConnectionGUID: wMwy1pM/Tz+hNYWNocDjyQ== X-CSE-MsgGUID: 21GU/grnSc6kPS0iKK2V2g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="84954631" Received: from black.fi.intel.com ([10.237.72.28]) by orviesa005.jf.intel.com with ESMTP; 23 Oct 2024 03:11:16 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 4C3647F9; Wed, 23 Oct 2024 13:11:12 +0300 (EEST) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Aapo Vienamo , Mika Westerberg Subject: [PATCH 5/8] thunderbolt: debugfs: Replace margining lane numbers with an enum Date: Wed, 23 Oct 2024 13:11:08 +0300 Message-ID: <20241023101111.3418311-6-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> References: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Aapo Vienamo Replace the raw values and macros with an enum and use it consistently. No functional changes. Signed-off-by: Aapo Vienamo Signed-off-by: Mika Westerberg --- drivers/thunderbolt/debugfs.c | 46 +++++++++++++++++++---------------- drivers/thunderbolt/sb_regs.h | 3 --- drivers/thunderbolt/tb.h | 10 ++++++-- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 5f9f8babeae2..3404237d167b 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -447,7 +447,7 @@ struct tb_margining { unsigned int gen; u32 caps[3]; u32 results[2]; - unsigned int lanes; + enum usb4_margining_lane lanes; unsigned int min_ber_level; unsigned int max_ber_level; unsigned int ber_level; @@ -757,13 +757,13 @@ margining_lanes_write(struct file *file, const char __user *user_buf, } if (!strcmp(buf, "0")) { - margining->lanes = 0; + margining->lanes = USB4_MARGINING_LANE_RX0; } else if (!strcmp(buf, "1")) { - margining->lanes = 1; + margining->lanes = USB4_MARGINING_LANE_RX1; } else if (!strcmp(buf, "all")) { /* Needs to be supported */ if (all_lanes(margining)) - margining->lanes = 7; + margining->lanes = USB4_MARGINING_LANE_ALL; else ret = -EINVAL; } else { @@ -781,21 +781,21 @@ static int margining_lanes_show(struct seq_file *s, void *not_used) { struct tb_margining *margining = s->private; struct tb *tb = margining->port->sw->tb; - unsigned int lanes; + enum usb4_margining_lane lanes; if (mutex_lock_interruptible(&tb->lock)) return -ERESTARTSYS; lanes = margining->lanes; if (all_lanes(margining)) { - if (!lanes) + if (lanes == USB4_MARGINING_LANE_RX0) seq_puts(s, "[0] 1 all\n"); - else if (lanes == 1) + else if (lanes == USB4_MARGINING_LANE_RX1) seq_puts(s, "0 [1] all\n"); else seq_puts(s, "0 1 [all]\n"); } else { - if (!lanes) + if (lanes == USB4_MARGINING_LANE_RX0) seq_puts(s, "[0] 1\n"); else seq_puts(s, "0 [1]\n"); @@ -1089,13 +1089,13 @@ static int margining_run_sw(struct tb_margining *margining, if (ret) break; - if (margining->lanes == USB4_MARGIN_SW_LANE_0) + if (margining->lanes == USB4_MARGINING_LANE_RX0) errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK, margining->results[1]); - else if (margining->lanes == USB4_MARGIN_SW_LANE_1) + else if (margining->lanes == USB4_MARGINING_LANE_RX1) errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK, margining->results[1]); - else if (margining->lanes == USB4_MARGIN_SW_ALL_LANES) + else if (margining->lanes == USB4_MARGINING_LANE_ALL) errors = margining->results[1]; /* Any errors stop the test */ @@ -1225,7 +1225,7 @@ static ssize_t margining_results_write(struct file *file, if (margining->software) { /* Clear the error counters */ margining_modify_error_counter(margining, - USB4_MARGIN_SW_ALL_LANES, + USB4_MARGINING_LANE_ALL, USB4_MARGIN_SW_ERROR_COUNTER_CLEAR); } @@ -1278,7 +1278,8 @@ static int margining_results_show(struct seq_file *s, void *not_used) seq_printf(s, "0x%08x\n", margining->results[1]); if (margining->time) { - if (!margining->lanes || margining->lanes == 7) { + if (margining->lanes == USB4_MARGINING_LANE_RX0 || + margining->lanes == USB4_MARGINING_LANE_ALL) { val = margining->results[1]; seq_puts(s, "# lane 0 right time margin: "); time_margin_show(s, margining, val); @@ -1287,7 +1288,8 @@ static int margining_results_show(struct seq_file *s, void *not_used) seq_puts(s, "# lane 0 left time margin: "); time_margin_show(s, margining, val); } - if (margining->lanes == 1 || margining->lanes == 7) { + if (margining->lanes == USB4_MARGINING_LANE_RX1 || + margining->lanes == USB4_MARGINING_LANE_ALL) { val = margining->results[1] >> USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT; seq_puts(s, "# lane 1 right time margin: "); @@ -1298,7 +1300,8 @@ static int margining_results_show(struct seq_file *s, void *not_used) time_margin_show(s, margining, val); } } else { - if (!margining->lanes || margining->lanes == 7) { + if (margining->lanes == USB4_MARGINING_LANE_RX0 || + margining->lanes == USB4_MARGINING_LANE_ALL) { val = margining->results[1]; seq_puts(s, "# lane 0 high voltage margin: "); voltage_margin_show(s, margining, val); @@ -1307,7 +1310,8 @@ static int margining_results_show(struct seq_file *s, void *not_used) seq_puts(s, "# lane 0 low voltage margin: "); voltage_margin_show(s, margining, val); } - if (margining->lanes == 1 || margining->lanes == 7) { + if (margining->lanes == USB4_MARGINING_LANE_RX1 || + margining->lanes == USB4_MARGINING_LANE_ALL) { val = margining->results[1] >> USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT; seq_puts(s, "# lane 1 high voltage margin: "); @@ -1322,16 +1326,16 @@ static int margining_results_show(struct seq_file *s, void *not_used) u32 lane_errors, result; seq_printf(s, "0x%08x\n", margining->results[1]); - result = FIELD_GET(USB4_MARGIN_SW_LANES_MASK, margining->results[0]); - if (result == USB4_MARGIN_SW_LANE_0 || - result == USB4_MARGIN_SW_ALL_LANES) { + result = FIELD_GET(USB4_MARGIN_SW_LANES_MASK, margining->results[0]); + if (result == USB4_MARGINING_LANE_RX0 || + result == USB4_MARGINING_LANE_ALL) { lane_errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK, margining->results[1]); seq_printf(s, "# lane 0 errors: %u\n", lane_errors); } - if (result == USB4_MARGIN_SW_LANE_1 || - result == USB4_MARGIN_SW_ALL_LANES) { + if (result == USB4_MARGINING_LANE_RX1 || + result == USB4_MARGINING_LANE_ALL) { lane_errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK, margining->results[1]); seq_printf(s, "# lane 1 errors: %u\n", lane_errors); diff --git a/drivers/thunderbolt/sb_regs.h b/drivers/thunderbolt/sb_regs.h index a3652b9cb246..91c6333d08c8 100644 --- a/drivers/thunderbolt/sb_regs.h +++ b/drivers/thunderbolt/sb_regs.h @@ -98,9 +98,6 @@ enum usb4_sb_opcode { /* USB4_SB_OPCODE_RUN_SW_LANE_MARGINING */ #define USB4_MARGIN_SW_LANES_MASK GENMASK(2, 0) -#define USB4_MARGIN_SW_LANE_0 0x0 -#define USB4_MARGIN_SW_LANE_1 0x1 -#define USB4_MARGIN_SW_ALL_LANES 0x7 #define USB4_MARGIN_SW_TIME BIT(3) #define USB4_MARGIN_SW_RH BIT(4) #define USB4_MARGIN_SW_OPT_VOLTAGE BIT(5) diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index ced9be271620..fb2e1f089169 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1367,11 +1367,17 @@ enum usb4_margin_sw_error_counter { USB4_MARGIN_SW_ERROR_COUNTER_STOP, }; +enum usb4_margining_lane { + USB4_MARGINING_LANE_RX0 = 0, + USB4_MARGINING_LANE_RX1 = 1, + USB4_MARGINING_LANE_ALL = 7, +}; + /** * struct usb4_port_margining_params - USB4 margining parameters * @error_counter: Error counter operation for software margining * @ber_level: Current BER level contour value - * @lanes: %0, %1 or %7 (all) + * @lanes: Lanes to enable for the margining operation * @voltage_time_offset: Offset for voltage / time for software margining * @optional_voltage_offset_range: Enable optional extended voltage range * @right_high: %false if left/low margin test is performed, %true if right/high @@ -1380,7 +1386,7 @@ enum usb4_margin_sw_error_counter { struct usb4_port_margining_params { enum usb4_margin_sw_error_counter error_counter; u32 ber_level; - u32 lanes; + enum usb4_margining_lane lanes; u32 voltage_time_offset; bool optional_voltage_offset_range; bool right_high; From patchwork Wed Oct 23 10:11:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 838050 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 B26831A38E3 for ; Wed, 23 Oct 2024 10:11:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678281; cv=none; b=ufZL11UjaGM4VpMFxmjw5a+CWI997QWV/lDly0fTcOOqydvt3oyYxpXp8dumEfYHvmA0JY/sCX243uSwfdTZjiLZLtxwLmRQD/vNcfVRNNLYLFYE6LQpFhj023J/Hs064jBuj2Xb/q0fBf9K+bF7rQ6dVaXpB8iFWgkNv75mVXE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678281; c=relaxed/simple; bh=9cZqaJ0msn7y4/dfoIXoe7Dselzmf+2DHyvcYbyJWrM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gpA/T8dr/uTl42mSkK3sQSZAC+t/6Lvy/iQaS/I4WHJ0gFGP5JED4mMkcX1z9u4sJxXiRhAb3yDrvdM46eq5ce738pRw3bfUxZciUmXPvVU4d00G5WQMZ4vSHzZXZNZQ1LGF2MCdvGoISUwBFYC/kKgILGTsSRJBAtNXQRxYhUs= 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=e4ZwnjjS; arc=none smtp.client-ip=192.198.163.17 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="e4ZwnjjS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729678280; x=1761214280; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9cZqaJ0msn7y4/dfoIXoe7Dselzmf+2DHyvcYbyJWrM=; b=e4ZwnjjSXD4bqGG0Kc/ZDXSSQoIf3FEt3VEY1c7yDRHgUp9W1DdV36pO Q0Pb4oRH+OlwZOpvD0ih28PM9tHi2CtG4rxIwu1j+E4OPpP86C4AvUorW 4N4UHqp/zyK8VOwp+28xGJT1H+Hw78QONnnXzqNSLHTjWL+5f3mFveDIZ nrLTtAwhG1Clv1uycDq1Gyzrk/pAgpRz+TtW67+eV45bb2u4WWALqJh/E 4DSAAcX4TKbESMSxsijSRaQuXX2MPRggzf5XthdwACxCAMxizBexvl+Pf SihbAmrBGOI5Sz8ch+/ttkhFRTB13/OMn6hqt+UqkjDT+gzauxR1XG29b g==; X-CSE-ConnectionGUID: cN47MBfwRgeKc4gJ+WXlVg== X-CSE-MsgGUID: /UL2xRe2SYmfJQvX/ZAG/A== X-IronPort-AV: E=McAfee;i="6700,10204,11233"; a="29149618" X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="29149618" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Oct 2024 03:11:18 -0700 X-CSE-ConnectionGUID: XKEyBxxoRZqskIjP4YL3iw== X-CSE-MsgGUID: gxeaXhrDSEuGqB/OB++Amg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="84954633" Received: from black.fi.intel.com ([10.237.72.28]) by orviesa005.jf.intel.com with ESMTP; 23 Oct 2024 03:11:16 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 551FA7B8; Wed, 23 Oct 2024 13:11:12 +0300 (EEST) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Aapo Vienamo , Mika Westerberg Subject: [PATCH 6/8] thunderbolt: debugfs: Refactor hardware margining result parsing Date: Wed, 23 Oct 2024 13:11:09 +0300 Message-ID: <20241023101111.3418311-7-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> References: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Aapo Vienamo Make the result parsing and formatting code less repetitive in preparation for adding another result for Gen 4 asymmetric link support. Signed-off-by: Aapo Vienamo Signed-off-by: Mika Westerberg --- drivers/thunderbolt/debugfs.c | 99 ++++++++++++++++++----------------- drivers/thunderbolt/sb_regs.h | 12 ++--- 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 3404237d167b..2f9756c201b6 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -1238,10 +1238,10 @@ static void voltage_margin_show(struct seq_file *s, { unsigned int tmp, voltage; - tmp = FIELD_GET(USB4_MARGIN_HW_RES_1_MARGIN_MASK, val); + tmp = FIELD_GET(USB4_MARGIN_HW_RES_MARGIN_MASK, val); voltage = tmp * margining->max_voltage_offset / margining->voltage_steps; seq_printf(s, "%u mV (%u)", voltage, tmp); - if (val & USB4_MARGIN_HW_RES_1_EXCEEDS) + if (val & USB4_MARGIN_HW_RES_EXCEEDS) seq_puts(s, " exceeds maximum"); seq_puts(s, "\n"); if (margining->optional_voltage_offset_range) @@ -1253,14 +1253,53 @@ static void time_margin_show(struct seq_file *s, { unsigned int tmp, interval; - tmp = FIELD_GET(USB4_MARGIN_HW_RES_1_MARGIN_MASK, val); + tmp = FIELD_GET(USB4_MARGIN_HW_RES_MARGIN_MASK, val); interval = tmp * margining->max_time_offset / margining->time_steps; seq_printf(s, "%u mUI (%u)", interval, tmp); - if (val & USB4_MARGIN_HW_RES_1_EXCEEDS) + if (val & USB4_MARGIN_HW_RES_EXCEEDS) seq_puts(s, " exceeds maximum"); seq_puts(s, "\n"); } +static u8 margining_hw_result_val(const u32 *results, + enum usb4_margining_lane lane, + bool right_high) +{ + u32 val; + + if (lane == USB4_MARGINING_LANE_RX0) + val = results[1]; + else if (lane == USB4_MARGINING_LANE_RX1) + val = results[1] >> USB4_MARGIN_HW_RES_LANE_SHIFT; + else + val = 0; + + return right_high ? val : val >> USB4_MARGIN_HW_RES_LL_SHIFT; +} + +static void margining_hw_result_format(struct seq_file *s, + const struct tb_margining *margining, + enum usb4_margining_lane lane) +{ + u8 val; + + if (margining->time) { + val = margining_hw_result_val(margining->results, lane, true); + seq_printf(s, "# lane %u right time margin: ", lane); + time_margin_show(s, margining, val); + val = margining_hw_result_val(margining->results, lane, false); + seq_printf(s, "# lane %u left time margin: ", lane); + time_margin_show(s, margining, val); + } else { + val = margining_hw_result_val(margining->results, lane, true); + seq_printf(s, "# lane %u high voltage margin: ", lane); + voltage_margin_show(s, margining, val); + val = margining_hw_result_val(margining->results, lane, false); + seq_printf(s, "# lane %u low voltage margin: ", lane); + voltage_margin_show(s, margining, val); + } +} + static int margining_results_show(struct seq_file *s, void *not_used) { struct tb_margining *margining = s->private; @@ -1273,54 +1312,16 @@ static int margining_results_show(struct seq_file *s, void *not_used) seq_printf(s, "0x%08x\n", margining->results[0]); /* Only the hardware margining has two result dwords */ if (!margining->software) { - unsigned int val; - seq_printf(s, "0x%08x\n", margining->results[1]); - if (margining->time) { - if (margining->lanes == USB4_MARGINING_LANE_RX0 || - margining->lanes == USB4_MARGINING_LANE_ALL) { - val = margining->results[1]; - seq_puts(s, "# lane 0 right time margin: "); - time_margin_show(s, margining, val); - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT; - seq_puts(s, "# lane 0 left time margin: "); - time_margin_show(s, margining, val); - } - if (margining->lanes == USB4_MARGINING_LANE_RX1 || - margining->lanes == USB4_MARGINING_LANE_ALL) { - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT; - seq_puts(s, "# lane 1 right time margin: "); - time_margin_show(s, margining, val); - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT; - seq_puts(s, "# lane 1 left time margin: "); - time_margin_show(s, margining, val); - } + if (margining->lanes == USB4_MARGINING_LANE_ALL) { + margining_hw_result_format(s, margining, + USB4_MARGINING_LANE_RX0); + margining_hw_result_format(s, margining, + USB4_MARGINING_LANE_RX1); } else { - if (margining->lanes == USB4_MARGINING_LANE_RX0 || - margining->lanes == USB4_MARGINING_LANE_ALL) { - val = margining->results[1]; - seq_puts(s, "# lane 0 high voltage margin: "); - voltage_margin_show(s, margining, val); - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT; - seq_puts(s, "# lane 0 low voltage margin: "); - voltage_margin_show(s, margining, val); - } - if (margining->lanes == USB4_MARGINING_LANE_RX1 || - margining->lanes == USB4_MARGINING_LANE_ALL) { - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT; - seq_puts(s, "# lane 1 high voltage margin: "); - voltage_margin_show(s, margining, val); - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT; - seq_puts(s, "# lane 1 low voltage margin: "); - voltage_margin_show(s, margining, val); - } + margining_hw_result_format(s, margining, + margining->lanes); } } else { u32 lane_errors, result; diff --git a/drivers/thunderbolt/sb_regs.h b/drivers/thunderbolt/sb_regs.h index 91c6333d08c8..7b5521ea0f74 100644 --- a/drivers/thunderbolt/sb_regs.h +++ b/drivers/thunderbolt/sb_regs.h @@ -89,12 +89,12 @@ enum usb4_sb_opcode { #define USB4_MARGIN_HW_OPT_VOLTAGE BIT(10) /* Applicable to all margin values */ -#define USB4_MARGIN_HW_RES_1_MARGIN_MASK GENMASK(6, 0) -#define USB4_MARGIN_HW_RES_1_EXCEEDS BIT(7) -/* Different lane margin shifts */ -#define USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT 8 -#define USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT 16 -#define USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT 24 +#define USB4_MARGIN_HW_RES_MARGIN_MASK GENMASK(6, 0) +#define USB4_MARGIN_HW_RES_EXCEEDS BIT(7) + +/* Shifts for parsing the lane results */ +#define USB4_MARGIN_HW_RES_LANE_SHIFT 16 +#define USB4_MARGIN_HW_RES_LL_SHIFT 8 /* USB4_SB_OPCODE_RUN_SW_LANE_MARGINING */ #define USB4_MARGIN_SW_LANES_MASK GENMASK(2, 0) From patchwork Wed Oct 23 10:11:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 838739 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.13]) (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 38DB11A3BA1 for ; Wed, 23 Oct 2024 10:11:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678281; cv=none; b=TZ1RlpNpNvf9Fr1ITfPx4pRgxsYu15clxC+MrUr0fCg5E0ldmmWc+GKkLISvrL6cJYvs9QMERato5TOEvXxjZl/GUqYrHzrJVtlYzGMNIL/Gg5bvUybJmF+XBhcFULfIJpEad4/BMzdrBVIyoAh4eyNK7kJLn7twV+gwsWEv+Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678281; c=relaxed/simple; bh=n378+DJm8s5oZJQ6X44LLO6UKYdj720LUK5JhDZITOc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hEsMnKurq/7wfJ04zjgOLvwJHSsQ/fQOORfBd2PWALN+DSoolJdOew15FsbnCiOohZOtTkwcKZ0SMDd38x6W3d1FvfSbTnhkFyPZs8J/TavDDbcD411BrTIv7kzWDhz5rFDl2m2wL57CUSnTNmxN+2jeH+vg/YvBprt2NYo4abQ= 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=U4/I2BGt; arc=none smtp.client-ip=192.198.163.13 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="U4/I2BGt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729678280; x=1761214280; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=n378+DJm8s5oZJQ6X44LLO6UKYdj720LUK5JhDZITOc=; b=U4/I2BGtFICB+8iENW0JzJHS/BsIyYKoERPyfsgG12+JJa/5CV50XCpz 2TrCOnKebF1XZ0WeJ6gGQ3NNSigVyNrP5IxdUmAM52e7OVlyTnBRZYNCp X8jXgyFOTUJTRVfJ7HfXWQRNWzjuOqkNPCcwbkp3Nf8aHUw5rqxrlLDKM R9EcX3x09Rt3yw2HAlVtrvmsdmi4+/06YGVlhyRAIhABroE7wlN6KLe+H pIdIrbVJwGz7zVtD5iEaeZfEdWrwQ38geEUoG8Me33zfgtJgmGfBgLq2i GMxhBNdv01xw+frgKeC9B1K0A0qfrhrBdCvJmJmT564srsmnA10060u/X Q==; X-CSE-ConnectionGUID: Iv99sRNZSi+Dr2/0Q1V8ag== X-CSE-MsgGUID: fxA3GjLLQ2O8fQvKxcrM2Q== X-IronPort-AV: E=McAfee;i="6700,10204,11233"; a="32116773" X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="32116773" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Oct 2024 03:11:18 -0700 X-CSE-ConnectionGUID: KeBFnSe7QJyI3U3wMmj9gg== X-CSE-MsgGUID: zOpS7CYjS8Wbj5iApwx0Cg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="80084202" Received: from black.fi.intel.com ([10.237.72.28]) by orviesa010.jf.intel.com with ESMTP; 23 Oct 2024 03:11:16 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 6287D8C4; Wed, 23 Oct 2024 13:11:12 +0300 (EEST) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Aapo Vienamo , Mika Westerberg Subject: [PATCH 7/8] thunderbolt: debugfs: Don't hardcode margining results size Date: Wed, 23 Oct 2024 13:11:10 +0300 Message-ID: <20241023101111.3418311-8-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> References: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Aapo Vienamo Use ARRAY_SIZE() when available or pass in the array size derived from it. This is in preparation for adding another result data word for supporting Gen 4 asymmetric links with an additional lane. Signed-off-by: Aapo Vienamo Signed-off-by: Mika Westerberg --- drivers/thunderbolt/debugfs.c | 8 ++++---- drivers/thunderbolt/tb.h | 2 +- drivers/thunderbolt/usb4.c | 7 ++++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 2f9756c201b6..9899d88b7371 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -1191,7 +1191,7 @@ static int margining_run_write(void *data, u64 val) margining->lanes); ret = usb4_port_hw_margin(port, margining->target, margining->index, ¶ms, - margining->results); + margining->results, ARRAY_SIZE(margining->results)); } if (down_sw) @@ -1219,8 +1219,7 @@ static ssize_t margining_results_write(struct file *file, return -ERESTARTSYS; /* Just clear the results */ - margining->results[0] = 0; - margining->results[1] = 0; + memset(margining->results, 0, sizeof(margining->results)); if (margining->software) { /* Clear the error counters */ @@ -1312,7 +1311,8 @@ static int margining_results_show(struct seq_file *s, void *not_used) seq_printf(s, "0x%08x\n", margining->results[0]); /* Only the hardware margining has two result dwords */ if (!margining->software) { - seq_printf(s, "0x%08x\n", margining->results[1]); + for (int i = 1; i < ARRAY_SIZE(margining->results); i++) + seq_printf(s, "0x%08x\n", margining->results[i]); if (margining->lanes == USB4_MARGINING_LANE_ALL) { margining_hw_result_format(s, margining, diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index fb2e1f089169..0954b8bafada 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1398,7 +1398,7 @@ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, u8 index, u32 *caps, size_t ncaps); int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, u8 index, const struct usb4_port_margining_params *params, - u32 *results); + u32 *results, size_t nresults); int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target, u8 index, const struct usb4_port_margining_params *params, u32 *results); diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 985f24b044b3..05985b18834e 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -1655,14 +1655,15 @@ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, * @target: Sideband target * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER * @params: Parameters for USB4 hardware margining - * @results: Array with at least two elements to hold the results + * @results: Array to hold the results + * @nresults: Number of elements in the results array * * Runs hardware lane margining on USB4 port and returns the result in * @results. */ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, u8 index, const struct usb4_port_margining_params *params, - u32 *results) + u32 *results, size_t nresults) { u32 val; int ret; @@ -1691,7 +1692,7 @@ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, return ret; return usb4_port_sb_read(port, target, index, USB4_SB_DATA, results, - sizeof(*results) * 2); + sizeof(*results) * nresults); } /** From patchwork Wed Oct 23 10:11:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 838049 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.13]) (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 B60A41A4B69 for ; Wed, 23 Oct 2024 10:11:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678282; cv=none; b=UcNSOA1eeXjfrLKWkGdEOvHoefpF3xtPvv05bPPYHbLOsl6P7pJEglqQm06WTf3An5F3oCtL4tiO+S3AZHrROJAF2Jy+yI2REtqNO5+lKBs7osWT9sOUk/+4wVAQCXBO2cpgJ7jxwIUeO7/ezzB3sRiQPxrlctCYcFqYHKk4IxI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729678282; c=relaxed/simple; bh=UZ82yjZjYDEM134h5ZOiNP2XIO0bvOtFKoI79OGZP40=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sSMgCcMKHrLUgvX2zRLXM9zdnHsNenlHU8SEV9V4or7MSHhXukVkDJFdcTK1CnVA+lTvG8+aZC2Q+WkbfTE/RD8tOhlfn6253/YUSnzNc5EJsyCiZc4r+TYrT+GhZmhDWBWBNjmFZTHULC8ic/d8/4cddd7CFsEDSxINCBaxymY= 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=BH7phyup; arc=none smtp.client-ip=192.198.163.13 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="BH7phyup" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729678281; x=1761214281; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UZ82yjZjYDEM134h5ZOiNP2XIO0bvOtFKoI79OGZP40=; b=BH7phyup0+T/+Kji2EdBeju1FBpGK4mwEW+J4LwDehV+f5Qqlg1MRvTi Jcc3ofzaMD7VjLoQ6KjwoIphWF6KamroYEvuByJf4LQUwbW2R4cGripsh uYU+taOu9DNmMjSIxtNMJgSbdUbNJ0d7uTDJ0+Ms51ovExZO8zm40d+GC 2B3Rd4gUpbNItrkpjbyF0iwdTqQ84clZyvIL29HiDbXT2T291AWYd4Lr2 LX0Gb9sYtoajaJDmj0+7ClLYUO0XTas+hXSDj7TumnZrTs+OMKLMWn6X1 6kqzPR35jdHJU5sZ7tnVsjduY3FuZWLa/+uQ0D1AEg0xgDDbRAdHmRScE A==; X-CSE-ConnectionGUID: g307wtu9SH+cwBnGWqV12g== X-CSE-MsgGUID: qPZq8jxHQwyVgbYjKofmNA== X-IronPort-AV: E=McAfee;i="6700,10204,11233"; a="32116777" X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="32116777" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Oct 2024 03:11:19 -0700 X-CSE-ConnectionGUID: 1pXYm8L1SeacmK9NZGExgQ== X-CSE-MsgGUID: OAuOMTgUT8mIHvK2uROeKQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,225,1725346800"; d="scan'208";a="80084204" Received: from black.fi.intel.com ([10.237.72.28]) by orviesa010.jf.intel.com with ESMTP; 23 Oct 2024 03:11:16 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 67F0C807; Wed, 23 Oct 2024 13:11:12 +0300 (EEST) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Aapo Vienamo , Mika Westerberg Subject: [PATCH 8/8] thunderbolt: debugfs: Implement asymmetric lane margining Date: Wed, 23 Oct 2024 13:11:11 +0300 Message-ID: <20241023101111.3418311-9-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> References: <20241023101111.3418311-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Aapo Vienamo Add support for the RX2 receiver which is used as the third receiver in asymmetric links. This requires expanding the results array for the additional third data word of the hardware margining results. Signed-off-by: Aapo Vienamo Signed-off-by: Mika Westerberg --- drivers/thunderbolt/debugfs.c | 157 +++++++++++++++++++++++++--------- drivers/thunderbolt/sb_regs.h | 1 + drivers/thunderbolt/tb.h | 1 + 3 files changed, 117 insertions(+), 42 deletions(-) diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 9899d88b7371..a1d0d8a33f20 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -415,6 +415,7 @@ static ssize_t retimer_sb_regs_write(struct file *file, * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER * @dev: Pointer to the device that is the target (USB4 port or retimer) * @gen: Link generation + * @asym_rx: %true% if @port supports asymmetric link with 3 Rx * @caps: Port lane margining capabilities * @results: Last lane margining results * @lanes: %0, %1 or %7 (all) @@ -445,8 +446,9 @@ struct tb_margining { u8 index; struct device *dev; unsigned int gen; + bool asym_rx; u32 caps[3]; - u32 results[2]; + u32 results[3]; enum usb4_margining_lane lanes; unsigned int min_ber_level; unsigned int max_ber_level; @@ -735,14 +737,37 @@ static int margining_caps_show(struct seq_file *s, void *not_used) } DEBUGFS_ATTR_RO(margining_caps); +static const struct { + enum usb4_margining_lane lane; + const char *name; +} lane_names[] = { + { + .lane = USB4_MARGINING_LANE_RX0, + .name = "0", + }, + { + .lane = USB4_MARGINING_LANE_RX1, + .name = "1", + }, + { + .lane = USB4_MARGINING_LANE_RX2, + .name = "2", + }, + { + .lane = USB4_MARGINING_LANE_ALL, + .name = "all", + }, +}; + static ssize_t margining_lanes_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct seq_file *s = file->private_data; struct tb_margining *margining = s->private; - struct tb *tb = margining->port->sw->tb; - int ret = 0; + struct tb_port *port = margining->port; + struct tb *tb = port->sw->tb; + int lane = -1; char *buf; buf = validate_and_copy_from_user(user_buf, &count); @@ -751,57 +776,60 @@ margining_lanes_write(struct file *file, const char __user *user_buf, buf[count - 1] = '\0'; - if (mutex_lock_interruptible(&tb->lock)) { - ret = -ERESTARTSYS; - goto out_free; + for (int i = 0; i < ARRAY_SIZE(lane_names); i++) { + if (!strcmp(buf, lane_names[i].name)) { + lane = lane_names[i].lane; + break; + } } - if (!strcmp(buf, "0")) { - margining->lanes = USB4_MARGINING_LANE_RX0; - } else if (!strcmp(buf, "1")) { - margining->lanes = USB4_MARGINING_LANE_RX1; - } else if (!strcmp(buf, "all")) { - /* Needs to be supported */ - if (all_lanes(margining)) - margining->lanes = USB4_MARGINING_LANE_ALL; - else - ret = -EINVAL; - } else { - ret = -EINVAL; - } + free_page((unsigned long)buf); - mutex_unlock(&tb->lock); + if (lane == -1) + return -EINVAL; -out_free: - free_page((unsigned long)buf); - return ret < 0 ? ret : count; + scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) { + if (lane == USB4_MARGINING_LANE_ALL && !all_lanes(margining)) + return -EINVAL; + /* + * Enabling on RX2 requires that it is supported by the + * USB4 port. + */ + if (lane == USB4_MARGINING_LANE_RX2 && !margining->asym_rx) + return -EINVAL; + + margining->lanes = lane; + } + + return count; } static int margining_lanes_show(struct seq_file *s, void *not_used) { struct tb_margining *margining = s->private; - struct tb *tb = margining->port->sw->tb; - enum usb4_margining_lane lanes; - - if (mutex_lock_interruptible(&tb->lock)) - return -ERESTARTSYS; + struct tb_port *port = margining->port; + struct tb *tb = port->sw->tb; - lanes = margining->lanes; - if (all_lanes(margining)) { - if (lanes == USB4_MARGINING_LANE_RX0) - seq_puts(s, "[0] 1 all\n"); - else if (lanes == USB4_MARGINING_LANE_RX1) - seq_puts(s, "0 [1] all\n"); - else - seq_puts(s, "0 1 [all]\n"); - } else { - if (lanes == USB4_MARGINING_LANE_RX0) - seq_puts(s, "[0] 1\n"); - else - seq_puts(s, "0 [1]\n"); + scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) { + for (int i = 0; i < ARRAY_SIZE(lane_names); i++) { + if (lane_names[i].lane == USB4_MARGINING_LANE_ALL && + !all_lanes(margining)) + continue; + if (lane_names[i].lane == USB4_MARGINING_LANE_RX2 && + !margining->asym_rx) + continue; + + if (i != 0) + seq_putc(s, ' '); + + if (lane_names[i].lane == margining->lanes) + seq_printf(s, "[%s]", lane_names[i].name); + else + seq_printf(s, "%s", lane_names[i].name); + } + seq_puts(s, "\n"); } - mutex_unlock(&tb->lock); return 0; } DEBUGFS_ATTR_RW(margining_lanes); @@ -1095,6 +1123,9 @@ static int margining_run_sw(struct tb_margining *margining, else if (margining->lanes == USB4_MARGINING_LANE_RX1) errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK, margining->results[1]); + else if (margining->lanes == USB4_MARGINING_LANE_RX2) + errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_2_MASK, + margining->results[1]); else if (margining->lanes == USB4_MARGINING_LANE_ALL) errors = margining->results[1]; @@ -1115,6 +1146,31 @@ static int margining_run_sw(struct tb_margining *margining, return ret; } +static int validate_margining(struct tb_margining *margining) +{ + /* + * For running on RX2 the link must be asymmetric with 3 + * receivers. Because this is can change dynamically, check it + * here before we start the margining and report back error if + * expectations are not met. + */ + if (margining->lanes == USB4_MARGINING_LANE_RX2) { + int ret; + + ret = tb_port_get_link_width(margining->port); + if (ret < 0) + return ret; + if (ret != TB_LINK_WIDTH_ASYM_RX) { + tb_port_warn(margining->port, "link is %s expected %s", + tb_width_name(ret), + tb_width_name(TB_LINK_WIDTH_ASYM_RX)); + return -EINVAL; + } + } + + return 0; +} + static int margining_run_write(void *data, u64 val) { struct tb_margining *margining = data; @@ -1135,6 +1191,10 @@ static int margining_run_write(void *data, u64 val) goto out_rpm_put; } + ret = validate_margining(margining); + if (ret) + goto out_unlock; + if (tb_is_upstream_port(port)) down_sw = sw; else if (port->remote) @@ -1270,6 +1330,8 @@ static u8 margining_hw_result_val(const u32 *results, val = results[1]; else if (lane == USB4_MARGINING_LANE_RX1) val = results[1] >> USB4_MARGIN_HW_RES_LANE_SHIFT; + else if (lane == USB4_MARGINING_LANE_RX2) + val = results[2]; else val = 0; @@ -1319,6 +1381,9 @@ static int margining_results_show(struct seq_file *s, void *not_used) USB4_MARGINING_LANE_RX0); margining_hw_result_format(s, margining, USB4_MARGINING_LANE_RX1); + if (margining->asym_rx) + margining_hw_result_format(s, margining, + USB4_MARGINING_LANE_RX2); } else { margining_hw_result_format(s, margining, margining->lanes); @@ -1341,6 +1406,13 @@ static int margining_results_show(struct seq_file *s, void *not_used) margining->results[1]); seq_printf(s, "# lane 1 errors: %u\n", lane_errors); } + if (margining->asym_rx && + (result == USB4_MARGINING_LANE_RX2 || + result == USB4_MARGINING_LANE_ALL)) { + lane_errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_2_MASK, + margining->results[1]); + seq_printf(s, "# lane 2 errors: %u\n", lane_errors); + } } mutex_unlock(&tb->lock); @@ -1548,6 +1620,7 @@ static struct tb_margining *margining_alloc(struct tb_port *port, margining->index = index; margining->dev = dev; margining->gen = ret; + margining->asym_rx = tb_port_width_supported(port, TB_LINK_WIDTH_ASYM_RX); ret = usb4_port_margining_caps(port, target, index, margining->caps, ARRAY_SIZE(margining->caps)); diff --git a/drivers/thunderbolt/sb_regs.h b/drivers/thunderbolt/sb_regs.h index 7b5521ea0f74..5391502a4b87 100644 --- a/drivers/thunderbolt/sb_regs.h +++ b/drivers/thunderbolt/sb_regs.h @@ -107,5 +107,6 @@ enum usb4_sb_opcode { #define USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK GENMASK(3, 0) #define USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK GENMASK(7, 4) +#define USB4_MARGIN_SW_ERR_COUNTER_LANE_2_MASK GENMASK(11, 8) #endif diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 0954b8bafada..ddbf0cd78377 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1370,6 +1370,7 @@ enum usb4_margin_sw_error_counter { enum usb4_margining_lane { USB4_MARGINING_LANE_RX0 = 0, USB4_MARGINING_LANE_RX1 = 1, + USB4_MARGINING_LANE_RX2 = 2, USB4_MARGINING_LANE_ALL = 7, };