Merge tag 'dm-pull9apr20' of git://git.denx.de/u-boot-dm
authorTom Rini <trini@konsulko.com>
Fri, 10 Apr 2020 15:40:28 +0000 (11:40 -0400)
committerTom Rini <trini@konsulko.com>
Fri, 10 Apr 2020 15:40:28 +0000 (11:40 -0400)
Fixes segfault in 'dm drivers' command

19 files changed:
arch/arm/mach-imx/mkimage_fit_atf.sh
arch/mips/cpu/time.c
arch/mips/lib/Makefile
arch/mips/lib/boot.c [new file with mode: 0644]
arch/mips/lib/cache.c
arch/mips/mach-mscc/cpu.c
arch/mips/mach-mscc/dram.c
arch/mips/mach-mscc/include/mach/ddr.h
arch/mips/mach-mscc/lowlevel_init.S
cmd/dm.c
common/usb.c
common/usb_storage.c
doc/board/emulation/qemu-mips.rst
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci.h
drivers/usb/host/usb-uclass.c
include/configs/vcoreiii.h
include/usb.h
test/py/tests/test_dm.py [new file with mode: 0644]

index ad81d5ecab225791e4e64f4760a1ba8ed35de26f..dd1ca5ad3fdf9e8282358a428eeef2ef33762aa1 100755 (executable)
@@ -116,8 +116,8 @@ if [ -f $BL32 ]; then
 cat << __CONF_SECTION_EOF
                config@$cnt {
                        description = "$(basename $dtname .dtb)";
-                       firmware = "atf@1";
-                       loadables = "uboot@1", "tee@1";
+                       firmware = "uboot@1";
+                       loadables = "atf@1", "tee@1";
                        fdt = "fdt@$cnt";
                };
 __CONF_SECTION_EOF
@@ -125,8 +125,8 @@ else
 cat << __CONF_SECTION1_EOF
                config@$cnt {
                        description = "$(basename $dtname .dtb)";
-                       firmware = "atf@1";
-                       loadables = "uboot@1";
+                       firmware = "uboot@1";
+                       loadables = "atf@1";
                        fdt = "fdt@$cnt";
                };
 __CONF_SECTION1_EOF
index a1508e3b8867d3cc9119386166779aa5ee662755..e0c1868b8c2a29df4777a3e9508da2bc19a54236 100644 (file)
@@ -13,7 +13,7 @@ unsigned long notrace timer_read_counter(void)
        return read_c0_count();
 }
 
-ulong notrace get_tbclk(void)
+ulong notrace __weak get_tbclk(void)
 {
        return CONFIG_SYS_MIPS_TIMER_FREQ;
 }
index 589bc651f94166aa538d4304bc96182f3c477903..24a72d9c973966a522fa73aa0c0cad421caf0853 100644 (file)
@@ -11,5 +11,6 @@ obj-y += stack.o
 obj-y  += traps.o
 
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_CMD_GO) += boot.o
 
 lib-$(CONFIG_USE_PRIVATE_LIBGCC) += ashldi3.o ashrdi3.o lshrdi3.o
diff --git a/arch/mips/lib/boot.c b/arch/mips/lib/boot.c
new file mode 100644 (file)
index 0000000..db862f6
--- /dev/null
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+unsigned long do_go_exec(ulong (*entry)(int, char * const []),
+                        int argc, char * const argv[])
+{
+       /*
+        * Flush cache before jumping to application. Let's flush the
+        * whole SDRAM area, since we don't know the size of the image
+        * that was loaded.
+        */
+       flush_cache(gd->bd->bi_memstart, gd->ram_top - gd->bd->bi_memstart);
+
+       return entry(argc, argv);
+}
index 502956d050c845f06091dec62cde51c311274a6d..1a8c87d09437258f7f2ce649646cdfe8be213694 100644 (file)
@@ -141,7 +141,7 @@ ops_done:
        instruction_hazard_barrier();
 }
 
