1# Copyright 2019 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import time 7 8from autotest_lib.client.common_lib import error 9from autotest_lib.server.cros.faft.cr50_test import Cr50Test 10 11 12class firmware_Cr50DeferredECReset(Cr50Test): 13 """Verify EC_RST_L stays asserted only if all conditions below are True. 14 (1) System got 'Power-On reset'. 15 (2) RDD cable is connected. 16 (3) The power button is held. 17 18 After this, EC_RST_L should be deasserted as soon as the power button 19 gets released. 20 """ 21 version = 1 22 23 def initialize(self, host, cmdline_args, full_args): 24 """Initialize the test and check if 25 cr50 is exists, 26 DTS is controllable, and 27 power delivery mode and power button is adjustable. 28 """ 29 super(firmware_Cr50DeferredECReset, self).initialize(host, cmdline_args, 30 full_args) 31 if not hasattr(self, 'cr50'): 32 raise error.TestNAError('Test can only be run on devices with ' 33 'access to the Cr50 console') 34 if not self.cr50.servo_v4_supports_dts_mode(): 35 raise error.TestNAError('Need working servo v4 DTS control') 36 37 self.fast_open(enable_testlab=True) 38 if not self.cr50.testlab_is_on(): 39 raise error.TestNAError('Cr50 testlab mode needs to be enabled') 40 41 # Test the external power delivery 42 self.servo.set('servo_v4_role', 'snk') 43 time.sleep(3) 44 45 rv = self.ec.send_command_get_output('chgstate',['.*>'])[0].strip() 46 logging.info(rv) 47 if not 'ac = 0' in rv: 48 raise error.TestFail('Failed in setting servo_v4_role sink') 49 50 # Test stopping the external power delivery 51 self.servo.set('servo_v4_role', 'src') 52 time.sleep(3) 53 54 rv = self.ec.send_command_get_output('chgstate',['.*>'])[0].strip() 55 logging.info(rv) 56 if not 'ac = 1' in rv: 57 raise error.TestFail('Failed in setting servo_v4_role source') 58 59 # Test if the power button is adjustable. 60 self.servo.set('pwr_button', 'press') 61 self.servo.set('pwr_button', 'release') 62 63 def check_ecrst_asserted(self, expect_assert): 64 """Ask CR50 whether EC_RST_L is asserted or deasserted. 65 66 Args: 67 expect_assert: True if it is expected asserted. 68 False otherwise. 69 """ 70 71 # If the console is responsive, then the EC is awake. 72 rv = self.cr50.send_command_get_output('ecrst', 73 ['EC_RST_L is \w{0,2}asserted.*>'])[0].strip() 74 logging.info(rv) 75 expecting_txt = ' asserted' if expect_assert else ' deasserted' 76 77 if not expecting_txt in rv: 78 raise error.TestFail(rv) 79 80 def ping_ec(self, expect_response): 81 """Check if EC is running and responding. 82 83 Args: 84 expect_response: True if EC should respond 85 False otherwise. 86 """ 87 try: 88 rv = self.ec.send_command_get_output('time', 89 ['time.*>'])[0].strip() 90 except error.TestFail as e: 91 logging.info(e) 92 if 'Timeout waiting for response' in str(e): 93 if not expect_response: 94 return 95 raise e 96 else: 97 if not expect_response: 98 raise error.TestFail(rv) 99 100 def test_deferred_ec_reset(self, power_button_hold, rdd_enable, 101 expect_ec_response): 102 """Do a power-on reset, and check if EC responds. 103 104 Args: 105 power_button_hold: True if it should be pressed on a system reset. 106 False otherwise. 107 rdd_enable: True if RDD should be detected on a system reset. 108 False otherwise. 109 expect_ec_response: True if EC should run and response on a system 110 reset. 111 False otherwise. 112 """ 113 logging.info('Test deferred_ec_reset starts.') 114 logging.info('Power button held: %s', power_button_hold) 115 logging.info('RDD connection : %s', rdd_enable) 116 117 # Stop power delivery to DUT 118 self.servo.set('servo_v4_role', 'snk') 119 time.sleep(3) 120 121 # Battery Cutoff 122 self.ec.send_command('cutoff') 123 time.sleep(3) 124 125 # EC should not respond 126 self.ping_ec(False) 127 128 # press (or release) the power button 129 power_button_setval = 'press' if power_button_hold else 'release' 130 # call set_nocheck, since power button shall be recognized as pressed 131 # at this point. 132 self.servo.set_nocheck('pwr_button', power_button_setval) 133 134 # enable RDD Connection (or disable) 135 self.servo.set_nocheck('servo_v4_dts_mode', 136 'on' if rdd_enable else 'off') 137 time.sleep(self.cr50.SHORT_WAIT) 138 139 # Enable power delivery to DUT 140 self.servo.set('servo_v4_role', 'src') 141 142 # Wait for a while 143 wait_sec = 30 144 logging.info('waiting for %d seconds', wait_sec) 145 time.sleep(wait_sec) 146 147 # Check if EC_RST_L is asserted (or deasserted) and EC is on (or off). 148 self.check_ecrst_asserted(not expect_ec_response) 149 self.ping_ec(expect_ec_response) 150 151 # Release power button 152 self.servo.set('pwr_button', 'release') 153 154 # Check if EC_RST_L is deasserted and EC is on. 155 self.check_ecrst_asserted(False) 156 self.ping_ec(True) 157 158 # Recover CCD 159 if self.servo.get('servo_v4_dts_mode') == 'off': 160 self.cr50.ccd_enable() 161 162 def run_once(self): 163 """Test deferred EC reset feature. """ 164 165 # Release power button and disable RDD on power-on reset. 166 # EC should be running. 167 self.test_deferred_ec_reset(power_button_hold=False, rdd_enable=False, 168 expect_ec_response=True) 169 170 # Release power button but enable RDD on power-on reset. 171 # EC should be running. 172 self.test_deferred_ec_reset(power_button_hold=False, rdd_enable=True, 173 expect_ec_response=True) 174 175 # Hold power button but disable RDD on power-on reset. 176 # EC should be running. 177 self.test_deferred_ec_reset(power_button_hold=True, rdd_enable=False, 178 expect_ec_response=True) 179 180 # Hold power button and enable RDD on power-on reset. 181 # EC should not be running. 182 self.test_deferred_ec_reset(power_button_hold=True, rdd_enable=True, 183 expect_ec_response=False) 184