811-USB-bcma-improve-USB-2.0-PHY-support-for-BCM4709-and.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
  2. Subject: [PATCH] USB: bcma: improve USB 2.0 PHY support for BCM4709 and
  3. BCM47094
  4. MIME-Version: 1.0
  5. Content-Type: text/plain; charset=UTF-8
  6. Content-Transfer-Encoding: 8bit
  7. Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
  8. ---
  9. --- a/drivers/usb/host/bcma-hcd.c
  10. +++ b/drivers/usb/host/bcma-hcd.c
  11. @@ -31,6 +31,17 @@
  12. #include <linux/usb/ohci_pdriver.h>
  13. #include <linux/usb/xhci_pdriver.h>
  14. +/* DMU (Device Management Unit) */
  15. +#define BCMA_DMU_CRU_USB2_CONTROL 0x0164
  16. +#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK 0x00000FFC
  17. +#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT 2
  18. +#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK 0x00007000
  19. +#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT 12
  20. +#define BCMA_DMU_CRU_CLKSET_KEY 0x0180
  21. +#define BCMA_DMU_CRU_STRAPS_CTRL 0x02A0
  22. +#define BCMA_DMU_CRU_STRAPS_CTRL_USB3 0x00000010
  23. +#define BCMA_DMU_CRU_STRAPS_CTRL_4BYTE 0x00008000
  24. +
  25. MODULE_AUTHOR("Hauke Mehrtens");
  26. MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
  27. MODULE_LICENSE("GPL");
  28. @@ -167,10 +178,35 @@ static void bcma_hcd_init_chip_mips(stru
  29. }
  30. }
  31. +static u32 bcma_hcd_usb_ref_clk_get_rate(void __iomem *dmu)
  32. +{
  33. + u32 val, ndiv, pdiv, ch2_mdiv, ch2_freq;
  34. +
  35. + /* get divider integer from the cru_genpll_control5 */
  36. + val = ioread32(dmu + 0x154);
  37. + ndiv = (val >> 20) & 0x3ff;
  38. + if (ndiv == 0)
  39. + ndiv = 1 << 10;
  40. +
  41. + /* get pdiv and ch2_mdiv from the cru_genpll_control6 */
  42. + val = ioread32(dmu + 0x158);
  43. + pdiv = (val >> 24) & 0x7;
  44. + pdiv = (pdiv == 0) ? (1 << 3) : pdiv;
  45. +
  46. + ch2_mdiv = val & 0xff;
  47. + ch2_mdiv = (ch2_mdiv == 0) ? (1 << 8) : ch2_mdiv;
  48. +
  49. + /* calculate ch2_freq based on 25MHz reference clock */
  50. + ch2_freq = (25000000 / (pdiv * ch2_mdiv)) * ndiv;
  51. +
  52. + return ch2_freq;
  53. +}
  54. +
  55. static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev)
  56. {
  57. struct bcma_device *arm_core;
  58. void __iomem *dmu;
  59. + u32 ref_clk_rate, usb2ctl, usb_pll_ndiv, usb_pll_pdiv;
  60. arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9);
  61. if (!arm_core) {
  62. @@ -184,14 +220,29 @@ static void bcma_hcd_init_chip_arm_phy(s
  63. return;
  64. }
  65. + ref_clk_rate = bcma_hcd_usb_ref_clk_get_rate(dmu);
  66. +
  67. + usb2ctl = ioread32(dmu + BCMA_DMU_CRU_USB2_CONTROL);
  68. +
  69. + usb_pll_pdiv = usb2ctl;
  70. + usb_pll_pdiv &= BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK;
  71. + usb_pll_pdiv >>= BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT;
  72. + if (!usb_pll_pdiv)
  73. + usb_pll_pdiv = 1 << 3;
  74. +
  75. + /* Calculate ndiv based on a solid 1920 MHz that is for USB2 PHY */
  76. + usb_pll_ndiv = (1920000000 * usb_pll_pdiv) / ref_clk_rate;
  77. +
  78. /* Unlock DMU PLL settings */
  79. - iowrite32(0x0000ea68, dmu + 0x180);
  80. + iowrite32(0x0000ea68, dmu + BCMA_DMU_CRU_CLKSET_KEY);
  81. /* Write USB 2.0 PLL control setting */
  82. - iowrite32(0x00dd10c3, dmu + 0x164);
  83. + usb2ctl &= ~BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK;
  84. + usb2ctl |= usb_pll_ndiv << BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT;
  85. + iowrite32(usb2ctl, dmu + BCMA_DMU_CRU_USB2_CONTROL);
  86. /* Lock DMU PLL settings */
  87. - iowrite32(0x00000000, dmu + 0x180);
  88. + iowrite32(0x00000000, dmu + BCMA_DMU_CRU_CLKSET_KEY);
  89. iounmap(dmu);
  90. }
  91. @@ -219,15 +270,17 @@ static void bcma_hcd_init_chip_arm_hc(st
  92. static void bcma_hcd_init_chip_arm(struct bcma_device *dev)
  93. {
  94. + struct bcma_chipinfo *chipinfo = &dev->bus->chipinfo;
  95. +
  96. bcma_core_enable(dev, 0);
  97. - if (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4707 ||
  98. - dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM53018) {
  99. - if (dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4707 ||
  100. - dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4708)
  101. - bcma_hcd_init_chip_arm_phy(dev);
  102. + if (chipinfo->id == BCMA_CHIP_ID_BCM4707 ||
  103. + chipinfo->id == BCMA_CHIP_ID_BCM47094 ||
  104. + chipinfo->id == BCMA_CHIP_ID_BCM53018) {
  105. + bcma_hcd_init_chip_arm_phy(dev);
  106. - bcma_hcd_init_chip_arm_hc(dev);
  107. + if (1) /* TODO: Exclude BCM53573 */
  108. + bcma_hcd_init_chip_arm_hc(dev);
  109. }
  110. }