-void flush_dcache_range(ulong start_addr, ulong stop)
+void __weak flush_dcache_range(ulong start_addr, ulong stop)
 {
        unsigned long lsize = dcache_line_size();
        unsigned long slsize = scache_line_size();
index ac75d51da5fb2ec07ae686b28535a213cb98d41e..3ee589891b1af035f2f7a63791af55757448991c 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <asm/io.h>
 #include <asm/types.h>
+#include <asm/mipsregs.h>
 
 #include <mach/tlb.h>
 #include <mach/ddr.h>
@@ -53,7 +54,6 @@ void vcoreiii_tlb_init(void)
                   MMU_REGIO_RW);
 #endif
 
-#if  CONFIG_SYS_TEXT_BASE == MSCC_FLASH_TO
        /*
         * If U-Boot is located in NOR then we want to be able to use
         * the data cache in order to boot in a decent duration
@@ -71,9 +71,10 @@ void vcoreiii_tlb_init(void)
        create_tlb(tlbix++, MSCC_DDR_TO, MSCC_RAM_TLB_SIZE, MMU_REGIO_RW,
                   MSCC_ATTRIB2);
 
-       /* Enable caches by clearing the bit ERL, which is set on reset */
-       write_c0_status(read_c0_status() & ~BIT(2));
-#endif /* CONFIG_SYS_TEXT_BASE */
+       /* Enable mapping (using TLB) kuseg by clearing the bit ERL,
+        * which is set on reset.
+        */
+       write_c0_status(read_c0_status() & ~ST0_ERL);
 }
 
 int mach_cpu_init(void)
index c43f7a585bf8a51f9bb7870919f88fd401891c5f..72c70c9e8432f36c6d23a5cc5ce88d29f9faaed5 100644 (file)
@@ -31,7 +31,7 @@ static inline int vcoreiii_train_bytelane(void)
 
 int vcoreiii_ddr_init(void)
 {
-       int res;
+       register int res;
 
        if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT)
              & ICPU_MEMCTRL_STAT_INIT_DONE)) {
@@ -40,20 +40,19 @@ int vcoreiii_ddr_init(void)
                if (hal_vcoreiii_init_dqs() || vcoreiii_train_bytelane())
                        hal_vcoreiii_ddr_failed();
        }
-#if (CONFIG_SYS_TEXT_BASE != 0x20000000)
+
        res = dram_check();
        if (res == 0)
                hal_vcoreiii_ddr_verified();
        else
                hal_vcoreiii_ddr_failed();
 
-       /* Clear boot-mode and read-back to activate/verify */
+       /*  Remap DDR to kuseg: Clear boot-mode */
        clrbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
                     ICPU_GENERAL_CTRL_BOOT_MODE_ENA);
+       /* - and read-back to activate/verify */
        readl(BASE_CFG + ICPU_GENERAL_CTRL);
-#else
-       res = 0;
-#endif
+
        return res;
 }
 
@@ -66,9 +65,6 @@ int print_cpuinfo(void)
 
 int dram_init(void)
 {
-       while (vcoreiii_ddr_init())
-               ;
-
        gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
        return 0;
 }
index d1f4287f654661727bba043984843c5c697002f8..bf75e52ec3c652a45b9f6d685a703904f9bba579 100644 (file)
@@ -435,16 +435,12 @@ static inline void hal_vcoreiii_ddr_failed(void)
        reset = KSEG0ADDR(_machine_restart);
        icache_lock((void *)reset, 128);
        asm volatile ("jr %0"::"r" (reset));
-
-       panic("DDR init failed\n");
 }
 #else                          /* JR2 || ServalT */
 static inline void hal_vcoreiii_ddr_failed(void)
 {
        writel(0, BASE_CFG + ICPU_RESET);
        writel(PERF_SOFT_RST_SOFT_CHIP_RST, BASE_CFG + PERF_SOFT_RST);
-
-       panic("DDR init failed\n");
 }
 #endif
 
