faft_cr50: add test verifying EC_RST_L
A couple of boards have had issues with cr50 being able to wake the EC
from hibernate. This change adds a test to verify EC_RST_L behavior, so
we can catch this sort of thing sooner.
BUG=none
BRANCH=none
TEST=run on nami
Change-Id: Ic35ad9085e4d45f7922795c3c623cbf05999268b
Signed-off-by: Mary Ruthven <mruthven@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1242329
Tested-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-by: Wai-Hong Tam <waihong@google.com>
Commit-Queue: Mary Ruthven <mruthven@chromium.org>
diff --git a/server/site_tests/firmware_Cr50ECReset/control b/server/site_tests/firmware_Cr50ECReset/control
new file mode 100644
index 0000000..eac2c02
--- /dev/null
+++ b/server/site_tests/firmware_Cr50ECReset/control
@@ -0,0 +1,35 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from autotest_lib.server import utils
+
+AUTHOR = "mruthven"
+NAME = "firmware_Cr50ECReset"
+PURPOSE = "Verify Cr50 EC reset."
+ATTRIBUTES = "suite:faft_cr50_prepvt, suite:faft_cr50_pvt"
+TIME = "SHORT"
+TEST_TYPE = "server"
+DEPENDENCIES = "servo"
+
+DOC = """Make sure 'cr50 ecrst' works as intended
+
+EC_RST_L needs to be able to wake the EC from hibernate and hold the EC in
+reset. This test verifies the hardware works as intended
+"""
+
+if 'args_dict' not in locals():
+ args_dict = {}
+
+args_dict.update(utils.args_to_dict(args))
+servo_args = hosts.CrosHost.get_servo_arguments(args_dict)
+
+def run(machine):
+ host = hosts.create_host(machine, servo_args=servo_args)
+
+ iterations = int(args_dict.get("iterations", 1))
+
+ job.run_test("firmware_Cr50ECReset", host=host, cmdline_args=args,
+ full_args=args_dict, iterations=iterations)
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/firmware_Cr50ECReset/firmware_Cr50ECReset.py b/server/site_tests/firmware_Cr50ECReset/firmware_Cr50ECReset.py
new file mode 100644
index 0000000..45123f5
--- /dev/null
+++ b/server/site_tests/firmware_Cr50ECReset/firmware_Cr50ECReset.py
@@ -0,0 +1,139 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import logging
+import time
+
+from autotest_lib.client.common_lib import error
+from autotest_lib.server.cros.faft.cr50_test import Cr50Test
+
+
+class firmware_Cr50ECReset(Cr50Test):
+ """Make sure 'cr50 ecrst' works as intended
+
+ EC_RST_L needs to be able to wake the EC from hibernate and hold the EC in
+ reset. This test verifies the hardware works as intended
+ """
+ version = 1
+
+ # Delays used by the test. Time is given in seconds
+ # Used to wait long enough for the EC to enter/resume from hibernate
+ EC_SETTLE_TIME = 10
+ RELEASE_RESET_DELAY = 3
+ SHORT_PULSE = 1
+
+ def cleanup(self):
+ """Make sure the EC is on"""
+ self.guarantee_ec_is_up()
+ super(firmware_Cr50ECReset, self).cleanup()
+
+
+ def ec_is_up(self):
+ """If the console is responsive, then the EC is awake"""
+ time.sleep(self.EC_SETTLE_TIME)
+ try:
+ self.ec.send_command_get_output('time', ['.*>'])
+ except error.TestFail, e:
+ logging.info(e)
+ if 'Timeout waiting for response' in str(e):
+ return False
+ raise
+ else:
+ return True
+
+
+ def cold_reset(self, state):
+ """Set cold reset"""
+ self.servo.set('cold_reset', state)
+
+
+ def power_button(self, state):
+ """Press or release the power button"""
+ self.servo.set('pwr_button', 'press' if state == 'on' else 'release')
+
+
+ def cr50_ecrst(self, state):
+ """Set ecrst on cr50"""
+ self.cr50.send_command('ecrst ' + state)
+
+
+ def wake_ec(self, wake_method):
+ """Pulse the wake method to wake the EC
+
+ Args:
+ wake_method: a function that takes in 'on' or 'off' to control the
+ wake source.
+ """
+ wake_method('on')
+ time.sleep(self.SHORT_PULSE)
+ wake_method('off')
+
+
+ def ec_hibernate(self):
+ """Put the EC in hibernate"""
+ self.ec.send_command('hibernate')
+ if self.ec_is_up():
+ raise error.TestError('Could not put the EC into hibernate')
+
+
+ def guarantee_ec_is_up(self):
+ """Make sure ec isn't held in reset. Use the power button to wake it
+
+ The power button wakes the EC on all systems. Use that to wake the EC
+ and make sure all versions of ecrst are released.
+ """
+ self.cold_reset('off')
+ self.cr50_ecrst('off')
+ time.sleep(self.RELEASE_RESET_DELAY)
+ self.wake_ec(self.power_button)
+ if not self.ec_is_up():
+ raise error.TestError('Could not recover EC')
+
+
+ def can_wake_ec(self, wake_method):
+ """Put the EC in hibernate and verify it can wake up with wake_method
+
+ Args:
+ wake_method: a function that takes in 'on' or 'off' to control the
+ wake source.
+ Returns:
+ True if wake_method can be used to wake the EC from hibernate
+ """
+ self.ec_hibernate()
+ self.wake_ec(self.cold_reset)
+ wake_successful = self.ec_is_up()
+ self.guarantee_ec_is_up()
+ return wake_successful
+
+
+ def check_basic_ecrst(self):
+ """Verify cr50 can hold the EC in reset"""
+ self.cr50_ecrst('on')
+ if self.ec_is_up():
+ raise error.TestFail('Could not use cr50 ecrst to hold the EC in '
+ 'reset')
+ # Verify cr50 can release the EC from reset
+ self.cr50_ecrst('off')
+ if not self.ec_is_up():
+ raise error.TestFail('Could not release the EC from reset')
+ self.guarantee_ec_is_up()
+
+
+ def run_once(self):
+ """Make sure 'cr50 ecrst' works as intended."""
+ failed_wake = []
+ # Open cr50 so the test has access to ecrst
+ self.fast_open(True)
+
+ self.check_basic_ecrst()
+
+ if not self.can_wake_ec(self.cr50_ecrst):
+ failed_wake.append('cr50 ecrst')
+
+ if not self.can_wake_ec(self.cold_reset):
+ failed_wake.append('servo cold_reset')
+
+ if failed_wake:
+ raise error.TestFail('Failed to wake EC with %s' %
+ ' and '.join(failed_wake))