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_warn("%s: vdd_%s TRANXDONE timeout exceeded. Voltage change aborted", 142 __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. TRANXDONE never got set after the voltage update\n", 161 __func__, voltdm->name); 162 163 omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel); 164 165 /* 166 * Disable TransactionDone interrupt , clear all status, clear 167 * control registers 168 */ 169 timeout = 0; 170 while (timeout++ < VP_TRANXDONE_TIMEOUT) { 171 vp->common->ops->clear_txdone(vp->id); 172 if (!vp->common->ops->check_txdone(vp->id)) 173 break; 174 udelay(1); 175 } 176 177 if (timeout >= VP_TRANXDONE_TIMEOUT) 178 pr_warn("%s: vdd_%s TRANXDONE timeout exceeded while trying to clear the TRANXDONE status\n", 179 __func__, voltdm->name); 180 181 /* Clear force bit */ 182 voltdm->write(vpconfig, vp->vpconfig); 183 184 return 0; 185 } 186 187 /** 188 * omap_vp_enable() - API to enable a particular VP 189 * @voltdm: pointer to the VDD whose VP is to be enabled. 190 * 191 * This API enables a particular voltage processor. Needed by the smartreflex 192 * class drivers. 193 */ 194 void omap_vp_enable(struct voltagedomain *voltdm) 195 { 196 struct omap_vp_instance *vp; 197 u32 vpconfig, volt; 198 199 if (!voltdm || IS_ERR(voltdm)) { 200 pr_warning("%s: VDD specified does not exist!\n", __func__); 201 return; 202 } 203 204 vp = voltdm->vp; 205 if (!voltdm->read || !voltdm->write) { 206 pr_err("%s: No read/write API for accessing vdd_%s regs\n", 207 __func__, voltdm->name); 208 return; 209 } 210 211 /* If VP is already enabled, do nothing. Return */ 212 if (vp->enabled) 213 return; 214 215 volt = voltdm_get_voltage(voltdm); 216 if (!volt) { 217 pr_warning("%s: unable to find current voltage for %s\n", 218 __func__, voltdm->name); 219 return; 220 } 221 222 vpconfig = _vp_set_init_voltage(voltdm, volt); 223 224 /* Enable VP */ 225 vpconfig |= vp->common->vpconfig_vpenable; 226 voltdm->write(vpconfig, vp->vpconfig); 227 228 vp->enabled = true; 229 } 230 231 /** 232 * omap_vp_disable() - API to disable a particular VP 233 * @voltdm: pointer to the VDD whose VP is to be disabled. 234 * 235 * This API disables a particular voltage processor. Needed by the smartreflex 236 * class drivers. 237 */ 238 void omap_vp_disable(struct voltagedomain *voltdm) 239 { 240 struct omap_vp_instance *vp; 241 u32 vpconfig; 242 int timeout; 243 244 if (!voltdm || IS_ERR(voltdm)) { 245 pr_warning("%s: VDD specified does not exist!\n", __func__); 246 return; 247 } 248 249 vp = voltdm->vp; 250 if (!voltdm->read || !voltdm->write) { 251 pr_err("%s: No read/write API for accessing vdd_%s regs\n", 252 __func__, voltdm->name); 253 return; 254 } 255 256 /* If VP is already disabled, do nothing. Return */ 257 if (!vp->enabled) { 258 pr_warn("%s: Trying to disable VP for vdd_%s when it is already disabled\n", 259 __func__, voltdm->name); 260 return; 261 } 262 263 /* Disable VP */ 264 vpconfig = voltdm->read(vp->vpconfig); 265 vpconfig &= ~vp->common->vpconfig_vpenable; 266 voltdm->write(vpconfig, vp->vpconfig); 267 268 /* 269 * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us 270 */ 271 omap_test_timeout((voltdm->read(vp->vstatus)), 272 VP_IDLE_TIMEOUT, timeout); 273 274 if (timeout >= VP_IDLE_TIMEOUT) 275 pr_warning("%s: vdd_%s idle timedout\n", 276 __func__, voltdm->name); 277 278 vp->enabled = false; 279 280 return; 281 } 282