index dfbe06766cde82da55aaa305f5740ae5ebc0e528..91f29ae252cc55308f1c0a3dec32fcb08131e617 100644 (file)
@@ -8,6 +8,7 @@
 
     .set noreorder
     .extern     vcoreiii_tlb_init
+    .extern     vcoreiii_ddr_init
 #ifdef CONFIG_SOC_LUTON
     .extern     pll_init
 #endif
@@ -17,14 +18,28 @@ LEAF(lowlevel_init)
         * As we have no stack yet, we can assume the restricted
         * luxury of the sX-registers without saving them
         */
-       move    s0,ra
+
+       /* Modify ra/s0 such we return to physical NOR location */
+       li      t0, 0x0fffffff
+       li      t1, CONFIG_SYS_TEXT_BASE
+       and     s0, ra, t0
+       add     s0, s0, t1
 
        jal     vcoreiii_tlb_init
         nop
+
 #ifdef CONFIG_SOC_LUTON
        jal     pll_init
         nop
 #endif
+
+       /* Initialize DDR controller to enable stack/gd/heap */
+0:
+       jal     vcoreiii_ddr_init
+        nop
+       bnez    v0, 0b          /* Retry on error */
+        nop
+
        jr      s0
         nop
        END(lowlevel_init)
index 108707c298a4d6fb35e148b7768e34bdd796b8b4..7a90685f8b66f451d837bcbb52b6fcc21ea92805 100644 (file)
--- a/cmd/dm.c
+++ b/cmd/dm.c
@@ -41,7 +41,7 @@ static int do_dm_dump_devres(cmd_tbl_t *cmdtp, int flag, int argc,
 }
 
 static int do_dm_dump_drivers(cmd_tbl_t *cmdtp, int flag, int argc,
-                              char * const argv[])
+                             char * const argv[])
 {
        dm_dump_drivers();
 
@@ -94,5 +94,5 @@ U_BOOT_CMD(
        "tree          Dump driver model tree ('*' = activated)\n"
        "dm uclass        Dump list of instances for each uclass\n"
        "dm devres        Dump list of device resources for each device\n"
-       "dm drivers       Dump list of drivers and their compatible strings\n"
+       "dm drivers       Dump list of drivers and their compatible strings"
 );
index 349e838f1d57785dff86eb5e8ee04d682d3841ec..686f09a77d1ec7caf151b21dadaa17ec979f7f4e 100644 (file)
@@ -172,6 +172,12 @@ int usb_detect_change(void)
        return change;
 }
 
+/* Lock or unlock async schedule on the controller */
+__weak int usb_lock_async(struct usb_device *dev, int lock)
+{
+       return 0;
+}
+
 /*
  * disables the asynch behaviour of the control message. This is used for data
  * transfers that uses the exclusiv access to the control and bulk messages.
index 097b6729c14d14c1dfd968499e056d8b07b60775..b291ac55d14542fa47af0c941d67598082adfbe7 100644 (file)
@@ -1157,6 +1157,7 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
        ss = (struct us_data *)udev->privptr;
 
        usb_disable_asynch(1); /* asynch transfer not allowed */
+       usb_lock_async(udev, 1);
        srb->lun = block_dev->lun;
        buf_addr = (uintptr_t)buffer;
        start = blknr;
@@ -1195,6 +1196,7 @@ retry_it:
        debug("usb_read: end startblk " LBAF ", blccnt %x buffer %lx\n",
              start, smallblks, buf_addr);
 
+       usb_lock_async(udev, 0);
        usb_disable_asynch(0); /* asynch transfer allowed */
        if (blkcnt >= ss->max_xfer_blk)
                debug("\n");
@@ -1239,6 +1241,7 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
        ss = (struct us_data *)udev->privptr;
 
        usb_disable_asynch(1); /* asynch transfer not allowed */
+       usb_lock_async(udev, 1);
 
        srb->lun = block_dev->lun;
        buf_addr = (uintptr_t)buffer;
