vp.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #include <plat/common.h>
  4. #include "voltage.h"
  5. #include "vp.h"
  6. #include "prm-regbits-34xx.h"
  7. #include "prm-regbits-44xx.h"
  8. #include "prm44xx.h"
  9. static void vp_latch_vsel(struct voltagedomain *voltdm)
  10. {
  11. struct omap_vp_instance *vp = voltdm->vp;
  12. u32 vpconfig;
  13. unsigned long uvdc;
  14. char vsel;
  15. uvdc = omap_voltage_get_nom_volt(voltdm);
  16. if (!uvdc) {
  17. pr_warning("%s: unable to find current voltage for vdd_%s\n",
  18. __func__, voltdm->name);
  19. return;
  20. }
  21. if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
  22. pr_warning("%s: PMIC function to convert voltage in uV to"
  23. " vsel not registered\n", __func__);
  24. return;
  25. }
  26. vsel = voltdm->pmic->uv_to_vsel(uvdc);
  27. vpconfig = voltdm->read(vp->vpconfig);
  28. vpconfig &= ~(vp->common->vpconfig_initvoltage_mask |
  29. vp->common->vpconfig_initvdd);
  30. vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask);
  31. voltdm->write(vpconfig, vp->vpconfig);
  32. /* Trigger initVDD value copy to voltage processor */
  33. voltdm->write((vpconfig | vp->common->vpconfig_initvdd),
  34. vp->vpconfig);
  35. /* Clear initVDD copy trigger bit */
  36. voltdm->write(vpconfig, vp->vpconfig);
  37. }
  38. /* Generic voltage init functions */
  39. void __init omap_vp_init(struct voltagedomain *voltdm)
  40. {
  41. struct omap_vp_instance *vp = voltdm->vp;
  42. struct omap_vdd_info *vdd = voltdm->vdd;
  43. u32 vp_val, sys_clk_rate, timeout_val, waittime;
  44. if (!voltdm->read || !voltdm->write) {
  45. pr_err("%s: No read/write API for accessing vdd_%s regs\n",
  46. __func__, voltdm->name);
  47. return;
  48. }
  49. vp->enabled = false;
  50. /* Divide to avoid overflow */
  51. sys_clk_rate = voltdm->sys_clk.rate / 1000;
  52. vdd->vp_rt_data.vpconfig_erroroffset =
  53. (voltdm->pmic->vp_erroroffset <<
  54. __ffs(voltdm->vp->common->vpconfig_erroroffset_mask));
  55. timeout_val = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
  56. vdd->vp_rt_data.vlimitto_timeout = timeout_val;
  57. vdd->vp_rt_data.vlimitto_vddmin = voltdm->pmic->vp_vddmin;
  58. vdd->vp_rt_data.vlimitto_vddmax = voltdm->pmic->vp_vddmax;
  59. waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
  60. sys_clk_rate) / 1000;
  61. vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime;
  62. vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime;
  63. vdd->vp_rt_data.vstepmin_stepmin = voltdm->pmic->vp_vstepmin;
  64. vdd->vp_rt_data.vstepmax_stepmax = voltdm->pmic->vp_vstepmax;
  65. vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
  66. (vdd->vp_rt_data.vpconfig_errorgain <<
  67. __ffs(vp->common->vpconfig_errorgain_mask)) |
  68. vp->common->vpconfig_timeouten;
  69. voltdm->write(vp_val, vp->vpconfig);
  70. vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
  71. vp->common->vstepmin_smpswaittimemin_shift) |
  72. (vdd->vp_rt_data.vstepmin_stepmin <<
  73. vp->common->vstepmin_stepmin_shift));
  74. voltdm->write(vp_val, vp->vstepmin);
  75. vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
  76. vp->common->vstepmax_smpswaittimemax_shift) |
  77. (vdd->vp_rt_data.vstepmax_stepmax <<
  78. vp->common->vstepmax_stepmax_shift));
  79. voltdm->write(vp_val, vp->vstepmax);
  80. vp_val = ((vdd->vp_rt_data.vlimitto_vddmax <<
  81. vp->common->vlimitto_vddmax_shift) |
  82. (vdd->vp_rt_data.vlimitto_vddmin <<
  83. vp->common->vlimitto_vddmin_shift) |
  84. (vdd->vp_rt_data.vlimitto_timeout <<
  85. vp->common->vlimitto_timeout_shift));
  86. voltdm->write(vp_val, vp->vlimitto);
  87. }
  88. /* VP force update method of voltage scaling */
  89. int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
  90. unsigned long target_volt)
  91. {
  92. struct omap_vp_instance *vp = voltdm->vp;
  93. u32 vpconfig;
  94. u8 target_vsel, current_vsel;
  95. int ret, timeout = 0;
  96. ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
  97. if (ret)
  98. return ret;
  99. /*
  100. * Clear all pending TransactionDone interrupt/status. Typical latency
  101. * is <3us
  102. */
  103. while (timeout++ < VP_TRANXDONE_TIMEOUT) {
  104. vp->common->ops->clear_txdone(vp->id);
  105. if (!vp->common->ops->check_txdone(vp->id))
  106. break;
  107. udelay(1);
  108. }
  109. if (timeout >= VP_TRANXDONE_TIMEOUT) {
  110. pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
  111. "Voltage change aborted", __func__, voltdm->name);
  112. return -ETIMEDOUT;
  113. }
  114. /* Configure for VP-Force Update */
  115. vpconfig = voltdm->read(vp->vpconfig);
  116. vpconfig &= ~(vp->common->vpconfig_initvdd |
  117. vp->common->vpconfig_forceupdate |
  118. vp->common->vpconfig_initvoltage_mask);
  119. vpconfig |= ((target_vsel <<
  120. __ffs(vp->common->vpconfig_initvoltage_mask)));
  121. voltdm->write(vpconfig, vp->vpconfig);
  122. /* Trigger initVDD value copy to voltage processor */
  123. vpconfig |= vp->common->vpconfig_initvdd;
  124. voltdm->write(vpconfig, vp->vpconfig);
  125. /* Force update of voltage */
  126. vpconfig |= vp->common->vpconfig_forceupdate;
  127. voltdm->write(vpconfig, vp->vpconfig);
  128. /*
  129. * Wait for TransactionDone. Typical latency is <200us.
  130. * Depends on SMPSWAITTIMEMIN/MAX and voltage change
  131. */
  132. timeout = 0;
  133. omap_test_timeout(vp->common->ops->check_txdone(vp->id),
  134. VP_TRANXDONE_TIMEOUT, timeout);
  135. if (timeout >= VP_TRANXDONE_TIMEOUT)
  136. pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
  137. "TRANXDONE never got set after the voltage update\n",
  138. __func__, voltdm->name);
  139. omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
  140. /*
  141. * Disable TransactionDone interrupt , clear all status, clear
  142. * control registers
  143. */
  144. timeout = 0;
  145. while (timeout++ < VP_TRANXDONE_TIMEOUT) {
  146. vp->common->ops->clear_txdone(vp->id);
  147. if (!vp->common->ops->check_txdone(vp->id))
  148. break;
  149. udelay(1);
  150. }
  151. if (timeout >= VP_TRANXDONE_TIMEOUT)
  152. pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
  153. "to clear the TRANXDONE status\n",
  154. __func__, voltdm->name);
  155. vpconfig = voltdm->read(vp->vpconfig);
  156. /* Clear initVDD copy trigger bit */
  157. vpconfig &= ~vp->common->vpconfig_initvdd;
  158. voltdm->write(vpconfig, vp->vpconfig);
  159. /* Clear force bit */
  160. vpconfig &= ~vp->common->vpconfig_forceupdate;
  161. voltdm->write(vpconfig, vp->vpconfig);
  162. return 0;
  163. }
  164. /**
  165. * omap_vp_get_curr_volt() - API to get the current vp voltage.
  166. * @voltdm: pointer to the VDD.
  167. *
  168. * This API returns the current voltage for the specified voltage processor
  169. */
  170. unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
  171. {
  172. struct omap_vp_instance *vp = voltdm->vp;
  173. u8 curr_vsel;
  174. if (!voltdm || IS_ERR(voltdm)) {
  175. pr_warning("%s: VDD specified does not exist!\n", __func__);
  176. return 0;
  177. }
  178. if (!voltdm->read) {
  179. pr_err("%s: No read API for reading vdd_%s regs\n",
  180. __func__, voltdm->name);
  181. return 0;
  182. }
  183. curr_vsel = voltdm->read(vp->voltage);
  184. if (!voltdm->pmic || !voltdm->pmic->vsel_to_uv) {
  185. pr_warning("%s: PMIC function to convert vsel to voltage"
  186. "in uV not registerd\n", __func__);
  187. return 0;
  188. }
  189. return voltdm->pmic->vsel_to_uv(curr_vsel);
  190. }
  191. /**
  192. * omap_vp_enable() - API to enable a particular VP
  193. * @voltdm: pointer to the VDD whose VP is to be enabled.
  194. *
  195. * This API enables a particular voltage processor. Needed by the smartreflex
  196. * class drivers.
  197. */
  198. void omap_vp_enable(struct voltagedomain *voltdm)
  199. {
  200. struct omap_vp_instance *vp;
  201. u32 vpconfig;
  202. if (!voltdm || IS_ERR(voltdm)) {
  203. pr_warning("%s: VDD specified does not exist!\n", __func__);
  204. return;
  205. }
  206. vp = voltdm->vp;
  207. if (!voltdm->read || !voltdm->write) {
  208. pr_err("%s: No read/write API for accessing vdd_%s regs\n",
  209. __func__, voltdm->name);
  210. return;
  211. }
  212. /* If VP is already enabled, do nothing. Return */
  213. if (vp->enabled)
  214. return;
  215. vp_latch_vsel(voltdm);
  216. /* Enable VP */
  217. vpconfig = voltdm->read(vp->vpconfig);
  218. vpconfig |= vp->common->vpconfig_vpenable;
  219. voltdm->write(vpconfig, vp->vpconfig);
  220. vp->enabled = true;
  221. }
  222. /**
  223. * omap_vp_disable() - API to disable a particular VP
  224. * @voltdm: pointer to the VDD whose VP is to be disabled.
  225. *
  226. * This API disables a particular voltage processor. Needed by the smartreflex
  227. * class drivers.
  228. */
  229. void omap_vp_disable(struct voltagedomain *voltdm)
  230. {
  231. struct omap_vp_instance *vp;
  232. u32 vpconfig;
  233. int timeout;
  234. if (!voltdm || IS_ERR(voltdm)) {
  235. pr_warning("%s: VDD specified does not exist!\n", __func__);
  236. return;
  237. }
  238. vp = voltdm->vp;
  239. if (!voltdm->read || !voltdm->write) {
  240. pr_err("%s: No read/write API for accessing vdd_%s regs\n",
  241. __func__, voltdm->name);
  242. return;
  243. }
  244. /* If VP is already disabled, do nothing. Return */
  245. if (!vp->enabled) {
  246. pr_warning("%s: Trying to disable VP for vdd_%s when"
  247. "it is already disabled\n", __func__, voltdm->name);
  248. return;
  249. }
  250. /* Disable VP */
  251. vpconfig = voltdm->read(vp->vpconfig);
  252. vpconfig &= ~vp->common->vpconfig_vpenable;
  253. voltdm->write(vpconfig, vp->vpconfig);
  254. /*
  255. * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
  256. */
  257. omap_test_timeout((voltdm->read(vp->vstatus)),
  258. VP_IDLE_TIMEOUT, timeout);
  259. if (timeout >= VP_IDLE_TIMEOUT)
  260. pr_warning("%s: vdd_%s idle timedout\n",
  261. __func__, voltdm->name);
  262. vp->enabled = false;
  263. return;
  264. }