Tom Rini 2022-02-11 07:22:30 -05:00
commit 86752b2814
4 changed files with 50 additions and 12 deletions

View File

@ -17,6 +17,9 @@
#include <stdio_dev.h> #include <stdio_dev.h>
#include <watchdog.h> #include <watchdog.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#ifdef CONFIG_SANDBOX
#include <asm/state.h>
#endif
#include <usb.h> #include <usb.h>
@ -118,7 +121,7 @@ struct usb_kbd_pdata {
extern int __maybe_unused net_busy_flag; extern int __maybe_unused net_busy_flag;
/* The period of time between two calls of usb_kbd_testc(). */ /* The period of time between two calls of usb_kbd_testc(). */
static unsigned long __maybe_unused kbd_testc_tms; static unsigned long kbd_testc_tms;
/* Puts character in the queue and sets up the in and out pointer. */ /* Puts character in the queue and sets up the in and out pointer. */
static void usb_kbd_put_queue(struct usb_kbd_pdata *data, u8 c) static void usb_kbd_put_queue(struct usb_kbd_pdata *data, u8 c)
@ -394,21 +397,39 @@ static int usb_kbd_testc(struct stdio_dev *sdev)
struct usb_device *usb_kbd_dev; struct usb_device *usb_kbd_dev;
struct usb_kbd_pdata *data; struct usb_kbd_pdata *data;
/*
* Polling the keyboard for an event can take dozens of milliseconds.
* Add a delay between polls to avoid blocking activity which polls
* rapidly, like the UEFI console timer.
*/
unsigned long poll_delay = CONFIG_SYS_HZ / 50;
#ifdef CONFIG_CMD_NET #ifdef CONFIG_CMD_NET
/* /*
* If net_busy_flag is 1, NET transfer is running, * If net_busy_flag is 1, NET transfer is running,
* then we check key-pressed every second (first check may be * then we check key-pressed every second (first check may be
* less than 1 second) to improve TFTP booting performance. * less than 1 second) to improve TFTP booting performance.
*/ */
if (net_busy_flag && (get_timer(kbd_testc_tms) < CONFIG_SYS_HZ)) if (net_busy_flag)
return 0; poll_delay = CONFIG_SYS_HZ;
kbd_testc_tms = get_timer(0);
#endif #endif
#ifdef CONFIG_SANDBOX
/*
* Skip delaying polls if a test requests it.
*/
if (state_get_skip_delays())
poll_delay = 0;
#endif
dev = stdio_get_by_name(sdev->name); dev = stdio_get_by_name(sdev->name);
usb_kbd_dev = (struct usb_device *)dev->priv; usb_kbd_dev = (struct usb_device *)dev->priv;
data = usb_kbd_dev->privptr; data = usb_kbd_dev->privptr;
usb_kbd_poll_for_event(usb_kbd_dev); if (get_timer(kbd_testc_tms) >= poll_delay) {
usb_kbd_poll_for_event(usb_kbd_dev);
kbd_testc_tms = get_timer(0);
}
return !(data->usb_in_pointer == data->usb_out_pointer); return !(data->usb_in_pointer == data->usb_out_pointer);
} }

View File

@ -402,6 +402,9 @@ align:
flush: flush:
hwaddr = (unsigned long)ci_req->hw_buf; hwaddr = (unsigned long)ci_req->hw_buf;
if (!hwaddr)
return 0;
aligned_used_len = roundup(req->length, ARCH_DMA_MINALIGN); aligned_used_len = roundup(req->length, ARCH_DMA_MINALIGN);
flush_dcache_range(hwaddr, hwaddr + aligned_used_len); flush_dcache_range(hwaddr, hwaddr + aligned_used_len);
@ -415,7 +418,7 @@ static void ci_debounce(struct ci_req *ci_req, int in)
unsigned long hwaddr = (unsigned long)ci_req->hw_buf; unsigned long hwaddr = (unsigned long)ci_req->hw_buf;
uint32_t aligned_used_len; uint32_t aligned_used_len;
if (in) if (in || !hwaddr)
return; return;
aligned_used_len = roundup(req->actual, ARCH_DMA_MINALIGN); aligned_used_len = roundup(req->actual, ARCH_DMA_MINALIGN);

View File

@ -543,7 +543,7 @@ static int ehci_usb_phy_mode(struct udevice *dev)
plat->init_type = USB_INIT_DEVICE; plat->init_type = USB_INIT_DEVICE;
else else
plat->init_type = USB_INIT_HOST; plat->init_type = USB_INIT_HOST;
} else if (is_mx7()) { } else if (is_mx7() || is_imx8mm() || is_imx8mn()) {
phy_status = (void __iomem *)(addr + phy_status = (void __iomem *)(addr +
USBNC_PHY_STATUS_OFFSET); USBNC_PHY_STATUS_OFFSET);
val = readl(phy_status); val = readl(phy_status);
@ -573,9 +573,8 @@ static int ehci_usb_of_to_plat(struct udevice *dev)
case USB_DR_MODE_PERIPHERAL: case USB_DR_MODE_PERIPHERAL:
plat->init_type = USB_INIT_DEVICE; plat->init_type = USB_INIT_DEVICE;
break; break;
case USB_DR_MODE_OTG: default:
case USB_DR_MODE_UNKNOWN: plat->init_type = USB_INIT_UNKNOWN;
return ehci_usb_phy_mode(dev);
}; };
return 0; return 0;
@ -677,6 +676,20 @@ static int ehci_usb_probe(struct udevice *dev)
mdelay(1); mdelay(1);
#endif #endif
/*
* If the device tree didn't specify host or device,
* the default is USB_INIT_UNKNOWN, so we need to check
* the register. For imx8mm and imx8mn, the clocks need to be
* running first, so we defer the check until they are.
*/
if (priv->init_type == USB_INIT_UNKNOWN) {
ret = ehci_usb_phy_mode(dev);
if (ret)
goto err_clk;
else
priv->init_type = plat->init_type;
}
#if CONFIG_IS_ENABLED(DM_REGULATOR) #if CONFIG_IS_ENABLED(DM_REGULATOR)
ret = device_get_supply_regulator(dev, "vbus-supply", ret = device_get_supply_regulator(dev, "vbus-supply",
&priv->vbus_supply); &priv->vbus_supply);
@ -741,8 +754,8 @@ err_regulator:
#if CONFIG_IS_ENABLED(DM_REGULATOR) #if CONFIG_IS_ENABLED(DM_REGULATOR)
if (priv->vbus_supply) if (priv->vbus_supply)
regulator_set_enable(priv->vbus_supply, false); regulator_set_enable(priv->vbus_supply, false);
err_clk:
#endif #endif
err_clk:
#if CONFIG_IS_ENABLED(CLK) #if CONFIG_IS_ENABLED(CLK)
clk_disable(&priv->clk); clk_disable(&priv->clk);
#else #else

View File

@ -163,7 +163,8 @@ struct int_queue;
*/ */
enum usb_init_type { enum usb_init_type {
USB_INIT_HOST, USB_INIT_HOST,
USB_INIT_DEVICE USB_INIT_DEVICE,
USB_INIT_UNKNOWN,
}; };
/********************************************************************** /**********************************************************************