@@ -1280,6 +1283,7 @@ retry_it:
        debug("usb_write: end startblk " LBAF ", blccnt %x buffer %lx\n",
              start, smallblks, buf_addr);
 
+       usb_lock_async(udev, 0);
        usb_disable_asynch(0); /* asynch transfer allowed */
        if (blkcnt >= ss->max_xfer_blk)
                debug("\n");
index 529a908b55b2e4454a08c17fa2698e6159848602..f206039f5483531b5d68a4d355d5958be53d2bb6 100644 (file)
@@ -25,37 +25,45 @@ Example usage
 
 Using u-boot.bin as ROM (replaces Qemu monitor):
 
-32 bit, big endian::
+32 bit, big endian
 
-   # make qemu_mips
-   # qemu-system-mips -M mips -bios u-boot.bin -nographic
+.. code-block:: bash
 
-32 bit, little endian::
+   make qemu_mips
+   qemu-system-mips -M mips -bios u-boot.bin -nographic
 
-   # make qemu_mipsel
-   # qemu-system-mipsel -M mips -bios u-boot.bin -nographic
+32 bit, little endian
 
-64 bit, big endian::
+.. code-block:: bash
 
-   # make qemu_mips64
-   # qemu-system-mips64 -cpu MIPS64R2-generic -M mips -bios u-boot.bin -nographic
+   make qemu_mipsel
+   qemu-system-mipsel -M mips -bios u-boot.bin -nographic
 
-64 bit, little endian::
+64 bit, big endian
 
-   # make qemu_mips64el
-   # qemu-system-mips64el -cpu MIPS64R2-generic -M mips -bios u-boot.bin -nographic
+.. code-block:: bash
+
+   make qemu_mips64
+   qemu-system-mips64 -cpu MIPS64R2-generic -M mips -bios u-boot.bin -nographic
+
+64 bit, little endian
+
+.. code-block:: bash
+
+   make qemu_mips64el
+   qemu-system-mips64el -cpu MIPS64R2-generic -M mips -bios u-boot.bin -nographic
 
 or using u-boot.bin from emulated flash:
 
-if you use a qemu version after commit 4224
+if you use a QEMU version after commit 4224
 
-.. code-block:: none
+.. code-block:: bash
 
-   create image:
-   dd of=flash bs=1k count=4k if=/dev/zero
-   dd of=flash bs=1k conv=notrunc if=u-boot.bin
-   start it (see above):
-   qemu-system-mips[64][el] [-cpu MIPS64R2-generic] -M mips -pflash flash -nographic
+   create image:
+   dd of=flash bs=1k count=4k if=/dev/zero
+   dd of=flash bs=1k conv=notrunc if=u-boot.bin
+   start it (see above):
+   qemu-system-mips[64][el] [-cpu MIPS64R2-generic] -M mips -pflash flash -nographic
 
 Download kernel + initrd
 ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -75,61 +83,63 @@ you can downland::
 Generate uImage
 ^^^^^^^^^^^^^^^
 
-.. code-block:: none
+.. code-block:: bash
 
-   tools/mkimage -A mips -O linux -T kernel -C gzip -a 0x80010000 -e 0x80245650 -n "Linux 2.6.24.y" -d vmlinux.bin.gz uImage
+   tools/mkimage -A mips -O linux -T kernel -C gzip -a 0x80010000 -e 0x80245650 -n "Linux 2.6.24.y" -d vmlinux.bin.gz uImage
 
 Copy uImage to Flash
 ^^^^^^^^^^^^^^^^^^^^
 
-.. code-block:: none
+.. code-block:: bash
 
-   dd if=uImage bs=1k conv=notrunc seek=224 of=flash
+   dd if=uImage bs=1k conv=notrunc seek=224 of=flash
 
 Generate Ide Disk
 ^^^^^^^^^^^^^^^^^
 
-.. code-block:: none
+.. code-block:: bash
 
-   # dd of=ide bs=1k cout=100k if=/dev/zero
+   dd of=ide bs=1k count=100k if=/dev/zero
 
