[U-Boot] [PATCH] sunxi: A64: OHCI: prevent turning off shared USB clock
Jagan Teki
jagannadh.teki at gmail.com
Wed Jul 4 06:26:35 UTC 2018
On Wed, Jul 4, 2018 at 5:35 AM, Andre Przywara <andre.przywara at arm.com> wrote:
> On the A64 the clock for the first USB controller is actually the parent
> of the clock for the second controller, so turning them off in that order
> makes the system hang.
> Fix this by *not* turning off any clock for OHCI0, but both clocks when
> OHCI1 is brought down.
>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
> Hi,
>
> this is a new approach to fix the USB hang we see with mainline U-Boot.
> Compared to the previous patch it just deals with the USB clock (the AHB
> gate was a red herring), and it eventually turns both clocks off instead
> of leaving them running. Please have a test on A64 boards!
>
> Cheers,
> Andre.
>
> drivers/usb/host/ohci-sunxi.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/host/ohci-sunxi.c b/drivers/usb/host/ohci-sunxi.c
> index 0ddbdbe460..8f108b48a8 100644
> --- a/drivers/usb/host/ohci-sunxi.c
> +++ b/drivers/usb/host/ohci-sunxi.c
> @@ -114,6 +114,7 @@ no_phy:
> static int ohci_usb_remove(struct udevice *dev)
> {
> struct ohci_sunxi_priv *priv = dev_get_priv(dev);
> + fdt_addr_t base_addr = devfdt_get_addr(dev);
> int ret;
>
> if (generic_phy_valid(&priv->phy)) {
> @@ -130,7 +131,17 @@ static int ohci_usb_remove(struct udevice *dev)
>
> if (priv->cfg->has_reset)
> clrbits_le32(priv->reset0_cfg, priv->ahb_gate_mask);
> - clrbits_le32(&priv->ccm->usb_clk_cfg, priv->usb_gate_mask);
> + /*
> + * On the A64 CLK_USB_OHCI0 is the parent of CLK_USB_OHCI1, so
> + * we have to bring down none for OHCI0, but both for OHCI1.
> + */
> + if (!priv->cfg->extra_usb_gate_mask || base_addr >= SUNXI_USB2_BASE) {
> + u32 usb_gate_mask = priv->usb_gate_mask;
> +
> + usb_gate_mask |= priv->cfg->extra_usb_gate_mask;
> + clrbits_le32(&priv->ccm->usb_clk_cfg, usb_gate_mask);
> + }
> +
> clrbits_le32(&priv->ccm->ahb_gate0, priv->ahb_gate_mask);
Reviewed-by: Jagan Teki <jagan at openedev.com>
Tested on
- A64=> BPI-M64, Nanopi-A64
=> usb reset
resetting USB...
ohci_usb_remove: Input: mask = 0x10000, usb_clk_cfg = 0x30303
ohci_usb_remove: Output: usb_clk_cfg = 0x30303
EHCI failed to shut down host controller.
ohci_usb_remove: Input: mask = 0x20000, usb_clk_cfg = 0x30101
ohci_usb_remove: Input: mask updated = 0x30000
ohci_usb_remove: Output: usb_clk_cfg = 0x101
USB0: USB EHCI 1.00
USB1: USB OHCI 1.0
USB2: USB EHCI 1.00
USB3: USB OHCI 1.0
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 2 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
- H5=> Orangepi PC2
- H3=> BPI-M2+
=> usb reset
resetting USB...
ohci_usb_remove: Input: mask = 0x10000, usb_clk_cfg = 0x70707
ohci_usb_remove: Input: mask updated = 0x10000
ohci_usb_remove: Output: usb_clk_cfg = 0x60707
EHCI failed to shut down host controller.
ohci_usb_remove: Input: mask = 0x20000, usb_clk_cfg = 0x60505
ohci_usb_remove: Input: mask updated = 0x20000
ohci_usb_remove: Output: usb_clk_cfg = 0x40505
EHCI failed to shut down host controller.
ohci_usb_remove: Input: mask = 0x40000, usb_clk_cfg = 0x40101
ohci_usb_remove: Input: mask updated = 0x40000
ohci_usb_remove: Output: usb_clk_cfg = 0x101
USB0: USB EHCI 1.00
USB1: USB OHCI 1.0
USB2: USB EHCI 1.00
USB3: USB OHCI 1.0
USB4: USB EHCI 1.00
USB5: USB OHCI 1.0
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 1 USB Device(s) found
scanning bus 4 for devices... 1 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
All working fine, so
Tested-by: Jagan Teki <jagan at openedev.com>
More information about the U-Boot
mailing list