1 # Copyright 2016 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 5 import logging, time 6 7 from autotest_lib.client.common_lib import error 8 from autotest_lib.client.common_lib import utils 9 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 10 11 # platform_S0ixCycle test timing constants 12 BEFORE_SUSPEND_WAIT_TIME_SECONDS = 10 13 BEFORE_RESUME_WAIT_TIME_SECONDS = 2 14 SUSPEND_WAIT_TIME_SECONDS = 5 15 LIDOPEN_WAIT_TIME_SECONDS = 2 16 POWER_STATE_RETRY_COUNT = 10 17 18 class platform_S0ixCycle(FirmwareTest): 19 ''' 20 Servo based S0ix cycle test and wake source. 21 ''' 22 version = 1 23 24 def initialize(self, host, cmdline_args): 25 dict_args = utils.args_to_dict(cmdline_args) 26 self.faft_iterations = int(dict_args.get('faft_iterations', 1)) 27 super(platform_S0ixCycle, self).initialize(host, cmdline_args) 28 self.switcher.setup_mode('normal') 29 30 def perform_s0ix_cycle(self): 31 """ 32 Perform S0ix suspend/resume cycle and check state transition. 33 """ 34 resume_sources = ['powerbtn', 'lid', 'kbpress'] 35 for resume_source in resume_sources: 36 time.sleep(BEFORE_SUSPEND_WAIT_TIME_SECONDS); 37 self.perform_suspend() 38 self.perform_resume(resume_source) 39 40 def perform_suspend(self): 41 """ 42 Perform suspend to idle and check state transition. 43 """ 44 logging.info('== S0ix suspend and check the state transition ==') 45 # check S0ix state transition 46 if not self.wait_power_state('S0', POWER_STATE_RETRY_COUNT): 47 raise error.TestFail('Platform failed to reach S0 state.') 48 self.faft_client.system.run_shell_command('echo freeze > /sys/power/state &') 49 time.sleep(SUSPEND_WAIT_TIME_SECONDS); 50 # check S0ix state transition 51 if not self.wait_power_state('S0ix', POWER_STATE_RETRY_COUNT): 52 raise error.TestFail('Platform failed to reach S0ix state.') 53 54 def perform_resume(self, resume_source): 55 """ 56 Perform resume with selected resume source and check state transition. 57 @param resume_source(string):resume source option. 58 """ 59 logging.info('== S0ix resume and check the state transition ==') 60 time.sleep(BEFORE_RESUME_WAIT_TIME_SECONDS); 61 if resume_source == 'powerbtn': 62 self.ec.send_command('powerbtn') 63 elif resume_source == 'lid': 64 self.ec.send_command('lidclose') 65 time.sleep(LIDOPEN_WAIT_TIME_SECONDS); 66 self.ec.send_command('lidopen') 67 elif resume_source == 'kbpress': 68 self.ec.key_press('<enter>') 69 else: 70 raise error.TestFail('Invalid resume source.') 71 # check S0 state transition 72 if not self.wait_power_state('S0', POWER_STATE_RETRY_COUNT): 73 raise error.TestFail('Platform failed to reach S0 state.') 74 75 def is_skl_board(self): 76 """ 77 Check this device is a SKL based ChromeBook. 78 """ 79 skl_boards = ('Kunimitsu', 'Lars', 'Glados', 'Chell', 'Sentry') 80 output = self.faft_client.system.get_platform_name() 81 return output in skl_boards 82 83 def is_s0ix_supported(self): 84 """ 85 Check this device supports suspend to idle. 86 """ 87 cmd = 'cat /var/lib/power_manager/suspend_to_idle' 88 output = self.faft_client.system.run_shell_command_get_output(cmd) 89 if not output: 90 return False 91 else: 92 return int(output[0]) == 1 93 94 def run_once(self): 95 if not self.faft_config.chrome_ec or not self.check_ec_capability(): 96 raise error.TestNAError('Chrome EC is not supported on this device.') 97 98 if not (self.is_skl_board() and self.is_s0ix_supported()): 99 raise error.TestNAError('Suspend to idle is not supported on this device.') 100 101 for i in xrange(self.faft_iterations): 102 logging.info('== Running FAFT ITERATION %d/%s ==',i+1, self.faft_iterations) 103 logging.info('S0ix suspend/resume back and check state transition.') 104 # wake the display by key press. 105 self.ec.key_press('<enter>') 106 self.switcher.mode_aware_reboot('custom', self.perform_s0ix_cycle) 107 108 def cleanup(self): 109 self.ec.set_uart_regexp('None') 110 # Test may failed before resume, wake the system. 111 self.ec.send_command('powerbtn') 112 # Perform a warm reboot as part of the cleanup. 113 self._client.reboot() 114 super(platform_S0ixCycle, self).cleanup() 115