summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2023-05-12 10:25:48 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-05-16 20:12:01 +0000
commit32a3d94e879efebef135062342fdbd9dae8ec463 (patch)
treeb3f1db163cb964449447af80cd18c04ca2ce837e
parent45397393246d14872a895cbefcb219bc5e31fc6f (diff)
downloadchrome-ec-32a3d94e879efebef135062342fdbd9dae8ec463.tar.gz
AMD Mux Emul: Stabilize delayed mux set code
The current emulator relies on timing in order to delay mux sets. However, this can lead to some surprising mismatches in time between the emulator and test (such as the write completing during a subsequent test case). Instead, delay by the number of reads the driver has done. BUG=b:234771735 TEST=./twister -s drivers/drivers.amd_fp6_usb_mux Change-Id: I71c78348e29b70c479da8009b8a085cf4e57c188 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4528795 Reviewed-by: Jeremy Bettis <jbettis@chromium.org> Commit-Queue: Diana Z <dzigterman@chromium.org> Tested-by: Diana Z <dzigterman@chromium.org>
-rw-r--r--zephyr/emul/emul_amd_fp6.c18
-rw-r--r--zephyr/include/emul/emul_amd_fp6.h9
-rw-r--r--zephyr/test/drivers/amd_fp6_usb_mux/src/amd_fp6_usb_mux_test.c2
3 files changed, 17 insertions, 12 deletions
diff --git a/zephyr/emul/emul_amd_fp6.c b/zephyr/emul/emul_amd_fp6.c
index dfb763e1c8..b0b618fd6a 100644
--- a/zephyr/emul/emul_amd_fp6.c
+++ b/zephyr/emul/emul_amd_fp6.c
@@ -28,8 +28,8 @@ enum amd_fp6_read_bytes {
struct amd_fp6_data {
struct i2c_common_emul_data common;
- int64_t finish_delay; /* How long before mux set "completes"? */
- int64_t set_time; /* Time of last set call */
+ int finish_delay; /* How many reads before mux set "completes"? */
+ int waiting_reads; /* How many reads have we waited to complete? */
uint8_t last_mux_set; /* Last value of mux set call */
uint8_t regs[AMD_FP6_MAX_REG];
};
@@ -58,11 +58,11 @@ void amd_fp6_emul_reset_regs(const struct emul *emul)
data->regs[AMD_FP6_PORT1] = 0;
}
-void amd_fp6_emul_set_delay(const struct emul *emul, int delay_ms)
+void amd_fp6_emul_set_delay(const struct emul *emul, int delay_reads)
{
struct amd_fp6_data *data = (struct amd_fp6_data *)emul->data;
- data->finish_delay = delay_ms;
+ data->finish_delay = delay_reads;
}
void amd_fp6_emul_set_xbar(const struct emul *emul, bool ready)
@@ -87,11 +87,11 @@ static int amd_fp6_emul_read(const struct emul *emul, int reg, uint8_t *val,
/* Decide if we've finally finished our operation */
if (pos == AMD_FP6_PORT0 && data->finish_delay > 0) {
- int64_t uptime = k_uptime_delta(&data->set_time);
+ data->waiting_reads++;
if (((regs[pos] >> AMD_FP6_MUX_PORT_STATUS_OFFSET) ==
AMD_FP6_MUX_PORT_CMD_BUSY) &&
- (uptime >= data->finish_delay))
+ (data->waiting_reads >= data->finish_delay))
regs[pos] =
amd_fp6_emul_mux_complete(data->last_mux_set);
}
@@ -113,11 +113,13 @@ static int amd_fp6_emul_write(const struct emul *emul, int reg, uint8_t val,
data->last_mux_set = val;
- if (data->finish_delay == 0)
+ if (data->finish_delay == 0) {
regs[AMD_FP6_PORT0] = amd_fp6_emul_mux_complete(val);
- else
+ } else {
+ data->waiting_reads = 0;
regs[AMD_FP6_PORT0] = AMD_FP6_MUX_PORT_CMD_BUSY
<< AMD_FP6_MUX_PORT_STATUS_OFFSET;
+ }
return 0;
}
diff --git a/zephyr/include/emul/emul_amd_fp6.h b/zephyr/include/emul/emul_amd_fp6.h
index 6c63a6caab..04dcd5dd31 100644
--- a/zephyr/include/emul/emul_amd_fp6.h
+++ b/zephyr/include/emul/emul_amd_fp6.h
@@ -29,10 +29,13 @@ void amd_fp6_emul_set_xbar(const struct emul *emul, bool ready);
* Set how long a command will take to complete. On a real system this can be
* anywhere from 50-100ms and the datasheet defines it can take up to 250ms.
*
+ * Getting timing to sync consistently in unit testing is difficult, so use the
+ * number of reads to wait instead.
+ *
* @param emul - AMD FP6 emulator data
- * @param delay_ms - how long after a mux set to wait before reporting the
- * status of the set as complete.
+ * @param delay_reads - how long after a mux set to wait before reporting the
+ * status of the set as complete (in number of reads)
*/
-void amd_fp6_emul_set_delay(const struct emul *emul, int delay_ms);
+void amd_fp6_emul_set_delay(const struct emul *emul, int delay_reads);
#endif
diff --git a/zephyr/test/drivers/amd_fp6_usb_mux/src/amd_fp6_usb_mux_test.c b/zephyr/test/drivers/amd_fp6_usb_mux/src/amd_fp6_usb_mux_test.c
index d900b2d3c2..8d8a6982cf 100644
--- a/zephyr/test/drivers/amd_fp6_usb_mux/src/amd_fp6_usb_mux_test.c
+++ b/zephyr/test/drivers/amd_fp6_usb_mux/src/amd_fp6_usb_mux_test.c
@@ -140,7 +140,7 @@ ZTEST_F(amd_fp6_usb_mux, test_chipset_reset)
ZTEST_F(amd_fp6_usb_mux, test_long_command)
{
/* Allow the mux to take a while, like on real systems */
- amd_fp6_emul_set_delay(fixture->amd_fp6_emul, 100);
+ amd_fp6_emul_set_delay(fixture->amd_fp6_emul, 6);
/* Send a basic set to USB mode */
usb_mux_set(TEST_PORT, USB_PD_MUX_USB_ENABLED, USB_SWITCH_CONNECT, 1);