vp.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #include "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 u32 _vp_set_init_voltage(struct voltagedomain *voltdm, u32 volt)
  10. {
  11. struct omap_vp_instance *vp = voltdm->vp;
  12. u32 vpconfig;
  13. char vsel;
  14. vsel = voltdm->pmic->uv_to_vsel(volt);
  15. vpconfig = voltdm->read(vp->vpconfig);
  16. vpconfig &= ~(vp->common->vpconfig_initvoltage_mask |
  17. vp->common->vpconfig_forceupdate |
  18. vp->common->vpconfig_initvdd);
  19. vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask);
  20. voltdm->write(vpconfig, vp->vpconfig);
  21. /* Trigger initVDD value copy to voltage processor */
  22. voltdm->write((vpconfig | vp->common->vpconfig_initvdd),
  23. vp->vpconfig);
  24. /* Clear initVDD copy trigger bit */
  25. voltdm->write(vpconfig, vp->vpconfig);
  26. return vpconfig;
  27. }
  28. /* Generic voltage init functions */
  29. void __init omap_vp_init(struct voltagedomain *voltdm)
  30. {
  31. struct omap_vp_instance *vp = voltdm->vp;
  32. u32 val, sys_clk_rate, timeout, waittime;
  33. u32 vddmin, vddmax, vstepmin, vstepmax;
  34. if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
  35. pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name);
  36. return;
  37. }
  38. if (!voltdm->read || !voltdm->write) {
  39. pr_err("%s: No read/write API for accessing vdd_%s regs\n",
  40. __func__, voltdm->name);
  41. return;
  42. }
  43. vp->enabled = false;
  44. /* Divide to avoid overflow */
  45. sys_clk_rate = voltdm->sys_clk.rate / 1000;
  46. timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
  47. vddmin = voltdm->pmic->vp_vddmin;
  48. vddmax = voltdm->pmic->vp_vddmax;
  49. waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate,
  50. 1000 * voltdm->pmic->slew_rate);
  51. vstepmin = voltdm->pmic->vp_vstepmin;
  52. vstepmax = voltdm->pmic->vp_vstepmax;
  53. /*
  54. * VP_CONFIG: error gain is not set here, it will be updated
  55. * on each scale, based on OPP.
  56. */
  57. val = (voltdm->pmic->vp_erroroffset <<
  58. __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)) |
  59. vp->common->vpconfig_timeouten;
  60. voltdm->write(val, vp->vpconfig);
  61. /* VSTEPMIN */
  62. val = (waittime << vp->common->vstepmin_smpswaittimemin_shift) |
  63. (vstepmin << vp->common->vstepmin_stepmin_shift);
  64. voltdm->write(val, vp->vstepmin);
  65. /* VSTEPMAX */
  66. val = (vstepmax << vp->common->vstepmax_stepmax_shift) |
  67. (waittime << vp->common->vstepmax_smpswaittimemax_shift);
  68. voltdm->write(val, vp->vstepmax);
  69. /* VLIMITTO */
  70. val = (vddmax << vp->common->vlimitto_vddmax_shift) |
  71. (vddmin << vp->common->vlimitto_vddmin_shift) |
  72. (timeout << vp->common->vlimitto_timeout_shift);
  73. voltdm->write(val, vp->vlimitto);
  74. }
  75. int omap_vp_update_errorgain(struct voltagedomain *voltdm,
  76. unsigned long target_volt)
  77. {
  78. struct omap_volt_data *volt_data;
  79. if (!voltdm->vp)
  80. return -EINVAL;
  81. /* Get volt_data corresponding to target_volt */
  82. volt_data = omap_voltage_get_voltdata(voltdm, target_volt);
  83. if (IS_ERR(volt_data))
  84. return -EINVAL;
  85. /* Setting vp errorgain based on the voltage */
  86. voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask,
  87. volt_data->vp_errgain <<
  88. __ffs(voltdm->vp->common->vpconfig_errorgain_mask),
  89. voltdm->vp->vpconfig);
  90. return 0;
  91. }
  92. /* VP force update method of voltage scaling */
  93. int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
  94. unsigned long target_volt)
  95. {
  96. struct omap_vp_instance *vp = voltdm->vp;
  97. u32 vpconfig;
  98. u8 target_vsel, current_vsel;
  99. int ret, timeout = 0;
  100. ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
  101. if (ret)
  102. return ret;
  103. /*
  104. * Clear all pending TransactionDone interrupt/status. Typical latency
  105. * is <3us
  106. */
  107. while (timeout++ < VP_TRANXDONE_TIMEOUT) {
  108. vp->common->ops->clear_txdone(vp->id);
  109. if (!vp->common->ops->check_txdone(vp->id))
  110. break;
  111. udelay(1);
  112. }
  113. if (timeout >= VP_TRANXDONE_TIMEOUT) {
  114. pr_warn("%s: vdd_%s TRANXDONE timeout exceeded. Voltage change aborted",
  115. __func__, voltdm->name);
  116. return -ETIMEDOUT;
  117. }
  118. vpconfig = _vp_set_init_voltage(voltdm, target_volt);
  119. /* Force update of voltage */
  120. voltdm->write(vpconfig | vp->common->vpconfig_forceupdate,
  121. voltdm->vp->vpconfig);
  122. /*
  123. * Wait for TransactionDone. Typical latency is <200us.
  124. * Depends on SMPSWAITTIMEMIN/MAX and voltage change
  125. */
  126. timeout = 0;
  127. omap_test_timeout(vp->common->ops->check_txdone(vp->id),
  128. VP_TRANXDONE_TIMEOUT, timeout);
  129. if (timeout >= VP_TRANXDONE_TIMEOUT)
  130. pr_err("%s: vdd_%s TRANXDONE timeout exceeded. TRANXDONE never got set after the voltage update\n",
  131. __func__, voltdm->name);
  132. omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
  133. /*
  134. * Disable TransactionDone interrupt , clear all status, clear
  135. * control registers
  136. */
  137. timeout = 0;
  138. while (timeout++ < VP_TRANXDONE_TIMEOUT) {
  139. vp->common->ops->clear_txdone(vp->id);
  140. if (!vp->common->ops->check_txdone(vp->id))
  141. break;
  142. udelay(1);
  143. }
  144. if (timeout >= VP_TRANXDONE_TIMEOUT)
  145. pr_warn("%s: vdd_%s TRANXDONE timeout exceeded while trying to clear the TRANXDONE status\n",
  146. __func__, voltdm->name);
  147. /* Clear force bit */
  148. voltdm->write(vpconfig, vp->vpconfig);
  149. return 0;
  150. }
  151. /**
  152. * omap_vp_enable() - API to enable a particular VP
  153. * @voltdm: pointer to the VDD whose VP is to be enabled.
  154. *
  155. * This API enables a particular voltage processor. Needed by the smartreflex
  156. * class drivers.
  157. */
  158. void omap_vp_enable(struct voltagedomain *voltdm)
  159. {
  160. struct omap_vp_instance *vp;
  161. u32 vpconfig, volt;
  162. if (!voltdm || IS_ERR(voltdm)) {
  163. pr_warning("%s: VDD specified does not exist!\n", __func__);
  164. return;
  165. }
  166. vp = voltdm->vp;
  167. if (!voltdm->read || !voltdm->write) {
  168. pr_err("%s: No read/write API for accessing vdd_%s regs\n",
  169. __func__, voltdm->name);
  170. return;
  171. }
  172. /* If VP is already enabled, do nothing. Return */
  173. if (vp->enabled)
  174. return;
  175. volt = voltdm_get_voltage(voltdm);
  176. if (!volt) {
  177. pr_warning("%s: unable to find current voltage for %s\n",
  178. __func__, voltdm->name);
  179. return;
  180. }
  181. vpconfig = _vp_set_init_voltage(voltdm, volt);
  182. /* Enable VP */
  183. vpconfig |= vp->common->vpconfig_vpenable;
  184. voltdm->write(vpconfig, vp->vpconfig);
  185. vp->enabled = true;
  186. }
  187. /**
  188. * omap_vp_disable() - API to disable a particular VP
  189. * @voltdm: pointer to the VDD whose VP is to be disabled.
  190. *
  191. * This API disables a particular voltage processor. Needed by the smartreflex
  192. * class drivers.
  193. */
  194. void omap_vp_disable(struct voltagedomain *voltdm)
  195. {
  196. struct omap_vp_instance *vp;
  197. u32 vpconfig;
  198. int timeout;
  199. if (!voltdm || IS_ERR(voltdm)) {
  200. pr_warning("%s: VDD specified does not exist!\n", __func__);
  201. return;
  202. }
  203. vp = voltdm->vp;
  204. if (!voltdm->read || !voltdm->write) {
  205. pr_err("%s: No read/write API for accessing vdd_%s regs\n",
  206. __func__, voltdm->name);
  207. return;
  208. }
  209. /* If VP is already disabled, do nothing. Return */
  210. if (!vp->enabled) {
  211. pr_warn("%s: Trying to disable VP for vdd_%s when it is already disabled\n",
  212. __func__, voltdm->name);
  213. return;
  214. }
  215. /* Disable VP */
  216. vpconfig = voltdm->read(vp->vpconfig);
  217. vpconfig &= ~vp->common->vpconfig_vpenable;
  218. voltdm->write(vpconfig, vp->vpconfig);
  219. /*
  220. * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
  221. */
  222. omap_test_timeout((voltdm->read(vp->vstatus)),
  223. VP_IDLE_TIMEOUT, timeout);
  224. if (timeout >= VP_IDLE_TIMEOUT)
  225. pr_warning("%s: vdd_%s idle timedout\n",
  226. __func__, voltdm->name);
  227. vp->enabled = false;
  228. return;
  229. }