usb: typec: tcpm: Wait for vbus discharge to VSAFE0V before toggling
Subsystems (3)
Badhri Jagan Sridharan
maintainerPATCH 1/1 usb: typec: tcpm: Wait for vbus discharge to VSAFE0V before toggling
When vbus auto discharge is enabled, TCPM can sometimes be faster than the TCPC i.e. TCPM can go ahead and move the port to unattached state (involves disabling vbus auto discharge) before TCPC could effectively discharge vbus to VSAFE0V. This leaves vbus with residual charge and increases the decay time which prevents tsafe0v from being met. This change introduces a new state VBUS_DISCHARGE where the TCPM waits for a maximum of tSafe0V(max) for vbus to discharge to VSAFE0V before transitioning to unattached state and re-enable toggling. If vbus discharges to vsafe0v sooner, then, transition to unattached state happens right away.
Also, while in SNK_READY, when auto discharge is enabled, drive disconnect based on vbus turning off instead of Rp disappearing on CC pins. Rp disappearing on CC pins is almost instanteous compared to vbus decay.
--- drivers/usb/typec/tcpm/tcpm.c | 60 +++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-)
drivers/usb/typec/tcpm/tcpm.c +53 -7
@@ -62,6 +62,8 @@S (SNK_TRANSITION_SINK_VBUS ), \S (SNK_READY ), \ \ +S (VBUS_DISCHARGE ), \ + \S (ACC_UNATTACHED ), \S (DEBUG_ACC_ATTACHED ), \ S(AUDIO_ACC_ATTACHED), \
@@ -438,6 +440,9 @@ struct tcpm_port {enum tcpm_ams next_ams;bool in_ams; +/* Auto vbus discharge state */ +bool auto_vbus_discharge_enabled; +#ifdef CONFIG_DEBUG_FS struct dentry *dentry;struct mutex logbuffer_lock;/* log buffer access lock */
@@ -3413,6 +3418,8 @@ static int tcpm_src_attach(struct tcpm_port *port)if (port->tcpc->enable_auto_vbus_discharge) { ret = port->tcpc->enable_auto_vbus_discharge (port->tcpc, true);tcpm_log_force (port,"enable vbus discharge ret:%d" , ret); +if (!ret) + port->auto_vbus_discharge_enabled = true; } ret =tcpm_set_roles (port, true,TYPEC_SOURCE ,tcpm_data_role_for_source (port));
@@ -3495,6 +3502,8 @@ static void tcpm_reset_port(struct tcpm_port *port)if (port->tcpc->enable_auto_vbus_discharge) { ret = port->tcpc->enable_auto_vbus_discharge (port->tcpc, false);tcpm_log_force (port,"Disable vbus discharge ret:%d" , ret); +if (!ret) + port->auto_vbus_discharge_enabled = false; } port->in_ams = false; port->ams =NONE_AMS ;
@@ -3568,6 +3577,8 @@ static int tcpm_snk_attach(struct tcpm_port *port)tcpm_set_auto_vbus_discharge_threshold (port,TYPEC_PWR_MODE_USB , false,VSAFE5V ); ret = port->tcpc->enable_auto_vbus_discharge (port->tcpc, true);tcpm_log_force (port,"enable vbus discharge ret:%d" , ret); +if (!ret) + port->auto_vbus_discharge_enabled = true; } ret =tcpm_set_roles (port, true,TYPEC_SINK ,tcpm_data_role_for_sink (port));
@@ -3684,6 +3695,12 @@ static void run_state_machine(struct tcpm_port *port)switch (port->state) {case TOGGLING :break ; +case VBUS_DISCHARGE : +if (port->port_type ==TYPEC_PORT_SRC ) +tcpm_set_state (port,SRC_UNATTACHED ,PD_T_SAFE_0V ); +else +tcpm_set_state (port,SNK_UNATTACHED ,PD_T_SAFE_0V ); +break ;/* SRC states */ case SRC_UNATTACHED :if (!port->non_pd_role_swap)
@@ -4669,7 +4686,9 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,case SRC_READY :if (tcpm_port_is_disconnected (port) || !tcpm_port_is_source (port)) { -if (port->port_type ==TYPEC_PORT_SRC ) +if (port->auto_vbus_discharge_enabled && !port->vbus_vsafe0v) +tcpm_set_state (port,VBUS_DISCHARGE ,0 ); +else if (port->port_type ==TYPEC_PORT_SRC )tcpm_set_state (port,SRC_UNATTACHED ,0 );else tcpm_set_state (port,SNK_UNATTACHED ,0 );
@@ -4703,7 +4722,18 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,tcpm_set_state (port,SNK_DEBOUNCED ,0 );break ;case SNK_READY : -if (tcpm_port_is_disconnected (port)) +/* +* When set_auto_vbus_discharge_threshold is enabled, CC pins go +* away before vbus decays to disconnect threshold. Allow +* disconnect to be driven by vbus disconnect when auto vbus +* discharge is enabled. +* +* EXIT condition is based primarily on vbus disconnect and CC is secondary. +* "A port that has entered into USB PD communications with the Source and +* has seen the CC voltage exceed vRd-USB may monitor the CC pin to detect +* cable disconnect in addition to monitoring VBUS. +*/ +if (!port->auto_vbus_discharge_enabled &&tcpm_port_is_disconnected (port))tcpm_set_state (port,unattached_state (port),0 );else if (!port->pd_capable && (cc1 != old_cc1 || cc2 != old_cc2))
@@ -4803,9 +4833,16 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,*/ break ; +case VBUS_DISCHARGE : +/* Do nothing. Waiting for vsafe0v signal */ +break ;default : -if (tcpm_port_is_disconnected (port)) -tcpm_set_state (port,unattached_state (port),0 ); +if (tcpm_port_is_disconnected (port)) { +if (port->auto_vbus_discharge_enabled && !port->vbus_vsafe0v) +tcpm_set_state (port,VBUS_DISCHARGE ,0 ); +else +tcpm_set_state (port,unattached_state (port),0 ); + }break ; } }
@@ -4988,9 +5025,12 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)break ;default : -if (port->pwr_role ==TYPEC_SINK && - port->attached) -tcpm_set_state (port,SNK_UNATTACHED ,0 ); +if (port->pwr_role ==TYPEC_SINK && port->attached) { +if (port->auto_vbus_discharge_enabled && !port->vbus_vsafe0v) +tcpm_set_state (port,VBUS_DISCHARGE ,0 ); +else +tcpm_set_state (port,SNK_UNATTACHED ,0 ); + }break ; } }
@@ -5012,6 +5052,12 @@ static void _tcpm_pd_vbus_vsafe0v(struct tcpm_port *port)tcpm_set_state (port,tcpm_try_snk (port) ?SNK_TRY :SRC_ATTACHED ,PD_T_CC_DEBOUNCE );break ; +case VBUS_DISCHARGE : +if (port->port_type ==TYPEC_PORT_SRC ) +tcpm_set_state (port,SRC_UNATTACHED ,0 ); +else +tcpm_set_state (port,SNK_UNATTACHED ,0 ); +break ;default :break ; }
Signature · 1 line
2.30.0.617.g56c4b15f3c-goog
Greg Kroah-Hartman
maintainerQuoted 16 lines · Badhri Jagan Sridharan
When vbus auto discharge is enabled, TCPM can sometimes be faster than the TCPC i.e. TCPM can go ahead and move the port to unattached state (involves disabling vbus auto discharge) before TCPC could effectively discharge vbus to VSAFE0V. This leaves vbus with residual charge and increases the decay time which prevents tsafe0v from being met. This change introduces a new state
VBUS_DISCHARGEwhere the TCPM waits for a maximum of tSafe0V(max) for vbus to discharge to VSAFE0V before transitioning to unattached state and re-enable toggling. If vbus discharges to vsafe0v sooner, then, transition to unattached state happens right away.Also, while in
SNK_READY, when auto discharge is enabled, drive disconnect based on vbus turning off instead of Rp disappearing on CC pins. Rp disappearing on CC pins is almost instanteous compared to vbus decay.
Quoted 4 lines
Signed-off-by Badhri Jagan Sridharan <[email protected]>--- drivers/usb/typec/tcpm/tcpm.c | 60 +++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-)
As this seems to be a bugfix, what commit does it fix? Should it go to stable kernels? If so, how far back?
And as this is the merge window, I can't do anything with this until 5.12-rc1 is out, so be prepared for the delay...
thanks,
greg k-h
Hi Greg,
This patch is a bug fix for the following patch which was introduced in 5.11.
commit f321a02caebdd0c56e167610cda2fa148cd96e8b
Author: Badhri Jagan Sridharan <[email protected]> Date: Wed Oct 28 23:31:35 2020 -0700
usb: typec: tcpm: Implement enabling Auto Discharge disconnect support
TCPCI spec allows TCPC hardware to autonomously discharge the vbus capacitance upon disconnect. The expectation is that the TCPM enables AutoDischargeDisconnect while entering SNK/SRC_ATTACHED states. Hardware then automously discharges vbus when the vbus falls below a certain threshold i.e. VBUS_SINK_DISCONNECT_THRESHOLD.
Apart from enabling the vbus discharge circuit, AutoDischargeDisconnect is also used a flag to move TCPCI based TCPC implementations into Attached.Snk/Attached.Src state as mentioned in
Figure 4-15. TCPC State Diagram before a Connection of the USB Type-C Port Controller Interface Specification.
In such TCPC implementations, setting AutoDischargeDisconnect would prevent TCPC into entering "Connection_Invalid" state as well.
Thanks,
Badhri
Quoted 32 lines · Greg Kroah-Hartman
Quoted 16 lines · Badhri Jagan Sridharan
When vbus auto discharge is enabled, TCPM can sometimes be faster than the TCPC i.e. TCPM can go ahead and move the port to unattached state (involves disabling vbus auto discharge) before TCPC could effectively discharge vbus to VSAFE0V. This leaves vbus with residual charge and increases the decay time which prevents tsafe0v from being met. This change introduces a new state
VBUS_DISCHARGEwhere the TCPM waits for a maximum of tSafe0V(max) for vbus to discharge to VSAFE0V before transitioning to unattached state and re-enable toggling. If vbus discharges to vsafe0v sooner, then, transition to unattached state happens right away.Also, while in
SNK_READY, when auto discharge is enabled, drive disconnect based on vbus turning off instead of Rp disappearing on CC pins. Rp disappearing on CC pins is almost instanteous compared to vbus decay.Quoted 4 lines
Signed-off-by Badhri Jagan Sridharan <[email protected]>--- drivers/usb/typec/tcpm/tcpm.c | 60 +++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-)As this seems to be a bugfix, what commit does it fix? Should it go to stable kernels? If so, how far back?
And as this is the merge window, I can't do anything with this until 5.12-rc1 is out, so be prepared for the delay...
thanks,
greg k-h
Greg Kroah-Hartman
maintainerQuoted 24 lines · Badhri Jagan Sridharan
Hi Greg,
This patch is a bug fix for the following patch which was introduced in 5.11.
commit
f321a02caebdd0c56e167610cda2fa148cd96e8bAuthor: Badhri Jagan Sridharan <[email protected]> Date: Wed Oct 28 23:31:35 2020 -0700usb: typec: tcpm: Implement enabling Auto Discharge disconnect support
TCPCI spec allows TCPC hardware to autonomously discharge the vbus capacitance upon disconnect. The expectation is that the TCPM enables AutoDischargeDisconnect while entering SNK/SRC_ATTACHED states. Hardware then automously discharges vbus when the vbus falls below a certain threshold i.e.
VBUS_SINK_DISCONNECT_THRESHOLD.Apart from enabling the vbus discharge circuit, AutoDischargeDisconnect is also used a flag to move TCPCI based TCPC implementations into Attached.Snk/Attached.Src state as mentioned in
Figure 4-15. TCPC State Diagram before a Connection of the USB Type-C Port Controller Interface Specification.
In such TCPC implementations, setting AutoDischargeDisconnect would prevent TCPC into entering "Connection_Invalid" state as well.
Quoted 4 lines
Signed-off-by Badhri Jagan Sridharan <[email protected]>Reviewed-by Heikki Krogerus <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
Great, then can you resend the patch and add a proper Fixes: tag, along with a cc: stable as well?
thanks,
greg k-h
Badhri Jagan Sridharan
maintainerDone. Just sent out the following patch and CCed [email protected] as well.
[PATCH v2] usb: typec: tcpm: Wait for vbus discharge to VSAFE0V before toggling
Thanks,
Badhri
Quoted 37 lines · Greg Kroah-Hartman
Quoted 24 lines · Badhri Jagan Sridharan
Hi Greg,
This patch is a bug fix for the following patch which was introduced in 5.11.
commit
f321a02caebdd0c56e167610cda2fa148cd96e8bAuthor: Badhri Jagan Sridharan <[email protected]> Date: Wed Oct 28 23:31:35 2020 -0700usb: typec: tcpm: Implement enabling Auto Discharge disconnect support
TCPCI spec allows TCPC hardware to autonomously discharge the vbus capacitance upon disconnect. The expectation is that the TCPM enables AutoDischargeDisconnect while entering SNK/SRC_ATTACHED states. Hardware then automously discharges vbus when the vbus falls below a certain threshold i.e.
VBUS_SINK_DISCONNECT_THRESHOLD.Apart from enabling the vbus discharge circuit, AutoDischargeDisconnect is also used a flag to move TCPCI based TCPC implementations into Attached.Snk/Attached.Src state as mentioned in
Figure 4-15. TCPC State Diagram before a Connection of the USB Type-C Port Controller Interface Specification.
In such TCPC implementations, setting AutoDischargeDisconnect would prevent TCPC into entering "Connection_Invalid" state as well.Quoted 4 lines
Signed-off-by Badhri Jagan Sridharan <[email protected]>Reviewed-by Heikki Krogerus <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>Great, then can you resend the patch and add a proper Fixes: tag, along with a cc: stable as well?
thanks,
greg k-h