]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
thunderbolt: Consolidate margining parameters into a structure
authorRene Sapiens <rene.sapiens@intel.com>
Fri, 19 Jul 2024 18:37:18 +0000 (21:37 +0300)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 22 Aug 2024 04:32:06 +0000 (07:32 +0300)
Consolidate the hardware and software margining parameters into a single
structure to reduce the number of parameters passed to the margining
functions.

Signed-off-by: Rene Sapiens <rene.sapiens@intel.com>
Co-developed-by: Aapo Vienamo <aapo.vienamo@linux.intel.com>
Signed-off-by: Aapo Vienamo <aapo.vienamo@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
drivers/thunderbolt/debugfs.c
drivers/thunderbolt/sb_regs.h
drivers/thunderbolt/tb.h
drivers/thunderbolt/usb4.c

index a0d07887990ef8b3778595f6e717f841b823cba6..5d1588baea6a95f13c652f35c633f7723b970e2c 100644 (file)
@@ -780,13 +780,20 @@ static int margining_run_write(void *data, u64 val)
        }
 
        if (margining->software) {
+               struct usb4_port_margining_params params = {
+                       .error_counter = USB4_MARGIN_SW_ERROR_COUNTER_CLEAR,
+                       .lanes = margining->lanes,
+                       .time = margining->time,
+                       .right_high = margining->right_high,
+               };
+
                tb_port_dbg(port,
                            "running software %s lane margining for %s lanes %u\n",
                            margining->time ? "time" : "voltage", dev_name(dev),
                            margining->lanes);
-               ret = usb4_port_sw_margin(port, margining->target, margining->index,
-                                         margining->lanes, margining->time, margining->right_high,
-                                         USB4_MARGIN_SW_COUNTER_CLEAR, &margining->results[0]);
+
+               ret = usb4_port_sw_margin(port, margining->target, margining->index, &params,
+                                         &margining->results[0]);
                if (ret)
                        goto out_clx;
 
@@ -794,16 +801,23 @@ static int margining_run_write(void *data, u64 val)
                                                 margining->index,
                                                 &margining->results[0]);
        } else {
+               struct usb4_port_margining_params params = {
+                       .ber_level = margining->ber_level,
+                       .lanes = margining->lanes,
+                       .time = margining->time,
+                       .right_high = margining->right_high,
+               };
+
+               /* Clear the results */
+               margining->results[0] = 0;
+               margining->results[1] = 0;
+
                tb_port_dbg(port,
                            "running hardware %s lane margining for %s lanes %u\n",
                            margining->time ? "time" : "voltage", dev_name(dev),
                            margining->lanes);
-               /* Clear the results */
-               margining->results[0] = 0;
-               margining->results[1] = 0;
-               ret = usb4_port_hw_margin(port, margining->target, margining->index,
-                                         margining->lanes, margining->ber_level,
-                                         margining->time, margining->right_high,
+
+               ret = usb4_port_hw_margin(port, margining->target, margining->index, &params,
                                          margining->results);
        }
 
index 2a88edfc97b2bafb1dbbfe7b75183d886ea1547c..86e80aa297f7facff4a95d82b3ffbbbeff6b9a4f 100644 (file)
@@ -85,10 +85,5 @@ enum usb4_sb_opcode {
 #define USB4_MARGIN_SW_TIME                    BIT(3)
 #define USB4_MARGIN_SW_RH                      BIT(4)
 #define USB4_MARGIN_SW_COUNTER_MASK            GENMASK(14, 13)
-#define USB4_MARGIN_SW_COUNTER_SHIFT           13
-#define USB4_MARGIN_SW_COUNTER_NOP             0x0
-#define USB4_MARGIN_SW_COUNTER_CLEAR           0x1
-#define USB4_MARGIN_SW_COUNTER_START           0x2
-#define USB4_MARGIN_SW_COUNTER_STOP            0x3
 
 #endif
index 321db407657389ccc0b67996caf56f8a68c30c4e..89ea66f885a46e976b1c5a9b86e77c1da781b4c7 100644 (file)
@@ -1353,14 +1353,44 @@ int usb4_port_sb_read(struct tb_port *port, enum usb4_sb_target target, u8 index
 int usb4_port_sb_write(struct tb_port *port, enum usb4_sb_target target,
                       u8 index, u8 reg, const void *buf, u8 size);
 
+/**
+ * enum usb4_margin_sw_error_counter - Software margining error counter operation
+ * @USB4_MARGIN_SW_ERROR_COUNTER_NOP: No change in counter setup
+ * @USB4_MARGIN_SW_ERROR_COUNTER_CLEAR: Set the error counter to 0, enable counter
+ * @USB4_MARGIN_SW_ERROR_COUNTER_START: Start counter, count from last value
+ * @USB4_MARGIN_SW_ERROR_COUNTER_STOP: Stop counter, do not clear value
+ */
+enum usb4_margin_sw_error_counter {
+       USB4_MARGIN_SW_ERROR_COUNTER_NOP,
+       USB4_MARGIN_SW_ERROR_COUNTER_CLEAR,
+       USB4_MARGIN_SW_ERROR_COUNTER_START,
+       USB4_MARGIN_SW_ERROR_COUNTER_STOP,
+};
+
+/**
+ * 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)
+ * @right_high: %false if left/low margin test is performed, %true if right/high
+ * @time: %true if time margining is used instead of voltage
+ */
+struct usb4_port_margining_params {
+       enum usb4_margin_sw_error_counter error_counter;
+       u32 ber_level;
+       u32 lanes;
+       bool right_high;
+       bool time;
+};
+
 int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target,
                             u8 index, u32 *caps);
 int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target,
-                       u8 index, unsigned int lanes, unsigned int ber_level,
-                       bool timing, bool right_high, u32 *results);
+                       u8 index, const struct usb4_port_margining_params *params,
+                       u32 *results);
 int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target,
