diff options
author | Patryk Duda <pdk@semihalf.com> | 2020-12-01 11:39:30 +0100 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-12-01 18:29:54 +0000 |
commit | 8fdf3d02e5d3045b737ac0de99b77b3394a0dcb4 (patch) | |
tree | 9096246cd4cd283f69261d5b9a5c76248f6eb6ef | |
parent | 6f2aa2eeb14edc0266b8a85bdd5769cac40bfbb6 (diff) | |
download | chrome-ec-8fdf3d02e5d3045b737ac0de99b77b3394a0dcb4.tar.gz |
servo_v4p1/usb_pd_policy: Reject SNK->SRC power swap if CC_ALLOW_SRC not set
Apply changes in CL:2566813 to ServoV4P1 too. Original message below.
When ServoV4 acts as sink ('cc snk' issued), and we issue 'cc pdsnk'
there are following state transitions (starting from C1 SNK_READY):
C1 st8 SNK_READY <--- From this point DUT acts as source
DUT's PE is in PE_SRC_Ready state
C1 RECV 196f/1 [0]ff008001
C1 RECV 0b67/0 <--- DUT asks for source capabilities
C1 srcCAP>1 <--- ServoV4 sends its capabilities
C1 RECV 0d6a/0 <--- DUT requests power swap
C1 CTRL[3]>1 <--- ServoV4 accepts
C1 st10 SNK_SWAP_SNK_DISABLE
C1 st11 SNK_SWAP_SRC_DISABLE
C1 RECV 0e66/0 <--- DUT sends PS_RDY to inform that it
disabled power
C1 st12 SNK_SWAP_STANDBY <--- ServoV4 enables power supply and waits
PD_POWER_SUPPLY_TURN_ON_DELAY to ensure
that it is turned on, before switching
to SNK_SWAP_COMPLETE
C1 st13 SNK_SWAP_COMPLETE <--- Power swap completed successfully
C1 CTRL[6]>1 <--- ServoV4 sends PS_RDY to inform that
power was enabled.
C1 st18 SRC_DISCOVERY
C1 srcCAP>1 <--- ServoV4 sends its capabilities
C1 st19 SRC_NEGOCIATE
C1 RECV 1062/1 [0]4304b12c
Requested 15000 mV 3000 mA (for 3000/3000 mA)
C1 CTRL[3]>1 <--- ServoV4 accepts
C1 st20 SRC_ACCEPTED
C1 st21 SRC_POWERED <--- Switching to requested voltage. This
calls pd_transition_voltage() from
servo_v4/usb_pd_policy which requests
charger to change its voltage.
[570.815776 Waiting for CHG port transition]
<--- Here we are changing active task to
PD_C0. This task changes dual role
for C1 (DUT port), because CC_ALLOW_SRC
is not set. Appropriate event is set too
C0 Req [4] 15000mV 3000mA
C0 REQ>1
C0 st6 SNK_REQUESTED
[570.822679 CL: p0 s0 i500 v5000]
C0 RECV 0763/0
C0 st7 SNK_TRANSITION
C0 RECV 0966/0
C0 st8 SNK_READY <--- Charger voltage changed successfully
[570.991969 CL: p0 s0 i3000 v15000]
<--- Context switch to PD_C1 task
[571.001981 CHG transitioned]
<--- Check event and call
update_dual_role_config() which
changes state to SNK_DISCONNECTED
C1 st2 SNK_DISCONNECTED
Port 1 switches to SNK_DISCONNECTED state because PD_C0 task calls
pd_send_request_msg() (reaction for voltage change request), which
limits maximum current by calling charge_manager_force_ceil().
Charge manager calls board_set_charge_limit() to limit current, which
calls update_ports() which calls board_manage_dut_port()
unconditionally. This function checks if charge through is allowed. It
turns out that it is not allowed, because CC_ALLOW_SRC bit is not set
in cc_config (see is_charge_through_allowed()), then
board_manage_dut_port() changes dual role of port 1 to force sink.
Fix for this issue is simple. Function is_charge_through_allowed()
actually tells us that we are not able to source power when 'cc snk' or
'cc pdsnk' was issued. So fix is just to reject power swap when our
power role is sink, and CC_ALLOW_SRC is not set.
BUG=b:162254118
BRANCH=none
TEST=Issue 'cc snk' from ServoV4 console and wait until state gets
stable. Issue 'cc pdsnk' from ServoV4 console and check if port 1
reaches SNK_READY state.
Signed-off-by: Patryk Duda <pdk@semihalf.com>
Change-Id: Iadf41bbb82d300bc05c1528a403267225a6907d4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2566991
Reviewed-by: Jett Rink <jettrink@chromium.org>
Commit-Queue: Jett Rink <jettrink@chromium.org>
-rw-r--r-- | board/servo_v4p1/usb_pd_policy.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/board/servo_v4p1/usb_pd_policy.c b/board/servo_v4p1/usb_pd_policy.c index 58f189dd39..9fa7187696 100644 --- a/board/servo_v4p1/usb_pd_policy.c +++ b/board/servo_v4p1/usb_pd_policy.c @@ -767,6 +767,9 @@ __override int pd_check_power_swap(int port) if (port == CHG) return 0; + if (pd_get_power_role(port) == PD_ROLE_SINK && !(cc_config & CC_ALLOW_SRC)) + return 0; + if (pd_snk_is_vbus_provided(CHG)) return allow_pr_swap; |