ehci-oxnas.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * drivers/usb/host/ehci-oxnas.c
  3. *
  4. * Tzachi Perelstein <tzachi@marvell.com>
  5. *
  6. * This file is licensed under the terms of the GNU General Public
  7. * License version 2. This program is licensed "as is" without any
  8. * warranty of any kind, whether express or implied.
  9. */
  10. #include <common.h>
  11. #include <asm/arch/hardware.h>
  12. #include <asm/arch/sysctl.h>
  13. #include <asm/arch/clock.h>
  14. #include "ehci.h"
  15. static struct ehci_hcor *ghcor;
  16. static int start_oxnas_usb_ehci(void)
  17. {
  18. #ifdef CONFIG_USB_PLLB_CLK
  19. reset_block(SYS_CTRL_RST_PLLB, 0);
  20. enable_clock(SYS_CTRL_CLK_REF600);
  21. writel((1 << PLLB_ENSAT) | (1 << PLLB_OUTDIV) | (2 << PLLB_REFDIV),
  22. SEC_CTRL_PLLB_CTRL0);
  23. /* 600MHz pllb divider for 12MHz */
  24. writel(PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0), SEC_CTRL_PLLB_DIV_CTRL);
  25. #else
  26. /* ref 300 divider for 12MHz */
  27. writel(REF300_DIV_INT(25) | REF300_DIV_FRAC(0), SYS_CTRL_REF300_DIV);
  28. #endif
  29. /* Ensure the USB block is properly reset */
  30. reset_block(SYS_CTRL_RST_USBHS, 1);
  31. reset_block(SYS_CTRL_RST_USBHS, 0);
  32. reset_block(SYS_CTRL_RST_USBHSPHYA, 1);
  33. reset_block(SYS_CTRL_RST_USBHSPHYA, 0);
  34. reset_block(SYS_CTRL_RST_USBHSPHYB, 1);
  35. reset_block(SYS_CTRL_RST_USBHSPHYB, 0);
  36. /* Force the high speed clock to be generated all the time, via serial
  37. programming of the USB HS PHY */
  38. writel((2UL << USBHSPHY_TEST_ADD) |
  39. (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
  40. writel((1UL << USBHSPHY_TEST_CLK) |
  41. (2UL << USBHSPHY_TEST_ADD) |
  42. (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
  43. writel((0xfUL << USBHSPHY_TEST_ADD) |
  44. (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
  45. writel((1UL << USBHSPHY_TEST_CLK) |
  46. (0xfUL << USBHSPHY_TEST_ADD) |
  47. (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
  48. #ifdef CONFIG_USB_PLLB_CLK /* use pllb clock */
  49. writel(USB_CLK_INTERNAL | USB_INT_CLK_PLLB, SYS_CTRL_USB_CTRL);
  50. #else /* use ref300 derived clock */
  51. writel(USB_CLK_INTERNAL | USB_INT_CLK_REF300, SYS_CTRL_USB_CTRL);
  52. #endif
  53. /* Enable the clock to the USB block */
  54. enable_clock(SYS_CTRL_CLK_USBHS);
  55. return 0;
  56. }
  57. int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
  58. struct ehci_hcor **hcor)
  59. {
  60. start_oxnas_usb_ehci();
  61. *hccr = (struct ehci_hccr *)(USB_HOST_BASE + 0x100);
  62. *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
  63. HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
  64. ghcor = *hcor;
  65. return 0;
  66. }
  67. int ehci_hcd_stop(int index)
  68. {
  69. reset_block(SYS_CTRL_RST_USBHS, 1);
  70. disable_clock(SYS_CTRL_CLK_USBHS);
  71. return 0;
  72. }
  73. extern void __ehci_set_usbmode(int index);
  74. void ehci_set_usbmode(int index)
  75. {
  76. #define or_txttfill_tuning _reserved_1_[0]
  77. u32 tmp;
  78. __ehci_set_usbmode(index);
  79. tmp = ehci_readl(&ghcor->or_txfilltuning);
  80. tmp &= ~0x00ff0000;
  81. tmp |= 0x003f0000; /* set burst pre load count to 0x40 (63 * 4 bytes) */
  82. tmp |= 0x16; /* set sheduler overhead to 22 * 1.267us (HS) or 22 * 6.33us (FS/LS)*/
  83. ehci_writel(&ghcor->or_txfilltuning, tmp);
  84. tmp = ehci_readl(&ghcor->or_txttfill_tuning);
  85. tmp |= 0x2; /* set sheduler overhead to 2 * 6.333us */
  86. ehci_writel(&ghcor->or_txttfill_tuning, tmp);
  87. }