diff options
Diffstat (limited to 'test/dm')
-rw-r--r-- | test/dm/Makefile | 3 | ||||
-rw-r--r-- | test/dm/eth.c | 14 | ||||
-rw-r--r-- | test/dm/gpio.c | 9 | ||||
-rw-r--r-- | test/dm/k210_pll.c | 96 | ||||
-rw-r--r-- | test/dm/simple-pm-bus.c | 45 | ||||
-rw-r--r-- | test/dm/spi.c | 2 | ||||
-rw-r--r-- | test/dm/syscon-reset.c | 59 | ||||
-rw-r--r-- | test/dm/test-fdt.c | 22 | ||||
-rw-r--r-- | test/dm/usb.c | 22 |
9 files changed, 259 insertions, 13 deletions
diff --git a/test/dm/Makefile b/test/dm/Makefile index 6c18fd04ce..0d1c66fa1e 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -73,4 +73,7 @@ obj-$(CONFIG_DMA) += dma.o obj-$(CONFIG_DM_MDIO) += mdio.o obj-$(CONFIG_DM_MDIO_MUX) += mdio_mux.o obj-$(CONFIG_DM_RNG) += rng.o +obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o +obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o +obj-$(CONFIG_RESET_SYSCON) += syscon-reset.o endif diff --git a/test/dm/eth.c b/test/dm/eth.c index 1fddcaabb0..b58c9640a2 100644 --- a/test/dm/eth.c +++ b/test/dm/eth.c @@ -48,7 +48,7 @@ static int dm_test_eth_alias(struct unit_test_state *uts) ut_assertok(net_loop(PING)); ut_asserteq_str("eth@10002000", env_get("ethact")); - env_set("ethact", "eth1"); + env_set("ethact", "eth6"); ut_assertok(net_loop(PING)); ut_asserteq_str("eth@10004000", env_get("ethact")); @@ -105,7 +105,7 @@ static int dm_test_eth_act(struct unit_test_state *uts) const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000", "sbe5", "eth@10004000"}; const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr", - "eth3addr", "eth1addr"}; + "eth3addr", "eth6addr"}; char ethaddr[DM_TEST_ETH_NUM][18]; int i; @@ -188,15 +188,15 @@ static int dm_test_eth_rotate(struct unit_test_state *uts) /* Invalidate eth1's MAC address */ memset(ethaddr, '\0', sizeof(ethaddr)); - strncpy(ethaddr, env_get("eth1addr"), 17); - /* Must disable access protection for eth1addr before clearing */ - env_set(".flags", "eth1addr"); - env_set("eth1addr", NULL); + strncpy(ethaddr, env_get("eth6addr"), 17); + /* Must disable access protection for eth6addr before clearing */ + env_set(".flags", "eth6addr"); + env_set("eth6addr", NULL); retval = _dm_test_eth_rotate1(uts); /* Restore the env */ - env_set("eth1addr", ethaddr); + env_set("eth6addr", ethaddr); env_set("ethrotate", NULL); if (!retval) { diff --git a/test/dm/gpio.c b/test/dm/gpio.c index ecba566983..fcee1fe598 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -132,6 +132,15 @@ static int dm_test_gpio(struct unit_test_state *uts) ut_assertok(dm_gpio_set_value(desc, 0)); ut_asserteq(0, dm_gpio_get_value(desc)); + /* Check if lookup for labels work */ + ut_assertok(gpio_lookup_name("hog_input_active_low", &dev, &offset, + &gpio)); + ut_asserteq_str(dev->name, "base-gpios"); + ut_asserteq(0, offset); + ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 0, gpio); + ut_assert(gpio_lookup_name("hog_not_exist", &dev, &offset, + &gpio)); + return 0; } DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/k210_pll.c b/test/dm/k210_pll.c new file mode 100644 index 0000000000..54764f269c --- /dev/null +++ b/test/dm/k210_pll.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com> + */ + +#include <common.h> +/* For DIV_ROUND_DOWN_ULL, defined in linux/kernel.h */ +#include <div64.h> +#include <dm/test.h> +#include <kendryte/pll.h> +#include <test/ut.h> + +static int dm_test_k210_pll_calc_config(u32 rate, u32 rate_in, + struct k210_pll_config *best) +{ + u64 f, r, od, max_r, inv_ratio; + s64 error, best_error; + + best_error = S64_MAX; + error = best_error; + max_r = min(16ULL, DIV_ROUND_DOWN_ULL(rate_in, 13300000)); + inv_ratio = DIV_ROUND_CLOSEST_ULL((u64)rate_in << 32, rate); + + /* Brute force it */ + for (r = 1; r <= max_r; r++) { + for (f = 1; f <= 64; f++) { + for (od = 1; od <= 16; od++) { + u64 vco = DIV_ROUND_CLOSEST_ULL(rate_in * f, r); + + if (vco > 1750000000 || vco < 340000000) + continue; + + error = DIV_ROUND_CLOSEST_ULL(f * inv_ratio, + r * od); + /* The lower 16 bits are spurious */ + error = abs((error - BIT(32))) >> 16; + if (error < best_error) { + best->r = r; + best->f = f; + best->od = od; + best_error = error; + } + } + } + } + + if (best_error == S64_MAX) + return -EINVAL; + return 0; +} + +static int dm_test_k210_pll_compare(struct k210_pll_config *ours, + struct k210_pll_config *theirs) +{ + return (u32)ours->f * theirs->r * theirs->od != + (u32)theirs->f * ours->r * ours->od; +} + +static int dm_test_k210_pll(struct unit_test_state *uts) +{ + struct k210_pll_config ours, theirs; + + /* General range checks */ + ut_asserteq(-EINVAL, k210_pll_calc_config(0, 26000000, &theirs)); + ut_asserteq(-EINVAL, k210_pll_calc_config(390000000, 0, &theirs)); + ut_asserteq(-EINVAL, k210_pll_calc_config(2000000000, 26000000, + &theirs)); + ut_asserteq(-EINVAL, k210_pll_calc_config(390000000, 2000000000, + &theirs)); + ut_asserteq(-EINVAL, k210_pll_calc_config(1500000000, 20000000, + &theirs)); + + /* Verify we get the same output with brute-force */ + ut_assertok(dm_test_k210_pll_calc_config(390000000, 26000000, &ours)); + ut_assertok(k210_pll_calc_config(390000000, 26000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + ut_assertok(dm_test_k210_pll_calc_config(26000000, 390000000, &ours)); + ut_assertok(k210_pll_calc_config(26000000, 390000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + ut_assertok(dm_test_k210_pll_calc_config(400000000, 26000000, &ours)); + ut_assertok(k210_pll_calc_config(400000000, 26000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + ut_assertok(dm_test_k210_pll_calc_config(27000000, 26000000, &ours)); + ut_assertok(k210_pll_calc_config(27000000, 26000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + ut_assertok(dm_test_k210_pll_calc_config(26000000, 27000000, &ours)); + ut_assertok(k210_pll_calc_config(26000000, 27000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + return 0; +} +DM_TEST(dm_test_k210_pll, 0); diff --git a/test/dm/simple-pm-bus.c b/test/dm/simple-pm-bus.c new file mode 100644 index 0000000000..978c7f191e --- /dev/null +++ b/test/dm/simple-pm-bus.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/test.h> +#include <dm/device-internal.h> +#include <test/ut.h> +#include <asm/clk.h> +#include <asm/power-domain.h> + +/* These must match the ids in the device tree */ +#define TEST_CLOCK_ID 4 +#define TEST_POWER_ID 1 + +static int dm_test_simple_pm_bus(struct unit_test_state *uts) +{ + struct udevice *power; + struct udevice *clock; + struct udevice *bus; + + ut_assertok(uclass_get_device_by_name(UCLASS_POWER_DOMAIN, + "power-domain", &power)); + ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-sbox", + &clock)); + ut_asserteq(0, sandbox_power_domain_query(power, TEST_POWER_ID)); + ut_asserteq(0, sandbox_clk_query_enable(clock, TEST_CLOCK_ID)); + + ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS, "pm-bus-test", + &bus)); + ut_asserteq(1, sandbox_power_domain_query(power, TEST_POWER_ID)); + ut_asserteq(1, sandbox_clk_query_enable(clock, TEST_CLOCK_ID)); + + ut_assertok(device_remove(bus, DM_REMOVE_NORMAL)); + /* must re-probe since device_remove also removes the power domain */ + ut_assertok(uclass_get_device_by_name(UCLASS_POWER_DOMAIN, + "power-domain", &power)); + ut_asserteq(0, sandbox_power_domain_query(power, TEST_POWER_ID)); + ut_asserteq(0, sandbox_clk_query_enable(clock, TEST_CLOCK_ID)); + + return 0; +} +DM_TEST(dm_test_simple_pm_bus, DM_TESTF_SCAN_FDT); diff --git a/test/dm/spi.c b/test/dm/spi.c index 8e417acc5f..474008cde0 100644 --- a/test/dm/spi.c +++ b/test/dm/spi.c @@ -117,7 +117,7 @@ static int dm_test_spi_xfer(struct unit_test_state *uts) * Since we are about to destroy all devices, we must tell sandbox * to forget the emulation device */ -#ifdef CONFIG_DM_SPI_FLASH +#if CONFIG_IS_ENABLED(DM_SPI_FLASH) sandbox_sf_unbind_emul(state_get_current(), busnum, cs); #endif diff --git a/test/dm/syscon-reset.c b/test/dm/syscon-reset.c new file mode 100644 index 0000000000..edabdb2e78 --- /dev/null +++ b/test/dm/syscon-reset.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/test.h> +#include <regmap.h> +#include <reset.h> +#include <syscon.h> +#include <test/ut.h> +#include <asm/test.h> +#include <linux/bitops.h> + +/* The following values must match the device tree */ +#define TEST_RESET_REG 1 +#define TEST_RESET_ASSERT_HIGH 0 +#define TEST_RESET_ASSERT (TEST_RESET_ASSERT_HIGH ? (u32)-1 : (u32)0) +#define TEST_RESET_DEASSERT (~TEST_RESET_ASSERT) + +#define TEST_RESET_VALID 15 +#define TEST_RESET_NOMASK 30 +#define TEST_RESET_OUTOFRANGE 60 + +static int dm_test_syscon_reset(struct unit_test_state *uts) +{ + struct regmap *map; + struct reset_ctl rst; + struct udevice *reset; + struct udevice *syscon; + struct udevice *syscon_reset; + uint reg; + + ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "syscon-reset-test", + &reset)); + ut_assertok(uclass_get_device_by_name(UCLASS_SYSCON, "syscon@0", + &syscon)); + ut_assertok(uclass_get_device_by_name(UCLASS_RESET, "syscon-reset", + &syscon_reset)); + ut_assertok_ptr((map = syscon_get_regmap(syscon))); + + ut_asserteq(-EINVAL, reset_get_by_name(reset, "no_mask", &rst)); + ut_asserteq(-EINVAL, reset_get_by_name(reset, "out_of_range", &rst)); + ut_assertok(reset_get_by_name(reset, "valid", &rst)); + + sandbox_set_enable_memio(true); + ut_assertok(regmap_write(map, TEST_RESET_REG, TEST_RESET_DEASSERT)); + ut_assertok(reset_assert(&rst)); + ut_assertok(regmap_read(map, TEST_RESET_REG, ®)); + ut_asserteq(TEST_RESET_DEASSERT ^ BIT(TEST_RESET_VALID), reg); + + ut_assertok(reset_deassert(&rst)); + ut_assertok(regmap_read(map, TEST_RESET_REG, ®)); + ut_asserteq(TEST_RESET_DEASSERT, reg); + + return 0; +} +DM_TEST(dm_test_syscon_reset, DM_TESTF_SCAN_FDT); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 4fcae03dc5..51f2547409 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -361,20 +361,32 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts) ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 2, &dev)); ut_asserteq_str("d-test", dev->name); - /* d-test actually gets 0 */ - ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 0, &dev)); + /* + * d-test actually gets 9, because thats the next free one after the + * aliases. + */ + ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 9, &dev)); ut_asserteq_str("d-test", dev->name); - /* initially no one wants seq 1 */ - ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, + /* initially no one wants seq 10 */ + ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 10, &dev)); ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev)); /* But now that it is probed, we can find it */ - ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev)); + ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 10, &dev)); ut_asserteq_str("f-test", dev->name); + /* + * And we should still have holes in our sequence numbers, that is 2 + * and 4 should not be used. + */ + ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 2, + true, &dev)); + ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 4, + true, &dev)); + return 0; } DM_TEST(dm_test_fdt_uclass_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/usb.c b/test/dm/usb.c index a25c2c1482..b273a515ef 100644 --- a/test/dm/usb.c +++ b/test/dm/usb.c @@ -78,6 +78,28 @@ static int dm_test_usb_multi(struct unit_test_state *uts) } DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +/* test that we have an associated ofnode with the usb device */ +static int dm_test_usb_fdt_node(struct unit_test_state *uts) +{ + struct udevice *dev; + ofnode node; + + state_set_skip_delays(true); + ut_assertok(usb_init()); + ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev)); + node = ofnode_path("/usb@1/hub/usbstor@1"); + ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev))); + ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev)); + ut_asserteq(1, ofnode_equal(ofnode_null(), dev_ofnode(dev))); + ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev)); + node = ofnode_path("/usb@1/hub/usbstor@3"); + ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev))); + ut_assertok(usb_stop()); + + return 0; +} +DM_TEST(dm_test_usb_fdt_node, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + static int count_usb_devices(void) { struct udevice *hub; |