-   # sfdisk -C 261 -d ide
-   # partition table of ide
+   # Create partion table
+   sudo sfdisk ide << EOF
+   label: dos
+   label-id: 0x6fe3a999
+   device: image
    unit: sectors
-
-        ide1 : start=       63, size=    32067, Id=83
-        ide2 : start=    32130, size=    32130, Id=83
-        ide3 : start=    64260, size=  4128705, Id=83
-        ide4 : start=        0, size=        0, Id= 0
+   image1 : start=       63, size=    32067, Id=83
+   image2 : start=    32130, size=    32130, Id=83
+   image3 : start=    64260, size=  4128705, Id=83
+   EOF
 
 Copy to ide
 ^^^^^^^^^^^
 
-.. code-block:: none
+.. code-block:: bash
 
-   dd if=uImage bs=512 conv=notrunc seek=63 of=ide
+   dd if=uImage bs=512 conv=notrunc seek=63 of=ide
 
 Generate ext2 on part 2 on Copy uImage and initrd.gz
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. code-block:: none
+.. code-block:: bash
 
    # Attached as loop device ide offset = 32130 * 512
-   # losetup -o 16450560 -f ide
+   sudo losetup -o 16450560 /dev/loop0 ide
    # Format as ext2 ( arg2 : nb blocks)
-   # mke2fs /dev/loop0 16065
-   # losetup -d /dev/loop0
+   sudo mkfs.ext2 /dev/loop0 16065
+   sudo losetup -d /dev/loop0
    # Mount and copy uImage and initrd.gz to it
-   # mount -o loop,offset=16450560 -t ext2 ide /mnt
-   # mkdir /mnt/boot
-   cp {initrd.gz,uImage} /mnt/boot/
+   sudo mount -o loop,offset=16450560 -t ext2 ide /mnt
+   sudo mkdir /mnt/boot
+   cp {initrd.gz,uImage} /mnt/boot/
    # Umount it
-   # umount /mnt
+   sudo umount /mnt
 
 Set Environment
 ^^^^^^^^^^^^^^^
 
-.. code-block:: none
+.. code-block:: bash
 
    setenv rd_start 0x80800000
    setenv rd_size 2663940
@@ -157,9 +167,11 @@ Set Environment
    setenv addmisc 'setenv bootargs ${bootargs} console=ttyS0,${baudrate} rd_start=${rd_start} rd_size=${rd_size} ethaddr=${ethaddr}'
    setenv bootcmd 'run boot_tftp_flash'
 
-Now you can boot from flash, ide, ide+ext2 and tfp::
+Now you can boot from flash, ide, ide+ext2 and tfp
+
+.. code-block:: bash
 
-   qemu-system-mips -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide
+   qemu-system-mips -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide
 
 
 How to debug U-Boot
@@ -168,9 +180,9 @@ How to debug U-Boot
 In order to debug U-Boot you need to start qemu with gdb server support (-s)
 and waiting the connection to start the CPU (-S)
 
-.. code-block:: none
+.. code-block:: bash
 
-   qemu-system-mips -S -s -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide
+   qemu-system-mips -S -s -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide
 
 in an other console you start gdb
 
@@ -182,7 +194,7 @@ by connecting to the gdb server localhost:1234
 
 .. code-block:: none
 
-   # mipsel-unknown-linux-gnu-gdb u-boot
+   $ mipsel-unknown-linux-gnu-gdb u-boot
    GNU gdb 6.6
    Copyright (C) 2006 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
index 1cc02052f5425120adbd1fe2c33eaf9747adbd69..1edb344d0fb22cfb97ee4c05d87a068ac772ce5c 100644 (file)
@@ -298,6 +298,51 @@ static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
                                     QH_ENDPT2_HUBADDR(hubaddr));
 }
 
