#include "prm-regbits-44xx.h"
#include "prm44xx.h"
-static void vp_latch_vsel(struct voltagedomain *voltdm)
+static u32 _vp_set_init_voltage(struct voltagedomain *voltdm, u32 volt)
{
struct omap_vp_instance *vp = voltdm->vp;
u32 vpconfig;
- unsigned long uvdc;
char vsel;
- uvdc = omap_voltage_get_nom_volt(voltdm);
- if (!uvdc) {
- pr_warning("%s: unable to find current voltage for vdd_%s\n",
- __func__, voltdm->name);
- return;
- }
-
- if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
- pr_warning("%s: PMIC function to convert voltage in uV to"
- " vsel not registered\n", __func__);
- return;
- }
-
- vsel = voltdm->pmic->uv_to_vsel(uvdc);
+ vsel = voltdm->pmic->uv_to_vsel(volt);
vpconfig = voltdm->read(vp->vpconfig);
vpconfig &= ~(vp->common->vpconfig_initvoltage_mask |
- vp->common->vpconfig_initvdd);
+ vp->common->vpconfig_forceupdate |
+ vp->common->vpconfig_initvdd);
vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask);
voltdm->write(vpconfig, vp->vpconfig);
/* Clear initVDD copy trigger bit */
voltdm->write(vpconfig, vp->vpconfig);
+
+ return vpconfig;
}
/* Generic voltage init functions */
u32 val, sys_clk_rate, timeout, waittime;
u32 vddmin, vddmax, vstepmin, vstepmax;
+ if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+ pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name);
+ return;
+ }
+
if (!voltdm->read || !voltdm->write) {
pr_err("%s: No read/write API for accessing vdd_%s regs\n",
__func__, voltdm->name);
vddmin = voltdm->pmic->vp_vddmin;
vddmax = voltdm->pmic->vp_vddmax;
- waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
- sys_clk_rate) / 1000;
+ waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate,
+ 1000 * voltdm->pmic->slew_rate);
vstepmin = voltdm->pmic->vp_vstepmin;
vstepmax = voltdm->pmic->vp_vstepmax;
return -ETIMEDOUT;
}
- /* Configure for VP-Force Update */
- vpconfig = voltdm->read(vp->vpconfig);
- vpconfig &= ~(vp->common->vpconfig_initvdd |
- vp->common->vpconfig_forceupdate |
- vp->common->vpconfig_initvoltage_mask);
- vpconfig |= ((target_vsel <<
- __ffs(vp->common->vpconfig_initvoltage_mask)));
- voltdm->write(vpconfig, vp->vpconfig);
-
- /* Trigger initVDD value copy to voltage processor */
- vpconfig |= vp->common->vpconfig_initvdd;
- voltdm->write(vpconfig, vp->vpconfig);
+ vpconfig = _vp_set_init_voltage(voltdm, target_volt);
/* Force update of voltage */
- vpconfig |= vp->common->vpconfig_forceupdate;
- voltdm->write(vpconfig, vp->vpconfig);
+ voltdm->write(vpconfig | vp->common->vpconfig_forceupdate,
+ voltdm->vp->vpconfig);
/*
* Wait for TransactionDone. Typical latency is <200us.
"to clear the TRANXDONE status\n",
__func__, voltdm->name);
- vpconfig = voltdm->read(vp->vpconfig);
- /* Clear initVDD copy trigger bit */
- vpconfig &= ~vp->common->vpconfig_initvdd;
- voltdm->write(vpconfig, vp->vpconfig);
/* Clear force bit */
- vpconfig &= ~vp->common->vpconfig_forceupdate;
voltdm->write(vpconfig, vp->vpconfig);
return 0;
}
-/**
- * omap_vp_get_curr_volt() - API to get the current vp voltage.
- * @voltdm: pointer to the VDD.
- *
- * This API returns the current voltage for the specified voltage processor
- */
-unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
-{
- struct omap_vp_instance *vp = voltdm->vp;
- u8 curr_vsel;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return 0;
- }
-
- if (!voltdm->read) {
- pr_err("%s: No read API for reading vdd_%s regs\n",
- __func__, voltdm->name);
- return 0;
- }
-
- curr_vsel = (voltdm->read(vp->voltage) & vp->common->vpvoltage_mask)
- >> __ffs(vp->common->vpvoltage_mask);
-
- if (!voltdm->pmic || !voltdm->pmic->vsel_to_uv) {
- pr_warning("%s: PMIC function to convert vsel to voltage"
- "in uV not registerd\n", __func__);
- return 0;
- }
-
- return voltdm->pmic->vsel_to_uv(curr_vsel);
-}
-
/**
* omap_vp_enable() - API to enable a particular VP
* @voltdm: pointer to the VDD whose VP is to be enabled.
void omap_vp_enable(struct voltagedomain *voltdm)
{
struct omap_vp_instance *vp;
- u32 vpconfig;
+ u32 vpconfig, volt;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
if (vp->enabled)
return;
- vp_latch_vsel(voltdm);
+ volt = voltdm_get_voltage(voltdm);
+ if (!volt) {
+ pr_warning("%s: unable to find current voltage for %s\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vpconfig = _vp_set_init_voltage(voltdm, volt);
/* Enable VP */
- vpconfig = voltdm->read(vp->vpconfig);
vpconfig |= vp->common->vpconfig_vpenable;
voltdm->write(vpconfig, vp->vpconfig);
+
vp->enabled = true;
}