vp.c 7.1 KB

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