mtk-phy-a60810.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. #include "mtk-phy.h"
  2. #ifdef CONFIG_A60810_SUPPORT
  3. #include "mtk-phy-a60810.h"
  4. PHY_INT32 phy_init_a60810(struct u3phy_info *info)
  5. {
  6. /* BANK 0x00 */
  7. /* for U2 hS eye diagram */
  8. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr1)
  9. , A60810_RG_USB20_TERM_VREF_SEL_OFST, A60810_RG_USB20_TERM_VREF_SEL,
  10. 0x05);
  11. /* for U2 hS eye diagram */
  12. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr1)
  13. , A60810_RG_USB20_VRT_VREF_SEL_OFST, A60810_RG_USB20_VRT_VREF_SEL, 0x05);
  14. /* for U2 sensititvity */
  15. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr6)
  16. , A60810_RG_USB20_SQTH_OFST, A60810_RG_USB20_SQTH, 0x04);
  17. /* BANK 0x10 */
  18. /* disable ssusb_p3_entry to work around resume from P3 bug */
  19. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->phyd_lfps0)
  20. , A60810_RG_SSUSB_P3_ENTRY_OFST, A60810_RG_SSUSB_P3_ENTRY, 0x00);
  21. /* force disable ssusb_p3_entry to work around resume from P3 bug */
  22. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->phyd_lfps0)
  23. , A60810_RG_SSUSB_P3_ENTRY_SEL_OFST, A60810_RG_SSUSB_P3_ENTRY_SEL, 0x01);
  24. /* BANK 0x40 */
  25. /* fine tune SSC delta1 to let SSC min average ~0ppm */
  26. U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg19)
  27. , A60810_RG_SSUSB_PLL_SSC_DELTA1_U3_OFST,
  28. A60810_RG_SSUSB_PLL_SSC_DELTA1_U3, 0x46);
  29. /* U3PhyWriteField32(((phys_addr_t)&info->u3phya_da_regs_a->reg19) */
  30. U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg21)
  31. , A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1H_OFST,
  32. A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1H, 0x40);
  33. /* fine tune SSC delta to let SSC min average ~0ppm */
  34. /* Fine tune SYSPLL to improve phase noise */
  35. /* I2C 60 0x08[01:00] 0x03 RW RG_SSUSB_PLL_BC_U3 */
  36. U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg4)
  37. , A60810_RG_SSUSB_PLL_BC_U3_OFST, A60810_RG_SSUSB_PLL_BC_U3, 0x3);
  38. /* I2C 60 0x08[12:10] 0x03 RW RG_SSUSB_PLL_DIVEN_U3 */
  39. U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg4)
  40. , A60810_RG_SSUSB_PLL_DIVEN_U3_OFST, A60810_RG_SSUSB_PLL_DIVEN_U3, 0x3);
  41. /* I2C 60 0x0C[03:00] 0x01 RW RG_SSUSB_PLL_IC_U3 */
  42. U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg5)
  43. , A60810_RG_SSUSB_PLL_IC_U3_OFST, A60810_RG_SSUSB_PLL_IC_U3, 0x1);
  44. /* I2C 60 0x0C[23:22] 0x01 RW RG_SSUSB_PLL_BR_U3 */
  45. U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg5)
  46. , A60810_RG_SSUSB_PLL_BR_U3_OFST, A60810_RG_SSUSB_PLL_BR_U3, 0x1);
  47. /* I2C 60 0x10[03:00] 0x01 RW RG_SSUSB_PLL_IR_U3 */
  48. U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg6)
  49. , A60810_RG_SSUSB_PLL_IR_U3_OFST, A60810_RG_SSUSB_PLL_IR_U3, 0x1);
  50. /* I2C 60 0x14[03:00] 0x0F RW RG_SSUSB_PLL_BP_U3 */
  51. U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg7)
  52. /* // , A60810_RG_SSUSB_PLL_BP_U3, A60810_RG_SSUSB_PLL_BP_U3, 0xF); */
  53. , A60810_RG_SSUSB_PLL_BP_U3_OFST, A60810_RG_SSUSB_PLL_BP_U3, 0x0f);
  54. /* BANK 0x60 */
  55. /* force xtal pwd mode enable */
  56. U3PhyWriteField32(((phys_addr_t) &info->spllc_regs_a->u3d_xtalctl_2)
  57. , A60810_RG_SSUSB_FORCE_XTAL_PWD_OFST, A60810_RG_SSUSB_FORCE_XTAL_PWD,
  58. 0x1);
  59. /* force bias pwd mode enable */
  60. U3PhyWriteField32(((phys_addr_t) &info->spllc_regs_a->u3d_xtalctl_2)
  61. , A60810_RG_SSUSB_FORCE_BIAS_PWD_OFST, A60810_RG_SSUSB_FORCE_BIAS_PWD,
  62. 0x1);
  63. /* force xtal pwd mode off to work around xtal drv de */
  64. U3PhyWriteField32(((phys_addr_t) &info->spllc_regs_a->u3d_xtalctl_2)
  65. , A60810_RG_SSUSB_XTAL_PWD_OFST, A60810_RG_SSUSB_XTAL_PWD, 0x0);
  66. /* force bias pwd mode off to work around xtal drv de */
  67. U3PhyWriteField32(((phys_addr_t) &info->spllc_regs_a->u3d_xtalctl_2)
  68. , A60810_RG_SSUSB_BIAS_PWD_OFST, A60810_RG_SSUSB_BIAS_PWD, 0x0);
  69. /* ******** test chip settings *********** */
  70. /* BANK 0x00 */
  71. /* slew rate setting */
  72. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5)
  73. , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL, 0x4);
  74. /* BANK 0x50 */
  75. /* Write Phase Scan Result */
  76. /* PIPE setting BANK5 */
  77. /* PIPE drv = 2 */
  78. U3PhyWriteReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 2, 0x10);
  79. /* PIPE phase */
  80. /* U3PhyWriteReg8(((phys_addr_t)&info->sifslv_chip_regs_a->gpio_ctla)+3, 0xdc); */
  81. U3PhyWriteReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 3, 0x24);
  82. return PHY_TRUE;
  83. }
  84. #define PHY_DRV_SHIFT 3
  85. #define PHY_PHASE_SHIFT 3
  86. #define PHY_PHASE_DRV_SHIFT 1
  87. PHY_INT32 phy_change_pipe_phase_a60810(struct u3phy_info *info, PHY_INT32 phy_drv,
  88. PHY_INT32 pipe_phase)
  89. {
  90. PHY_INT32 drv_reg_value;
  91. PHY_INT32 phase_reg_value;
  92. PHY_INT32 temp;
  93. pr_debug("phy_change_pipe_phase_a60810: %d", pipe_phase);
  94. drv_reg_value = phy_drv << PHY_DRV_SHIFT;
  95. phase_reg_value = (pipe_phase << PHY_PHASE_SHIFT) | (phy_drv << PHY_PHASE_DRV_SHIFT);
  96. temp = U3PhyReadReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 2);
  97. temp &= ~(0x3 << PHY_DRV_SHIFT);
  98. temp |= drv_reg_value;
  99. U3PhyWriteReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 2, temp);
  100. pr_debug("gpio_clta+2=0x%x\n",
  101. U3PhyReadReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 2));
  102. temp = U3PhyReadReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 3);
  103. temp &= ~((0x3 << PHY_PHASE_DRV_SHIFT) | (0x1f << PHY_PHASE_SHIFT));
  104. temp |= phase_reg_value;
  105. U3PhyWriteReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 3, temp);
  106. pr_debug("gpio_clta+3=0x%x\n",
  107. U3PhyReadReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 3));
  108. return PHY_TRUE;
  109. }
  110. /* -------------------------------------------------------- */
  111. /* Function : fgEyeScanHelper_CheckPtInRegion() */
  112. /* Description : Check if the test point is in a rectangle region. */
  113. /* If it is in the rectangle, also check if this point */
  114. /* is on the multiple of deltaX and deltaY. */
  115. /* Parameter : strucScanRegion * prEye - the region */
  116. /* BYTE bX */
  117. /* BYTE bY */
  118. /* Return : BYTE - TRUE : This point needs to be tested */
  119. /* FALSE: This point will be omitted */
  120. /* Note : First check within the rectangle. */
  121. /* Secondly, use modulous to check if the point will be tested. */
  122. /* -------------------------------------------------------- */
  123. static PHY_INT8 fgEyeScanHelper_CheckPtInRegion(struct strucScanRegion *prEye, PHY_INT8 bX,
  124. PHY_INT8 bY)
  125. {
  126. PHY_INT8 fgValid = true;
  127. /* / Be careful, the axis origin is on the TOP-LEFT corner. */
  128. /* / Therefore the top-left point has the minimum X and Y */
  129. /* / Botton-right point is the maximum X and Y */
  130. if ((prEye->bX_tl <= bX) && (bX <= prEye->bX_br)
  131. && (prEye->bY_tl <= bY) && (bY <= prEye->bX_br)) {
  132. /* With the region, now check whether or not the input test point is */
  133. /* on the multiples of X and Y */
  134. /* Do not have to worry about negative value, because we have already */
  135. /* check the input bX, and bY is within the region. */
  136. if (((bX - prEye->bX_tl) % (prEye->bDeltaX))
  137. || ((bY - prEye->bY_tl) % (prEye->bDeltaY))) {
  138. /* if the division will have remainder, that means */
  139. /* the input test point is on the multiples of X and Y */
  140. fgValid = false;
  141. } else {
  142. }
  143. } else {
  144. fgValid = false;
  145. }
  146. return fgValid;
  147. }
  148. /* -------------------------------------------------------- */
  149. /* Function : EyeScanHelper_RunTest() */
  150. /* Description : Enable the test, and wait til it is completed */
  151. /* Parameter : None */
  152. /* Return : None */
  153. /* Note : None */
  154. /* -------------------------------------------------------- */
  155. static void EyeScanHelper_RunTest(struct u3phy_info *info)
  156. {
  157. /* Disable the test */
  158. /* RG_SSUSB_RX_EYE_CNT_EN = 0 */
  159. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  160. , A60810_RG_SSUSB_EQ_EYE_CNT_EN_OFST, A60810_RG_SSUSB_EQ_EYE_CNT_EN, 0);
  161. /* Run the test */
  162. /* RG_SSUSB_RX_EYE_CNT_EN = 1 */
  163. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  164. , A60810_RG_SSUSB_EQ_EYE_CNT_EN_OFST, A60810_RG_SSUSB_EQ_EYE_CNT_EN, 1);
  165. /* Wait til it's done */
  166. /* RGS_SSUSB_RX_EYE_CNT_RDY */
  167. while (!U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->phya_rx_mon5)
  168. , A60810_RGS_SSUSB_EQ_EYE_CNT_RDY_OFST, A60810_RGS_SSUSB_EQ_EYE_CNT_RDY));
  169. }
  170. /* -------------------------------------------------------- */
  171. /* Function : fgEyeScanHelper_CalNextPoint() */
  172. /* Description : Calcualte the test point for the measurement */
  173. /* Parameter : None */
  174. /* Return : BOOL - TRUE : the next point is within the */
  175. /* boundaryof HW limit */
  176. /* FALSE: the next point is out of the HW limit */
  177. /* Note : The next point is obtained by calculating */
  178. /* from the bottom left of the region rectangle */
  179. /* and then scanning up until it reaches the upper */
  180. /* limit. At this time, the x will increment, and */
  181. /* start scanning downwards until the y hits the */
  182. /* zero. */
  183. /* -------------------------------------------------------- */
  184. static PHY_INT8 fgEyeScanHelper_CalNextPoint(void)
  185. {
  186. if (((_bYcurr == MAX_Y) && (_eScanDir == SCAN_DN))
  187. || ((_bYcurr == MIN_Y) && (_eScanDir == SCAN_UP))
  188. ) {
  189. /* / Reaches the limit of Y axis */
  190. /* / Increment X */
  191. _bXcurr++;
  192. _fgXChged = true;
  193. _eScanDir = (_eScanDir == SCAN_UP) ? SCAN_DN : SCAN_UP;
  194. if (_bXcurr > MAX_X)
  195. return false;
  196. } else {
  197. _bYcurr = (_eScanDir == SCAN_DN) ? _bYcurr + 1 : _bYcurr - 1;
  198. _fgXChged = false;
  199. }
  200. return PHY_TRUE;
  201. }
  202. PHY_INT32 eyescan_init_a60810(struct u3phy_info *info)
  203. {
  204. /* initial PHY setting */
  205. U3PhyWriteField32(((phys_addr_t) &info->u3phya_regs_a->reg9)
  206. , A60810_RG_SSUSB_CDR_EPEN_OFST, A60810_RG_SSUSB_CDR_EPEN, 1);
  207. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->phyd_mix3)
  208. , A60810_RG_SSUSB_FORCE_CDR_PI_PWD_OFST, A60810_RG_SSUSB_FORCE_CDR_PI_PWD,
  209. 1);
  210. return PHY_TRUE;
  211. }
  212. PHY_INT32 phy_eyescan_a60810(struct u3phy_info *info, PHY_INT32 x_t1, PHY_INT32 y_t1,
  213. PHY_INT32 x_br, PHY_INT32 y_br, PHY_INT32 delta_x, PHY_INT32 delta_y,
  214. PHY_INT32 eye_cnt, PHY_INT32 num_cnt, PHY_INT32 PI_cal_en,
  215. PHY_INT32 num_ignore_cnt)
  216. {
  217. PHY_INT32 cOfst = 0;
  218. PHY_UINT8 bIdxX = 0;
  219. PHY_UINT8 bIdxY = 0;
  220. PHY_UINT8 bIdxCycCnt = 0;
  221. PHY_INT8 fgValid;
  222. PHY_INT8 cX;
  223. PHY_INT8 cY;
  224. PHY_UINT8 bExtendCnt;
  225. PHY_INT8 isContinue;
  226. phys_addr_t wErr0 = 0, wErr1 = 0;
  227. _rEye1.bX_tl = x_t1;
  228. _rEye1.bY_tl = y_t1;
  229. _rEye1.bX_br = x_br;
  230. _rEye1.bY_br = y_br;
  231. _rEye1.bDeltaX = delta_x;
  232. _rEye1.bDeltaY = delta_y;
  233. _rEye2.bX_tl = x_t1;
  234. _rEye2.bY_tl = y_t1;
  235. _rEye2.bX_br = x_br;
  236. _rEye2.bY_br = y_br;
  237. _rEye2.bDeltaX = delta_x;
  238. _rEye2.bDeltaY = delta_y;
  239. _rTestCycle.wEyeCnt = eye_cnt;
  240. _rTestCycle.bNumOfEyeCnt = num_cnt;
  241. _rTestCycle.bNumOfIgnoreCnt = num_ignore_cnt;
  242. _rTestCycle.bPICalEn = PI_cal_en;
  243. _bXcurr = 0;
  244. _bYcurr = 0;
  245. _eScanDir = SCAN_DN;
  246. _fgXChged = false;
  247. pr_debug("x_t1: %x, y_t1: %x, x_br: %x, y_br: %x, delta_x: %x, delta_y: %x\n",
  248. x_t1, y_t1, x_br, y_br, delta_x, delta_y);
  249. pr_debug("eye_cnt: %x, num_cnt: %x, PI_cal_en: %x, num_ignore_cnt: %x\n",
  250. eye_cnt, num_cnt, PI_cal_en, num_ignore_cnt);
  251. /* force SIGDET to OFF */
  252. /* RG_SSUSB_RX_SIGDET_SEL = 1 */
  253. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0)
  254. , A60810_RG_SSUSB_RX_SIGDET_EN_SEL_OFST, A60810_RG_SSUSB_RX_SIGDET_EN_SEL,
  255. 1);
  256. /* RG_SSUSB_RX_SIGDET_EN = 0 */
  257. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0)
  258. , A60810_RG_SSUSB_RX_SIGDET_EN_OFST, A60810_RG_SSUSB_RX_SIGDET_EN, 0);
  259. /* RG_SSUSB_RX_SIGDET = 0 */
  260. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye1)
  261. , A60810_RG_SSUSB_EQ_SIGDET_OFST, A60810_RG_SSUSB_EQ_SIGDET, 0);
  262. /* RX_TRI_DET_EN to Disable */
  263. /* RG_SSUSB_RX_TRI_DET_EN = 0 */
  264. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq3)
  265. , A60810_RG_SSUSB_EQ_TRI_DET_EN_OFST, A60810_RG_SSUSB_EQ_TRI_DET_EN, 0);
  266. /* RG_SSUSB_EYE_MON_EN = 1 */
  267. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  268. , A60810_RG_SSUSB_EQ_EYE_MON_EN_OFST, A60810_RG_SSUSB_EQ_EYE_MON_EN, 1);
  269. /* RG_SSUSB_RX_EYE_XOFFSET = 0 */
  270. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  271. , A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST, A60810_RG_SSUSB_EQ_EYE_XOFFSET, 0);
  272. /* RG_SSUSB_RX_EYE0_Y = 0 */
  273. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  274. , A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y, 0);
  275. /* RG_SSUSB_RX_EYE1_Y = 0 */
  276. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  277. , A60810_RG_SSUSB_EQ_EYE1_Y_OFST, A60810_RG_SSUSB_EQ_EYE1_Y, 0);
  278. if (PI_cal_en) {
  279. /* PI Calibration */
  280. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0)
  281. , A60810_RG_SSUSB_RX_PI_CAL_EN_SEL_OFST,
  282. A60810_RG_SSUSB_RX_PI_CAL_EN_SEL, 1);
  283. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0)
  284. , A60810_RG_SSUSB_RX_PI_CAL_EN_OFST, A60810_RG_SSUSB_RX_PI_CAL_EN,
  285. 0);
  286. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0)
  287. , A60810_RG_SSUSB_RX_PI_CAL_EN_OFST, A60810_RG_SSUSB_RX_PI_CAL_EN,
  288. 1);
  289. DRV_UDELAY(20);
  290. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0)
  291. , A60810_RG_SSUSB_RX_PI_CAL_EN_OFST, A60810_RG_SSUSB_RX_PI_CAL_EN,
  292. 0);
  293. _bPIResult = U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->phya_rx_mon5)
  294. , A60810_RGS_SSUSB_EQ_PILPO_OFST,
  295. A60810_RGS_SSUSB_EQ_PILPO);
  296. pr_debug("PI result: %d\n", _bPIResult);
  297. }
  298. /* Read Initial DAC */
  299. /* Set CYCLE */
  300. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye3)
  301. , A60810_RG_SSUSB_EQ_EYE_CNT_OFST, A60810_RG_SSUSB_EQ_EYE_CNT, eye_cnt);
  302. /* Eye Monitor Feature */
  303. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye1)
  304. , A60810_RG_SSUSB_EQ_EYE_MASK_OFST, A60810_RG_SSUSB_EQ_EYE_MASK, 0x3ff);
  305. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  306. , A60810_RG_SSUSB_EQ_EYE_MON_EN_OFST, A60810_RG_SSUSB_EQ_EYE_MON_EN, 1);
  307. /* Move X,Y to the top-left corner */
  308. for (cOfst = 0; cOfst >= -64; cOfst--) {
  309. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  310. , A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST,
  311. A60810_RG_SSUSB_EQ_EYE_XOFFSET, cOfst);
  312. }
  313. for (cOfst = 0; cOfst < 64; cOfst++) {
  314. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  315. , A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y,
  316. cOfst);
  317. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  318. , A60810_RG_SSUSB_EQ_EYE1_Y_OFST, A60810_RG_SSUSB_EQ_EYE1_Y,
  319. cOfst);
  320. }
  321. /* ClearErrorResult */
  322. for (bIdxCycCnt = 0; bIdxCycCnt < CYCLE_COUNT_MAX; bIdxCycCnt++) {
  323. for (bIdxX = 0; bIdxX < ERRCNT_MAX; bIdxX++) {
  324. for (bIdxY = 0; bIdxY < ERRCNT_MAX; bIdxY++) {
  325. pwErrCnt0[bIdxCycCnt][bIdxX][bIdxY] = 0;
  326. pwErrCnt1[bIdxCycCnt][bIdxX][bIdxY] = 0;
  327. }
  328. }
  329. }
  330. isContinue = true;
  331. while (isContinue) {
  332. pr_debug("_bXcurr: %d, _bYcurr: %d\n", _bXcurr, _bYcurr);
  333. /* The point is within the boundary, then let's check if it is within */
  334. /* the testing region. */
  335. /* The point is only test-able if one of the eye region */
  336. /* includes this point. */
  337. fgValid = fgEyeScanHelper_CheckPtInRegion(&_rEye1, _bXcurr, _bYcurr)
  338. || fgEyeScanHelper_CheckPtInRegion(&_rEye2, _bXcurr, _bYcurr);
  339. /* Translate bX and bY to 2's complement from where the origin was on the */
  340. /* top left corner. */
  341. /* 0x40 and 0x3F needs a bit of thinking!!!! >"< */
  342. cX = (_bXcurr ^ 0x40);
  343. cY = (_bYcurr ^ 0x3F);
  344. /* Set X if necessary */
  345. if (_fgXChged == true) {
  346. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  347. , A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST,
  348. A60810_RG_SSUSB_EQ_EYE_XOFFSET, cX);
  349. }
  350. /* Set Y */
  351. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  352. , A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y, cY);
  353. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  354. , A60810_RG_SSUSB_EQ_EYE1_Y_OFST, A60810_RG_SSUSB_EQ_EYE1_Y, cY);
  355. /* / Test this point! */
  356. if (fgValid) {
  357. for (bExtendCnt = 0; bExtendCnt < num_ignore_cnt; bExtendCnt++) {
  358. /* run test */
  359. EyeScanHelper_RunTest(info);
  360. }
  361. for (bExtendCnt = 0; bExtendCnt < num_cnt; bExtendCnt++) {
  362. EyeScanHelper_RunTest(info);
  363. wErr0 =
  364. U3PhyReadField32(((phys_addr_t) &info->
  365. u3phyd_regs_a->phya_rx_mon3)
  366. ,
  367. A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_0_OFST,
  368. A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_0);
  369. wErr1 =
  370. U3PhyReadField32(((phys_addr_t) &info->
  371. u3phyd_regs_a->phya_rx_mon4)
  372. ,
  373. A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_1_OFST,
  374. A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_1);
  375. pwErrCnt0[bExtendCnt][_bXcurr][_bYcurr] = wErr0;
  376. pwErrCnt1[bExtendCnt][_bXcurr][_bYcurr] = wErr1;
  377. /* EyeScanHelper_GetResult(&_rRes.pwErrCnt0[bCnt], &_rRes.pwErrCnt1[bCnt]); */
  378. /* pr_debug("cnt[%d] cur_x,y [0x%x][0x%x], cX,cY [0x%x][0x%x], ErrCnt[%d][%d]\n",
  379. bExtendCnt, _bXcurr, _bYcurr, cX, cY,
  380. pwErrCnt0[bExtendCnt][_bXcurr][_bYcurr],
  381. pwErrCnt1[bExtendCnt][_bXcurr][_bYcurr]); */
  382. }
  383. /* pr_debug("cur_x,y [0x%x][0x%x], cX,cY [0x%x][0x%x], ErrCnt[%d][%d]\n",
  384. _bXcurr, _bYcurr, cX, cY, pwErrCnt0[0][_bXcurr][_bYcurr],
  385. pwErrCnt1[0][_bXcurr][_bYcurr]); */
  386. } else {
  387. }
  388. if (fgEyeScanHelper_CalNextPoint() == false) {
  389. #if 1
  390. pr_debug("Xcurr [0x%x] Ycurr [0x%x]\n", _bXcurr, _bYcurr);
  391. pr_debug("XcurrREG [0x%x] YcurrREG [0x%x]\n", cX, cY);
  392. #endif
  393. pr_debug("end of eye scan\n");
  394. isContinue = false;
  395. }
  396. }
  397. pr_debug("CurX [0x%x] CurY [0x%x]\n",
  398. U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0),
  399. A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST,
  400. A60810_RG_SSUSB_EQ_EYE_XOFFSET)
  401. , U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0),
  402. A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y));
  403. /* Move X,Y to the top-left corner */
  404. for (cOfst = 63; cOfst >= 0; cOfst--) {
  405. /* RG_SSUSB_RX_EYE_XOFFSET */
  406. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  407. , A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST,
  408. A60810_RG_SSUSB_EQ_EYE_XOFFSET, cOfst);
  409. }
  410. for (cOfst = 63; cOfst >= 0; cOfst--) {
  411. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  412. , A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y,
  413. cOfst);
  414. U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0)
  415. , A60810_RG_SSUSB_EQ_EYE1_Y_OFST, A60810_RG_SSUSB_EQ_EYE1_Y,
  416. cOfst);
  417. }
  418. pr_debug("CurX [0x%x] CurY [0x%x]\n",
  419. U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0),
  420. A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST,
  421. A60810_RG_SSUSB_EQ_EYE_XOFFSET)
  422. , U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0),
  423. A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y));
  424. pr_debug("PI result: %d\n", _bPIResult);
  425. pr_debug("pwErrCnt0 addr: %p\n", pwErrCnt0);
  426. pr_debug("pwErrCnt1 addr: %p\n", pwErrCnt1);
  427. return PHY_TRUE;
  428. }
  429. PHY_INT32 u2_connect_a60810(struct u3phy_info *info)
  430. {
  431. /* for better LPM BESL value */
  432. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->u2phydcr1)
  433. , A60810_RG_USB20_SW_PLLMODE_OFST, A60810_RG_USB20_SW_PLLMODE, 0x1);
  434. return PHY_TRUE;
  435. }
  436. PHY_INT32 u2_disconnect_a60810(struct u3phy_info *info)
  437. {
  438. /* for better LPM BESL value */
  439. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->u2phydcr1)
  440. , A60810_RG_USB20_SW_PLLMODE_OFST, A60810_RG_USB20_SW_PLLMODE, 0x0);
  441. return PHY_TRUE;
  442. }
  443. PHY_INT32 u2_save_cur_en_a60810(struct u3phy_info *info)
  444. {
  445. return PHY_TRUE;
  446. }
  447. PHY_INT32 u2_save_cur_re_a60810(struct u3phy_info *info)
  448. {
  449. return PHY_TRUE;
  450. }
  451. PHY_INT32 u2_slew_rate_calibration_a60810(struct u3phy_info *info)
  452. {
  453. PHY_INT32 i = 0;
  454. PHY_INT32 fgRet = 0;
  455. PHY_INT32 u4FmOut = 0;
  456. PHY_INT32 u4Tmp = 0;
  457. /* => RG_USB20_HSTX_SRCAL_EN = 1 */
  458. /* enable HS TX SR calibration */
  459. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5)
  460. , A60810_RG_USB20_HSTX_SRCAL_EN_OFST, A60810_RG_USB20_HSTX_SRCAL_EN, 1);
  461. DRV_MSLEEP(1);
  462. /* => RG_FRCK_EN = 1 */
  463. /* Enable free run clock */
  464. U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmmonr1)
  465. , A60810_RG_FRCK_EN_OFST, A60810_RG_FRCK_EN, 0x1);
  466. /* => RG_CYCLECNT = 0x400 */
  467. /* Setting cyclecnt = 0x400 */
  468. U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmcr0)
  469. , A60810_RG_CYCLECNT_OFST, A60810_RG_CYCLECNT, 0x400);
  470. /* => RG_FREQDET_EN = 1 */
  471. /* Enable frequency meter */
  472. U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmcr0)
  473. , A60810_RG_FREQDET_EN_OFST, A60810_RG_FREQDET_EN, 0x1);
  474. /* wait for FM detection done, set 10ms timeout */
  475. for (i = 0; i < 10; i++) {
  476. /* => u4FmOut = USB_FM_OUT */
  477. /* read FM_OUT */
  478. u4FmOut = U3PhyReadReg32(((phys_addr_t) &info->sifslv_fm_regs_a->fmmonr0));
  479. pr_debug("FM_OUT value: u4FmOut = %d(0x%08X)\n", u4FmOut, u4FmOut);
  480. /* check if FM detection done */
  481. if (u4FmOut != 0) {
  482. fgRet = 0;
  483. pr_debug("FM detection done! loop = %d\n", i);
  484. break;
  485. }
  486. fgRet = 1;
  487. DRV_MSLEEP(1);
  488. }
  489. /* => RG_FREQDET_EN = 0 */
  490. /* disable frequency meter */
  491. U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmcr0)
  492. , A60810_RG_FREQDET_EN_OFST, A60810_RG_FREQDET_EN, 0);
  493. /* => RG_FRCK_EN = 0 */
  494. /* disable free run clock */
  495. U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmmonr1)
  496. , A60810_RG_FRCK_EN_OFST, A60810_RG_FRCK_EN, 0);
  497. /* => RG_USB20_HSTX_SRCAL_EN = 0 */
  498. /* disable HS TX SR calibration */
  499. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5)
  500. , A60810_RG_USB20_HSTX_SRCAL_EN_OFST, A60810_RG_USB20_HSTX_SRCAL_EN, 0);
  501. DRV_MSLEEP(1);
  502. if (u4FmOut == 0) {
  503. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5)
  504. , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL,
  505. 0x4);
  506. fgRet = 1;
  507. } else {
  508. /* set reg = (1024/FM_OUT) * REF_CK * U2_SR_COEF_A60810 / 1000 (round to the nearest digits) */
  509. u4Tmp = (((1024 * REF_CK * U2_SR_COEF_A60810) / u4FmOut) + 500) / 1000;
  510. pr_debug("SR calibration value u1SrCalVal = %d\n", (PHY_UINT8) u4Tmp);
  511. U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5)
  512. , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL,
  513. u4Tmp);
  514. }
  515. return fgRet;
  516. }
  517. #endif