diff options
Diffstat (limited to 'drivers/usb/host/xhci-rcar.c')
-rw-r--r-- | drivers/usb/host/xhci-rcar.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 623100e9385e..0e4535e632ec 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -11,6 +11,7 @@ #include <linux/firmware.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/of.h> #include <linux/usb/phy.h> #include "xhci.h" @@ -76,6 +77,24 @@ static void xhci_rcar_start_gen2(struct usb_hcd *hcd) writel(RCAR_USB3_TX_POL_VAL, hcd->regs + RCAR_USB3_TX_POL); } +static int xhci_rcar_is_gen2(struct device *dev) +{ + struct device_node *node = dev->of_node; + + return of_device_is_compatible(node, "renesas,xhci-r8a7790") || + of_device_is_compatible(node, "renesas,xhci-r8a7791") || + of_device_is_compatible(node, "renesas,xhci-r8a7793") || + of_device_is_compatible(node, "renensas,rcar-gen2-xhci"); +} + +static int xhci_rcar_is_gen3(struct device *dev) +{ + struct device_node *node = dev->of_node; + + return of_device_is_compatible(node, "renesas,xhci-r8a7795") || + of_device_is_compatible(node, "renesas,rcar-gen3-xhci"); +} + void xhci_rcar_start(struct usb_hcd *hcd) { u32 temp; @@ -85,7 +104,7 @@ void xhci_rcar_start(struct usb_hcd *hcd) temp = readl(hcd->regs + RCAR_USB3_INT_ENA); temp |= RCAR_USB3_INT_ENA_VAL; writel(temp, hcd->regs + RCAR_USB3_INT_ENA); - if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2)) + if (xhci_rcar_is_gen2(hcd->self.controller)) xhci_rcar_start_gen2(hcd); } } @@ -156,9 +175,22 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd) /* This function needs to initialize a "phy" of usb before */ int xhci_rcar_init_quirk(struct usb_hcd *hcd) { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + /* If hcd->regs is NULL, we don't just call the following function */ if (!hcd->regs) return 0; + /* + * On R-Car Gen2 and Gen3, the AC64 bit (bit 0) of HCCPARAMS1 is set + * to 1. However, these SoCs don't support 64-bit address memory + * pointers. So, this driver clears the AC64 bit of xhci->hcc_params + * to call dma_set_coherent_mask(dev, DMA_BIT_MASK(32)) in + * xhci_gen_setup(). + */ + if (xhci_rcar_is_gen2(hcd->self.controller) || + xhci_rcar_is_gen3(hcd->self.controller)) + xhci->quirks |= XHCI_NO_64BIT_SUPPORT; + return xhci_rcar_download_firmware(hcd); } |