[PATCH] usb: ehci-mx6: Enable OTG detection on imx8mm and imx8mn

Marek Vasut marex at denx.de
Wed Dec 22 20:31:33 CET 2021


On 12/22/21 13:52, Adam Ford wrote:
> The imx8mm and imx8mn appear compatible with imx7d-usb
> flags in the OTG driver.  If the dr_mode is defined as
> host or peripheral, the device appears to operate correctly,
> however the auto host/peripheral detection results in an error.
> 
> Simply adding checks in ehci_usb_phy_mode for 8mm and
> 8mn in ehci_usb_phy_mode is not enough, because ehci_usb_of_to_plat
> is run before the clock is enabled which results in a hang.
> 
> Enable the USB clock in ehci_usb_of_to_plat and add checks in
> ehci_usb_phy_mode for 8mm and 8mn to enable auto detection of
> the OTG mode on i.MX8M Mini and Nano.

I was under the impression that of_to_plat() was meant to parse DT into 
driver local data, so frobbing with clock there could be a problem, 
right ? +CC Simon.

> diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
> index 1bd6147c76..fa0798171b 100644
> --- a/drivers/usb/host/ehci-mx6.c
> +++ b/drivers/usb/host/ehci-mx6.c
> @@ -543,7 +543,7 @@ static int ehci_usb_phy_mode(struct udevice *dev)
>   			plat->init_type = USB_INIT_DEVICE;
>   		else
>   			plat->init_type = USB_INIT_HOST;
> -	} else if (is_mx7()) {
> +	} else if (is_mx7() || is_imx8mm() || is_imx8mn()) {
>   		phy_status = (void __iomem *)(addr +
>   					      USBNC_PHY_STATUS_OFFSET);
>   		val = readl(phy_status);
> @@ -561,11 +561,30 @@ static int ehci_usb_phy_mode(struct udevice *dev)
>   
>   static int ehci_usb_of_to_plat(struct udevice *dev)
>   {
> +#if CONFIG_IS_ENABLED(CLK)
> +	int ret = 0;
> +	struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
> +
> +	ret = clk_get_by_index(dev, 0, &priv->clk);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = clk_enable(&priv->clk);
> +	if (ret)
> +		return ret;
> +#endif
> +
>   	struct usb_plat *plat = dev_get_plat(dev);
>   	enum usb_dr_mode dr_mode;
>   
>   	dr_mode = usb_get_dr_mode(dev_ofnode(dev));
>   
> +#if CONFIG_IS_ENABLED(CLK)
> +	ret = clk_disable(&priv->clk);
> +	if (ret)
> +		return ret;
> +#endif
> +
>   	switch (dr_mode) {
>   	case USB_DR_MODE_HOST:
>   		plat->init_type = USB_INIT_HOST;


More information about the U-Boot mailing list