usb-tusb6010.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * linux/arch/arm/mach-omap2/usb-tusb6010.c
  4. *
  5. * Copyright (C) 2006 Nokia Corporation
  6. */
  7. #include <linux/err.h>
  8. #include <linux/string.h>
  9. #include <linux/types.h>
  10. #include <linux/errno.h>
  11. #include <linux/delay.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/gpio.h>
  14. #include <linux/export.h>
  15. #include <linux/platform_data/usb-omap.h>
  16. #include <linux/usb/musb.h>
  17. #include "gpmc.h"
  18. static u8 async_cs, sync_cs;
  19. static unsigned refclk_psec;
  20. static struct gpmc_settings tusb_async = {
  21. .wait_on_read = true,
  22. .wait_on_write = true,
  23. .device_width = GPMC_DEVWIDTH_16BIT,
  24. .mux_add_data = GPMC_MUX_AD,
  25. };
  26. static struct gpmc_settings tusb_sync = {
  27. .burst_read = true,
  28. .burst_write = true,
  29. .sync_read = true,
  30. .sync_write = true,
  31. .wait_on_read = true,
  32. .wait_on_write = true,
  33. .burst_len = GPMC_BURST_16,
  34. .device_width = GPMC_DEVWIDTH_16BIT,
  35. .mux_add_data = GPMC_MUX_AD,
  36. };
  37. /* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
  38. static int tusb_set_async_mode(unsigned sysclk_ps)
  39. {
  40. struct gpmc_device_timings dev_t;
  41. struct gpmc_timings t;
  42. unsigned t_acsnh_advnh = sysclk_ps + 3000;
  43. memset(&dev_t, 0, sizeof(dev_t));
  44. dev_t.t_ceasu = 8 * 1000;
  45. dev_t.t_avdasu = t_acsnh_advnh - 7000;
  46. dev_t.t_ce_avd = 1000;
  47. dev_t.t_avdp_r = t_acsnh_advnh;
  48. dev_t.t_oeasu = t_acsnh_advnh + 1000;
  49. dev_t.t_oe = 300;
  50. dev_t.t_cez_r = 7000;
  51. dev_t.t_cez_w = dev_t.t_cez_r;
  52. dev_t.t_avdp_w = t_acsnh_advnh;
  53. dev_t.t_weasu = t_acsnh_advnh + 1000;
  54. dev_t.t_wpl = 300;
  55. dev_t.cyc_aavdh_we = 1;
  56. gpmc_calc_timings(&t, &tusb_async, &dev_t);
  57. return gpmc_cs_set_timings(async_cs, &t, &tusb_async);
  58. }
  59. static int tusb_set_sync_mode(unsigned sysclk_ps)
  60. {
  61. struct gpmc_device_timings dev_t;
  62. struct gpmc_timings t;
  63. unsigned t_scsnh_advnh = sysclk_ps + 3000;
  64. memset(&dev_t, 0, sizeof(dev_t));
  65. dev_t.clk = 11100;
  66. dev_t.t_bacc = 1000;
  67. dev_t.t_ces = 1000;
  68. dev_t.t_ceasu = 8 * 1000;
  69. dev_t.t_avdasu = t_scsnh_advnh - 7000;
  70. dev_t.t_ce_avd = 1000;
  71. dev_t.t_avdp_r = t_scsnh_advnh;
  72. dev_t.cyc_aavdh_oe = 3;
  73. dev_t.cyc_oe = 5;
  74. dev_t.t_ce_rdyz = 7000;
  75. dev_t.t_avdp_w = t_scsnh_advnh;
  76. dev_t.cyc_aavdh_we = 3;
  77. dev_t.cyc_wpl = 6;
  78. gpmc_calc_timings(&t, &tusb_sync, &dev_t);
  79. return gpmc_cs_set_timings(sync_cs, &t, &tusb_sync);
  80. }
  81. /* tusb driver calls this when it changes the chip's clocking */
  82. int tusb6010_platform_retime(unsigned is_refclk)
  83. {
  84. static const char error[] =
  85. KERN_ERR "tusb6010 %s retime error %d\n";
  86. unsigned sysclk_ps;
  87. int status;
  88. if (!refclk_psec)
  89. return -ENODEV;
  90. sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
  91. status = tusb_set_async_mode(sysclk_ps);
  92. if (status < 0) {
  93. printk(error, "async", status);
  94. goto done;
  95. }
  96. status = tusb_set_sync_mode(sysclk_ps);
  97. if (status < 0)
  98. printk(error, "sync", status);
  99. done:
  100. return status;
  101. }
  102. EXPORT_SYMBOL_GPL(tusb6010_platform_retime);
  103. static struct resource tusb_resources[] = {
  104. /* Order is significant! The start/end fields
  105. * are updated during setup..
  106. */
  107. { /* Asynchronous access */
  108. .flags = IORESOURCE_MEM,
  109. },
  110. { /* Synchronous access */
  111. .flags = IORESOURCE_MEM,
  112. },
  113. { /* IRQ */
  114. .name = "mc",
  115. .flags = IORESOURCE_IRQ,
  116. },
  117. };
  118. static u64 tusb_dmamask = ~(u32)0;
  119. static struct platform_device tusb_device = {
  120. .name = "musb-tusb",
  121. .id = -1,
  122. .dev = {
  123. .dma_mask = &tusb_dmamask,
  124. .coherent_dma_mask = 0xffffffff,
  125. },
  126. .num_resources = ARRAY_SIZE(tusb_resources),
  127. .resource = tusb_resources,
  128. };
  129. /* this may be called only from board-*.c setup code */
  130. int __init
  131. tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
  132. unsigned ps_refclk, unsigned waitpin,
  133. unsigned async, unsigned sync,
  134. unsigned irq, unsigned dmachan)
  135. {
  136. int status;
  137. static char error[] __initdata =
  138. KERN_ERR "tusb6010 init error %d, %d\n";
  139. /* ASYNC region, primarily for PIO */
  140. status = gpmc_cs_request(async, SZ_16M, (unsigned long *)
  141. &tusb_resources[0].start);
  142. if (status < 0) {
  143. printk(error, 1, status);
  144. return status;
  145. }
  146. tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
  147. tusb_async.wait_pin = waitpin;
  148. async_cs = async;
  149. status = gpmc_cs_program_settings(async_cs, &tusb_async);
  150. if (status < 0)
  151. return status;
  152. /* SYNC region, primarily for DMA */
  153. status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
  154. &tusb_resources[1].start);
  155. if (status < 0) {
  156. printk(error, 2, status);
  157. return status;
  158. }
  159. tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
  160. tusb_sync.wait_pin = waitpin;
  161. sync_cs = sync;
  162. status = gpmc_cs_program_settings(sync_cs, &tusb_sync);
  163. if (status < 0)
  164. return status;
  165. /* IRQ */
  166. status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
  167. if (status < 0) {
  168. printk(error, 3, status);
  169. return status;
  170. }
  171. tusb_resources[2].start = gpio_to_irq(irq);
  172. /* set up memory timings ... can speed them up later */
  173. if (!ps_refclk) {
  174. printk(error, 4, status);
  175. return -ENODEV;
  176. }
  177. refclk_psec = ps_refclk;
  178. status = tusb6010_platform_retime(1);
  179. if (status < 0) {
  180. printk(error, 5, status);
  181. return status;
  182. }
  183. /* finish device setup ... */
  184. if (!data) {
  185. printk(error, 6, status);
  186. return -ENODEV;
  187. }
  188. tusb_device.dev.platform_data = data;
  189. /* so far so good ... register the device */
  190. status = platform_device_register(&tusb_device);
  191. if (status < 0) {
  192. printk(error, 7, status);
  193. return status;
  194. }
  195. return 0;
  196. }