From: Kevin Hilman <khilman@ti.com>
To: Tero Kristo <t-kristo@ti.com>
Cc: linux-omap@vger.kernel.org
Subject: Re: [PATCHv3 06/11] omap3+: vc: use new vc_params and vp_params in parameter calculations
Date: Fri, 04 Nov 2011 14:11:28 -0700 [thread overview]
Message-ID: <87zkgb7fun.fsf@ti.com> (raw)
In-Reply-To: <1317835031-8201-7-git-send-email-t-kristo@ti.com> (Tero Kristo's message of "Wed, 5 Oct 2011 20:17:06 +0300")
Tero Kristo <t-kristo@ti.com> writes:
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
Missing descriptive changelog.
Some minor comments below...
Also, all of these timing calculations would benefit from a few more
pairs of eyes looking at this stuff, as I'm not the expert here. In
particular, I'd like to see a reviewed-by/acked-by on this stuff from
Nishanth Menon and anyone else who is familiar with the various timing
calculations.
> ---
> arch/arm/mach-omap2/vc.c | 166 ++++++++++++++++++++++++++++++++++++++--------
> 1 files changed, 138 insertions(+), 28 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
> index 16fa912..c50e598 100644
> --- a/arch/arm/mach-omap2/vc.c
> +++ b/arch/arm/mach-omap2/vc.c
> @@ -1,14 +1,18 @@
> #include <linux/kernel.h>
> #include <linux/delay.h>
> #include <linux/init.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
>
> #include <plat/cpu.h>
> +#include <plat/prcm.h>
>
> #include "voltage.h"
> #include "vc.h"
> #include "prm-regbits-34xx.h"
> #include "prm-regbits-44xx.h"
> #include "prm44xx.h"
> +#include "scrm44xx.h"
>
> /**
> * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
> @@ -194,44 +198,156 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm,
> return 0;
> }
>
> -static void __init omap3_vfsm_init(struct voltagedomain *voltdm)
> +static void omap3_set_ret_timings(struct voltagedomain *voltdm)
> {
> - /*
> - * Voltage Manager FSM parameters init
> - * XXX This data should be passed in from the board file
> - */
> - voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET);
> - voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET);
> - voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET);
> + unsigned long voltsetup1;
> + struct clk *sys_ck;
> + u32 sys_clk_rate;
> +
> + sys_ck = clk_get(NULL, "sys_ck");
> + if (IS_ERR(sys_ck)) {
> + pr_warning("%s: unable to get sys_ck to calculate "
> + "vdd_%s timings\n", __func__, voltdm->name);
> + return;
> + }
> + sys_clk_rate = clk_get_rate(sys_ck);
> + clk_put(sys_ck);
sys_clk_rate is already available in voltdm->sys_clk.rate, initialized
in late_init.
> + voltsetup1 = (voltdm->vc_param->on - voltdm->vc_param->ret) /
> + voltdm->pmic->slew_rate;
> +
> + voltsetup1 = voltsetup1 * sys_clk_rate / 8 / 1000000 + 1;
> + voltdm->rmw(voltdm->vfsm->voltsetup_mask,
> + voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
> + voltdm->vfsm->voltsetup_reg);
> +
> + /* set voltsetup 2 to 0 */
Comment is not helpful. Either describe why, or remove the comment
(preferably the former.)
> + voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
> +}
> +
> +static void omap3_set_off_timings(struct voltagedomain *voltdm)
> +{
> + unsigned long clksetup;
> + unsigned long voltsetup2;
> +
> + clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
> +
> + /* voltsetup 2 in us */
> + voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate;
> +
> + /* convert to 32k clk cycles */
> + voltsetup2 = voltsetup2 * 32768 / 1000000 + 1;
> +
> + voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET);
> +
> + /* set voltsetup1 to 0 */
> + voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0,
> + voltdm->vfsm->voltsetup_reg);
> +
> + /* set voltoffset */
comment not helpful
> + voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
> }
>
> static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
> {
> - static bool is_initialized;
> + omap3_set_off_timings(voltdm);
> +}
>
> - if (is_initialized)
> - return;
> +static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff,
> + u32 clk_rate)
> +{
> + u32 prescaler;
> + u32 cycles;
> + u32 time;
> +
> + time = voltage_diff / voltdm->pmic->slew_rate;
> +
> + cycles = clk_rate / 1000 * time;
> +
> + cycles /= 64;
> + prescaler = 0;
> +
> + /* shift to next prescaler until no overflow */
> +
> + /* scale for div 256 = 64 * 4 */
> + if (cycles > 63) {
> + cycles /= 4;
> + prescaler++;
> + }
> +
> + /* scale for div 512 = 256 * 2 */
> + if (cycles > 63) {
> + cycles /= 2;
> + prescaler++;
> + }
> +
> + /* scale for div 2048 = 512 * 4 */
> + if (cycles > 63) {
> + cycles /= 4;
> + prescaler++;
> + }
> +
> + /* check for overflow => invalid ramp time */
> + if (cycles > 63) {
> + pr_warning("%s: invalid setuptime for vdd_%s\n", __func__,
> + voltdm->name);
> + return 0;
> + }
>
> - omap3_vfsm_init(voltdm);
> + cycles++;
>
> - is_initialized = true;
> + return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) |
> + (cycles << OMAP4430_RAMP_UP_COUNT_SHIFT);
> }
>
> +static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
> +{
> + struct clk *sys_ck;
> + u32 sys_clk_rate;
> + u32 val;
> + u32 ramp;
> +
> + sys_ck = clk_get(NULL, "sys_clkin_ck");
> + if (IS_ERR(sys_ck)) {
> + pr_warning("%s: unable to get sys_ck to calculate "
> + "vdd_%s timings\n", __func__, voltdm->name);
> + return;
> + }
> + sys_clk_rate = clk_get_rate(sys_ck);
> + clk_put(sys_ck);
> +
> + /* configure the setup times */
> + val = voltdm->read(voltdm->vfsm->voltsetup_reg);
> +
> + if (off_mode)
> + ramp = omap4_calc_volt_ramp(voltdm,
> + voltdm->vc_param->on - voltdm->vc_param->off,
> + sys_clk_rate);
> + else
> + ramp = omap4_calc_volt_ramp(voltdm,
> + voltdm->vc_param->on - voltdm->vc_param->ret,
> + sys_clk_rate);
> +
> + if (!ramp)
> + return;
> +
> + val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT;
> +
> + val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT;
> +
> + voltdm->write(val, voltdm->vfsm->voltsetup_reg);
> +}
>
> /* OMAP4 specific voltage init functions */
> static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
> {
> - static bool is_initialized;
> u32 vc_val;
>
> - if (is_initialized)
> - return;
> + omap4_set_timings(voltdm, true);
Why the 2nd argument (off_mode)? Is it planned to change the timings
at runtime later?
> /* XXX These are magic numbers and do not belong! */
> vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
> voltdm->write(vc_val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
> -
> - is_initialized = true;
> }
>
> /**
> @@ -305,7 +421,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,
> @@ -329,10 +444,10 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
> }
>
> /* Set up the on, inactive, retention and off voltage */
> - on_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->on_volt);
> - onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt);
> - ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt);
> - off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt);
> + on_vsel = voltdm->pmic->uv_to_vsel(voltdm->vc_param->on);
> + onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->vc_param->onlp);
> + ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->vc_param->ret);
> + off_vsel = voltdm->pmic->uv_to_vsel(voltdm->vc_param->off);
> val = ((on_vsel << vc->common->cmd_on_shift) |
> (onlp_vsel << vc->common->cmd_onlp_shift) |
> (ret_vsel << vc->common->cmd_ret_shift) |
> @@ -343,11 +458,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())
Kevin
next prev parent reply other threads:[~2011-11-04 21:11 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-05 17:17 [PATCHv3 00/11] voltage domain cleanup Tero Kristo
2011-10-05 17:17 ` [PATCHv3 01/11] OMAP3+: PM: VP: use uV for max and min voltage limits Tero Kristo
2011-10-05 17:17 ` [PATCHv3 02/11] omap: voltage: add definitions for omap_vp_param and omap_vc_param Tero Kristo
2011-10-05 17:17 ` [PATCHv3 03/11] omap3: add vp and vc parameter data Tero Kristo
2011-11-04 20:22 ` Kevin Hilman
2011-10-05 17:17 ` [PATCHv3 04/11] omap4: " Tero Kristo
2011-11-04 20:22 ` Kevin Hilman
2011-10-05 17:17 ` [PATCHv3 05/11] OMAP2+: PM: provide mechanism to describe overall behavior of osc and PMIC Tero Kristo
2011-11-04 21:02 ` Kevin Hilman
2011-10-05 17:17 ` [PATCHv3 06/11] omap3+: vc: use new vc_params and vp_params in parameter calculations Tero Kristo
2011-11-04 21:11 ` Kevin Hilman [this message]
2011-10-05 17:17 ` [PATCHv3 07/11] omap3+: vp: use new vp_params for calculating vddmin and vddmax Tero Kristo
2011-11-04 21:13 ` Kevin Hilman
2011-10-05 17:17 ` [PATCHv3 08/11] omap3+: voltage: remove obsolete parameters Tero Kristo
2011-11-04 21:17 ` Kevin Hilman
2011-10-05 17:17 ` [PATCHv3 09/11] omap4: twl: added pmic startup / shutdown times Tero Kristo
2011-11-04 21:21 ` Kevin Hilman
2011-11-04 21:21 ` Kevin Hilman
2011-10-05 17:17 ` [PATCHv3 10/11] omap3+: use lp params for calculating clock setup times Tero Kristo
2011-11-04 21:38 ` Kevin Hilman
2011-11-15 17:22 ` Tero Kristo
2011-11-17 0:10 ` Kevin Hilman
2011-10-05 17:17 ` [PATCHv3 11/11] omap4: use lp params for calculating pmic " Tero Kristo
2011-11-04 20:49 ` Kevin Hilman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87zkgb7fun.fsf@ti.com \
--to=khilman@ti.com \
--cc=linux-omap@vger.kernel.org \
--cc=t-kristo@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.