-                       u8 index, unsigned int lanes, bool timing,
-                       bool right_high, u32 counter, u32 *results);
+                       u8 index, const struct usb4_port_margining_params *params,
+                       u32 *results);
 int usb4_port_sw_margin_errors(struct tb_port *port, enum usb4_sb_target target,
                               u8 index, u32 *errors);
 
index 5505aa95c2eae401d137b0eab9f8e00810711b89..cb51cafcf20c6c1e475e44ecd6224b68dd254a07 100644 (file)
@@ -1653,31 +1653,29 @@ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target,
  * @port: USB4 port
  * @target: Sideband target
  * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER
- * @lanes: Which lanes to run (must match the port capabilities). Can be
- *        %0, %1 or %7.
- * @ber_level: BER level contour value
- * @timing: Perform timing margining instead of voltage
- * @right_high: Use Right/high margin instead of left/low
+ * @params: Parameters for USB4 hardware margining
  * @results: Array with at least two elements to hold the results
  *
  * 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, unsigned int lanes, unsigned int ber_level,
-                       bool timing, bool right_high, u32 *results)
+                       u8 index, const struct usb4_port_margining_params *params,
+                       u32 *results)
 {
        u32 val;
        int ret;
 
-       val = lanes;
-       if (timing)
+       if (WARN_ON_ONCE(!params))
+               return -EINVAL;
+
+       val = params->lanes;
+       if (params->time)
                val |= USB4_MARGIN_HW_TIME;
-       if (right_high)
+       if (params->right_high)
                val |= USB4_MARGIN_HW_RH;
-       if (ber_level)
-               val |= (ber_level << USB4_MARGIN_HW_BER_SHIFT) &
-                       USB4_MARGIN_HW_BER_MASK;
+       if (params->ber_level)
+               val |= FIELD_PREP(USB4_MARGIN_HW_BER_MASK, params->ber_level);
 
        ret = usb4_port_sb_write(port, target, index, USB4_SB_METADATA, &val,
                                 sizeof(val));
@@ -1698,11 +1696,7 @@ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target,
  * @port: USB4 port
  * @target: Sideband target
  * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER
- * @lanes: Which lanes to run (must match the port capabilities). Can be
- *        %0, %1 or %7.
- * @timing: Perform timing margining instead of voltage
- * @right_high: Use Right/high margin instead of left/low
- * @counter: What to do with the error counter
+ * @params: Parameters for USB4 software margining
  * @results: Data word for the operation completion data
  *
  * Runs software lane margining on USB4 port. Read back the error
@@ -1710,19 +1704,21 @@ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target,
  * success and negative errno otherwise.
  */
 int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target,
-                       u8 index, unsigned int lanes, bool timing,
-                       bool right_high, u32 counter, u32 *results)
+                       u8 index, const struct usb4_port_margining_params *params,
+                       u32 *results)
 {
        u32 val;
        int ret;
 
-       val = lanes;
-       if (timing)
+       if (WARN_ON_ONCE(!params))
+               return -EINVAL;
+
+       val = params->lanes;
+       if (params->time)
                val |= USB4_MARGIN_SW_TIME;
-       if (right_high)
+       if (params->right_high)
                val |= USB4_MARGIN_SW_RH;
-       val |= (counter << USB4_MARGIN_SW_COUNTER_SHIFT) &
-               USB4_MARGIN_SW_COUNTER_MASK;
+       val |= FIELD_PREP(USB4_MARGIN_SW_COUNTER_MASK, params->error_counter);
 
        ret = usb4_port_sb_write(port, target, index, USB4_SB_METADATA, &val,
                                 sizeof(val));