Skip to content

Commit c97cd0b

Browse files
RD Babieragregkh
authored andcommitted
usb: typec: tcpm: set initial svdm version based on pd revision
When sending Discover Identity messages to a Port Partner that uses Power Delivery v2 and SVDM v1, we currently send PD v2 messages with SVDM v2.0, expecting the port partner to respond with its highest supported SVDM version as stated in Section 6.4.4.2.3 in the Power Delivery v3 specification. However, sending SVDM v2 to some Power Delivery v2 port partners results in a NAK whereas sending SVDM v1 does not. NAK messages can be handled by the initiator (PD v3 section 6.4.4.2.5.1), and one solution could be to resend Discover Identity on a lower SVDM version if possible. But, Section 6.4.4.3 of PD v2 states that "A NAK response Should be taken as an indication not to retry that particular Command." Instead, we can set the SVDM version to the maximum one supported by the negotiated PD revision. When operating in PD v2, this obeys Section 6.4.4.2.3, which states the SVDM field "Shall be set to zero to indicate Version 1.0." In PD v3, the SVDM field "Shall be set to 01b to indicate Version 2.0." Fixes: c34e85f ("usb: typec: tcpm: Send DISCOVER_IDENTITY from dedicated work") Cc: [email protected] Signed-off-by: RD Babiera <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e16d5f1 commit c97cd0b

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

drivers/usb/typec/tcpm/tcpm.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3859,6 +3859,29 @@ static enum typec_cc_status tcpm_pwr_opmode_to_rp(enum typec_pwr_opmode opmode)
38593859
}
38603860
}
38613861

3862+
static void tcpm_set_initial_svdm_version(struct tcpm_port *port)
3863+
{
3864+
switch (port->negotiated_rev) {
3865+
case PD_REV30:
3866+
break;
3867+
/*
3868+
* 6.4.4.2.3 Structured VDM Version
3869+
* 2.0 states "At this time, there is only one version (1.0) defined.
3870+
* This field Shall be set to zero to indicate Version 1.0."
3871+
* 3.0 states "This field Shall be set to 01b to indicate Version 2.0."
3872+
* To ensure that we follow the Power Delivery revision we are currently
3873+
* operating on, downgrade the SVDM version to the highest one supported
3874+
* by the Power Delivery revision.
3875+
*/
3876+
case PD_REV20:
3877+
typec_partner_set_svdm_version(port->partner, SVDM_VER_1_0);
3878+
break;
3879+
default:
3880+
typec_partner_set_svdm_version(port->partner, SVDM_VER_1_0);
3881+
break;
3882+
}
3883+
}
3884+
38623885
static void run_state_machine(struct tcpm_port *port)
38633886
{
38643887
int ret;
@@ -4096,10 +4119,12 @@ static void run_state_machine(struct tcpm_port *port)
40964119
* For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using
40974120
* port->explicit_contract to decide whether to send the command.
40984121
*/
4099-
if (port->explicit_contract)
4122+
if (port->explicit_contract) {
4123+
tcpm_set_initial_svdm_version(port);
41004124
mod_send_discover_delayed_work(port, 0);
4101-
else
4125+
} else {
41024126
port->send_discover = false;
4127+
}
41034128

41044129
/*
41054130
* 6.3.5
@@ -4388,10 +4413,12 @@ static void run_state_machine(struct tcpm_port *port)
43884413
* For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using
43894414
* port->explicit_contract.
43904415
*/
4391-
if (port->explicit_contract)
4416+
if (port->explicit_contract) {
4417+
tcpm_set_initial_svdm_version(port);
43924418
mod_send_discover_delayed_work(port, 0);
4393-
else
4419+
} else {
43944420
port->send_discover = false;
4421+
}
43954422

43964423
power_supply_changed(port->psy);
43974424
break;

0 commit comments

Comments
 (0)