+static int ehci_enable_async(struct ehci_ctrl *ctrl)
+{
+       u32 cmd;
+       int ret;
+
+       /* Enable async. schedule. */
+       cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
+       if (cmd & CMD_ASE)
+               return 0;
+
+       cmd |= CMD_ASE;
+       ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+
+       ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, STS_ASS,
+                       100 * 1000);
+       if (ret < 0)
+               printf("EHCI fail timeout STS_ASS set\n");
+
+       return ret;
+}
+
+static int ehci_disable_async(struct ehci_ctrl *ctrl)
+{
+       u32 cmd;
+       int ret;
+
+       if (ctrl->async_locked)
+               return 0;
+
+       /* Disable async schedule. */
+       cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
+       if (!(cmd & CMD_ASE))
+               return 0;
+
+       cmd &= ~CMD_ASE;
+       ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+
+       ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, 0,
+                       100 * 1000);
+       if (ret < 0)
+               printf("EHCI fail timeout STS_ASS reset\n");
+
+       return ret;
+}
+
 static int
 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                   int length, struct devrequest *req)
@@ -311,7 +356,6 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
        uint32_t *tdp;
        uint32_t endpt, maxpacket, token, usbsts, qhtoken;
        uint32_t c, toggle;
-       uint32_t cmd;
        int timeout;
        int ret = 0;
        struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
@@ -556,19 +600,9 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
        usbsts = ehci_readl(&ctrl->hcor->or_usbsts);
        ehci_writel(&ctrl->hcor->or_usbsts, (usbsts & 0x3f));
 
-       /* Enable async. schedule. */
-       cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
-       if (!(cmd & CMD_ASE)) {
-               cmd |= CMD_ASE;
-               ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
-
-               ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, STS_ASS,
-                               100 * 1000);
-               if (ret < 0) {
-                       printf("EHCI fail timeout STS_ASS set\n");
-                       goto fail;
-               }
-       }
+       ret = ehci_enable_async(ctrl);
+       if (ret)
+               goto fail;
 
        /* Wait for TDs to be processed. */
        ts = get_timer(0);
@@ -611,6 +645,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
        if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)
                printf("EHCI timed out on TD - token=%#x\n", token);
 
+       ret = ehci_disable_async(ctrl);
+       if (ret)
+               goto fail;
+
        if (!(QT_TOKEN_GET_STATUS(qhtoken) & QT_TOKEN_STATUS_ACTIVE)) {
                debug("TOKEN=%#x\n", qhtoken);
                switch (QT_TOKEN_GET_STATUS(qhtoken) &
@@ -1512,6 +1550,16 @@ static int _ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe,
        return result;
 }
 
+static int _ehci_lock_async(struct ehci_ctrl *ctrl, int lock)
+{
+       ctrl->async_locked = lock;
+
+       if (lock)
+               return 0;
+
+       return ehci_disable_async(ctrl);
+}
+
 #if !CONFIG_IS_ENABLED(DM_USB)
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
                            void *buffer, int length)
@@ -1549,6 +1597,13 @@ int destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
 {
        return _ehci_destroy_int_queue(dev, queue);
 }
+
+int usb_lock_async(struct usb_device *dev, int lock)
+{
+       struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
+
+       return _ehci_lock_async(ctrl, lock);
+}
 #endif
 
 #if CONFIG_IS_ENABLED(DM_USB)
@@ -1612,6 +1667,13 @@ static int ehci_get_max_xfer_size(struct udevice *dev, size_t *size)
        return 0;
 }
 
+static int ehci_lock_async(struct udevice *dev, int lock)
+{
+       struct ehci_ctrl *ctrl = dev_get_priv(dev);
+
+       return _ehci_lock_async(ctrl, lock);
+}
+
 int ehci_register(struct udevice *dev, struct ehci_hccr *hccr,
                  struct ehci_hcor *hcor, const struct ehci_ops *ops,
                  uint tweaks, enum usb_init_type init)
