Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 342421
b: refs/heads/master
c: c589eb3
h: refs/heads/master
i:
  342419: 6ed9179
v: v3
  • Loading branch information
Tero Kristo authored and Kevin Hilman committed Nov 5, 2012
1 parent 357b6e6 commit 723ed39
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8b5d8c0d718379ce29dad74b4bda8b669fc1f1c2
refs/heads/master: c589eb3869a8ad6185669f5477bf72d6d46068de
108 changes: 91 additions & 17 deletions trunk/arch/arm/mach-omap2/vc.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,29 +204,109 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm,
return 0;
}

static void __init omap3_vfsm_init(struct voltagedomain *voltdm)
/**
* omap3_set_i2c_timings - sets i2c sleep timings for a channel
* @voltdm: channel to configure
* @off_mode: select whether retention or off mode values used
*
* Calculates and sets up voltage controller to use I2C based
* voltage scaling for sleep modes. This can be used for either off mode
* or retention. Off mode has additionally an option to use sys_off_mode
* pad, which uses a global signal to program the whole power IC to
* off-mode.
*/
static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
{
unsigned long voltsetup1;
u32 tgt_volt;

if (off_mode)
tgt_volt = voltdm->vc_param->off;
else
tgt_volt = voltdm->vc_param->ret;

voltsetup1 = (voltdm->vc_param->on - tgt_volt) /
voltdm->pmic->slew_rate;

voltsetup1 = voltsetup1 * voltdm->sys_clk.rate / 8 / 1000000 + 1;

voltdm->rmw(voltdm->vfsm->voltsetup_mask,
voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
voltdm->vfsm->voltsetup_reg);

/*
* Voltage Manager FSM parameters init
* XXX This data should be passed in from the board file
* pmic is not controlling the voltage scaling during retention,
* thus set voltsetup2 to 0
*/
voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET);
voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET);
voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET);
voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
}

static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
/**
* omap3_set_off_timings - sets off-mode timings for a channel
* @voltdm: channel to configure
*
* Calculates and sets up off-mode timings for a channel. Off-mode
* can use either I2C based voltage scaling, or alternatively
* sys_off_mode pad can be used to send a global command to power IC.
* This function first checks which mode is being used, and calls
* omap3_set_i2c_timings() if the system is using I2C control mode.
* sys_off_mode has the additional benefit that voltages can be
* scaled to zero volt level with TWL4030 / TWL5030, I2C can only
* scale to 600mV.
*/
static void omap3_set_off_timings(struct voltagedomain *voltdm)
{
static bool is_initialized;
unsigned long clksetup;
unsigned long voltsetup2;
unsigned long voltsetup2_old;
u32 val;

if (is_initialized)
/* check if sys_off_mode is used to control off-mode voltages */
val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
if (!(val & OMAP3430_SEL_OFF_MASK)) {
/* No, omap is controlling them over I2C */
omap3_set_i2c_timings(voltdm, true);
return;
}

omap3_vfsm_init(voltdm);
clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);

is_initialized = true;
/* voltsetup 2 in us */
voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate;

/* convert to 32k clk cycles */
voltsetup2 = DIV_ROUND_UP(voltsetup2 * 32768, 1000000);

voltsetup2_old = voltdm->read(OMAP3_PRM_VOLTSETUP2_OFFSET);

/*
* Update voltsetup2 if higher than current value (needed because
* we have multiple channels with different ramp times), also
* update voltoffset always to value recommended by TRM
*/
if (voltsetup2 > voltsetup2_old) {
voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET);
voltdm->write(clksetup - voltsetup2,
OMAP3_PRM_VOLTOFFSET_OFFSET);
} else
voltdm->write(clksetup - voltsetup2_old,
OMAP3_PRM_VOLTOFFSET_OFFSET);

/*
* omap is not controlling voltage scaling during off-mode,
* thus set voltsetup1 to 0
*/
voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0,
voltdm->vfsm->voltsetup_reg);

/* voltoffset must be clksetup minus voltsetup2 according to TRM */
voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
}

static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
{
omap3_set_off_timings(voltdm);
}

/* OMAP4 specific voltage init functions */
static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
Expand Down Expand Up @@ -337,7 +417,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr;
vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
vc->setup_time = voltdm->pmic->volt_setup_time;

/* Configure the i2c slave address for this VC */
voltdm->rmw(vc->smps_sa_mask,
Expand Down Expand Up @@ -376,11 +455,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
/* Channel configuration */
omap_vc_config_channel(voltdm);

/* Configure the setup times */
voltdm->rmw(voltdm->vfsm->voltsetup_mask,
vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask),
voltdm->vfsm->voltsetup_reg);

omap_vc_i2c_init(voltdm);

if (cpu_is_omap34xx())
Expand Down
1 change: 0 additions & 1 deletion trunk/arch/arm/mach-omap2/vc.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ struct omap_vc_channel {
u16 i2c_slave_addr;
u16 volt_reg_addr;
u16 cmd_reg_addr;
u16 setup_time;
u8 cfg_channel;
bool i2c_high_speed;

Expand Down

0 comments on commit 723ed39

Please sign in to comment.