mtk-phy-7621.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. #include "mtk-phy.h"
  2. #ifdef CONFIG_PROJECT_7621
  3. #include "mtk-phy-7621.h"
  4. //not used on SoC
  5. PHY_INT32 phy_init(struct u3phy_info *info){
  6. return PHY_TRUE;
  7. }
  8. //not used on SoC
  9. PHY_INT32 phy_change_pipe_phase(struct u3phy_info *info, PHY_INT32 phy_drv, PHY_INT32 pipe_phase){
  10. return PHY_TRUE;
  11. }
  12. //--------------------------------------------------------
  13. // Function : fgEyeScanHelper_CheckPtInRegion()
  14. // Description : Check if the test point is in a rectangle region.
  15. // If it is in the rectangle, also check if this point
  16. // is on the multiple of deltaX and deltaY.
  17. // Parameter : strucScanRegion * prEye - the region
  18. // BYTE bX
  19. // BYTE bY
  20. // Return : BYTE - TRUE : This point needs to be tested
  21. // FALSE: This point will be omitted
  22. // Note : First check within the rectangle.
  23. // Secondly, use modulous to check if the point will be tested.
  24. //--------------------------------------------------------
  25. static PHY_INT8 fgEyeScanHelper_CheckPtInRegion(struct strucScanRegion * prEye, PHY_INT8 bX, PHY_INT8 bY)
  26. {
  27. PHY_INT8 fgValid = true;
  28. /// Be careful, the axis origin is on the TOP-LEFT corner.
  29. /// Therefore the top-left point has the minimum X and Y
  30. /// Botton-right point is the maximum X and Y
  31. if ( (prEye->bX_tl <= bX) && (bX <= prEye->bX_br)
  32. && (prEye->bY_tl <= bY) && (bY <= prEye->bX_br))
  33. {
  34. // With the region, now check whether or not the input test point is
  35. // on the multiples of X and Y
  36. // Do not have to worry about negative value, because we have already
  37. // check the input bX, and bY is within the region.
  38. if ( ((bX - prEye->bX_tl) % (prEye->bDeltaX))
  39. || ((bY - prEye->bY_tl) % (prEye->bDeltaY)) )
  40. {
  41. // if the division will have remainder, that means
  42. // the input test point is on the multiples of X and Y
  43. fgValid = false;
  44. }
  45. else
  46. {
  47. }
  48. }
  49. else
  50. {
  51. fgValid = false;
  52. }
  53. return fgValid;
  54. }
  55. //--------------------------------------------------------
  56. // Function : EyeScanHelper_RunTest()
  57. // Description : Enable the test, and wait til it is completed
  58. // Parameter : None
  59. // Return : None
  60. // Note : None
  61. //--------------------------------------------------------
  62. static void EyeScanHelper_RunTest(struct u3phy_info *info)
  63. {
  64. DRV_UDELAY(100);
  65. // Disable the test
  66. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  67. , RG_SSUSB_EQ_EYE_CNT_EN_OFST, RG_SSUSB_EQ_EYE_CNT_EN, 0); //RG_SSUSB_RX_EYE_CNT_EN = 0
  68. DRV_UDELAY(100);
  69. // Run the test
  70. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  71. , RG_SSUSB_EQ_EYE_CNT_EN_OFST, RG_SSUSB_EQ_EYE_CNT_EN, 1); //RG_SSUSB_RX_EYE_CNT_EN = 1
  72. DRV_UDELAY(100);
  73. // Wait til it's done
  74. //RGS_SSUSB_RX_EYE_CNT_RDY
  75. while(!U3PhyReadField32(((PHY_UINT32)&info->u3phyd_regs->phya_rx_mon5)
  76. , RGS_SSUSB_EQ_EYE_CNT_RDY_OFST, RGS_SSUSB_EQ_EYE_CNT_RDY));
  77. }
  78. //--------------------------------------------------------
  79. // Function : fgEyeScanHelper_CalNextPoint()
  80. // Description : Calcualte the test point for the measurement
  81. // Parameter : None
  82. // Return : BOOL - TRUE : the next point is within the
  83. // boundaryof HW limit
  84. // FALSE: the next point is out of the HW limit
  85. // Note : The next point is obtained by calculating
  86. // from the bottom left of the region rectangle
  87. // and then scanning up until it reaches the upper
  88. // limit. At this time, the x will increment, and
  89. // start scanning downwards until the y hits the
  90. // zero.
  91. //--------------------------------------------------------
  92. static PHY_INT8 fgEyeScanHelper_CalNextPoint(void)
  93. {
  94. if ( ((_bYcurr == MAX_Y) && (_eScanDir == SCAN_DN))
  95. || ((_bYcurr == MIN_Y) && (_eScanDir == SCAN_UP))
  96. )
  97. {
  98. /// Reaches the limit of Y axis
  99. /// Increment X
  100. _bXcurr++;
  101. _fgXChged = true;
  102. _eScanDir = (_eScanDir == SCAN_UP) ? SCAN_DN : SCAN_UP;
  103. if (_bXcurr > MAX_X)
  104. {
  105. return false;
  106. }
  107. }
  108. else
  109. {
  110. _bYcurr = (_eScanDir == SCAN_DN) ? _bYcurr + 1 : _bYcurr - 1;
  111. _fgXChged = false;
  112. }
  113. return PHY_TRUE;
  114. }
  115. PHY_INT32 eyescan_init(struct u3phy_info *info){
  116. //initial PHY setting
  117. U3PhyWriteField32(((PHY_UINT32)&info->u3phya_regs->rega)
  118. , RG_SSUSB_CDR_EPEN_OFST, RG_SSUSB_CDR_EPEN, 1);
  119. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->phyd_mix3)
  120. , RG_SSUSB_FORCE_CDR_PI_PWD_OFST, RG_SSUSB_FORCE_CDR_PI_PWD, 1);
  121. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_bank2_regs->b2_phyd_misc0)
  122. , RG_SSUSB_RX_PI_CAL_EN_SEL_OFST, RG_SSUSB_RX_PI_CAL_EN_SEL, 1); //RG_SSUSB_RX_PI_CAL_MANUAL_SEL = 1
  123. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_bank2_regs->b2_phyd_misc0)
  124. , RG_SSUSB_RX_PI_CAL_EN_OFST, RG_SSUSB_RX_PI_CAL_EN, 1); //RG_SSUSB_RX_PI_CAL_MANUAL_EN = 1
  125. return PHY_TRUE;
  126. }
  127. PHY_INT32 phy_eyescan(struct u3phy_info *info, PHY_INT32 x_t1, PHY_INT32 y_t1, PHY_INT32 x_br, PHY_INT32 y_br, PHY_INT32 delta_x, PHY_INT32 delta_y
  128. , PHY_INT32 eye_cnt, PHY_INT32 num_cnt, PHY_INT32 PI_cal_en, PHY_INT32 num_ignore_cnt){
  129. PHY_INT32 cOfst = 0;
  130. PHY_UINT8 bIdxX = 0;
  131. PHY_UINT8 bIdxY = 0;
  132. //PHY_INT8 bCnt = 0;
  133. PHY_UINT8 bIdxCycCnt = 0;
  134. PHY_INT8 fgValid;
  135. PHY_INT8 cX;
  136. PHY_INT8 cY;
  137. PHY_UINT8 bExtendCnt;
  138. PHY_INT8 isContinue;
  139. //PHY_INT8 isBreak;
  140. PHY_UINT32 wErr0 = 0, wErr1 = 0;
  141. //PHY_UINT32 temp;
  142. PHY_UINT32 pwErrCnt0[CYCLE_COUNT_MAX][ERRCNT_MAX][ERRCNT_MAX];
  143. PHY_UINT32 pwErrCnt1[CYCLE_COUNT_MAX][ERRCNT_MAX][ERRCNT_MAX];
  144. _rEye1.bX_tl = x_t1;
  145. _rEye1.bY_tl = y_t1;
  146. _rEye1.bX_br = x_br;
  147. _rEye1.bY_br = y_br;
  148. _rEye1.bDeltaX = delta_x;
  149. _rEye1.bDeltaY = delta_y;
  150. _rEye2.bX_tl = x_t1;
  151. _rEye2.bY_tl = y_t1;
  152. _rEye2.bX_br = x_br;
  153. _rEye2.bY_br = y_br;
  154. _rEye2.bDeltaX = delta_x;
  155. _rEye2.bDeltaY = delta_y;
  156. _rTestCycle.wEyeCnt = eye_cnt;
  157. _rTestCycle.bNumOfEyeCnt = num_cnt;
  158. _rTestCycle.bNumOfIgnoreCnt = num_ignore_cnt;
  159. _rTestCycle.bPICalEn = PI_cal_en;
  160. _bXcurr = 0;
  161. _bYcurr = 0;
  162. _eScanDir = SCAN_DN;
  163. _fgXChged = false;
  164. printk("x_t1: %x, y_t1: %x, x_br: %x, y_br: %x, delta_x: %x, delta_y: %x, \
  165. eye_cnt: %x, num_cnt: %x, PI_cal_en: %x, num_ignore_cnt: %x\n", \
  166. x_t1, y_t1, x_br, y_br, delta_x, delta_y, eye_cnt, num_cnt, PI_cal_en, num_ignore_cnt);
  167. //force SIGDET to OFF
  168. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_bank2_regs->b2_phyd_misc0)
  169. , RG_SSUSB_RX_SIGDET_EN_SEL_OFST, RG_SSUSB_RX_SIGDET_EN_SEL, 1); //RG_SSUSB_RX_SIGDET_SEL = 1
  170. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_bank2_regs->b2_phyd_misc0)
  171. , RG_SSUSB_RX_SIGDET_EN_OFST, RG_SSUSB_RX_SIGDET_EN, 0); //RG_SSUSB_RX_SIGDET_EN = 0
  172. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye1)
  173. , RG_SSUSB_EQ_SIGDET_OFST, RG_SSUSB_EQ_SIGDET, 0); //RG_SSUSB_RX_SIGDET = 0
  174. // RX_TRI_DET_EN to Disable
  175. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq3)
  176. , RG_SSUSB_EQ_TRI_DET_EN_OFST, RG_SSUSB_EQ_TRI_DET_EN, 0); //RG_SSUSB_RX_TRI_DET_EN = 0
  177. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  178. , RG_SSUSB_EQ_EYE_MON_EN_OFST, RG_SSUSB_EQ_EYE_MON_EN, 1); //RG_SSUSB_EYE_MON_EN = 1
  179. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  180. , RG_SSUSB_EQ_EYE_XOFFSET_OFST, RG_SSUSB_EQ_EYE_XOFFSET, 0); //RG_SSUSB_RX_EYE_XOFFSET = 0
  181. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  182. , RG_SSUSB_EQ_EYE0_Y_OFST, RG_SSUSB_EQ_EYE0_Y, 0); //RG_SSUSB_RX_EYE0_Y = 0
  183. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  184. , RG_SSUSB_EQ_EYE1_Y_OFST, RG_SSUSB_EQ_EYE1_Y, 0); //RG_SSUSB_RX_EYE1_Y = 0
  185. if (PI_cal_en){
  186. // PI Calibration
  187. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_bank2_regs->b2_phyd_misc0)
  188. , RG_SSUSB_RX_PI_CAL_EN_SEL_OFST, RG_SSUSB_RX_PI_CAL_EN_SEL, 1); //RG_SSUSB_RX_PI_CAL_MANUAL_SEL = 1
  189. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_bank2_regs->b2_phyd_misc0)
  190. , RG_SSUSB_RX_PI_CAL_EN_OFST, RG_SSUSB_RX_PI_CAL_EN, 0); //RG_SSUSB_RX_PI_CAL_MANUAL_EN = 0
  191. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_bank2_regs->b2_phyd_misc0)
  192. , RG_SSUSB_RX_PI_CAL_EN_OFST, RG_SSUSB_RX_PI_CAL_EN, 1); //RG_SSUSB_RX_PI_CAL_MANUAL_EN = 1
  193. DRV_UDELAY(20);
  194. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_bank2_regs->b2_phyd_misc0)
  195. , RG_SSUSB_RX_PI_CAL_EN_OFST, RG_SSUSB_RX_PI_CAL_EN, 0); //RG_SSUSB_RX_PI_CAL_MANUAL_EN = 0
  196. _bPIResult = U3PhyReadField32(((PHY_UINT32)&info->u3phyd_regs->phya_rx_mon5)
  197. , RGS_SSUSB_EQ_PILPO_OFST, RGS_SSUSB_EQ_PILPO); //read RGS_SSUSB_RX_PILPO
  198. printk(KERN_ERR "PI result: %d\n", _bPIResult);
  199. }
  200. // Read Initial DAC
  201. // Set CYCLE
  202. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye3)
  203. ,RG_SSUSB_EQ_EYE_CNT_OFST, RG_SSUSB_EQ_EYE_CNT, eye_cnt); //RG_SSUSB_RX_EYE_CNT
  204. // Eye Monitor Feature
  205. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye1)
  206. , RG_SSUSB_EQ_EYE_MASK_OFST, RG_SSUSB_EQ_EYE_MASK, 0x3ff); //RG_SSUSB_RX_EYE_MASK = 0x3ff
  207. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  208. , RG_SSUSB_EQ_EYE_MON_EN_OFST, RG_SSUSB_EQ_EYE_MON_EN, 1); //RG_SSUSB_EYE_MON_EN = 1
  209. // Move X,Y to the top-left corner
  210. for (cOfst = 0; cOfst >= -64; cOfst--)
  211. {
  212. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  213. ,RG_SSUSB_EQ_EYE_XOFFSET_OFST, RG_SSUSB_EQ_EYE_XOFFSET, cOfst); //RG_SSUSB_RX_EYE_XOFFSET
  214. }
  215. for (cOfst = 0; cOfst < 64; cOfst++)
  216. {
  217. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  218. , RG_SSUSB_EQ_EYE0_Y_OFST, RG_SSUSB_EQ_EYE0_Y, cOfst); //RG_SSUSB_RX_EYE0_Y
  219. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  220. , RG_SSUSB_EQ_EYE1_Y_OFST, RG_SSUSB_EQ_EYE1_Y, cOfst); //RG_SSUSB_RX_EYE1_Y
  221. }
  222. //ClearErrorResult
  223. for(bIdxCycCnt = 0; bIdxCycCnt < CYCLE_COUNT_MAX; bIdxCycCnt++){
  224. for(bIdxX = 0; bIdxX < ERRCNT_MAX; bIdxX++)
  225. {
  226. for(bIdxY = 0; bIdxY < ERRCNT_MAX; bIdxY++){
  227. pwErrCnt0[bIdxCycCnt][bIdxX][bIdxY] = 0;
  228. pwErrCnt1[bIdxCycCnt][bIdxX][bIdxY] = 0;
  229. }
  230. }
  231. }
  232. isContinue = true;
  233. while(isContinue){
  234. //printk(KERN_ERR "_bXcurr: %d, _bYcurr: %d\n", _bXcurr, _bYcurr);
  235. // The point is within the boundary, then let's check if it is within
  236. // the testing region.
  237. // The point is only test-able if one of the eye region
  238. // includes this point.
  239. fgValid = fgEyeScanHelper_CheckPtInRegion(&_rEye1, _bXcurr, _bYcurr)
  240. || fgEyeScanHelper_CheckPtInRegion(&_rEye2, _bXcurr, _bYcurr);
  241. // Translate bX and bY to 2's complement from where the origin was on the
  242. // top left corner.
  243. // 0x40 and 0x3F needs a bit of thinking!!!! >"<
  244. cX = (_bXcurr ^ 0x40);
  245. cY = (_bYcurr ^ 0x3F);
  246. // Set X if necessary
  247. if (_fgXChged == true)
  248. {
  249. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  250. , RG_SSUSB_EQ_EYE_XOFFSET_OFST, RG_SSUSB_EQ_EYE_XOFFSET, cX); //RG_SSUSB_RX_EYE_XOFFSET
  251. }
  252. // Set Y
  253. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  254. , RG_SSUSB_EQ_EYE0_Y_OFST, RG_SSUSB_EQ_EYE0_Y, cY); //RG_SSUSB_RX_EYE0_Y
  255. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  256. , RG_SSUSB_EQ_EYE1_Y_OFST, RG_SSUSB_EQ_EYE1_Y, cY); //RG_SSUSB_RX_EYE1_Y
  257. /// Test this point!
  258. if (fgValid){
  259. for (bExtendCnt = 0; bExtendCnt < num_ignore_cnt; bExtendCnt++)
  260. {
  261. //run test
  262. EyeScanHelper_RunTest(info);
  263. }
  264. for (bExtendCnt = 0; bExtendCnt < num_cnt; bExtendCnt++)
  265. {
  266. EyeScanHelper_RunTest(info);
  267. wErr0 = U3PhyReadField32(((PHY_UINT32)&info->u3phyd_regs->phya_rx_mon3)
  268. , RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_0_OFST, RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_0);
  269. wErr1 = U3PhyReadField32(((PHY_UINT32)&info->u3phyd_regs->phya_rx_mon4)
  270. , RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_1_OFST, RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_1);
  271. pwErrCnt0[bExtendCnt][_bXcurr][_bYcurr] = wErr0;
  272. pwErrCnt1[bExtendCnt][_bXcurr][_bYcurr] = wErr1;
  273. //EyeScanHelper_GetResult(&_rRes.pwErrCnt0[bCnt], &_rRes.pwErrCnt1[bCnt]);
  274. // printk(KERN_ERR "cnt[%d] cur_x,y [0x%x][0x%x], cX,cY [0x%x][0x%x], ErrCnt[%d][%d]\n"
  275. // , bExtendCnt, _bXcurr, _bYcurr, cX, cY, pwErrCnt0[bExtendCnt][_bXcurr][_bYcurr], pwErrCnt1[bExtendCnt][_bXcurr][_bYcurr]);
  276. }
  277. //printk(KERN_ERR "cur_x,y [0x%x][0x%x], cX,cY [0x%x][0x%x], ErrCnt[%d][%d]\n", _bXcurr, _bYcurr, cX, cY, pwErrCnt0[0][_bXcurr][_bYcurr], pwErrCnt1[0][_bXcurr][_bYcurr]);
  278. }
  279. else{
  280. }
  281. if (fgEyeScanHelper_CalNextPoint() == false){
  282. #if 0
  283. printk(KERN_ERR "Xcurr [0x%x] Ycurr [0x%x]\n", _bXcurr, _bYcurr);
  284. printk(KERN_ERR "XcurrREG [0x%x] YcurrREG [0x%x]\n", cX, cY);
  285. #endif
  286. printk(KERN_ERR "end of eye scan\n");
  287. isContinue = false;
  288. }
  289. }
  290. printk(KERN_ERR "CurX [0x%x] CurY [0x%x]\n"
  291. , U3PhyReadField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0), RG_SSUSB_EQ_EYE_XOFFSET_OFST, RG_SSUSB_EQ_EYE_XOFFSET)
  292. , U3PhyReadField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0), RG_SSUSB_EQ_EYE0_Y_OFST, RG_SSUSB_EQ_EYE0_Y));
  293. // Move X,Y to the top-left corner
  294. for (cOfst = 63; cOfst >= 0; cOfst--)
  295. {
  296. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  297. , RG_SSUSB_EQ_EYE_XOFFSET_OFST, RG_SSUSB_EQ_EYE_XOFFSET, cOfst); //RG_SSUSB_RX_EYE_XOFFSET
  298. }
  299. for (cOfst = 63; cOfst >= 0; cOfst--)
  300. {
  301. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  302. , RG_SSUSB_EQ_EYE0_Y_OFST, RG_SSUSB_EQ_EYE0_Y, cOfst);
  303. U3PhyWriteField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0)
  304. , RG_SSUSB_EQ_EYE1_Y_OFST, RG_SSUSB_EQ_EYE1_Y, cOfst);
  305. }
  306. printk(KERN_ERR "CurX [0x%x] CurY [0x%x]\n"
  307. , U3PhyReadField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0), RG_SSUSB_EQ_EYE_XOFFSET_OFST, RG_SSUSB_EQ_EYE_XOFFSET)
  308. , U3PhyReadField32(((PHY_UINT32)&info->u3phyd_regs->eq_eye0), RG_SSUSB_EQ_EYE0_Y_OFST, RG_SSUSB_EQ_EYE0_Y));
  309. printk(KERN_ERR "PI result: %d\n", _bPIResult);
  310. printk(KERN_ERR "pwErrCnt0 addr: 0x%x\n", (PHY_UINT32)pwErrCnt0);
  311. printk(KERN_ERR "pwErrCnt1 addr: 0x%x\n", (PHY_UINT32)pwErrCnt1);
  312. return PHY_TRUE;
  313. }
  314. //not used on SoC
  315. PHY_INT32 u2_save_cur_en(struct u3phy_info *info){
  316. return PHY_TRUE;
  317. }
  318. //not used on SoC
  319. PHY_INT32 u2_save_cur_re(struct u3phy_info *info){
  320. return PHY_TRUE;
  321. }
  322. PHY_INT32 u2_slew_rate_calibration(struct u3phy_info *info){
  323. PHY_INT32 i=0;
  324. //PHY_INT32 j=0;
  325. //PHY_INT8 u1SrCalVal = 0;
  326. //PHY_INT8 u1Reg_addr_HSTX_SRCAL_EN;
  327. PHY_INT32 fgRet = 0;
  328. PHY_INT32 u4FmOut = 0;
  329. PHY_INT32 u4Tmp = 0;
  330. //PHY_INT32 temp;
  331. // => RG_USB20_HSTX_SRCAL_EN = 1
  332. // enable HS TX SR calibration
  333. U3PhyWriteField32(((PHY_UINT32)&info->u2phy_regs->u2phyacr0)
  334. , RG_USB20_HSTX_SRCAL_EN_OFST, RG_USB20_HSTX_SRCAL_EN, 0x1);
  335. DRV_MSLEEP(1);
  336. // => RG_FRCK_EN = 1
  337. // Enable free run clock
  338. U3PhyWriteField32(((PHY_UINT32)&info->sifslv_fm_regs->fmmonr1)
  339. , RG_FRCK_EN_OFST, RG_FRCK_EN, 1);
  340. // MT6290 HS signal quality patch
  341. // => RG_CYCLECNT = 400
  342. // Setting cyclecnt =400
  343. U3PhyWriteField32(((PHY_UINT32)&info->sifslv_fm_regs->fmcr0)
  344. , RG_CYCLECNT_OFST, RG_CYCLECNT, 0x400);
  345. // => RG_FREQDET_EN = 1
  346. // Enable frequency meter
  347. U3PhyWriteField32(((PHY_UINT32)&info->sifslv_fm_regs->fmcr0)
  348. , RG_FREQDET_EN_OFST, RG_FREQDET_EN, 0x1);
  349. // wait for FM detection done, set 10ms timeout
  350. for(i=0; i<10; i++){
  351. // => u4FmOut = USB_FM_OUT
  352. // read FM_OUT
  353. u4FmOut = U3PhyReadReg32(((PHY_UINT32)&info->sifslv_fm_regs->fmmonr0));
  354. printk("FM_OUT value: u4FmOut = %d(0x%08X)\n", u4FmOut, u4FmOut);
  355. // check if FM detection done
  356. if (u4FmOut != 0)
  357. {
  358. fgRet = 0;
  359. printk("FM detection done! loop = %d\n", i);
  360. break;
  361. }
  362. fgRet = 1;
  363. DRV_MSLEEP(1);
  364. }
  365. // => RG_FREQDET_EN = 0
  366. // disable frequency meter
  367. U3PhyWriteField32(((PHY_UINT32)&info->sifslv_fm_regs->fmcr0)
  368. , RG_FREQDET_EN_OFST, RG_FREQDET_EN, 0);
  369. // => RG_FRCK_EN = 0
  370. // disable free run clock
  371. U3PhyWriteField32(((PHY_UINT32)&info->sifslv_fm_regs->fmmonr1)
  372. , RG_FRCK_EN_OFST, RG_FRCK_EN, 0);
  373. // => RG_USB20_HSTX_SRCAL_EN = 0
  374. // disable HS TX SR calibration
  375. U3PhyWriteField32(((PHY_UINT32)&info->u2phy_regs->u2phyacr0)
  376. , RG_USB20_HSTX_SRCAL_EN_OFST, RG_USB20_HSTX_SRCAL_EN, 0);
  377. DRV_MSLEEP(1);
  378. if(u4FmOut == 0){
  379. U3PhyWriteField32(((PHY_UINT32)&info->u2phy_regs->u2phyacr0)
  380. , RG_USB20_HSTX_SRCTRL_OFST, RG_USB20_HSTX_SRCTRL, 0x4);
  381. fgRet = 1;
  382. }
  383. else{
  384. // set reg = (1024/FM_OUT) * 25 * 0.028 (round to the nearest digits)
  385. u4Tmp = (((1024 * 25 * U2_SR_COEF_7621) / u4FmOut) + 500) / 1000;
  386. printk("SR calibration value u1SrCalVal = %d\n", (PHY_UINT8)u4Tmp);
  387. U3PhyWriteField32(((PHY_UINT32)&info->u2phy_regs->u2phyacr0)
  388. , RG_USB20_HSTX_SRCTRL_OFST, RG_USB20_HSTX_SRCTRL, u4Tmp);
  389. }
  390. return fgRet;
  391. }
  392. #endif