Skip to content

Commit 81f848d

Browse files
renesapiensiwesteri
authored andcommitted
thunderbolt: Consolidate margining parameters into a structure
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 <[email protected]> Co-developed-by: Aapo Vienamo <[email protected]> Signed-off-by: Aapo Vienamo <[email protected]> Signed-off-by: Mika Westerberg <[email protected]>
1 parent 24edc39 commit 81f848d

File tree

4 files changed

+78
-43
lines changed

4 files changed

+78
-43
lines changed

drivers/thunderbolt/debugfs.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -780,30 +780,44 @@ static int margining_run_write(void *data, u64 val)
780780
}
781781

782782
if (margining->software) {
783+
struct usb4_port_margining_params params = {
784+
.error_counter = USB4_MARGIN_SW_ERROR_COUNTER_CLEAR,
785+
.lanes = margining->lanes,
786+
.time = margining->time,
787+
.right_high = margining->right_high,
788+
};
789+
783790
tb_port_dbg(port,
784791
"running software %s lane margining for %s lanes %u\n",
785792
margining->time ? "time" : "voltage", dev_name(dev),
786793
margining->lanes);
787-
ret = usb4_port_sw_margin(port, margining->target, margining->index,
788-
margining->lanes, margining->time, margining->right_high,
789-
USB4_MARGIN_SW_COUNTER_CLEAR, &margining->results[0]);
794+
795+
ret = usb4_port_sw_margin(port, margining->target, margining->index, &params,
796+
&margining->results[0]);
790797
if (ret)
791798
goto out_clx;
792799

793800
ret = usb4_port_sw_margin_errors(port, margining->target,
794801
margining->index,
795802
&margining->results[0]);
796803
} else {
804+
struct usb4_port_margining_params params = {
805+
.ber_level = margining->ber_level,
806+
.lanes = margining->lanes,
807+
.time = margining->time,
808+
.right_high = margining->right_high,
809+
};
810+
811+
/* Clear the results */
812+
margining->results[0] = 0;
813+
margining->results[1] = 0;
814+
797815
tb_port_dbg(port,
798816
"running hardware %s lane margining for %s lanes %u\n",
799817
margining->time ? "time" : "voltage", dev_name(dev),
800818
margining->lanes);
801-
/* Clear the results */
802-
margining->results[0] = 0;
803-
margining->results[1] = 0;
804-
ret = usb4_port_hw_margin(port, margining->target, margining->index,
805-
margining->lanes, margining->ber_level,
806-
margining->time, margining->right_high,
819+
820+
ret = usb4_port_hw_margin(port, margining->target, margining->index, &params,
807821
margining->results);
808822
}
809823

drivers/thunderbolt/sb_regs.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,5 @@ enum usb4_sb_opcode {
8585
#define USB4_MARGIN_SW_TIME BIT(3)
8686
#define USB4_MARGIN_SW_RH BIT(4)
8787
#define USB4_MARGIN_SW_COUNTER_MASK GENMASK(14, 13)
88-
#define USB4_MARGIN_SW_COUNTER_SHIFT 13
89-
#define USB4_MARGIN_SW_COUNTER_NOP 0x0
90-
#define USB4_MARGIN_SW_COUNTER_CLEAR 0x1
91-
#define USB4_MARGIN_SW_COUNTER_START 0x2
92-
#define USB4_MARGIN_SW_COUNTER_STOP 0x3
9388

9489
#endif

drivers/thunderbolt/tb.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,14 +1353,44 @@ int usb4_port_sb_read(struct tb_port *port, enum usb4_sb_target target, u8 index
13531353
int usb4_port_sb_write(struct tb_port *port, enum usb4_sb_target target,
13541354
u8 index, u8 reg, const void *buf, u8 size);
13551355

1356+
/**
1357+
* enum usb4_margin_sw_error_counter - Software margining error counter operation
1358+
* @USB4_MARGIN_SW_ERROR_COUNTER_NOP: No change in counter setup
1359+
* @USB4_MARGIN_SW_ERROR_COUNTER_CLEAR: Set the error counter to 0, enable counter
1360+
* @USB4_MARGIN_SW_ERROR_COUNTER_START: Start counter, count from last value
1361+
* @USB4_MARGIN_SW_ERROR_COUNTER_STOP: Stop counter, do not clear value
1362+
*/
1363+
enum usb4_margin_sw_error_counter {
1364+
USB4_MARGIN_SW_ERROR_COUNTER_NOP,
1365+
USB4_MARGIN_SW_ERROR_COUNTER_CLEAR,
1366+
USB4_MARGIN_SW_ERROR_COUNTER_START,
1367+
USB4_MARGIN_SW_ERROR_COUNTER_STOP,
1368+
};
1369+
1370+
/**
1371+
* struct usb4_port_margining_params - USB4 margining parameters
1372+
* @error_counter: Error counter operation for software margining
1373+
* @ber_level: Current BER level contour value
1374+
* @lanes: %0, %1 or %7 (all)
1375+
* @right_high: %false if left/low margin test is performed, %true if right/high
1376+
* @time: %true if time margining is used instead of voltage
1377+
*/
1378+
struct usb4_port_margining_params {
1379+
enum usb4_margin_sw_error_counter error_counter;
1380+
u32 ber_level;
1381+
u32 lanes;
1382+
bool right_high;
1383+
bool time;
1384+
};
1385+
13561386
int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target,
13571387
u8 index, u32 *caps);
13581388
int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target,
1359-
u8 index, unsigned int lanes, unsigned int ber_level,
1360-
bool timing, bool right_high, u32 *results);
1389+
u8 index, const struct usb4_port_margining_params *params,
1390+
u32 *results);
13611391
int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target,
1362-
u8 index, unsigned int lanes, bool timing,
1363-
bool right_high, u32 counter, u32 *results);
1392+
u8 index, const struct usb4_port_margining_params *params,
1393+
u32 *results);
13641394
int usb4_port_sw_margin_errors(struct tb_port *port, enum usb4_sb_target target,
13651395
u8 index, u32 *errors);
13661396

