vp.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. u32 val, sys_clk_rate, timeout, waittime;
  43. u32 vddmin, vddmax, vstepmin, vstepmax;
  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. timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
  53. vddmin = voltdm->pmic->vp_vddmin;
  54. vddmax = voltdm->pmic->vp_vddmax;
  55. waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
  56. sys_clk_rate) / 1000;
  57. vstepmin = voltdm->pmic->vp_vstepmin;
  58. vstepmax = voltdm->pmic->vp_vstepmax;
  59. /*
  60. * VP_CONFIG: error gain is not set here, it will be updated
  61. * on each scale, based on OPP.
  62. */
  63. val = (voltdm->pmic->vp_erroroffset <<
  64. __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)) |
  65. vp->common->vpconfig_timeouten;
  66. voltdm->write(val, vp->vpconfig);
  67. /* VSTEPMIN */
  68. val = (waittime << vp->common->vstepmin_smpswaittimemin_shift) |
  69. (vstepmin << vp->common->vstepmin_stepmin_shift);
  70. voltdm->write(val, vp->vstepmin);
  71. /* VSTEPMAX */
  72. val = (vstepmax << vp->common->vstepmax_stepmax_shift) |
  73. (waittime << vp->common->vstepmax_smpswaittimemax_shift);
  74. voltdm->write(val, vp->vstepmax);
  75. /* VLIMITTO */
  76. val = (vddmax << vp->common->vlimitto_vddmax_shift) |
  77. (vddmin << vp->common->vlimitto_vddmin_shift) |
  78. (timeout << vp->common->vlimitto_timeout_shift);
  79. voltdm->write(val, vp->vlimitto);
  80. }
  81. int omap_vp_update_errorgain(struct voltagedomain *voltdm,
  82. unsigned long target_volt)
  83. {
  84. struct omap_volt_data *volt_data;
  85. if (!voltdm->vp)
  86. return -EINVAL;
  87. /* Get volt_data corresponding to target_volt */
  88. volt_data = omap_voltage_get_voltdata(voltdm, target_volt);
  89. if (IS_ERR(volt_data))
  90. return -EINVAL;
  91. /* Setting vp errorgain based on the voltage */
  92. voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask,
  93. volt_data->vp_errgain <<
  94. __ffs(voltdm->vp->common->vpconfig_errorgain_mask),
  95. voltdm->vp->vpconfig);
  96. return 0;
  97. }
  98. /* VP force update method of voltage scaling */
  99. int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
  100. unsigned long target_volt)
  101. {
  102. struct omap_vp_instance *vp = voltdm->vp;
  103. u32 vpconfig;
  104. u8 target_vsel, current_vsel;
  105. int ret, timeout = 0;
  106. ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
  107. if (ret)
  108. return ret;
  109. /*
  110. * Clear all pending TransactionDone interrupt/status. Typical latency
  111. * is <3us
  112. */
  113. while (timeout++ < VP_TRANXDONE_TIMEOUT) {
  114. vp->common->ops->clear_txdone(vp->id);
  115. if (!vp->common->ops->check_txdone(vp->id))
  116. break;
  117. udelay(1);
  118. }
  119. if (timeout >= VP_TRANXDONE_TIMEOUT) {
  120. pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
  121. "Voltage change aborted", __func__, voltdm->name);
  122. return -ETIMEDOUT;
  123. }
  124. /* Configure for VP-Force Update */
  125. vpconfig = voltdm->read(vp->vpconfig);
  126. vpconfig &= ~(vp->common->vpconfig_initvdd |
  127. vp->common->vpconfig_forceupdate |
  128. vp->common->vpconfig_initvoltage_mask);
  129. vpconfig |= ((target_vsel <<
  130. __ffs(vp->common->vpconfig_initvoltage_mask)));
  131. voltdm->write(vpconfig, vp->vpconfig);
  132. /* Trigger initVDD value copy to voltage processor */
  133. vpconfig |= vp->common->vpconfig_initvdd;
  134. voltdm->write(vpconfig, vp->vpconfig);
  135. /* Force update of voltage */
  136. vpconfig |= vp->common->vpconfig_forceupdate;
  137. voltdm->write(vpconfig, vp->vpconfig);
  138. /*
  139. * Wait for TransactionDone. Typical latency is <200us.
  140. * Depends on SMPSWAITTIMEMIN/MAX and voltage change
  141. */
  142. timeout = 0;
  143. omap_test_timeout(vp->common->ops->check_txdone(vp->id),
  144. VP_TRANXDONE_TIMEOUT, timeout);
  145. if (timeout >= VP_TRANXDONE_TIMEOUT)
  146. pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
  147. "TRANXDONE never got set after the voltage update\n",
  148. __func__, voltdm->name);
  149. omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
  150. /*
  151. * Disable TransactionDone interrupt , clear all status, clear
  152. * control registers
  153. */
  154. timeout = 0;
  155. while (timeout++ < VP_TRANXDONE_TIMEOUT) {
  156. vp->common->ops->clear_txdone(vp->id);
  157. if (!vp->common->ops->check_txdone(vp->id))
  158. break;
  159. udelay(1);
  160. }
  161. if (timeout >= VP_TRANXDONE_TIMEOUT)
  162. pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
  163. "to clear the TRANXDONE status\n",
  164. __func__, voltdm->name);
  165. vpconfig = voltdm->read(vp->vpconfig);
  166. /* Clear initVDD copy trigger bit */
  167. vpconfig &= ~vp->common->vpconfig_initvdd;
  168. voltdm->write(vpconfig, vp->vpconfig);
  169. /* Clear force bit */
  170. vpconfig &= ~vp->common->vpconfig_forceupdate;
  171. voltdm->write(vpconfig, vp->vpconfig);
  172. return 0;
  173. }
  174. /**
  175. * omap_vp_get_curr_volt() - API to get the current vp voltage.
  176. * @voltdm: pointer to the VDD.
  177. *
  178. * This API returns the current voltage for the specified voltage processor
  179. */
  180. unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
  181. {
  182. struct omap_vp_instance *vp = voltdm->vp;
  183. u8 curr_vsel;
  184. if (!voltdm || IS_ERR(voltdm)) {
  185. pr_warning("%s: VDD specified does not exist!\n", __func__);
  186. return 0;
  187. }
  188. if (!voltdm->read) {
  189. pr_err("%s: No read API for reading vdd_%s regs\n",
  190. __func__, voltdm->name);
  191. return 0;
  192. }
  193. curr_vsel = (voltdm->read(vp->voltage) & vp->common->vpvoltage_mask)
  194. >> __ffs(vp->common->vpvoltage_mask);
  195. if (!voltdm->pmic || !voltdm->pmic->vsel_to_uv) {
  196. pr_warning("%s: PMIC function to convert vsel to voltage"
  197. "in uV not registerd\n", __func__);
  198. return 0;
  199. }
  200. return voltdm->pmic->vsel_to_uv(curr_vsel);
  201. }
  202. /**
  203. * omap_vp_enable() - API to enable a particular VP
  204. * @voltdm: pointer to the VDD whose VP is to be enabled.
  205. *
  206. * This API enables a particular voltage processor. Needed by the smartreflex
  207. * class drivers.
  208. */
  209. void omap_vp_enable(struct voltagedomain *voltdm)
  210. {
  211. struct omap_vp_instance *vp;
  212. u32 vpconfig;
  213. if (!voltdm || IS_ERR(voltdm)) {
  214. pr_warning("%s: VDD specified does not exist!\n", __func__);
  215. return;
  216. }
  217. vp = voltdm->vp;
  218. if (!voltdm->read || !voltdm->write) {
  219. pr_err("%s: No read/write API for accessing vdd_%s regs\n",
  220. __func__, voltdm->name);
  221. return;
  222. }
  223. /* If VP is already enabled, do nothing. Return */
  224. if (vp->enabled)
  225. return;
  226. vp_latch_vsel(voltdm);
  227. /* Enable VP */
  228. vpconfig = voltdm->read(vp->vpconfig);
  229. vpconfig |= vp->common->vpconfig_vpenable;
  230. voltdm->write(vpconfig, vp->vpconfig);
  231. vp->enabled = true;
  232. }
  233. /**
  234. * omap_vp_disable() - API to disable a particular VP
  235. * @voltdm: pointer to the VDD whose VP is to be disabled.
  236. *
  237. * This API disables a particular voltage processor. Needed by the smartreflex
  238. * class drivers.
  239. */
  240. void omap_vp_disable(struct voltagedomain *voltdm)
  241. {
  242. struct omap_vp_instance *vp;
  243. u32 vpconfig;
  244. int timeout;
  245. if (!voltdm || IS_ERR(voltdm)) {
  246. pr_warning("%s: VDD specified does not exist!\n", __func__);
  247. return;
  248. }
  249. vp = voltdm->vp;
  250. if (!voltdm->read || !voltdm->write) {
  251. pr_err("%s: No read/write API for accessing vdd_%s regs\n",
  252. __func__, voltdm->name);
  253. return;
  254. }
  255. /* If VP is already disabled, do nothing. Return */
  256. if (!vp->enabled) {
  257. pr_warning("%s: Trying to disable VP for vdd_%s when"
  258. "it is already disabled\n", __func__, voltdm->name);
  259. return;
  260. }
  261. /* Disable VP */
  262. vpconfig = voltdm->read(vp->vpconfig);
  263. vpconfig &= ~vp->common->vpconfig_vpenable;
  264. voltdm->write(vpconfig, vp->vpconfig);
  265. /*
  266. * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
  267. */
  268. omap_test_timeout((voltdm->read(vp->vstatus)),
  269. VP_IDLE_TIMEOUT, timeout);
  270. if (timeout >= VP_IDLE_TIMEOUT)
  271. pr_warning("%s: vdd_%s idle timedout\n",
  272. __func__, voltdm->name);
  273. vp->enabled = false;
  274. return;
  275. }