summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2023-02-02 11:23:48 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-05-05 19:40:25 +0000
commit69004202ef54a678e151b402febba2a81bf7eff2 (patch)
treeac035ab0815da84166f8af8be4c78dc5596c54d5
parent256d78d446cb277ba16fe1df986f7ed56a7779b2 (diff)
downloadchrome-ec-69004202ef54a678e151b402febba2a81bf7eff2.tar.gz
Zephyr test: Add HPD GPIO test to AP VDM control
Add tests ensuring we set the HPD gpio correctly for the AP when we get VDM:Attention messages in for DisplayPort, and also wake the AP when needed. BUG=b:266714542 TEST=./twister -T ./zephyr/test Change-Id: Ie9946477ae4b1a3e22b5cd92a02fe844a32ae5c4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4218927 Tested-by: Diana Z <dzigterman@chromium.org> Reviewed-by: Jeremy Bettis <jbettis@chromium.org> Commit-Queue: Diana Z <dzigterman@chromium.org>
-rw-r--r--zephyr/test/drivers/ap_vdm_control/prj.conf1
-rw-r--r--zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c242
2 files changed, 243 insertions, 0 deletions
diff --git a/zephyr/test/drivers/ap_vdm_control/prj.conf b/zephyr/test/drivers/ap_vdm_control/prj.conf
index 215a8ab36d..5267603e32 100644
--- a/zephyr/test/drivers/ap_vdm_control/prj.conf
+++ b/zephyr/test/drivers/ap_vdm_control/prj.conf
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+CONFIG_PLATFORM_EC_USB_PD_DP_HPD_GPIO=y
CONFIG_PLATFORM_EC_USB_MUX_AP_CONTROL=y
CONFIG_PLATFORM_EC_USB_MUX_TASK=y
CONFIG_PLATFORM_EC_USB_PD_VDM_AP_CONTROL=y
diff --git a/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c b/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
index 6c31880625..a5f5fbd7ef 100644
--- a/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
+++ b/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
@@ -13,10 +13,13 @@
#include <stdint.h>
+#include <zephyr/drivers/gpio/gpio_emul.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/ztest.h>
+#include <gpio.h>
+
#define TEST_PORT USBC_PORT_C0
struct ap_vdm_control_fixture {
@@ -871,3 +874,242 @@ ZTEST_F(ap_vdm_control, test_no_ec_dp_mode)
status = host_cmd_typec_status(TEST_PORT);
zassert_equal(status.dp_pin, 0);
}
+
+ZTEST_F(ap_vdm_control, test_vdm_hpd_level)
+{
+ uint32_t vdm_attention_data[2];
+ int opos = 1;
+ const struct gpio_dt_spec *gpio =
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd);
+
+ /* HPD GPIO should be low before the test */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+
+ run_verify_dp_entry(fixture, opos);
+
+ /* Now send Attention to change HPD */
+ vdm_attention_data[0] =
+ VDO(USB_SID_DISPLAYPORT, 1,
+ VDO_OPOS(opos) | VDO_CMDT(CMDT_INIT) | CMD_ATTENTION) |
+ VDO_SVDM_VERS(VDM_VER20);
+ vdm_attention_data[1] = VDO_DP_STATUS(1, /* IRQ_HPD */
+ true, /* HPD_HI|LOW - Changed*/
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ 0, /* MF pref */
+ true, /* DP Enabled */
+ 0, /* power low e.g. normal */
+ 0x2 /* Connected as Sink */);
+ tcpci_partner_send_data_msg(&fixture->partner, PD_DATA_VENDOR_DEF,
+ vdm_attention_data, 2, 0);
+
+ k_sleep(K_MSEC(100));
+ /*
+ * Verify the HPD GPIO is set now
+ */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1);
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_hpd_irq_ignored)
+{
+ uint32_t vdm_attention_data[2];
+ int opos = 1;
+ const struct gpio_dt_spec *gpio =
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd);
+
+ /* HPD GPIO should be low before the test */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+
+ run_verify_dp_entry(fixture, opos);
+
+ /* Send our bad Attention message */
+ vdm_attention_data[0] =
+ VDO(USB_SID_DISPLAYPORT, 1,
+ VDO_OPOS(opos) | VDO_CMDT(CMDT_INIT) | CMD_ATTENTION) |
+ VDO_SVDM_VERS(VDM_VER20);
+ vdm_attention_data[1] = VDO_DP_STATUS(1, /* IRQ_HPD */
+ false, /* HPD_HI|LOW - Changed*/
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ 0, /* MF pref */
+ true, /* DP Enabled */
+ 0, /* power low e.g. normal */
+ 0x2 /* Connected as Sink */);
+ tcpci_partner_send_data_msg(&fixture->partner, PD_DATA_VENDOR_DEF,
+ vdm_attention_data, 2, 0);
+
+ k_sleep(K_MSEC(100));
+ /*
+ * Verify the HPD IRQ was rejected since HPD is low
+ */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_status_hpd)
+{
+ int opos = 1;
+ const struct gpio_dt_spec *gpio =
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd);
+
+ /* HPD GPIO should be low before the test */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+
+ /* Set up our slightly different DP Status */
+ fixture->partner.dp_status_vdm[VDO_INDEX_HDR + 1] =
+ VDO_DP_STATUS(0, /* IRQ_HPD */
+ true, /* HPD_HI|LOW - Changed*/
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ 1, /* MF pref */
+ true, /* DP Enabled */
+ 0, /* power low e.g. normal */
+ 0x2 /* Connected as Sink */);
+
+ /* Run Entry step by step to check HPD at each point */
+ struct typec_vdm_req req = {
+ .vdm_data = { VDO(USB_SID_DISPLAYPORT, 1,
+ CMD_ENTER_MODE | VDO_OPOS(opos)) |
+ VDO_SVDM_VERS(VDM_VER20) },
+ .vdm_data_objects = 1,
+ .partner_type = TYPEC_PARTNER_SOP,
+ };
+
+ /* Step 1: EnterMode */
+ host_cmd_typec_control_vdm_req(TEST_PORT, req);
+ k_sleep(K_MSEC(100));
+
+ verify_expected_reply(req.partner_type,
+ fixture->partner.enter_mode_vdos,
+ fixture->partner.enter_mode_vdm);
+
+ /* Step 2: DP Status */
+ req.vdm_data[0] =
+ VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_STATUS | VDO_OPOS(opos)) |
+ VDO_SVDM_VERS(VDM_VER20);
+ req.vdm_data[1] = VDO_DP_STATUS(0, /* HPD IRQ ... not applicable */
+ 0, /* HPD level ... not applicable */
+ 0, /* exit DP? ... no */
+ 0, /* usb mode? ... no */
+ 0, /* multi-function ... no */
+ 0, /* currently enabled ... no */
+ 0, /* power low? ... no */
+ 1 /* DP source connected */);
+ req.vdm_data_objects = 2;
+ req.partner_type = TYPEC_PARTNER_SOP;
+
+ host_cmd_typec_control_vdm_req(TEST_PORT, req);
+ k_sleep(K_MSEC(100));
+
+ verify_expected_reply(req.partner_type, fixture->partner.dp_status_vdos,
+ fixture->partner.dp_status_vdm);
+ /* Wait for it... */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+
+ /* Step 3: DP Configure */
+ req.vdm_data[0] =
+ VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_CONFIG | VDO_OPOS(opos)) |
+ VDO_SVDM_VERS(VDM_VER20);
+ req.vdm_data[1] = VDO_DP_CFG(MODE_DP_PIN_D, /* pin mode */
+ 1, /* DPv1.3 signaling */
+ 2); /* Set that partner should be DP sink
+ */
+ req.vdm_data_objects = 2;
+ req.partner_type = TYPEC_PARTNER_SOP;
+
+ host_cmd_typec_control_vdm_req(TEST_PORT, req);
+ k_sleep(K_MSEC(100));
+
+ verify_expected_reply(req.partner_type, fixture->partner.dp_config_vdos,
+ fixture->partner.dp_config_vdm);
+ /* Now! */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1);
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_hpd_disconnect_clear)
+{
+ uint32_t vdm_attention_data[2];
+ int opos = 1;
+ const struct gpio_dt_spec *gpio =
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd);
+
+ run_verify_dp_entry(fixture, opos);
+
+ /* Test that we see our Attention message */
+ vdm_attention_data[0] =
+ VDO(USB_SID_DISPLAYPORT, 1,
+ VDO_OPOS(opos) | VDO_CMDT(CMDT_INIT) | CMD_ATTENTION) |
+ VDO_SVDM_VERS(VDM_VER20);
+ vdm_attention_data[1] = VDO_DP_STATUS(1, /* IRQ_HPD */
+ true, /* HPD_HI|LOW - Changed*/
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ 0, /* MF pref */
+ true, /* DP Enabled */
+ 0, /* power low e.g. normal */
+ 0x2 /* Connected as Sink */);
+ tcpci_partner_send_data_msg(&fixture->partner, PD_DATA_VENDOR_DEF,
+ vdm_attention_data, 2, 0);
+
+ k_sleep(K_MSEC(100));
+ /*
+ * Verify the HPD GPIO is set now
+ */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1);
+
+ /* And disconnect */
+ disconnect_source_from_port(fixture->tcpci_emul, fixture->charger_emul);
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_wake_on_dock)
+{
+ uint32_t vdm_attention_data[2];
+ int opos = 1;
+ const struct gpio_dt_spec *gpio =
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd);
+
+ /* HPD GPIO should be low before the test */
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+
+ run_verify_dp_entry(fixture, opos);
+
+ /* Now put the AP to "sleep" */
+ test_set_chipset_to_power_level(POWER_S3);
+
+ /* Drain the MKBP event queue first */
+ struct host_cmd_handler_args args;
+ struct ec_response_get_next_event event;
+
+ args.version = 0;
+ args.command = EC_CMD_GET_NEXT_EVENT;
+ args.params = NULL;
+ args.params_size = 0;
+ args.response = &event;
+ args.response_max = sizeof(event);
+ args.response_size = 0;
+
+ while (host_command_process(&args) == EC_RES_SUCCESS) {
+ }
+
+ /* Test that we see our Attention message cause an event */
+ vdm_attention_data[0] =
+ VDO(USB_SID_DISPLAYPORT, 1,
+ VDO_OPOS(opos) | VDO_CMDT(CMDT_INIT) | CMD_ATTENTION) |
+ VDO_SVDM_VERS(VDM_VER20);
+ vdm_attention_data[1] = VDO_DP_STATUS(1, /* IRQ_HPD */
+ true, /* HPD_HI|LOW - Changed*/
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ 0, /* MF pref */
+ true, /* DP Enabled */
+ 0, /* power low e.g. normal */
+ 0x2 /* Connected as Sink */);
+ tcpci_partner_send_data_msg(&fixture->partner, PD_DATA_VENDOR_DEF,
+ vdm_attention_data, 2, 0);
+
+ k_sleep(K_MSEC(100));
+
+ /* Look for our MKBP event */
+ zassert_equal(host_command_process(&args), EC_RES_SUCCESS);
+ zassert_equal(event.event_type, EC_MKBP_EVENT_DP_ALT_MODE_ENTERED);
+}