dra7xx_iodelay.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2015
  4. * Texas Instruments Incorporated, <www.ti.com>
  5. *
  6. * Lokesh Vutla <lokeshvutla@ti.com>
  7. */
  8. #include <common.h>
  9. #include <asm/utils.h>
  10. #include <asm/arch/dra7xx_iodelay.h>
  11. #include <asm/arch/omap.h>
  12. #include <asm/arch/sys_proto.h>
  13. #include <asm/arch/clock.h>
  14. #include <asm/arch/mux_dra7xx.h>
  15. #include <asm/omap_common.h>
  16. static int isolate_io(u32 isolate)
  17. {
  18. if (isolate) {
  19. clrsetbits_le32((*ctrl)->control_pbias, SDCARD_PWRDNZ,
  20. SDCARD_PWRDNZ);
  21. clrsetbits_le32((*ctrl)->control_pbias, SDCARD_BIAS_PWRDNZ,
  22. SDCARD_BIAS_PWRDNZ);
  23. }
  24. /* Override control on ISOCLKIN signal to IO pad ring. */
  25. clrsetbits_le32((*prcm)->prm_io_pmctrl, PMCTRL_ISOCLK_OVERRIDE_MASK,
  26. PMCTRL_ISOCLK_OVERRIDE_CTRL);
  27. if (!wait_on_value(PMCTRL_ISOCLK_STATUS_MASK, PMCTRL_ISOCLK_STATUS_MASK,
  28. (u32 *)(*prcm)->prm_io_pmctrl, LDELAY))
  29. return ERR_DEISOLATE_IO << isolate;
  30. /* Isolate/Deisolate IO */
  31. clrsetbits_le32((*ctrl)->ctrl_core_sma_sw_0, CTRL_ISOLATE_MASK,
  32. isolate << CTRL_ISOLATE_SHIFT);
  33. /* Dummy read to add delay t > 10ns */
  34. readl((*ctrl)->ctrl_core_sma_sw_0);
  35. /* Return control on ISOCLKIN to hardware */
  36. clrsetbits_le32((*prcm)->prm_io_pmctrl, PMCTRL_ISOCLK_OVERRIDE_MASK,
  37. PMCTRL_ISOCLK_NOT_OVERRIDE_CTRL);
  38. if (!wait_on_value(PMCTRL_ISOCLK_STATUS_MASK,
  39. 0 << PMCTRL_ISOCLK_STATUS_SHIFT,
  40. (u32 *)(*prcm)->prm_io_pmctrl, LDELAY))
  41. return ERR_DEISOLATE_IO << isolate;
  42. return 0;
  43. }
  44. static int calibrate_iodelay(u32 base)
  45. {
  46. u32 reg;
  47. /* Configure REFCLK period */
  48. reg = readl(base + CFG_REG_2_OFFSET);
  49. reg &= ~CFG_REG_REFCLK_PERIOD_MASK;
  50. reg |= CFG_REG_REFCLK_PERIOD;
  51. writel(reg, base + CFG_REG_2_OFFSET);
  52. /* Initiate Calibration */
  53. clrsetbits_le32(base + CFG_REG_0_OFFSET, CFG_REG_CALIB_STRT_MASK,
  54. CFG_REG_CALIB_STRT << CFG_REG_CALIB_STRT_SHIFT);
  55. if (!wait_on_value(CFG_REG_CALIB_STRT_MASK, CFG_REG_CALIB_END,
  56. (u32 *)(base + CFG_REG_0_OFFSET), LDELAY))
  57. return ERR_CALIBRATE_IODELAY;
  58. return 0;
  59. }
  60. static int update_delay_mechanism(u32 base)
  61. {
  62. /* Initiate the reload of calibrated values. */
  63. clrsetbits_le32(base + CFG_REG_0_OFFSET, CFG_REG_ROM_READ_MASK,
  64. CFG_REG_ROM_READ_START);
  65. if (!wait_on_value(CFG_REG_ROM_READ_MASK, CFG_REG_ROM_READ_END,
  66. (u32 *)(base + CFG_REG_0_OFFSET), LDELAY))
  67. return ERR_UPDATE_DELAY;
  68. return 0;
  69. }
  70. static u32 calculate_delay(u32 base, u16 offset, u16 den)
  71. {
  72. u16 refclk_period, dly_cnt, ref_cnt;
  73. u32 reg, q, r;
  74. refclk_period = readl(base + CFG_REG_2_OFFSET) &
  75. CFG_REG_REFCLK_PERIOD_MASK;
  76. reg = readl(base + offset);
  77. dly_cnt = (reg & CFG_REG_DLY_CNT_MASK) >> CFG_REG_DLY_CNT_SHIFT;
  78. ref_cnt = (reg & CFG_REG_REF_CNT_MASK) >> CFG_REG_REF_CNT_SHIFT;
  79. if (!dly_cnt || !den)
  80. return 0;
  81. /*
  82. * To avoid overflow and integer truncation, delay value
  83. * is calculated as quotient + remainder.
  84. */
  85. q = 5 * ((ref_cnt * refclk_period) / (dly_cnt * den));
  86. r = (10 * ((ref_cnt * refclk_period) % (dly_cnt * den))) /
  87. (2 * dly_cnt * den);
  88. return q + r;
  89. }
  90. static u32 get_cfg_reg(u16 a_delay, u16 g_delay, u32 cpde, u32 fpde)
  91. {
  92. u32 g_delay_coarse, g_delay_fine;
  93. u32 a_delay_coarse, a_delay_fine;
  94. u32 c_elements, f_elements;
  95. u32 total_delay, reg = 0;
  96. g_delay_coarse = g_delay / 920;
  97. g_delay_fine = ((g_delay % 920) * 10) / 60;
  98. a_delay_coarse = a_delay / cpde;
  99. a_delay_fine = ((a_delay % cpde) * 10) / fpde;
  100. c_elements = g_delay_coarse + a_delay_coarse;
  101. f_elements = (g_delay_fine + a_delay_fine) / 10;
  102. if (f_elements > 22) {
  103. total_delay = c_elements * cpde + f_elements * fpde;
  104. c_elements = total_delay / cpde;
  105. f_elements = (total_delay % cpde) / fpde;
  106. }
  107. reg = (c_elements << CFG_X_COARSE_DLY_SHIFT) & CFG_X_COARSE_DLY_MASK;
  108. reg |= (f_elements << CFG_X_FINE_DLY_SHIFT) & CFG_X_FINE_DLY_MASK;
  109. reg |= CFG_X_SIGNATURE << CFG_X_SIGNATURE_SHIFT;
  110. reg |= CFG_X_LOCK << CFG_X_LOCK_SHIFT;
  111. return reg;
  112. }
  113. int do_set_iodelay(u32 base, struct iodelay_cfg_entry const *array,
  114. int niodelays)
  115. {
  116. struct iodelay_cfg_entry *iodelay = (struct iodelay_cfg_entry *)array;
  117. u32 reg, cpde, fpde, i;
  118. if (!niodelays)
  119. return 0;
  120. cpde = calculate_delay((*ctrl)->iodelay_config_base, CFG_REG_3_OFFSET,
  121. 88);
  122. if (!cpde)
  123. return ERR_CPDE;
  124. fpde = calculate_delay((*ctrl)->iodelay_config_base, CFG_REG_4_OFFSET,
  125. 264);
  126. if (!fpde)
  127. return ERR_FPDE;
  128. for (i = 0; i < niodelays; i++, iodelay++) {
  129. reg = get_cfg_reg(iodelay->a_delay, iodelay->g_delay, cpde,
  130. fpde);
  131. writel(reg, base + iodelay->offset);
  132. }
  133. return 0;
  134. }
  135. int __recalibrate_iodelay_start(void)
  136. {
  137. int ret = 0;
  138. /* IO recalibration should be done only from SRAM */
  139. if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) {
  140. puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n");
  141. return -1;
  142. }
  143. /* unlock IODELAY CONFIG registers */
  144. writel(CFG_IODELAY_UNLOCK_KEY, (*ctrl)->iodelay_config_base +
  145. CFG_REG_8_OFFSET);
  146. ret = calibrate_iodelay((*ctrl)->iodelay_config_base);
  147. if (ret)
  148. goto err;
  149. ret = isolate_io(ISOLATE_IO);
  150. if (ret)
  151. goto err;
  152. ret = update_delay_mechanism((*ctrl)->iodelay_config_base);
  153. err:
  154. return ret;
  155. }
  156. void __recalibrate_iodelay_end(int ret)
  157. {
  158. /* IO recalibration should be done only from SRAM */
  159. if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) {
  160. puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n");
  161. return;
  162. }
  163. if (!ret)
  164. ret = isolate_io(DEISOLATE_IO);
  165. /* lock IODELAY CONFIG registers */
  166. writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base +
  167. CFG_REG_8_OFFSET);
  168. /*
  169. * UART cannot be used during IO recalibration sequence as IOs are in
  170. * isolation. So error handling and debug prints are done after
  171. * complete IO delay recalibration sequence
  172. */
  173. switch (ret) {
  174. case ERR_CALIBRATE_IODELAY:
  175. puts("IODELAY: IO delay calibration sequence failed\n");
  176. break;
  177. case ERR_ISOLATE_IO:
  178. puts("IODELAY: Isolation of Device IOs failed\n");
  179. break;
  180. case ERR_UPDATE_DELAY:
  181. puts("IODELAY: Delay mechanism update with new calibrated values failed\n");
  182. break;
  183. case ERR_DEISOLATE_IO:
  184. puts("IODELAY: De-isolation of Device IOs failed\n");
  185. break;
  186. case ERR_CPDE:
  187. puts("IODELAY: CPDE calculation failed\n");
  188. break;
  189. case ERR_FPDE:
  190. puts("IODELAY: FPDE calculation failed\n");
  191. break;
  192. case -1:
  193. puts("IODELAY: Wrong Context call?\n");
  194. break;
  195. default:
  196. debug("IODELAY: IO delay recalibration successfully completed\n");
  197. }
  198. return;
  199. }
  200. void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads,
  201. struct iodelay_cfg_entry const *iodelay,
  202. int niodelays)
  203. {
  204. int ret = 0;
  205. /* IO recalibration should be done only from SRAM */
  206. if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) {
  207. puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n");
  208. return;
  209. }
  210. ret = __recalibrate_iodelay_start();
  211. if (ret)
  212. goto err;
  213. /* Configure Mux settings */
  214. do_set_mux32((*ctrl)->control_padconf_core_base, pad, npads);
  215. /* Configure Manual IO timing modes */
  216. ret = do_set_iodelay((*ctrl)->iodelay_config_base, iodelay, niodelays);
  217. if (ret)
  218. goto err;
  219. err:
  220. __recalibrate_iodelay_end(ret);
  221. }
  222. void late_recalibrate_iodelay(struct pad_conf_entry const *pad, int npads,
  223. struct iodelay_cfg_entry const *iodelay,
  224. int niodelays)
  225. {
  226. int ret = 0;
  227. /* unlock IODELAY CONFIG registers */
  228. writel(CFG_IODELAY_UNLOCK_KEY, (*ctrl)->iodelay_config_base +
  229. CFG_REG_8_OFFSET);
  230. ret = calibrate_iodelay((*ctrl)->iodelay_config_base);
  231. if (ret)
  232. goto err;
  233. ret = update_delay_mechanism((*ctrl)->iodelay_config_base);
  234. /* Configure Mux settings */
  235. do_set_mux32((*ctrl)->control_padconf_core_base, pad, npads);
  236. /* Configure Manual IO timing modes */
  237. ret = do_set_iodelay((*ctrl)->iodelay_config_base, iodelay, niodelays);
  238. if (ret)
  239. goto err;
  240. err:
  241. /* lock IODELAY CONFIG registers */
  242. writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base +
  243. CFG_REG_8_OFFSET);
  244. }