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