alchemy-common.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * USB block power/access management abstraction.
  3. *
  4. * Au1000+: The OHCI block control register is at the far end of the OHCI memory
  5. * area. Au1550 has OHCI on different base address. No need to handle
  6. * UDC here.
  7. * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG
  8. * as well as the PHY for EHCI and UDC.
  9. *
  10. */
  11. #include <linux/init.h>
  12. #include <linux/io.h>
  13. #include <linux/module.h>
  14. #include <linux/spinlock.h>
  15. #include <linux/syscore_ops.h>
  16. #include <asm/mach-au1x00/au1000.h>
  17. /* control register offsets */
  18. #define AU1000_OHCICFG 0x7fffc
  19. #define AU1550_OHCICFG 0x07ffc
  20. #define AU1200_USBCFG 0x04
  21. /* Au1000 USB block config bits */
  22. #define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */
  23. #define USBHEN_CE (1 << 3) /* OHCI block clock enable */
  24. #define USBHEN_E (1 << 2) /* OHCI block enable */
  25. #define USBHEN_C (1 << 1) /* OHCI block coherency bit */
  26. #define USBHEN_BE (1 << 0) /* OHCI Big-Endian */
  27. /* Au1200 USB config bits */
  28. #define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */
  29. #define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */
  30. #define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */
  31. #define USBCFG_SSD (1 << 23) /* serial short detect en */
  32. #define USBCFG_PPE (1 << 19) /* HS PHY PLL */
  33. #define USBCFG_UCE (1 << 18) /* UDC clock enable */
  34. #define USBCFG_ECE (1 << 17) /* EHCI clock enable */
  35. #define USBCFG_OCE (1 << 16) /* OHCI clock enable */
  36. #define USBCFG_FLA(x) (((x) & 0x3f) << 8)
  37. #define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */
  38. #define USBCFG_GME (1 << 6) /* OTG mem access */
  39. #define USBCFG_DBE (1 << 5) /* UDC busmaster enable */
  40. #define USBCFG_DME (1 << 4) /* UDC mem enable */
  41. #define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */
  42. #define USBCFG_EME (1 << 2) /* EHCI mem enable */
  43. #define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */
  44. #define USBCFG_OME (1 << 0) /* OHCI mem enable */
  45. #define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\
  46. USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \
  47. USBCFG_GME | USBCFG_DBE | USBCFG_DME | \
  48. USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \
  49. USBCFG_OME)
  50. static DEFINE_SPINLOCK(alchemy_usb_lock);
  51. static inline void __au1200_ohci_control(void __iomem *base, int enable)
  52. {
  53. unsigned long r = __raw_readl(base + AU1200_USBCFG);
  54. if (enable) {
  55. __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG);
  56. wmb();
  57. udelay(2000);
  58. } else {
  59. __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG);
  60. wmb();
  61. udelay(1000);
  62. }
  63. }
  64. static inline void __au1200_ehci_control(void __iomem *base, int enable)
  65. {
  66. unsigned long r = __raw_readl(base + AU1200_USBCFG);
  67. if (enable) {
  68. __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG);
  69. wmb();
  70. udelay(1000);
  71. } else {
  72. if (!(r & USBCFG_UCE)) /* UDC also off? */
  73. r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
  74. __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG);
  75. wmb();
  76. udelay(1000);
  77. }
  78. }
  79. static inline void __au1200_udc_control(void __iomem *base, int enable)
  80. {
  81. unsigned long r = __raw_readl(base + AU1200_USBCFG);
  82. if (enable) {
  83. __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG);
  84. wmb();
  85. } else {
  86. if (!(r & USBCFG_ECE)) /* EHCI also off? */
  87. r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
  88. __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG);
  89. wmb();
  90. }
  91. }
  92. static inline int au1200_coherency_bug(void)
  93. {
  94. #if defined(CONFIG_DMA_COHERENT)
  95. /* Au1200 AB USB does not support coherent memory */
  96. if (!(read_c0_prid() & 0xff)) {
  97. printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n");
  98. printk(KERN_INFO "Au1200 USB: update your board or re-configure"
  99. " the kernel\n");
  100. return -ENODEV;
  101. }
  102. #endif
  103. return 0;
  104. }
  105. static inline int au1200_usb_control(int block, int enable)
  106. {
  107. void __iomem *base =
  108. (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
  109. int ret = 0;
  110. switch (block) {
  111. case ALCHEMY_USB_OHCI0:
  112. ret = au1200_coherency_bug();
  113. if (ret && enable)
  114. goto out;
  115. __au1200_ohci_control(base, enable);
  116. break;
  117. case ALCHEMY_USB_UDC0:
  118. __au1200_udc_control(base, enable);
  119. break;
  120. case ALCHEMY_USB_EHCI0:
  121. ret = au1200_coherency_bug();
  122. if (ret && enable)
  123. goto out;
  124. __au1200_ehci_control(base, enable);
  125. break;
  126. default:
  127. ret = -ENODEV;
  128. }
  129. out:
  130. return ret;
  131. }
  132. /* initialize USB block(s) to a known working state */
  133. static inline void au1200_usb_init(void)
  134. {
  135. void __iomem *base =
  136. (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
  137. __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG);
  138. wmb();
  139. udelay(1000);
  140. }
  141. static inline void au1000_usb_init(unsigned long rb, int reg)
  142. {
  143. void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg);
  144. unsigned long r = __raw_readl(base);
  145. #if defined(__BIG_ENDIAN)
  146. r |= USBHEN_BE;
  147. #endif
  148. r |= USBHEN_C;
  149. __raw_writel(r, base);
  150. wmb();
  151. udelay(1000);
  152. }
  153. static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
  154. {
  155. void __iomem *base = (void __iomem *)KSEG1ADDR(rb);
  156. unsigned long r = __raw_readl(base + creg);
  157. if (enable) {
  158. __raw_writel(r | USBHEN_CE, base + creg);
  159. wmb();
  160. udelay(1000);
  161. __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg);
  162. wmb();
  163. udelay(1000);
  164. /* wait for reset complete (read reg twice: au1500 erratum) */
  165. while (__raw_readl(base + creg),
  166. !(__raw_readl(base + creg) & USBHEN_RD))
  167. udelay(1000);
  168. } else {
  169. __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg);
  170. wmb();
  171. }
  172. }
  173. static inline int au1000_usb_control(int block, int enable, unsigned long rb,
  174. int creg)
  175. {
  176. int ret = 0;
  177. switch (block) {
  178. case ALCHEMY_USB_OHCI0:
  179. __au1xx0_ohci_control(enable, rb, creg);
  180. break;
  181. default:
  182. ret = -ENODEV;
  183. }
  184. return ret;
  185. }
  186. /*
  187. * alchemy_usb_control - control Alchemy on-chip USB blocks
  188. * @block: USB block to target
  189. * @enable: set 1 to enable a block, 0 to disable
  190. */
  191. int alchemy_usb_control(int block, int enable)
  192. {
  193. unsigned long flags;
  194. int ret;
  195. spin_lock_irqsave(&alchemy_usb_lock, flags);
  196. switch (alchemy_get_cputype()) {
  197. case ALCHEMY_CPU_AU1000:
  198. case ALCHEMY_CPU_AU1500:
  199. case ALCHEMY_CPU_AU1100:
  200. ret = au1000_usb_control(block, enable,
  201. AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
  202. break;
  203. case ALCHEMY_CPU_AU1550:
  204. ret = au1000_usb_control(block, enable,
  205. AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
  206. break;
  207. case ALCHEMY_CPU_AU1200:
  208. ret = au1200_usb_control(block, enable);
  209. break;
  210. default:
  211. ret = -ENODEV;
  212. }
  213. spin_unlock_irqrestore(&alchemy_usb_lock, flags);
  214. return ret;
  215. }
  216. EXPORT_SYMBOL_GPL(alchemy_usb_control);
  217. static unsigned long alchemy_usb_pmdata[2];
  218. static void au1000_usb_pm(unsigned long br, int creg, int susp)
  219. {
  220. void __iomem *base = (void __iomem *)KSEG1ADDR(br);
  221. if (susp) {
  222. alchemy_usb_pmdata[0] = __raw_readl(base + creg);
  223. /* There appears to be some undocumented reset register.... */
  224. __raw_writel(0, base + 0x04);
  225. wmb();
  226. __raw_writel(0, base + creg);
  227. wmb();
  228. } else {
  229. __raw_writel(alchemy_usb_pmdata[0], base + creg);
  230. wmb();
  231. }
  232. }
  233. static void au1200_usb_pm(int susp)
  234. {
  235. void __iomem *base =
  236. (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR);
  237. if (susp) {
  238. /* save OTG_CAP/MUX registers which indicate port routing */
  239. /* FIXME: write an OTG driver to do that */
  240. alchemy_usb_pmdata[0] = __raw_readl(base + 0x00);
  241. alchemy_usb_pmdata[1] = __raw_readl(base + 0x04);
  242. } else {
  243. /* restore access to all MMIO areas */
  244. au1200_usb_init();
  245. /* restore OTG_CAP/MUX registers */
  246. __raw_writel(alchemy_usb_pmdata[0], base + 0x00);
  247. __raw_writel(alchemy_usb_pmdata[1], base + 0x04);
  248. wmb();
  249. }
  250. }
  251. static void alchemy_usb_pm(int susp)
  252. {
  253. switch (alchemy_get_cputype()) {
  254. case ALCHEMY_CPU_AU1000:
  255. case ALCHEMY_CPU_AU1500:
  256. case ALCHEMY_CPU_AU1100:
  257. au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp);
  258. break;
  259. case ALCHEMY_CPU_AU1550:
  260. au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp);
  261. break;
  262. case ALCHEMY_CPU_AU1200:
  263. au1200_usb_pm(susp);
  264. break;
  265. }
  266. }
  267. static int alchemy_usb_suspend(void)
  268. {
  269. alchemy_usb_pm(1);
  270. return 0;
  271. }
  272. static void alchemy_usb_resume(void)
  273. {
  274. alchemy_usb_pm(0);
  275. }
  276. static struct syscore_ops alchemy_usb_pm_ops = {
  277. .suspend = alchemy_usb_suspend,
  278. .resume = alchemy_usb_resume,
  279. };
  280. static int __init alchemy_usb_init(void)
  281. {
  282. switch (alchemy_get_cputype()) {
  283. case ALCHEMY_CPU_AU1000:
  284. case ALCHEMY_CPU_AU1500:
  285. case ALCHEMY_CPU_AU1100:
  286. au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
  287. break;
  288. case ALCHEMY_CPU_AU1550:
  289. au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
  290. break;
  291. case ALCHEMY_CPU_AU1200:
  292. au1200_usb_init();
  293. break;
  294. }
  295. register_syscore_ops(&alchemy_usb_pm_ops);
  296. return 0;
  297. }
  298. arch_initcall(alchemy_usb_init);