From 2983ad55a13e9afcdf1a3d8f55eea038c0a0e8a3 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Wed, 30 Dec 2020 00:06:31 +0100 Subject: clk: add clk_round_rate() It returns the rate which will be set if you ask clk_set_rate() to set that rate. It provides a way to query exactly what rate you'll get if you call clk_set_rate() with that same argument. So essentially, clk_round_rate() and clk_set_rate() are equivalent except the former does not modify the clock hardware in any way. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass Reviewed-by: Sean Anderson --- test/dm/clk.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'test') diff --git a/test/dm/clk.c b/test/dm/clk.c index edca3b49f60..21997ed8922 100644 --- a/test/dm/clk.c +++ b/test/dm/clk.c @@ -112,6 +112,28 @@ static int dm_test_clk(struct unit_test_state *uts) rate = sandbox_clk_test_set_rate(dev_test, SANDBOX_CLK_TEST_ID_I2C, 0); ut_assert(IS_ERR_VALUE(rate)); + ut_asserteq(10000, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_SPI)); + ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_I2C)); + + ut_asserteq(5000, sandbox_clk_test_round_rate(dev_test, + SANDBOX_CLK_TEST_ID_SPI, + 5000)); + ut_asserteq(7000, sandbox_clk_test_round_rate(dev_test, + SANDBOX_CLK_TEST_ID_I2C, + 7000)); + + ut_asserteq(10000, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_SPI)); + ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_I2C)); + + rate = sandbox_clk_test_round_rate(dev_test, SANDBOX_CLK_TEST_ID_SPI, 0); + ut_assert(IS_ERR_VALUE(rate)); + rate = sandbox_clk_test_round_rate(dev_test, SANDBOX_CLK_TEST_ID_I2C, 0); + ut_assert(IS_ERR_VALUE(rate)); + ut_asserteq(10000, sandbox_clk_test_get_rate(dev_test, SANDBOX_CLK_TEST_ID_SPI)); ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test, -- cgit v1.2.3 From d64b9cdcd475eb7f07b49741ded87e24dae4a5fc Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Wed, 30 Dec 2020 00:16:21 +0100 Subject: fdt: translate address if #size-cells = <0> The __of_translate_address routine translates an address from the device tree into a CPU physical address. A note in the description of the routine explains that the crossing of any level with since inherited from IBM. This does not happen for Texas Instruments, or at least for the beaglebone device tree. Without this patch, in fact, the translation into physical addresses of the registers contained in the am33xx-clocks.dtsi nodes would not be possible. They all have a parent with #size-cells = <0>. The CONFIG_OF_TRANSLATE_ZERO_SIZE_CELLS symbol makes translation possible even in the case of crossing levels with #size-cells = <0>. The patch acts conservatively on address translation, except for removing a check within the of_translate_one function in the drivers/core/of_addr.c file: + ranges = of_get_property(parent, rprop, &rlen); - if (ranges == NULL && !of_empty_ranges_quirk(parent)) { - debug("no ranges; cannot translate\n"); - return 1; - } if (ranges == NULL || rlen == 0) { offset = of_read_number(addr, na); memset(addr, 0, pna * 4); debug("empty ranges; 1:1 translation\n"); There are two reasons: 1 The function of_empty_ranges_quirk always returns false, invalidating the following if statement in case of null ranges. Therefore one of the two checks is useless. 2 The implementation of the of_translate_one function found in the common/fdt_support.c file has removed this check while keeping the one about the 1:1 translation. The patch adds a test and modifies a check for the correctness of an address in the case of enabling translation also for zero size cells. The added test checks translations of addresses generated by nodes of a device tree similar to those you can find in the files am33xx.dtsi and am33xx-clocks.dtsi for which the patch was created. The patch was also tested on a beaglebone black board. The addresses generated for the registers of the loaded drivers are those specified by the AM335x reference manual. Signed-off-by: Dario Binacchi Tested-by: Dario Binacchi Reviewed-by: Simon Glass --- test/dm/test-fdt.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'test') diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index b53539055b6..31fb6663a25 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -549,6 +550,64 @@ U_BOOT_DRIVER(fdt_dummy_drv) = { .id = UCLASS_TEST_DUMMY, }; +static int zero_size_cells_bus_bind(struct udevice *dev) +{ + ofnode child; + int err; + + ofnode_for_each_subnode(child, dev_ofnode(dev)) { + if (ofnode_get_property(child, "compatible", NULL)) + continue; + + err = device_bind_driver_to_node(dev, + "zero_size_cells_bus_child_drv", + "zero_size_cells_bus_child", + child, NULL); + if (err) { + dev_err(dev, "%s: failed to bind %s\n", __func__, + ofnode_get_name(child)); + return err; + } + } + + return 0; +} + +static const struct udevice_id zero_size_cells_bus_ids[] = { + { .compatible = "sandbox,zero-size-cells-bus" }, + { } +}; + +U_BOOT_DRIVER(zero_size_cells_bus) = { + .name = "zero_size_cells_bus_drv", + .id = UCLASS_TEST_DUMMY, + .of_match = zero_size_cells_bus_ids, + .bind = zero_size_cells_bus_bind, +}; + +static int zero_size_cells_bus_child_bind(struct udevice *dev) +{ + ofnode child; + int err; + + ofnode_for_each_subnode(child, dev_ofnode(dev)) { + err = lists_bind_fdt(dev, child, NULL, false); + if (err) { + dev_err(dev, "%s: lists_bind_fdt, err=%d\n", + __func__, err); + return err; + } + } + + return 0; +} + +U_BOOT_DRIVER(zero_size_cells_bus_child_drv) = { + .name = "zero_size_cells_bus_child_drv", + .id = UCLASS_TEST_DUMMY, + .bind = zero_size_cells_bus_child_bind, +}; + static int dm_test_fdt_translation(struct unit_test_state *uts) { struct udevice *dev; @@ -570,8 +629,17 @@ static int dm_test_fdt_translation(struct unit_test_state *uts) /* No translation for busses with #size-cells == 0 */ ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 3, &dev)); ut_asserteq_str("dev@42", dev->name); + /* No translation for busses with #size-cells == 0 */ ut_asserteq(0x42, dev_read_addr(dev)); + /* Translation for busses with #size-cells == 0 */ + gd->dm_flags |= GD_DM_FLG_SIZE_CELLS_0; + ut_asserteq(0x8042, dev_read_addr(dev)); + ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 4, &dev)); + ut_asserteq_str("dev@19", dev->name); + ut_asserteq(0xc019, dev_read_addr(dev)); + gd->dm_flags &= ~GD_DM_FLG_SIZE_CELLS_0; + /* dma address translation */ ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev)); dma_addr[0] = cpu_to_be32(0); -- cgit v1.2.3 From 15daa4860bf3c49f53ae76812e0033e4d5faa0a2 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Wed, 30 Dec 2020 00:16:26 +0100 Subject: dm: core: add a function to decode display timings The patch adds a function to get display timings from the device tree node attached to the device. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- test/dm/test-fdt.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'test') diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 31fb6663a25..b5ac9bba24e 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -1152,3 +1152,83 @@ static int dm_test_ofdata_order(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofdata_order, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Test dev_decode_display_timing() */ +static int dm_test_decode_display_timing(struct unit_test_state *uts) +{ + struct udevice *dev; + struct display_timing timing; + + ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev)); + ut_asserteq_str("a-test", dev->name); + + ut_assertok(dev_decode_display_timing(dev, 0, &timing)); + ut_assert(timing.hactive.typ == 240); + ut_assert(timing.hback_porch.typ == 7); + ut_assert(timing.hfront_porch.typ == 6); + ut_assert(timing.hsync_len.typ == 1); + ut_assert(timing.vactive.typ == 320); + ut_assert(timing.vback_porch.typ == 5); + ut_assert(timing.vfront_porch.typ == 8); + ut_assert(timing.vsync_len.typ == 2); + ut_assert(timing.pixelclock.typ == 6500000); + ut_assert(timing.flags & DISPLAY_FLAGS_HSYNC_HIGH); + ut_assert(!(timing.flags & DISPLAY_FLAGS_HSYNC_LOW)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_VSYNC_HIGH)); + ut_assert(timing.flags & DISPLAY_FLAGS_VSYNC_LOW); + ut_assert(timing.flags & DISPLAY_FLAGS_DE_HIGH); + ut_assert(!(timing.flags & DISPLAY_FLAGS_DE_LOW)); + ut_assert(timing.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE); + ut_assert(!(timing.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)); + ut_assert(timing.flags & DISPLAY_FLAGS_INTERLACED); + ut_assert(timing.flags & DISPLAY_FLAGS_DOUBLESCAN); + ut_assert(timing.flags & DISPLAY_FLAGS_DOUBLECLK); + + ut_assertok(dev_decode_display_timing(dev, 1, &timing)); + ut_assert(timing.hactive.typ == 480); + ut_assert(timing.hback_porch.typ == 59); + ut_assert(timing.hfront_porch.typ == 10); + ut_assert(timing.hsync_len.typ == 12); + ut_assert(timing.vactive.typ == 800); + ut_assert(timing.vback_porch.typ == 15); + ut_assert(timing.vfront_porch.typ == 17); + ut_assert(timing.vsync_len.typ == 16); + ut_assert(timing.pixelclock.typ == 9000000); + ut_assert(!(timing.flags & DISPLAY_FLAGS_HSYNC_HIGH)); + ut_assert(timing.flags & DISPLAY_FLAGS_HSYNC_LOW); + ut_assert(timing.flags & DISPLAY_FLAGS_VSYNC_HIGH); + ut_assert(!(timing.flags & DISPLAY_FLAGS_VSYNC_LOW)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_DE_HIGH)); + ut_assert(timing.flags & DISPLAY_FLAGS_DE_LOW); + ut_assert(!(timing.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)); + ut_assert(timing.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE); + ut_assert(!(timing.flags & DISPLAY_FLAGS_INTERLACED)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_DOUBLESCAN)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_DOUBLECLK)); + + ut_assertok(dev_decode_display_timing(dev, 2, &timing)); + ut_assert(timing.hactive.typ == 800); + ut_assert(timing.hback_porch.typ == 89); + ut_assert(timing.hfront_porch.typ == 164); + ut_assert(timing.hsync_len.typ == 11); + ut_assert(timing.vactive.typ == 480); + ut_assert(timing.vback_porch.typ == 23); + ut_assert(timing.vfront_porch.typ == 10); + ut_assert(timing.vsync_len.typ == 13); + ut_assert(timing.pixelclock.typ == 33500000); + ut_assert(!(timing.flags & DISPLAY_FLAGS_HSYNC_HIGH)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_HSYNC_LOW)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_VSYNC_HIGH)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_VSYNC_LOW)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_DE_HIGH)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_DE_LOW)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_INTERLACED)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_DOUBLESCAN)); + ut_assert(!(timing.flags & DISPLAY_FLAGS_DOUBLECLK)); + + ut_assert(dev_decode_display_timing(dev, 3, &timing)); + return 0; +} +DM_TEST(dm_test_decode_display_timing, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -- cgit v1.2.3 From 1ce0e1cbcc8c7943f7f98e57417430ae183a0aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 29 Nov 2020 17:15:05 +0100 Subject: Nokia RX-51: Add test for U-Boot serial console MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a new test which checks that U-Boot for Nokia RX-51 running in qemu can print test line to serial console and also checks that test line appeared on qemu serial console. Signed-off-by: Pali Rohár Reviewed-by: Pavel Machek --- test/nokia_rx51_test.sh | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/nokia_rx51_test.sh b/test/nokia_rx51_test.sh index 23fa935310e..ee45e8d6dd5 100755 --- a/test/nokia_rx51_test.sh +++ b/test/nokia_rx51_test.sh @@ -150,6 +150,15 @@ fakeroot sh -c ' ' /usr/sbin/ubinize -o ubi.img -p 128KiB -m 2048 -s 512 ubi.ini +# Generate bootmenu for U-Boot serial console testing +cat > bootmenu_uboot << EOF +setenv bootmenu_0 'Serial console test=echo; echo "Testing serial console"; echo; echo "Successfully booted"; echo; poweroff'; +setenv bootmenu_1; +setenv bootmenu_delay 1; +setenv bootdelay 1; +EOF +./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_uboot -d bootmenu_uboot bootmenu_uboot.scr + # Generate bootmenu for eMMC booting cat > bootmenu_emmc << EOF setenv bootmenu_0 'uImage-2.6.28-omap1 from eMMC=setenv mmcnum 1; setenv mmcpart 1; setenv mmctype fat; setenv bootargs; setenv setup_omap_atag 1; setenv mmckernfile uImage-2.6.28-omap1; run trymmckernboot'; @@ -177,6 +186,11 @@ dd if=kernel_2.6.28/boot/zImage-2.6.28-20103103+0m5.fiasco of=zImage-2.6.28-omap cp u-boot.bin combined_hack.bin dd if=uImage-2.6.28-omap1 of=combined_hack.bin bs=1024 seek=$((2048-2)) +# Generate FAT32 eMMC image for U-Boot serial console testing +truncate -s 50MiB emmc_uboot.img +mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_uboot.img +mcopy bootmenu_uboot.scr ::/bootmenu.scr -i emmc_uboot.img + # Generate FAT32 eMMC image for eMMC booting truncate -s 50MiB emmc_emmc.img mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_emmc.img @@ -188,6 +202,10 @@ truncate -s 50MiB emmc_nand.img mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_nand.img mcopy bootmenu_nand.scr ::/bootmenu.scr -i emmc_nand.img +# Generate MTD image for U-Boot serial console testing +rm -f mtd_uboot.img +./qflasher -v -x xloader-qemu.bin -s secondary-qemu.bin -k u-boot.bin -m rx51 -o mtd_uboot.img + # Generate MTD image for RAM booting from bootloader nolo images, compiled image and rootfs image rm -f mtd_ram.img ./qflasher -v -x xloader-qemu.bin -s secondary-qemu.bin -k combined.bin -r ubi.img -m rx51 -o mtd_ram.img @@ -208,6 +226,18 @@ echo "========== Running test images in n900 qemu ==========" echo "======================================================" echo +# Run MTD image in qemu and wait for 300s if U-Boot prints testing string to serial console and poweroff +rm -f qemu_uboot.log +./qemu-system-arm -M n900 -mtdblock mtd_uboot.img -sd emmc_uboot.img -serial /dev/stdout -display none > qemu_uboot.log & +qemu_pid=$! +tail -F qemu_uboot.log & +tail_pid=$! +sleep 300 & +sleep_pid=$! +wait -n $sleep_pid $qemu_pid || true +kill -9 $tail_pid $sleep_pid $qemu_pid 2>/dev/null || true +wait || true + # Run MTD image in qemu and wait for 300s if kernel from RAM is correctly booted rm -f qemu_ram.log ./qemu-system-arm -M n900 -mtdblock mtd_ram.img -serial /dev/stdout -display none > qemu_ram.log & @@ -250,13 +280,14 @@ echo "========== Results ==========" echo "=============================" echo +if grep -q 'Successfully booted' qemu_uboot.log; then echo "U-Boot serial console is working"; else echo "U-Boot serial console test failed"; fi if grep -q 'Successfully booted' qemu_ram.log; then echo "Kernel was successfully booted from RAM"; else echo "Failed to boot kernel from RAM"; fi if grep -q 'Successfully booted' qemu_emmc.log; then echo "Kernel was successfully booted from eMMC"; else echo "Failed to boot kernel from eMMC"; fi if grep -q 'Successfully booted' qemu_nand.log; then echo "Kernel was successfully booted from OneNAND"; else echo "Failed to boot kernel from OneNAND"; fi echo -if grep -q 'Successfully booted' qemu_ram.log && grep -q 'Successfully booted' qemu_emmc.log && grep -q 'Successfully booted' qemu_nand.log; then +if grep -q 'Successfully booted' qemu_uboot.log && grep -q 'Successfully booted' qemu_ram.log && grep -q 'Successfully booted' qemu_emmc.log && grep -q 'Successfully booted' qemu_nand.log; then echo "All tests passed" exit 0 else -- cgit v1.2.3