xhci-rcar.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * xHCI host controller driver for R-Car SoCs
  3. *
  4. * Copyright (C) 2014 Renesas Electronics Corporation
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * version 2 as published by the Free Software Foundation.
  9. */
  10. #include <linux/firmware.h>
  11. #include <linux/module.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/usb/phy.h>
  14. #include "xhci.h"
  15. #include "xhci-rcar.h"
  16. #define FIRMWARE_NAME "r8a779x_usb3_v1.dlmem"
  17. MODULE_FIRMWARE(FIRMWARE_NAME);
  18. /*** Register Offset ***/
  19. #define RCAR_USB3_INT_ENA 0x224 /* Interrupt Enable */
  20. #define RCAR_USB3_DL_CTRL 0x250 /* FW Download Control & Status */
  21. #define RCAR_USB3_FW_DATA0 0x258 /* FW Data0 */
  22. #define RCAR_USB3_LCLK 0xa44 /* LCLK Select */
  23. #define RCAR_USB3_CONF1 0xa48 /* USB3.0 Configuration1 */
  24. #define RCAR_USB3_CONF2 0xa5c /* USB3.0 Configuration2 */
  25. #define RCAR_USB3_CONF3 0xaa8 /* USB3.0 Configuration3 */
  26. #define RCAR_USB3_RX_POL 0xab0 /* USB3.0 RX Polarity */
  27. #define RCAR_USB3_TX_POL 0xab8 /* USB3.0 TX Polarity */
  28. /*** Register Settings ***/
  29. /* Interrupt Enable */
  30. #define RCAR_USB3_INT_XHC_ENA 0x00000001
  31. #define RCAR_USB3_INT_PME_ENA 0x00000002
  32. #define RCAR_USB3_INT_HSE_ENA 0x00000004
  33. #define RCAR_USB3_INT_ENA_VAL (RCAR_USB3_INT_XHC_ENA | \
  34. RCAR_USB3_INT_PME_ENA | RCAR_USB3_INT_HSE_ENA)
  35. /* FW Download Control & Status */
  36. #define RCAR_USB3_DL_CTRL_ENABLE 0x00000001
  37. #define RCAR_USB3_DL_CTRL_FW_SUCCESS 0x00000010
  38. #define RCAR_USB3_DL_CTRL_FW_SET_DATA0 0x00000100
  39. /* LCLK Select */
  40. #define RCAR_USB3_LCLK_ENA_VAL 0x01030001
  41. /* USB3.0 Configuration */
  42. #define RCAR_USB3_CONF1_VAL 0x00030204
  43. #define RCAR_USB3_CONF2_VAL 0x00030300
  44. #define RCAR_USB3_CONF3_VAL 0x13802007
  45. /* USB3.0 Polarity */
  46. #define RCAR_USB3_RX_POL_VAL BIT(21)
  47. #define RCAR_USB3_TX_POL_VAL BIT(4)
  48. void xhci_rcar_start(struct usb_hcd *hcd)
  49. {
  50. u32 temp;
  51. if (hcd->regs != NULL) {
  52. /* Interrupt Enable */
  53. temp = readl(hcd->regs + RCAR_USB3_INT_ENA);
  54. temp |= RCAR_USB3_INT_ENA_VAL;
  55. writel(temp, hcd->regs + RCAR_USB3_INT_ENA);
  56. /* LCLK Select */
  57. writel(RCAR_USB3_LCLK_ENA_VAL, hcd->regs + RCAR_USB3_LCLK);
  58. /* USB3.0 Configuration */
  59. writel(RCAR_USB3_CONF1_VAL, hcd->regs + RCAR_USB3_CONF1);
  60. writel(RCAR_USB3_CONF2_VAL, hcd->regs + RCAR_USB3_CONF2);
  61. writel(RCAR_USB3_CONF3_VAL, hcd->regs + RCAR_USB3_CONF3);
  62. /* USB3.0 Polarity */
  63. writel(RCAR_USB3_RX_POL_VAL, hcd->regs + RCAR_USB3_RX_POL);
  64. writel(RCAR_USB3_TX_POL_VAL, hcd->regs + RCAR_USB3_TX_POL);
  65. }
  66. }
  67. static int xhci_rcar_download_firmware(struct device *dev, void __iomem *regs)
  68. {
  69. const struct firmware *fw;
  70. int retval, index, j, time;
  71. int timeout = 10000;
  72. u32 data, val, temp;
  73. /* request R-Car USB3.0 firmware */
  74. retval = request_firmware(&fw, FIRMWARE_NAME, dev);
  75. if (retval)
  76. return retval;
  77. /* download R-Car USB3.0 firmware */
  78. temp = readl(regs + RCAR_USB3_DL_CTRL);
  79. temp |= RCAR_USB3_DL_CTRL_ENABLE;
  80. writel(temp, regs + RCAR_USB3_DL_CTRL);
  81. for (index = 0; index < fw->size; index += 4) {
  82. /* to avoid reading beyond the end of the buffer */
  83. for (data = 0, j = 3; j >= 0; j--) {
  84. if ((j + index) < fw->size)
  85. data |= fw->data[index + j] << (8 * j);
  86. }
  87. writel(data, regs + RCAR_USB3_FW_DATA0);
  88. temp = readl(regs + RCAR_USB3_DL_CTRL);
  89. temp |= RCAR_USB3_DL_CTRL_FW_SET_DATA0;
  90. writel(temp, regs + RCAR_USB3_DL_CTRL);
  91. for (time = 0; time < timeout; time++) {
  92. val = readl(regs + RCAR_USB3_DL_CTRL);
  93. if ((val & RCAR_USB3_DL_CTRL_FW_SET_DATA0) == 0)
  94. break;
  95. udelay(1);
  96. }
  97. if (time == timeout) {
  98. retval = -ETIMEDOUT;
  99. break;
  100. }
  101. }
  102. temp = readl(regs + RCAR_USB3_DL_CTRL);
  103. temp &= ~RCAR_USB3_DL_CTRL_ENABLE;
  104. writel(temp, regs + RCAR_USB3_DL_CTRL);
  105. for (time = 0; time < timeout; time++) {
  106. val = readl(regs + RCAR_USB3_DL_CTRL);
  107. if (val & RCAR_USB3_DL_CTRL_FW_SUCCESS) {
  108. retval = 0;
  109. break;
  110. }
  111. udelay(1);
  112. }
  113. if (time == timeout)
  114. retval = -ETIMEDOUT;
  115. release_firmware(fw);
  116. return retval;
  117. }
  118. /* This function needs to initialize a "phy" of usb before */
  119. int xhci_rcar_init_quirk(struct usb_hcd *hcd)
  120. {
  121. /* If hcd->regs is NULL, we don't just call the following function */
  122. if (!hcd->regs)
  123. return 0;
  124. return xhci_rcar_download_firmware(hcd->self.controller, hcd->regs);
  125. }