Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * xHCI host controller driver for R-Car SoCs
0004  *
0005  * Copyright (C) 2014 Renesas Electronics Corporation
0006  */
0007 
0008 #include <linux/firmware.h>
0009 #include <linux/iopoll.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/of.h>
0013 #include <linux/usb/phy.h>
0014 #include <linux/sys_soc.h>
0015 
0016 #include "xhci.h"
0017 #include "xhci-plat.h"
0018 #include "xhci-rcar.h"
0019 
0020 /*
0021 * - The V3 firmware is for almost all R-Car Gen3 (except r8a7795 ES1.x)
0022 * - The V2 firmware is for r8a7795 ES1.x.
0023 * - The V2 firmware is possible to use on R-Car Gen2. However, the V2 causes
0024 *   performance degradation. So, this driver continues to use the V1 if R-Car
0025 *   Gen2.
0026 * - The V1 firmware is impossible to use on R-Car Gen3.
0027 */
0028 MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V1);
0029 MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V2);
0030 MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3);
0031 
0032 /*** Register Offset ***/
0033 #define RCAR_USB3_AXH_STA   0x104   /* AXI Host Control Status */
0034 #define RCAR_USB3_INT_ENA   0x224   /* Interrupt Enable */
0035 #define RCAR_USB3_DL_CTRL   0x250   /* FW Download Control & Status */
0036 #define RCAR_USB3_FW_DATA0  0x258   /* FW Data0 */
0037 
0038 #define RCAR_USB3_LCLK      0xa44   /* LCLK Select */
0039 #define RCAR_USB3_CONF1     0xa48   /* USB3.0 Configuration1 */
0040 #define RCAR_USB3_CONF2     0xa5c   /* USB3.0 Configuration2 */
0041 #define RCAR_USB3_CONF3     0xaa8   /* USB3.0 Configuration3 */
0042 #define RCAR_USB3_RX_POL    0xab0   /* USB3.0 RX Polarity */
0043 #define RCAR_USB3_TX_POL    0xab8   /* USB3.0 TX Polarity */
0044 
0045 /*** Register Settings ***/
0046 /* AXI Host Control Status */
0047 #define RCAR_USB3_AXH_STA_B3_PLL_ACTIVE     0x00010000
0048 #define RCAR_USB3_AXH_STA_B2_PLL_ACTIVE     0x00000001
0049 #define RCAR_USB3_AXH_STA_PLL_ACTIVE_MASK (RCAR_USB3_AXH_STA_B3_PLL_ACTIVE | \
0050                        RCAR_USB3_AXH_STA_B2_PLL_ACTIVE)
0051 
0052 /* Interrupt Enable */
0053 #define RCAR_USB3_INT_XHC_ENA   0x00000001
0054 #define RCAR_USB3_INT_PME_ENA   0x00000002
0055 #define RCAR_USB3_INT_HSE_ENA   0x00000004
0056 #define RCAR_USB3_INT_ENA_VAL   (RCAR_USB3_INT_XHC_ENA | \
0057                 RCAR_USB3_INT_PME_ENA | RCAR_USB3_INT_HSE_ENA)
0058 
0059 /* FW Download Control & Status */
0060 #define RCAR_USB3_DL_CTRL_ENABLE    0x00000001
0061 #define RCAR_USB3_DL_CTRL_FW_SUCCESS    0x00000010
0062 #define RCAR_USB3_DL_CTRL_FW_SET_DATA0  0x00000100
0063 
0064 /* LCLK Select */
0065 #define RCAR_USB3_LCLK_ENA_VAL  0x01030001
0066 
0067 /* USB3.0 Configuration */
0068 #define RCAR_USB3_CONF1_VAL 0x00030204
0069 #define RCAR_USB3_CONF2_VAL 0x00030300
0070 #define RCAR_USB3_CONF3_VAL 0x13802007
0071 
0072 /* USB3.0 Polarity */
0073 #define RCAR_USB3_RX_POL_VAL    BIT(21)
0074 #define RCAR_USB3_TX_POL_VAL    BIT(4)
0075 
0076 /* For soc_device_attribute */
0077 #define RCAR_XHCI_FIRMWARE_V2   BIT(0) /* FIRMWARE V2 */
0078 #define RCAR_XHCI_FIRMWARE_V3   BIT(1) /* FIRMWARE V3 */
0079 
0080 static const struct soc_device_attribute rcar_quirks_match[]  = {
0081     {
0082         .soc_id = "r8a7795", .revision = "ES1.*",
0083         .data = (void *)RCAR_XHCI_FIRMWARE_V2,
0084     },
0085     { /* sentinel */ }
0086 };
0087 
0088 static void xhci_rcar_start_gen2(struct usb_hcd *hcd)
0089 {
0090     /* LCLK Select */
0091     writel(RCAR_USB3_LCLK_ENA_VAL, hcd->regs + RCAR_USB3_LCLK);
0092     /* USB3.0 Configuration */
0093     writel(RCAR_USB3_CONF1_VAL, hcd->regs + RCAR_USB3_CONF1);
0094     writel(RCAR_USB3_CONF2_VAL, hcd->regs + RCAR_USB3_CONF2);
0095     writel(RCAR_USB3_CONF3_VAL, hcd->regs + RCAR_USB3_CONF3);
0096     /* USB3.0 Polarity */
0097     writel(RCAR_USB3_RX_POL_VAL, hcd->regs + RCAR_USB3_RX_POL);
0098     writel(RCAR_USB3_TX_POL_VAL, hcd->regs + RCAR_USB3_TX_POL);
0099 }
0100 
0101 static int xhci_rcar_is_gen2(struct device *dev)
0102 {
0103     struct device_node *node = dev->of_node;
0104 
0105     return of_device_is_compatible(node, "renesas,xhci-r8a7790") ||
0106         of_device_is_compatible(node, "renesas,xhci-r8a7791") ||
0107         of_device_is_compatible(node, "renesas,xhci-r8a7793") ||
0108         of_device_is_compatible(node, "renesas,rcar-gen2-xhci");
0109 }
0110 
0111 void xhci_rcar_start(struct usb_hcd *hcd)
0112 {
0113     u32 temp;
0114 
0115     if (hcd->regs != NULL) {
0116         /* Interrupt Enable */
0117         temp = readl(hcd->regs + RCAR_USB3_INT_ENA);
0118         temp |= RCAR_USB3_INT_ENA_VAL;
0119         writel(temp, hcd->regs + RCAR_USB3_INT_ENA);
0120         if (xhci_rcar_is_gen2(hcd->self.controller))
0121             xhci_rcar_start_gen2(hcd);
0122     }
0123 }
0124 
0125 static int xhci_rcar_download_firmware(struct usb_hcd *hcd)
0126 {
0127     struct device *dev = hcd->self.controller;
0128     void __iomem *regs = hcd->regs;
0129     struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
0130     const struct firmware *fw;
0131     int retval, index, j;
0132     u32 data, val, temp;
0133     u32 quirks = 0;
0134     const struct soc_device_attribute *attr;
0135     const char *firmware_name;
0136 
0137     /*
0138      * According to the datasheet, "Upon the completion of FW Download,
0139      * there is no need to write or reload FW".
0140      */
0141     if (readl(regs + RCAR_USB3_DL_CTRL) & RCAR_USB3_DL_CTRL_FW_SUCCESS)
0142         return 0;
0143 
0144     attr = soc_device_match(rcar_quirks_match);
0145     if (attr)
0146         quirks = (uintptr_t)attr->data;
0147 
0148     if (quirks & RCAR_XHCI_FIRMWARE_V2)
0149         firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2;
0150     else if (quirks & RCAR_XHCI_FIRMWARE_V3)
0151         firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3;
0152     else
0153         firmware_name = priv->firmware_name;
0154 
0155     /* request R-Car USB3.0 firmware */
0156     retval = request_firmware(&fw, firmware_name, dev);
0157     if (retval)
0158         return retval;
0159 
0160     /* download R-Car USB3.0 firmware */
0161     temp = readl(regs + RCAR_USB3_DL_CTRL);
0162     temp |= RCAR_USB3_DL_CTRL_ENABLE;
0163     writel(temp, regs + RCAR_USB3_DL_CTRL);
0164 
0165     for (index = 0; index < fw->size; index += 4) {
0166         /* to avoid reading beyond the end of the buffer */
0167         for (data = 0, j = 3; j >= 0; j--) {
0168             if ((j + index) < fw->size)
0169                 data |= fw->data[index + j] << (8 * j);
0170         }
0171         writel(data, regs + RCAR_USB3_FW_DATA0);
0172         temp = readl(regs + RCAR_USB3_DL_CTRL);
0173         temp |= RCAR_USB3_DL_CTRL_FW_SET_DATA0;
0174         writel(temp, regs + RCAR_USB3_DL_CTRL);
0175 
0176         retval = readl_poll_timeout_atomic(regs + RCAR_USB3_DL_CTRL,
0177                 val, !(val & RCAR_USB3_DL_CTRL_FW_SET_DATA0),
0178                 1, 10000);
0179         if (retval < 0)
0180             break;
0181     }
0182 
0183     temp = readl(regs + RCAR_USB3_DL_CTRL);
0184     temp &= ~RCAR_USB3_DL_CTRL_ENABLE;
0185     writel(temp, regs + RCAR_USB3_DL_CTRL);
0186 
0187     retval = readl_poll_timeout_atomic((regs + RCAR_USB3_DL_CTRL),
0188             val, val & RCAR_USB3_DL_CTRL_FW_SUCCESS, 1, 10000);
0189 
0190     release_firmware(fw);
0191 
0192     return retval;
0193 }
0194 
0195 static bool xhci_rcar_wait_for_pll_active(struct usb_hcd *hcd)
0196 {
0197     int retval;
0198     u32 val, mask = RCAR_USB3_AXH_STA_PLL_ACTIVE_MASK;
0199 
0200     retval = readl_poll_timeout_atomic(hcd->regs + RCAR_USB3_AXH_STA,
0201             val, (val & mask) == mask, 1, 1000);
0202     return !retval;
0203 }
0204 
0205 /* This function needs to initialize a "phy" of usb before */
0206 int xhci_rcar_init_quirk(struct usb_hcd *hcd)
0207 {
0208     /* If hcd->regs is NULL, we don't just call the following function */
0209     if (!hcd->regs)
0210         return 0;
0211 
0212     if (!xhci_rcar_wait_for_pll_active(hcd))
0213         return -ETIMEDOUT;
0214 
0215     return xhci_rcar_download_firmware(hcd);
0216 }
0217 
0218 int xhci_rcar_resume_quirk(struct usb_hcd *hcd)
0219 {
0220     int ret;
0221 
0222     ret = xhci_rcar_download_firmware(hcd);
0223     if (!ret)
0224         xhci_rcar_start(hcd);
0225 
0226     return ret;
0227 }