summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Kconfig8
-rw-r--r--test/Makefile1
-rw-r--r--test/dm/.gitignore1
-rw-r--r--test/dm/Makefile3
-rw-r--r--test/dm/eth.c2
-rw-r--r--test/dm/i2c.c8
-rw-r--r--test/dm/pmic.c69
-rw-r--r--test/dm/regulator.c325
-rw-r--r--test/dm/rtc.c175
-rwxr-xr-xtest/dm/test-dm.sh3
-rw-r--r--test/dm/test-main.c3
-rw-r--r--test/dm/test.dts230
-rw-r--r--test/time_ut.c137
13 files changed, 730 insertions, 235 deletions
diff --git a/test/Kconfig b/test/Kconfig
index 1fb1716a4ad..3270c84213b 100644
--- a/test/Kconfig
+++ b/test/Kconfig
@@ -1 +1,9 @@
+config CMD_UT_TIME
+ bool "Unit tests for time functions"
+ help
+ Enables the 'ut_time' command which tests that the time functions
+ work correctly. The test is fairly simple and will not catch all
+ problems. But if you are having problems with udelay() and the like,
+ this is a good place to start.
+
source "test/dm/Kconfig"
diff --git a/test/Makefile b/test/Makefile
index 9c95805c44e..08330e020c5 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -6,3 +6,4 @@
obj-$(CONFIG_SANDBOX) += command_ut.o
obj-$(CONFIG_SANDBOX) += compression.o
+obj-$(CONFIG_CMD_UT_TIME) += time_ut.o
diff --git a/test/dm/.gitignore b/test/dm/.gitignore
deleted file mode 100644
index b741b8ab00b..00000000000
--- a/test/dm/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/test.dtb
diff --git a/test/dm/Makefile b/test/dm/Makefile
index fd9e29f201c..c7087bbfbaa 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -21,7 +21,10 @@ obj-$(CONFIG_DM_ETH) += eth.o
obj-$(CONFIG_DM_GPIO) += gpio.o
obj-$(CONFIG_DM_I2C) += i2c.o
obj-$(CONFIG_DM_PCI) += pci.o
+obj-$(CONFIG_DM_RTC) += rtc.o
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
obj-$(CONFIG_DM_SPI) += spi.o
obj-$(CONFIG_DM_USB) += usb.o
+obj-$(CONFIG_DM_PMIC) += pmic.o
+obj-$(CONFIG_DM_REGULATOR) += regulator.o
endif
diff --git a/test/dm/eth.c b/test/dm/eth.c
index 4891f3ad34f..196eba85a2b 100644
--- a/test/dm/eth.c
+++ b/test/dm/eth.c
@@ -135,6 +135,7 @@ static int dm_test_net_retry(struct dm_test_state *dms)
sandbox_eth_disable_response(1, true);
setenv("ethact", "eth@10004000");
setenv("netretry", "yes");
+ sandbox_eth_skip_timeout();
ut_assertok(net_loop(PING));
ut_asserteq_str("eth@10002000", getenv("ethact"));
@@ -144,6 +145,7 @@ static int dm_test_net_retry(struct dm_test_state *dms)
*/
setenv("ethact", "eth@10004000");
setenv("netretry", "no");
+ sandbox_eth_skip_timeout();
ut_asserteq(-ETIMEDOUT, net_loop(PING));
ut_asserteq_str("eth@10004000", getenv("ethact"));
diff --git a/test/dm/i2c.c b/test/dm/i2c.c
index 541b73b8037..c5939a165e9 100644
--- a/test/dm/i2c.c
+++ b/test/dm/i2c.c
@@ -66,6 +66,9 @@ static int dm_test_i2c_speed(struct dm_test_state *dms)
uint8_t buf[5];
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
+
+ /* Use test mode so we create the required errors for invalid speeds */
+ sandbox_i2c_set_test_mode(bus, true);
ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
ut_assertok(dm_i2c_set_bus_speed(bus, 100000));
ut_assertok(dm_i2c_read(dev, 0, buf, 5));
@@ -73,6 +76,7 @@ static int dm_test_i2c_speed(struct dm_test_state *dms)
ut_asserteq(400000, dm_i2c_get_bus_speed(bus));
ut_assertok(dm_i2c_read(dev, 0, buf, 5));
ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5));
+ sandbox_i2c_set_test_mode(bus, false);
return 0;
}
@@ -100,7 +104,11 @@ static int dm_test_i2c_probe_empty(struct dm_test_state *dms)
struct udevice *bus, *dev;
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
+
+ /* Use test mode so that this chip address will always probe */
+ sandbox_i2c_set_test_mode(bus, true);
ut_assertok(dm_i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev));
+ sandbox_i2c_set_test_mode(bus, false);
return 0;
}
diff --git a/test/dm/pmic.c b/test/dm/pmic.c
new file mode 100644
index 00000000000..e9c904c9f15
--- /dev/null
+++ b/test/dm/pmic.c
@@ -0,0 +1,69 @@
+/*
+ * Tests for the driver model pmic API
+ *
+ * Copyright (c) 2015 Samsung Electronics
+ * Przemyslaw Marczak <p.marczak@samsung.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <dm/device-internal.h>
+#include <dm/root.h>
+#include <dm/ut.h>
+#include <dm/util.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <power/pmic.h>
+#include <power/sandbox_pmic.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Test PMIC get method */
+static int dm_test_power_pmic_get(struct dm_test_state *dms)
+{
+ const char *name = "sandbox_pmic";
+ struct udevice *dev;
+
+ ut_assertok(pmic_get(name, &dev));
+ ut_assertnonnull(dev);
+
+ /* Check PMIC's name */
+ ut_asserteq_str(name, dev->name);
+
+ return 0;
+}
+DM_TEST(dm_test_power_pmic_get, DM_TESTF_SCAN_FDT);
+
+/* Test PMIC I/O */
+static int dm_test_power_pmic_io(struct dm_test_state *dms)
+{
+ const char *name = "sandbox_pmic";
+ uint8_t out_buffer, in_buffer;
+ struct udevice *dev;
+ int reg_count, i;
+
+ ut_assertok(pmic_get(name, &dev));
+
+ reg_count = pmic_reg_count(dev);
+ ut_asserteq(reg_count, SANDBOX_PMIC_REG_COUNT);
+
+ /*
+ * Test PMIC I/O - write and read a loop counter.
+ * usually we can't write to all PMIC's registers in the real hardware,
+ * but we can to the sandbox pmic.
+ */
+ for (i = 0; i < reg_count; i++) {
+ out_buffer = i;
+ ut_assertok(pmic_write(dev, i, &out_buffer, 1));
+ ut_assertok(pmic_read(dev, i, &in_buffer, 1));
+ ut_asserteq(out_buffer, in_buffer);
+ }
+
+ return 0;
+}
+DM_TEST(dm_test_power_pmic_io, DM_TESTF_SCAN_FDT);
diff --git a/test/dm/regulator.c b/test/dm/regulator.c
new file mode 100644
index 00000000000..c4f14bdac58
--- /dev/null
+++ b/test/dm/regulator.c
@@ -0,0 +1,325 @@
+/*
+ * Tests for the driver model regulator API
+ *
+ * Copyright (c) 2015 Samsung Electronics
+ * Przemyslaw Marczak <p.marczak@samsung.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <dm/device-internal.h>
+#include <dm/root.h>
+#include <dm/ut.h>
+#include <dm/util.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/sandbox_pmic.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+ BUCK1,
+ BUCK2,
+ LDO1,
+ LDO2,
+ OUTPUT_COUNT,
+};
+
+enum {
+ DEVNAME = 0,
+ PLATNAME,
+ OUTPUT_NAME_COUNT,
+};
+
+static const char *regulator_names[OUTPUT_COUNT][OUTPUT_NAME_COUNT] = {
+ /* devname, platname */
+ { SANDBOX_BUCK1_DEVNAME, SANDBOX_BUCK1_PLATNAME },
+ { SANDBOX_BUCK2_DEVNAME, SANDBOX_BUCK2_PLATNAME },
+ { SANDBOX_LDO1_DEVNAME, SANDBOX_LDO1_PLATNAME},
+ { SANDBOX_LDO2_DEVNAME, SANDBOX_LDO2_PLATNAME},
+};
+
+/* Test regulator get method */
+static int dm_test_power_regulator_get(struct dm_test_state *dms)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+ struct udevice *dev_by_devname;
+ struct udevice *dev_by_platname;
+ const char *devname;
+ const char *platname;
+ int i;
+
+ for (i = 0; i < OUTPUT_COUNT; i++) {
+ /*
+ * Do the test for each regulator's devname and platname,
+ * which are related to a single device.
+ */
+ devname = regulator_names[i][DEVNAME];
+ platname = regulator_names[i][PLATNAME];
+
+ /*
+ * Check, that regulator_get_by_devname() function, returns
+ * a device with the name equal to the requested one.
+ */
+ ut_assertok(regulator_get_by_devname(devname, &dev_by_devname));
+ ut_asserteq_str(devname, dev_by_devname->name);
+
+ /*
+ * Check, that regulator_get_by_platname() function, returns
+ * a device with the name equal to the requested one.
+ */
+ ut_assertok(regulator_get_by_platname(platname, &dev_by_platname));
+ uc_pdata = dev_get_uclass_platdata(dev_by_platname);
+ ut_assert(uc_pdata);
+ ut_asserteq_str(platname, uc_pdata->name);
+
+ /*
+ * Check, that the pointers returned by both get functions,
+ * points to the same regulator device.
+ */
+ ut_asserteq_ptr(dev_by_devname, dev_by_platname);
+ }
+
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_get, DM_TESTF_SCAN_FDT);
+
+/* Test regulator set and get Voltage method */
+static int dm_test_power_regulator_set_get_voltage(struct dm_test_state *dms)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+ struct udevice *dev;
+ const char *platname;
+ int val_set, val_get;
+
+ /* Set and get Voltage of BUCK1 - set to 'min' constraint */
+ platname = regulator_names[BUCK1][PLATNAME];
+ ut_assertok(regulator_get_by_platname(platname, &dev));
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ ut_assert(uc_pdata);
+
+ val_set = uc_pdata->min_uV;
+ ut_assertok(regulator_set_value(dev, val_set));
+
+ val_get = regulator_get_value(dev);
+ ut_assert(val_get >= 0);
+
+ ut_asserteq(val_set, val_get);
+
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_set_get_voltage, DM_TESTF_SCAN_FDT);
+
+/* Test regulator set and get Current method */
+static int dm_test_power_regulator_set_get_current(struct dm_test_state *dms)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+ struct udevice *dev;
+ const char *platname;
+ int val_set, val_get;
+
+ /* Set and get the Current of LDO1 - set to 'min' constraint */
+ platname = regulator_names[LDO1][PLATNAME];
+ ut_assertok(regulator_get_by_platname(platname, &dev));
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ ut_assert(uc_pdata);
+
+ val_set = uc_pdata->min_uA;
+ ut_assertok(regulator_set_current(dev, val_set));
+
+ val_get = regulator_get_current(dev);
+ ut_assert(val_get >= 0);
+
+ ut_asserteq(val_set, val_get);
+
+ /* Check LDO2 current limit constraints - should be -ENODATA */
+ platname = regulator_names[LDO2][PLATNAME];
+ ut_assertok(regulator_get_by_platname(platname, &dev));
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ ut_assert(uc_pdata);
+ ut_asserteq(-ENODATA, uc_pdata->min_uA);
+ ut_asserteq(-ENODATA, uc_pdata->max_uA);
+
+ /* Try set the Current of LDO2 - should return -ENOSYS */
+ ut_asserteq(-ENOSYS, regulator_set_current(dev, 0));
+
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_set_get_current, DM_TESTF_SCAN_FDT);
+
+/* Test regulator set and get Enable method */
+static int dm_test_power_regulator_set_get_enable(struct dm_test_state *dms)
+{
+ const char *platname;
+ struct udevice *dev;
+ bool val_set = true;
+
+ /* Set the Enable of LDO1 - default is disabled */
+ platname = regulator_names[LDO1][PLATNAME];
+ ut_assertok(regulator_get_by_platname(platname, &dev));
+ ut_assertok(regulator_set_enable(dev, val_set));
+
+ /* Get the Enable state of LDO1 and compare it with the requested one */
+ ut_asserteq(regulator_get_enable(dev), val_set);
+
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_set_get_enable, DM_TESTF_SCAN_FDT);
+
+/* Test regulator set and get mode method */
+static int dm_test_power_regulator_set_get_mode(struct dm_test_state *dms)
+{
+ const char *platname;
+ struct udevice *dev;
+ int val_set = LDO_OM_SLEEP;
+
+ /* Set the mode id to LDO_OM_SLEEP of LDO1 - default is LDO_OM_OFF */
+ platname = regulator_names[LDO1][PLATNAME];
+ ut_assertok(regulator_get_by_platname(platname, &dev));
+ ut_assertok(regulator_set_mode(dev, val_set));
+
+ /* Get the mode id of LDO1 and compare it with the requested one */
+ ut_asserteq(regulator_get_mode(dev), val_set);
+
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_set_get_mode, DM_TESTF_SCAN_FDT);
+
+/* Test regulator autoset method */
+static int dm_test_power_regulator_autoset(struct dm_test_state *dms)
+{
+ const char *platname;
+ struct udevice *dev, *dev_autoset;
+
+ /*
+ * Test the BUCK1 with fdt properties
+ * - min-microvolt = max-microvolt = 1200000
+ * - min-microamp = max-microamp = 200000
+ * - always-on = set
+ * - boot-on = not set
+ * Expected output state: uV=1200000; uA=200000; output enabled
+ */
+ platname = regulator_names[BUCK1][PLATNAME];
+ ut_assertok(regulator_autoset(platname, &dev_autoset, false));
+
+ /* Check, that the returned device is proper */
+ ut_assertok(regulator_get_by_platname(platname, &dev));
+ ut_asserteq_ptr(dev, dev_autoset);
+
+ /* Check the setup after autoset */
+ ut_asserteq(regulator_get_value(dev),
+ SANDBOX_BUCK1_AUTOSET_EXPECTED_UV);
+ ut_asserteq(regulator_get_current(dev),
+ SANDBOX_BUCK1_AUTOSET_EXPECTED_UA);
+ ut_asserteq(regulator_get_enable(dev),
+ SANDBOX_BUCK1_AUTOSET_EXPECTED_ENABLE);
+
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_autoset, DM_TESTF_SCAN_FDT);
+
+/*
+ * Struct setting: to keep the expected output settings.
+ * @voltage: Voltage value [uV]
+ * @current: Current value [uA]
+ * @enable: output enable state: true/false
+ */
+struct setting {
+ int voltage;
+ int current;
+ bool enable;
+};
+
+/*
+ * platname_list: an array of regulator platform names.
+ * For testing regulator_list_autoset() for outputs:
+ * - LDO1
+ * - LDO2
+ */
+static const char *platname_list[] = {
+ SANDBOX_LDO1_PLATNAME,
+ SANDBOX_LDO2_PLATNAME,
+ NULL,
+};
+
+/*
+ * expected_setting_list: an array of regulator output setting, expected after
+ * call of the regulator_list_autoset() for the "platname_list" array.
+ * For testing results of regulator_list_autoset() for outputs:
+ * - LDO1
+ * - LDO2
+ * The settings are defined in: include/power/sandbox_pmic.h
+ */
+static const struct setting expected_setting_list[] = {
+ [0] = { /* LDO1 */
+ .voltage = SANDBOX_LDO1_AUTOSET_EXPECTED_UV,
+ .current = SANDBOX_LDO1_AUTOSET_EXPECTED_UA,
+ .enable = SANDBOX_LDO1_AUTOSET_EXPECTED_ENABLE,
+ },
+ [1] = { /* LDO2 */
+ .voltage = SANDBOX_LDO2_AUTOSET_EXPECTED_UV,
+ .current = SANDBOX_LDO2_AUTOSET_EXPECTED_UA,
+ .enable = SANDBOX_LDO2_AUTOSET_EXPECTED_ENABLE,
+ },
+};
+
+static int list_count = ARRAY_SIZE(expected_setting_list);
+
+/* Test regulator list autoset method */
+static int dm_test_power_regulator_autoset_list(struct dm_test_state *dms)
+{
+ struct udevice *dev_list[2], *dev;
+ int i;
+
+ /*
+ * Test the settings of the regulator list:
+ * LDO1 with fdt properties:
+ * - min-microvolt = max-microvolt = 1800000
+ * - min-microamp = max-microamp = 100000
+ * - always-on = not set
+ * - boot-on = set
+ * Expected output state: uV=1800000; uA=100000; output enabled
+ *
+ * LDO2 with fdt properties:
+ * - min-microvolt = max-microvolt = 3300000
+ * - always-on = not set
+ * - boot-on = not set
+ * Expected output state: uV=300000(default); output disabled(default)
+ * The expected settings are defined in: include/power/sandbox_pmic.h.
+ */
+ ut_assertok(regulator_list_autoset(platname_list, dev_list, false));
+
+ for (i = 0; i < list_count; i++) {
+ /* Check, that the returned device is non-NULL */
+ ut_assert(dev_list[i]);
+
+ /* Check, that the returned device is proper */
+ ut_assertok(regulator_get_by_platname(platname_list[i], &dev));
+ ut_asserteq_ptr(dev_list[i], dev);
+
+ /* Check, that regulator output Voltage value is as expected */
+ ut_asserteq(regulator_get_value(dev_list[i]),
+ expected_setting_list[i].voltage);
+
+ /* Check, that regulator output Current value is as expected */
+ ut_asserteq(regulator_get_current(dev_list[i]),
+ expected_setting_list[i].current);
+
+ /* Check, that regulator output Enable state is as expected */
+ ut_asserteq(regulator_get_enable(dev_list[i]),
+ expected_setting_list[i].enable);
+ }
+
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_autoset_list, DM_TESTF_SCAN_FDT);
diff --git a/test/dm/rtc.c b/test/dm/rtc.c
new file mode 100644
index 00000000000..9397cf72a73
--- /dev/null
+++ b/test/dm/rtc.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <rtc.h>
+#include <asm/io.h>
+#include <dm/test.h>
+#include <dm/ut.h>
+#include <asm/test.h>
+
+/* Simple RTC sanity check */
+static int dm_test_rtc_base(struct dm_test_state *dms)
+{
+ struct udevice *dev;
+
+ ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_RTC, 2, &dev));
+ ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
+ ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev));
+
+ return 0;
+}
+DM_TEST(dm_test_rtc_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static void show_time(const char *msg, struct rtc_time *time)
+{
+ printf("%s: %02d/%02d/%04d %02d:%02d:%02d\n", msg,
+ time->tm_mday, time->tm_mon, time->tm_year,
+ time->tm_hour, time->tm_min, time->tm_sec);
+}
+
+static int cmp_times(struct rtc_time *expect, struct rtc_time *time, bool show)
+{
+ bool same;
+
+ same = expect->tm_sec == time->tm_sec;
+ same &= expect->tm_min == time->tm_min;
+ same &= expect->tm_hour == time->tm_hour;
+ same &= expect->tm_mday == time->tm_mday;
+ same &= expect->tm_mon == time->tm_mon;
+ same &= expect->tm_year == time->tm_year;
+ if (!same && show) {
+ show_time("expected", expect);
+ show_time("actual", time);
+ }
+
+ return same ? 0 : -EINVAL;
+}
+
+/* Set and get the time */
+static int dm_test_rtc_set_get(struct dm_test_state *dms)
+{
+ struct rtc_time now, time, cmp;
+ struct udevice *dev, *emul;
+ long offset, old_offset, old_base_time;
+
+ ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
+ ut_assertok(dm_rtc_get(dev, &now));
+
+ ut_assertok(device_find_first_child(dev, &emul));
+ ut_assert(emul != NULL);
+
+ /* Tell the RTC to go into manual mode */
+ old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
+ old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1);
+
+ memset(&time, '\0', sizeof(time));
+ time.tm_mday = 25;
+ time.tm_mon = 8;
+ time.tm_year = 2004;
+ time.tm_sec = 0;
+ time.tm_min = 18;
+ time.tm_hour = 18;
+ ut_assertok(dm_rtc_set(dev, &time));
+
+ memset(&cmp, '\0', sizeof(cmp));
+ ut_assertok(dm_rtc_get(dev, &cmp));
+ ut_assertok(cmp_times(&time, &cmp, true));
+
+ /* Increment by 1 second */
+ offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
+ sandbox_i2c_rtc_set_offset(emul, false, offset + 1);
+
+ memset(&cmp, '\0', sizeof(cmp));
+ ut_assertok(dm_rtc_get(dev, &cmp));
+ ut_asserteq(1, cmp.tm_sec);
+
+ /* Check against original offset */
+ sandbox_i2c_rtc_set_offset(emul, false, old_offset);
+ ut_assertok(dm_rtc_get(dev, &cmp));
+ ut_assertok(cmp_times(&now, &cmp, true));
+
+ /* Back to the original offset */
+ sandbox_i2c_rtc_set_offset(emul, false, 0);
+ memset(&cmp, '\0', sizeof(cmp));
+ ut_assertok(dm_rtc_get(dev, &cmp));
+ ut_assertok(cmp_times(&now, &cmp, true));
+
+ /* Increment the base time by 1 emul */
+ sandbox_i2c_rtc_get_set_base_time(emul, old_base_time + 1);
+ memset(&cmp, '\0', sizeof(cmp));
+ ut_assertok(dm_rtc_get(dev, &cmp));
+ if (now.tm_sec == 59) {
+ ut_asserteq(0, cmp.tm_sec);
+ } else {
+ ut_asserteq(now.tm_sec + 1, cmp.tm_sec);
+ }
+
+ old_offset = sandbox_i2c_rtc_set_offset(emul, true, 0);
+
+ return 0;
+}
+DM_TEST(dm_test_rtc_set_get, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Reset the time */
+static int dm_test_rtc_reset(struct dm_test_state *dms)
+{
+ struct rtc_time now;
+ struct udevice *dev, *emul;
+ long old_base_time, base_time;
+
+ ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
+ ut_assertok(dm_rtc_get(dev, &now));
+
+ ut_assertok(device_find_first_child(dev, &emul));
+ ut_assert(emul != NULL);
+
+ old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0);
+
+ ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1));
+
+ /* Resetting the RTC should put he base time back to normal */
+ ut_assertok(dm_rtc_reset(dev));
+ base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1);
+ ut_asserteq(old_base_time, base_time);
+
+ return 0;
+}
+DM_TEST(dm_test_rtc_reset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Check that two RTC devices can be used independently */
+static int dm_test_rtc_dual(struct dm_test_state *dms)
+{
+ struct rtc_time now1, now2, cmp;
+ struct udevice *dev1, *dev2;
+ struct udevice *emul1, *emul2;
+ long offset;
+
+ ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev1));
+ ut_assertok(dm_rtc_get(dev1, &now1));
+ ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev2));
+ ut_assertok(dm_rtc_get(dev2, &now2));
+
+ ut_assertok(device_find_first_child(dev1, &emul1));
+ ut_assert(emul1 != NULL);
+ ut_assertok(device_find_first_child(dev2, &emul2));
+ ut_assert(emul2 != NULL);
+
+ offset = sandbox_i2c_rtc_set_offset(emul1, false, -1);
+ sandbox_i2c_rtc_set_offset(emul2, false, offset + 1);
+ memset(&cmp, '\0', sizeof(cmp));
+ ut_assertok(dm_rtc_get(dev2, &cmp));
+ ut_asserteq(-EINVAL, cmp_times(&now1, &cmp, false));
+
+ memset(&cmp, '\0', sizeof(cmp));
+ ut_assertok(dm_rtc_get(dev1, &cmp));
+ ut_assertok(cmp_times(&now1, &cmp, true));
+
+ return 0;
+}
+DM_TEST(dm_test_rtc_dual, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/test-dm.sh b/test/dm/test-dm.sh
index 6158f6833f9..5c47ffd5d23 100755
--- a/test/dm/test-dm.sh
+++ b/test/dm/test-dm.sh
@@ -6,12 +6,11 @@ die() {
}
NUM_CPUS=$(cat /proc/cpuinfo |grep -c processor)
-dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb
make O=sandbox sandbox_config || die "Cannot configure U-Boot"
make O=sandbox -s -j${NUM_CPUS} || die "Cannot build U-Boot"
dd if=/dev/zero of=spi.bin bs=1M count=2
echo -n "this is a test" > testflash.bin
dd if=/dev/zero bs=1M count=4 >>testflash.bin
-./sandbox/u-boot -d test/dm/test.dtb -c "dm test"
+./sandbox/u-boot -d ./sandbox/arch/sandbox/dts/test.dtb -c "dm test"
rm spi.bin
rm testflash.bin
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index a47bb370223..7348f691657 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -78,8 +78,7 @@ int dm_test_main(const char *test_name)
*/
if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) {
puts("Please run with test device tree:\n"
- " dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb\n"
- " ./u-boot -d test/dm/test.dtb\n");
+ " ./u-boot -d arch/sandbox/dts/test.dtb\n");
ut_assert(gd->fdt_blob);
}
diff --git a/test/dm/test.dts b/test/dm/test.dts
deleted file mode 100644
index d0c40be6b0a..00000000000
--- a/test/dm/test.dts
+++ /dev/null
@@ -1,230 +0,0 @@
-/dts-v1/;
-
-/ {
- model = "sandbox";
- compatible = "sandbox";
- #address-cells = <1>;
- #size-cells = <0>;
-
- aliases {
- console = &uart0;
- i2c0 = "/i2c@0";
- spi0 = "/spi@0";
- pci0 = &pci;
- testfdt6 = "/e-test";
- testbus3 = "/some-bus";
- testfdt0 = "/some-bus/c-test@0";
- testfdt1 = "/some-bus/c-test@1";
- testfdt3 = "/b-test";
- testfdt5 = "/some-bus/c-test@5";
- testfdt8 = "/a-test";
- eth0 = "/eth@10002000";
- eth5 = &eth_5;
- usb0 = &usb_0;
- usb1 = &usb_1;
- usb2 = &usb_2;
- };
-
- uart0: serial {
- compatible = "sandbox,serial";
- u-boot,dm-pre-reloc;
- };
-
- a-test {
- reg = <0>;
- compatible = "denx,u-boot-fdt-test";
- ping-expect = <0>;
- ping-add = <0>;
- u-boot,dm-pre-reloc;
- test-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 5 0 3 2 1>,
- <0>, <&gpio_a 12>;
- test2-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 6 1 3 2 1>,
- <&gpio_b 7 2 3 2 1>, <&gpio_b 8 4 3 2 1>,
- <&gpio_b 9 0xc 3 2 1>;
- };
-
- junk {
- reg = <1>;
- compatible = "not,compatible";
- };
-
- no-compatible {
- reg = <2>;
- };
-
- b-test {
- reg = <3>;
- compatible = "denx,u-boot-fdt-test";
- ping-expect = <3>;
- ping-add = <3>;
- };
-
- some-bus {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "denx,u-boot-test-bus";
- reg = <3>;
- ping-expect = <4>;
- ping-add = <4>;
- c-test@5 {
- compatible = "denx,u-boot-fdt-test";
- reg = <5>;
- ping-expect = <5>;
- ping-add = <5>;
- };
- c-test@0 {
- compatible = "denx,u-boot-fdt-test";
- reg = <0>;
- ping-expect = <6>;
- ping-add = <6>;
- };
- c-test@1 {
- compatible = "denx,u-boot-fdt-test";
- reg = <1>;
- ping-expect = <7>;
- ping-add = <7>;
- };
- };
-
- d-test {
- reg = <3>;
- ping-expect = <6>;
- ping-add = <6>;
- compatible = "google,another-fdt-test";
- };
-
- e-test {
- reg = <3>;
- ping-expect = <6>;
- ping-add = <6>;
- compatible = "google,another-fdt-test";
- };
-
- f-test {
- compatible = "denx,u-boot-fdt-test";
- };
-
- g-test {
- compatible = "denx,u-boot-fdt-test";
- };
-
- gpio_a: base-gpios {
- compatible = "sandbox,gpio";
- gpio-controller;
- #gpio-cells = <1>;
- gpio-bank-name = "a";
- num-gpios = <20>;
- };
-
- gpio_b: extra-gpios {
- compatible = "sandbox,gpio";
- gpio-controller;
- #gpio-cells = <5>;
- gpio-bank-name = "b";
- num-gpios = <10>;
- };
-
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- compatible = "sandbox,i2c";
- clock-frequency = <100000>;
- eeprom@2c {
- reg = <0x2c>;
- compatible = "i2c-eeprom";
- emul {
- compatible = "sandbox,i2c-eeprom";
- sandbox,filename = "i2c.bin";
- sandbox,size = <256>;
- };
- };
- };
-
- pci: pci-controller {
- compatible = "sandbox,pci";
- device_type = "pci";
- #address-cells = <3>;
- #size-cells = <2>;
- ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
- 0x01000000 0 0x20000000 0x20000000 0 0x2000>;
- pci@1f,0 {
- compatible = "pci-generic";
- reg = <0xf800 0 0 0 0>;
- emul@1f,0 {
- compatible = "sandbox,swap-case";
- };
- };
- };
-
- spi@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- compatible = "sandbox,spi";
- cs-gpios = <0>, <&gpio_a 0>;
- spi.bin@0 {
- reg = <0>;
- compatible = "spansion,m25p16", "spi-flash";
- spi-max-frequency = <40000000>;
- sandbox,filename = "spi.bin";
- };
- };
-
- eth@10002000 {
- compatible = "sandbox,eth";
- reg = <0x10002000 0x1000>;
- fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>;
- };
-
- eth_5: eth@10003000 {
- compatible = "sandbox,eth";
- reg = <0x10003000 0x1000>;
- fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>;
- };
-
- eth@10004000 {
- compatible = "sandbox,eth";
- reg = <0x10004000 0x1000>;
- fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>;
- };
-
- usb_0: usb@0 {
- compatible = "sandbox,usb";
- status = "disabled";
- hub {
- compatible = "sandbox,usb-hub";
- #address-cells = <1>;
- #size-cells = <0>;
- flash-stick {
- reg = <0>;
- compatible = "sandbox,usb-flash";
- };
- };
- };
-
- usb_1: usb@1 {
- compatible = "sandbox,usb";
- hub {
- compatible = "usb-hub";
- usb,device-class = <9>;
- hub-emul {
- compatible = "sandbox,usb-hub";
- #address-cells = <1>;
- #size-cells = <0>;
- flash-stick {
- reg = <0>;
- compatible = "sandbox,usb-flash";
- sandbox,filepath = "testflash.bin";
- };
-
- };
- };
- };
-
- usb_2: usb@2 {
- compatible = "sandbox,usb";
- status = "disabled";
- };
-
-};
diff --git a/test/time_ut.c b/test/time_ut.c
new file mode 100644
index 00000000000..6b52245d7ff
--- /dev/null
+++ b/test/time_ut.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <errno.h>
+
+static int test_get_timer(void)
+{
+ ulong base, start, next, diff;
+ int iter;
+
+ base = get_timer(0);
+ start = get_timer(0);
+ for (iter = 0; iter < 10; iter++) {
+ do {
+ next = get_timer(0);
+ } while (start == next);
+
+ if (start + 1 != next) {
+ printf("%s: iter=%d, start=%lu, next=%lu, expected a difference of 1\n",
+ __func__, iter, start, next);
+ return -EINVAL;
+ }
+ start++;
+ }
+
+ /*
+ * Check that get_timer(base) matches our elapsed time, allowing that
+ * an extra millisecond may have passed.
+ */
+ diff = get_timer(base);
+ if (diff != iter && diff != iter + 1) {
+ printf("%s: expected get_timer(base) to match elapsed time: diff=%lu, expected=%d\n",
+ __func__, diff, iter);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int test_timer_get_us(void)
+{
+ ulong prev, next, min = 1000000;
+ long delta;
+ int iter;
+
+ /* Find the minimum delta we can measure, in microseconds */
+ prev = timer_get_us();
+ for (iter = 0; iter < 100; ) {
+ next = timer_get_us();
+ if (next != prev) {
+ delta = next - prev;
+ if (delta < 0) {
+ printf("%s: timer_get_us() went backwards from %lu to %lu\n",
+ __func__, prev, next);
+ return -EINVAL;
+ } else if (delta != 0) {
+ if (delta < min)
+ min = delta;
+ prev = next;
+ iter++;
+ }
+ }
+ }
+
+ if (min != 1) {
+ printf("%s: Minimum microsecond delta should be 1 but is %lu\n",
+ __func__, min);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int test_time_comparison(void)
+{
+ ulong start_us, end_us, delta_us;
+ long error;
+ ulong start;
+
+ start = get_timer(0);
+ start_us = timer_get_us();
+ while (get_timer(start) < 1000)
+ ;
+ end_us = timer_get_us();
+ delta_us = end_us - start_us;
+ error = delta_us - 1000000;
+ printf("%s: Microsecond time for 1 second: %lu, error = %ld\n",
+ __func__, delta_us, error);
+ if (abs(error) > 1000)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int test_udelay(void)
+{
+ long error;
+ ulong start, delta;
+ int iter;
+
+ start = get_timer(0);
+ for (iter = 0; iter < 1000; iter++)
+ udelay(1000);
+ delta = get_timer(start);
+ error = delta - 1000;
+ printf("%s: Delay time for 1000 udelay(1000): %lu ms, error = %ld\n",
+ __func__, delta, error);
+ if (abs(error) > 100)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int do_ut_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret = 0;
+
+ ret |= test_get_timer();
+ ret |= test_timer_get_us();
+ ret |= test_time_comparison();
+ ret |= test_udelay();
+
+ printf("Test %s\n", ret ? "failed" : "passed");
+
+ return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+ ut_time, 1, 1, do_ut_time,
+ "Very basic test of time functions",
+ ""
+);