vp.c 11 KB

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