1 #include <linux/kernel.h>
2 #include <linux/init.h>
4 #include <plat/common.h>
8 #include "prm-regbits-34xx.h"
9 #include "prm-regbits-44xx.h"
12 static void vp_latch_vsel(struct voltagedomain *voltdm)
14 struct omap_vp_instance *vp = voltdm->vp;
19 uvdc = omap_voltage_get_nom_volt(voltdm);
21 pr_warning("%s: unable to find current voltage for vdd_%s\n",
22 __func__, voltdm->name);
26 if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
27 pr_warning("%s: PMIC function to convert voltage in uV to"
28 " vsel not registered\n", __func__);
32 vsel = voltdm->pmic->uv_to_vsel(uvdc);
34 vpconfig = voltdm->read(vp->vpconfig);
35 vpconfig &= ~(vp->common->vpconfig_initvoltage_mask |
36 vp->common->vpconfig_initvdd);
37 vpconfig |= vsel << vp->common->vpconfig_initvoltage_shift;
39 voltdm->write(vpconfig, vp->vpconfig);
41 /* Trigger initVDD value copy to voltage processor */
42 voltdm->write((vpconfig | vp->common->vpconfig_initvdd),
45 /* Clear initVDD copy trigger bit */
46 voltdm->write(vpconfig, vp->vpconfig);
49 /* Generic voltage init functions */
50 void __init omap_vp_init(struct voltagedomain *voltdm)
52 struct omap_vp_instance *vp = voltdm->vp;
53 struct omap_vdd_info *vdd = voltdm->vdd;
56 if (!voltdm->read || !voltdm->write) {
57 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
58 __func__, voltdm->name);
62 vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
63 (vdd->vp_rt_data.vpconfig_errorgain <<
64 vp->common->vpconfig_errorgain_shift) |
65 vp->common->vpconfig_timeouten;
66 voltdm->write(vp_val, vp->vpconfig);
68 vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
69 vp->common->vstepmin_smpswaittimemin_shift) |
70 (vdd->vp_rt_data.vstepmin_stepmin <<
71 vp->common->vstepmin_stepmin_shift));
72 voltdm->write(vp_val, vp->vstepmin);
74 vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
75 vp->common->vstepmax_smpswaittimemax_shift) |
76 (vdd->vp_rt_data.vstepmax_stepmax <<
77 vp->common->vstepmax_stepmax_shift));
78 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);
89 /* VP force update method of voltage scaling */
90 int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
91 unsigned long target_volt)
93 struct omap_vp_instance *vp = voltdm->vp;
95 u8 target_vsel, current_vsel;
98 ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, ¤t_vsel);
103 * Clear all pending TransactionDone interrupt/status. Typical latency
106 while (timeout++ < VP_TRANXDONE_TIMEOUT) {
107 vp->common->ops->clear_txdone(vp->id);
108 if (!vp->common->ops->check_txdone(vp->id))
112 if (timeout >= VP_TRANXDONE_TIMEOUT) {
113 pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
114 "Voltage change aborted", __func__, voltdm->name);
118 /* Configure for VP-Force Update */
119 vpconfig = voltdm->read(vp->vpconfig);
120 vpconfig &= ~(vp->common->vpconfig_initvdd |
121 vp->common->vpconfig_forceupdate |
122 vp->common->vpconfig_initvoltage_mask);
123 vpconfig |= ((target_vsel <<
124 vp->common->vpconfig_initvoltage_shift));
125 voltdm->write(vpconfig, vp->vpconfig);
127 /* Trigger initVDD value copy to voltage processor */
128 vpconfig |= vp->common->vpconfig_initvdd;
129 voltdm->write(vpconfig, vp->vpconfig);
131 /* Force update of voltage */
132 vpconfig |= vp->common->vpconfig_forceupdate;
133 voltdm->write(vpconfig, vp->vpconfig);
136 * Wait for TransactionDone. Typical latency is <200us.
137 * Depends on SMPSWAITTIMEMIN/MAX and voltage change
140 omap_test_timeout(vp->common->ops->check_txdone(vp->id),
141 VP_TRANXDONE_TIMEOUT, timeout);
142 if (timeout >= VP_TRANXDONE_TIMEOUT)
143 pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
144 "TRANXDONE never got set after the voltage update\n",
145 __func__, voltdm->name);
147 omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
150 * Disable TransactionDone interrupt , clear all status, clear
154 while (timeout++ < VP_TRANXDONE_TIMEOUT) {
155 vp->common->ops->clear_txdone(vp->id);
156 if (!vp->common->ops->check_txdone(vp->id))
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);
166 vpconfig = voltdm->read(vp->vpconfig);
167 /* Clear initVDD copy trigger bit */
168 vpconfig &= ~vp->common->vpconfig_initvdd;
169 voltdm->write(vpconfig, vp->vpconfig);
170 /* Clear force bit */
171 vpconfig &= ~vp->common->vpconfig_forceupdate;
172 voltdm->write(vpconfig, vp->vpconfig);
178 * omap_vp_get_curr_volt() - API to get the current vp voltage.
179 * @voltdm: pointer to the VDD.
181 * This API returns the current voltage for the specified voltage processor
183 unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
185 struct omap_vp_instance *vp = voltdm->vp;
188 if (!voltdm || IS_ERR(voltdm)) {
189 pr_warning("%s: VDD specified does not exist!\n", __func__);
194 pr_err("%s: No read API for reading vdd_%s regs\n",
195 __func__, voltdm->name);
199 curr_vsel = voltdm->read(vp->voltage);
201 if (!voltdm->pmic || !voltdm->pmic->vsel_to_uv) {
202 pr_warning("%s: PMIC function to convert vsel to voltage"
203 "in uV not registerd\n", __func__);
207 return voltdm->pmic->vsel_to_uv(curr_vsel);
211 * omap_vp_enable() - API to enable a particular VP
212 * @voltdm: pointer to the VDD whose VP is to be enabled.
214 * This API enables a particular voltage processor. Needed by the smartreflex
217 void omap_vp_enable(struct voltagedomain *voltdm)
219 struct omap_vp_instance *vp;
222 if (!voltdm || IS_ERR(voltdm)) {
223 pr_warning("%s: VDD specified does not exist!\n", __func__);
228 if (!voltdm->read || !voltdm->write) {
229 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
230 __func__, voltdm->name);
234 /* If VP is already enabled, do nothing. Return */
238 vp_latch_vsel(voltdm);
241 vpconfig = voltdm->read(vp->vpconfig);
242 vpconfig |= vp->common->vpconfig_vpenable;
243 voltdm->write(vpconfig, vp->vpconfig);
248 * omap_vp_disable() - API to disable a particular VP
249 * @voltdm: pointer to the VDD whose VP is to be disabled.
251 * This API disables a particular voltage processor. Needed by the smartreflex
254 void omap_vp_disable(struct voltagedomain *voltdm)
256 struct omap_vp_instance *vp;
260 if (!voltdm || IS_ERR(voltdm)) {
261 pr_warning("%s: VDD specified does not exist!\n", __func__);
266 if (!voltdm->read || !voltdm->write) {
267 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
268 __func__, voltdm->name);
272 /* If VP is already disabled, do nothing. Return */
274 pr_warning("%s: Trying to disable VP for vdd_%s when"
275 "it is already disabled\n", __func__, voltdm->name);
280 vpconfig = voltdm->read(vp->vpconfig);
281 vpconfig &= ~vp->common->vpconfig_vpenable;
282 voltdm->write(vpconfig, vp->vpconfig);
285 * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
287 omap_test_timeout((voltdm->read(vp->vstatus)),
288 VP_IDLE_TIMEOUT, timeout);
290 if (timeout >= VP_IDLE_TIMEOUT)
291 pr_warning("%s: vdd_%s idle timedout\n",
292 __func__, voltdm->name);