@@ -1678,6 +1740,7 @@ struct dm_usb_ops ehci_usb_ops = {
        .poll_int_queue = ehci_poll_int_queue,
        .destroy_int_queue = ehci_destroy_int_queue,
        .get_max_xfer_size  = ehci_get_max_xfer_size,
+       .lock_async = ehci_lock_async,
 };
 
 #endif
index 6c359af90c9459baabbba55663627d3c2cae690e..66c1d61dbf28109f3ed82a9a9387311e6e87c182 100644 (file)
@@ -255,6 +255,7 @@ struct ehci_ctrl {
        int periodic_schedules;
        int ntds;
        bool has_fsl_erratum_a005275;   /* Freescale HS silicon quirk */
+       bool async_locked;
        struct ehci_ops ops;
        void *priv;     /* client's private data */
 };
index 852165158869f7031c48b76d11281f3e5d519aef..5e423012dfd8faa3af5e17cf2413f612c483b638 100644 (file)
@@ -22,6 +22,17 @@ struct usb_uclass_priv {
        int companion_device_count;
 };
 
+int usb_lock_async(struct usb_device *udev, int lock)
+{
+       struct udevice *bus = udev->controller_dev;
+       struct dm_usb_ops *ops = usb_get_ops(bus);
+
+       if (!ops->lock_async)
+               return -ENOSYS;
+
+       return ops->lock_async(bus, lock);
+}
+
 int usb_disable_asynch(int disable)
 {
        int old_value = asynch_allowed;
index e69456ef7ce2bcf10776b0fe17f751a57dee27b1..6a2f80c2fb42dd80c1cd96c83c4c629ded9124d7 100644 (file)
@@ -39,7 +39,8 @@
 #define CONFIG_CONS_INDEX              1
 
 #define CONFIG_SYS_MEMTEST_START       CONFIG_SYS_SDRAM_BASE
-#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE - SZ_1M)
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_SDRAM_BASE + \
+                                        CONFIG_SYS_SDRAM_SIZE - SZ_4M)
 
 #define CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
 
index efb67ea33ffbdbe3e8ee9460fd3977a73811d591..22f6088fe66afc8a63dc5533aa2fd2926cb4afee 100644 (file)
@@ -269,6 +269,7 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
                        void *data, int len, int *actual_length, int timeout);
 int usb_int_msg(struct usb_device *dev, unsigned long pipe,
                void *buffer, int transfer_len, int interval, bool nonblock);
+int usb_lock_async(struct usb_device *dev, int lock);
 int usb_disable_asynch(int disable);
 int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
 int usb_get_configuration_no(struct usb_device *dev, int cfgno,
@@ -791,6 +792,16 @@ struct dm_usb_ops {
         * in a USB transfer. USB class driver needs to be aware of this.
         */
        int (*get_max_xfer_size)(struct udevice *bus, size_t *size);
+
+       /**
+        * lock_async() - Keep async schedule after a transfer
+        *
+        * It may be desired to keep the asynchronous schedule running even
+        * after a transfer finishes, usually when doing multiple transfers
+        * back-to-back. This callback allows signalling the USB controller
+        * driver to do just that.
+        */
+       int (*lock_async)(struct udevice *udev, int lock);
 };
 
 #define usb_get_ops(dev)       ((struct dm_usb_ops *)(dev)->driver->ops)
diff --git a/test/py/tests/test_dm.py b/test/py/tests/test_dm.py
new file mode 100644 (file)
index 0000000..f6fbf8b
--- /dev/null
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2020 Sean Anderson
+
+import pytest
+
+@pytest.mark.buildconfigspec('cmd_dm')
+def test_dm_drivers(u_boot_console):
+    """Test that each driver in `dm tree` is also listed in `dm drivers`."""
+    response = u_boot_console.run_command('dm tree')
+    driver_index = response.find('Driver')
+    assert driver_index != -1
+    drivers = (line[driver_index:].split()[0]
+               for line in response[:-1].split('\n')[2:])
+
+    response = u_boot_console.run_command('dm drivers')
+    for driver in drivers:
+        assert driver in response