usbclock.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. *
  3. * arch/arm/mach-meson6/usbclock.c
  4. *
  5. * Copyright (C) 2011 AMLOGIC, INC.
  6. *
  7. * by Victor Wan 2012.2.14 @Santa Clara, CA
  8. *
  9. * License terms: GNU General Public License (GPL) version 2
  10. * Platform machine definition.
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/mm.h>
  15. #include <linux/sched.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/ioport.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/io.h>
  20. #include <linux/dma-mapping.h>
  21. #include <asm/mach-types.h>
  22. #include <asm/mach/arch.h>
  23. #include <asm/delay.h>
  24. #include <plat/platform.h>
  25. #include <plat/lm.h>
  26. #include <plat/regops.h>
  27. #include <mach/hardware.h>
  28. #include <mach/memory.h>
  29. #include <mach/clock.h>
  30. #include <mach/reg_addr.h>
  31. #include <mach/usbclock.h>
  32. /*
  33. * M chip USB clock setting
  34. */
  35. /*
  36. * Clock source name index must sync with chip's spec
  37. * M1/M2/M3/M6 are different!
  38. * This is only for M6
  39. */
  40. static const char * clock_src_name[] = {
  41. "XTAL input",
  42. "XTAL input divided by 2",
  43. "DDR PLL",
  44. "MPLL OUT0"
  45. "MPLL OUT1",
  46. "MPLL OUT2",
  47. "FCLK / 2",
  48. "FCLK / 3"
  49. };
  50. #if 1
  51. static int init_count = 0;
  52. int set_usb_phy_clk(struct lm_device * plmdev,int is_enable)
  53. {
  54. int port_idx,i;
  55. usb_peri_reg_t * peri_a,* peri_b,*peri;
  56. usb_config_data_t config;
  57. usb_ctrl_data_t control;
  58. usb_dbg_uart_data_t uart;
  59. int clk_sel,clk_div,clk_src;
  60. int time_dly = 500; //usec
  61. if(!plmdev)
  62. return -1;
  63. port_idx = plmdev->param.usb.port_idx;
  64. if(port_idx < 0 || port_idx > 1)
  65. return -1;
  66. peri_a = (usb_peri_reg_t *)P_USB_ADDR0;
  67. peri_b = (usb_peri_reg_t *)P_USB_ADDR8;
  68. if(port_idx == USB_PORT_IDX_A)
  69. peri = peri_a;
  70. else
  71. peri = peri_b;
  72. if(is_enable){
  73. if(!init_count){
  74. init_count++;
  75. aml_set_reg32_bits(P_RESET1_REGISTER, 1, 2, 1);
  76. for(i = 0; i < 1000; i++)
  77. udelay(time_dly);
  78. clk_sel = plmdev->clock.sel;
  79. clk_div = plmdev->clock.div;
  80. clk_src = plmdev->clock.src;
  81. config.d32 = peri_a->config;
  82. config.b.clk_sel = clk_sel;
  83. config.b.clk_div = clk_div;
  84. config.b.clk_en = 1;
  85. peri_a->config = config.d32;
  86. config.d32 = peri_b->config;
  87. config.b.clk_sel = clk_sel;
  88. config.b.clk_div = clk_div;
  89. config.b.clk_en = 1;
  90. peri_b->config = config.d32;
  91. printk(KERN_NOTICE"USB (%d) use clock source: %s\n",port_idx,clock_src_name[clk_sel]);
  92. control.d32 = peri_b->ctrl;
  93. control.b.fsel = 2; /* PHY default is 24M (5), change to 12M (2) */
  94. control.b.por = 1;
  95. peri_b->ctrl = control.d32;
  96. control.d32 = peri_a->ctrl;
  97. control.b.fsel = 2; /* PHY default is 24M (5), change to 12M (2) */
  98. control.b.por = 1;
  99. peri_a->ctrl = control.d32;
  100. udelay(time_dly);
  101. control.b.por = 0;
  102. peri_a->ctrl = control.d32;
  103. udelay(time_dly);
  104. /* read back clock detected flag*/
  105. control.d32 = peri_a->ctrl;
  106. if(!control.b.clk_detected){
  107. printk(KERN_ERR"USB (%d) PHY Clock not detected!\n",0);
  108. }
  109. control.d32 = peri_b->ctrl;
  110. if(!control.b.clk_detected){
  111. printk(KERN_ERR"USB (%d) PHY Clock not detected!\n",1);
  112. }
  113. }
  114. uart.d32 = peri->dbg_uart;
  115. uart.b.set_iddq = 0;
  116. peri->dbg_uart = uart.d32;
  117. }else{
  118. init_count--;
  119. uart.d32 = peri->dbg_uart;
  120. uart.b.set_iddq = 1;
  121. peri->dbg_uart = uart.d32;
  122. }
  123. dmb();
  124. return 0;
  125. }
  126. #else
  127. static int reset_count = 0;
  128. int set_usb_phy_clk(struct lm_device * plmdev,int is_enable)
  129. {
  130. int port_idx;
  131. usb_peri_reg_t * peri;
  132. usb_config_data_t config;
  133. usb_ctrl_data_t control;
  134. int clk_sel,clk_div,clk_src;
  135. int time_dly = 500; //usec
  136. if(!plmdev)
  137. return -1;
  138. port_idx = plmdev->param.usb.port_idx;
  139. if(port_idx < 0 || port_idx > 1)
  140. return -1;
  141. peri = (usb_peri_reg_t *)plmdev->param.usb.phy_tune_reg;
  142. printk(KERN_NOTICE"USB (%d) peri reg base: %x\n",port_idx,(uint32_t)peri);
  143. if(is_enable){
  144. clk_sel = plmdev->clock.sel;
  145. clk_div = plmdev->clock.div;
  146. clk_src = plmdev->clock.src;
  147. config.d32 = peri->config;
  148. config.b.clk_sel = clk_sel;
  149. config.b.clk_div = clk_div;
  150. config.b.clk_en = 1;
  151. peri->config = config.d32;
  152. printk(KERN_NOTICE"USB (%d) use clock source: %s\n",port_idx,clock_src_name[clk_sel]);
  153. control.d32 = peri->ctrl;
  154. control.b.fsel = 2; /* PHY default is 24M (5), change to 12M (2) */
  155. control.b.por = 1;
  156. peri->ctrl = control.d32;
  157. udelay(time_dly);
  158. control.b.por = 0;
  159. peri->ctrl = control.d32;
  160. udelay(time_dly);
  161. /* read back clock detected flag*/
  162. control.d32 = peri->ctrl;
  163. if(!control.b.clk_detected){
  164. printk(KERN_ERR"USB (%d) PHY Clock not detected!\n",port_idx);
  165. return -1;
  166. }
  167. }else{
  168. if(reset_count)
  169. reset_count--;
  170. config.d32 = peri->config;
  171. config.b.clk_en = 0;
  172. peri->config = config.d32;
  173. control.d32 = peri->ctrl;
  174. control.b.por = 1;
  175. peri->ctrl = control.d32;
  176. }
  177. dmb();
  178. return 0;
  179. }
  180. #endif
  181. EXPORT_SYMBOL(set_usb_phy_clk);