We now use the previously defined oscillator setup / shutdown times to calculate the register values for CLKSETUP. Signed-off-by: Tero Kristo <t-kristo@xxxxxx> --- arch/arm/mach-omap2/vc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 8384b70..351319c 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -13,6 +13,8 @@ #include <linux/clk.h> #include <linux/io.h> +#include <asm/div64.h> + #include <plat/cpu.h> #include <plat/prcm.h> @@ -22,6 +24,7 @@ #include "prm-regbits-44xx.h" #include "prm44xx.h" #include "scrm44xx.h" +#include "pm.h" /** * struct omap_vc_channel_cfg - describe the cfg_channel bitfield @@ -209,11 +212,27 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm, return 0; } +static u32 omap_usec_to_32k(u32 usec) +{ + /* DIV_ROUND_UP expanded to 64bit to avoid overflow */ + u64 val = 32768ULL * (u64)usec + 1000000ULL - 1; + do_div(val, 1000000ULL); + return val; +} + +static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm) +{ + voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET); +} + static void omap3_set_i2c_timings(struct voltagedomain *voltdm, int off_mode) { unsigned long voltsetup1; u32 tgt_volt; + /* Oscillator is not shut down if omap is controlling voltages */ + omap3_set_clksetup(1, voltdm); + if (off_mode) tgt_volt = voltdm->vc_param->off; else @@ -241,6 +260,7 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm) unsigned long voltsetup2; unsigned long voltsetup2_old; u32 val; + u32 tstart, tshut; /* check if pmic is controlling off-mode voltages */ val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET); @@ -250,6 +270,9 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm) return; } + omap_pm_get_oscillator(&tstart, &tshut); + omap3_set_clksetup(tstart, voltdm); + clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET); /* voltsetup 2 in us */ @@ -336,10 +359,24 @@ static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff, (cycles << OMAP4430_RAMP_UP_COUNT_SHIFT); } +static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask) +{ + u32 val; + + val = omap_usec_to_32k(usec) << shift; + + /* Check for overflow, if yes, force to max value */ + if (val > mask) + val = mask; + + return val; +} + static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode) { u32 val; u32 ramp; + u32 tstart, tshut; /* configure the setup times */ val = voltdm->read(voltdm->vfsm->voltsetup_reg); @@ -361,6 +398,15 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode) val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT; voltdm->write(val, voltdm->vfsm->voltsetup_reg); + + omap_pm_get_oscillator(&tstart, &tshut); + + val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT, + OMAP4_SETUPTIME_MASK); + val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT, + OMAP4_DOWNTIME_MASK); + + __raw_writel(val, OMAP4_SCRM_CLKSETUPTIME); } /* OMAP4 specific voltage init functions */ -- 1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html