drivers/thunderbolt/usb4.c

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,31 +1653,29 @@ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target,
16531653
* @port: USB4 port
16541654
* @target: Sideband target
16551655
* @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER
1656-
* @lanes: Which lanes to run (must match the port capabilities). Can be
1657-
* %0, %1 or %7.
1658-
* @ber_level: BER level contour value
1659-
* @timing: Perform timing margining instead of voltage
1660-
* @right_high: Use Right/high margin instead of left/low
1656+
* @params: Parameters for USB4 hardware margining
16611657
* @results: Array with at least two elements to hold the results
16621658
*
16631659
* Runs hardware lane margining on USB4 port and returns the result in
16641660
* @results.
16651661
*/
16661662
int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target,
1667-
u8 index, unsigned int lanes, unsigned int ber_level,
1668-
bool timing, bool right_high, u32 *results)
1663+
u8 index, const struct usb4_port_margining_params *params,
1664+
u32 *results)
16691665
{
16701666
u32 val;
16711667
int ret;
16721668

1673-
val = lanes;
1674-
if (timing)
1669+
if (WARN_ON_ONCE(!params))
1670+
return -EINVAL;
1671+
1672+
val = params->lanes;
1673+
if (params->time)
16751674
val |= USB4_MARGIN_HW_TIME;
1676-
if (right_high)
1675+
if (params->right_high)
16771676
val |= USB4_MARGIN_HW_RH;
1678-
if (ber_level)
1679-
val |= (ber_level << USB4_MARGIN_HW_BER_SHIFT) &
1680-
USB4_MARGIN_HW_BER_MASK;
1677+
if (params->ber_level)
1678+
val |= FIELD_PREP(USB4_MARGIN_HW_BER_MASK, params->ber_level);
16811679

16821680
ret = usb4_port_sb_write(port, target, index, USB4_SB_METADATA, &val,
16831681
sizeof(val));
@@ -1698,31 +1696,29 @@ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target,
16981696
* @port: USB4 port
16991697
* @target: Sideband target
17001698
* @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER
1701-
* @lanes: Which lanes to run (must match the port capabilities). Can be
1702-
* %0, %1 or %7.
1703-
* @timing: Perform timing margining instead of voltage
1704-
* @right_high: Use Right/high margin instead of left/low
1705-
* @counter: What to do with the error counter
1699+
* @params: Parameters for USB4 software margining
17061700
* @results: Data word for the operation completion data
17071701
*
17081702
* Runs software lane margining on USB4 port. Read back the error
17091703
* counters by calling usb4_port_sw_margin_errors(). Returns %0 in
17101704
* success and negative errno otherwise.
17111705
*/
17121706
int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target,
1713-
u8 index, unsigned int lanes, bool timing,
1714-
bool right_high, u32 counter, u32 *results)
1707+
u8 index, const struct usb4_port_margining_params *params,
1708+
u32 *results)
17151709
{
17161710
u32 val;
17171711
int ret;
17181712

1719-
val = lanes;
1720-
if (timing)
1713+
if (WARN_ON_ONCE(!params))
1714+
return -EINVAL;
1715+
1716+
val = params->lanes;
1717+
if (params->time)
17211718
val |= USB4_MARGIN_SW_TIME;
1722-
if (right_high)
1719+
if (params->right_high)
17231720
val |= USB4_MARGIN_SW_RH;
1724-
val |= (counter << USB4_MARGIN_SW_COUNTER_SHIFT) &
1725-
USB4_MARGIN_SW_COUNTER_MASK;
1721+
val |= FIELD_PREP(USB4_MARGIN_SW_COUNTER_MASK, params->error_counter);
17261722

17271723
ret = usb4_port_sb_write(port, target, index, USB4_SB_METADATA, &val,
17281724
sizeof(val));

0 commit comments

Comments
 (0)