summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra_cl_dvfs.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2014-04-08 22:15:59 -0700
committerYu-Huan Hsu <yhsu@nvidia.com>2014-04-10 13:22:47 -0700
commit5893a1db722af8827a108c880d5d16d9eeb34990 (patch)
tree98a0cabf486a44854658905ad4c59c4dbac96349 /arch/arm/mach-tegra/tegra_cl_dvfs.c
parente594b048123536ff28013ae7d688be129178e6a1 (diff)
ARM: tegra: dvfs: Use hrtimer for DFLL tuning
Used high resolution timer for DFLL tuning. Since Tegra13 is running with HZ = 100, regular timer resolution 10ms is too coarse for 1-2ms tuning delay. Change-Id: I10adf8518973256bb1c1e6129af60893c02ceabf Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/393776 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra_cl_dvfs.c')
-rw-r--r--arch/arm/mach-tegra/tegra_cl_dvfs.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/arch/arm/mach-tegra/tegra_cl_dvfs.c b/arch/arm/mach-tegra/tegra_cl_dvfs.c
index ab76c08453e4..f6cfca034b01 100644
--- a/arch/arm/mach-tegra/tegra_cl_dvfs.c
+++ b/arch/arm/mach-tegra/tegra_cl_dvfs.c
@@ -237,8 +237,8 @@ struct tegra_cl_dvfs {
enum tegra_cl_dvfs_tune_state tune_state;
enum tegra_cl_dvfs_ctrl_mode mode;
- struct timer_list tune_timer;
- unsigned long tune_delay;
+ struct hrtimer tune_timer;
+ ktime_t tune_delay;
struct timer_list calibration_timer;
unsigned long calibration_delay;
ktime_t last_calibration;
@@ -768,7 +768,8 @@ static void set_cl_config(struct tegra_cl_dvfs *cld, struct dfll_rate_req *req)
case TEGRA_CL_DVFS_TUNE_LOW:
if (cl_tune_target(cld, req->rate) > TEGRA_CL_DVFS_TUNE_LOW) {
set_tune_state(cld, TEGRA_CL_DVFS_TUNE_HIGH_REQUEST);
- mod_timer(&cld->tune_timer, jiffies + cld->tune_delay);
+ hrtimer_start(&cld->tune_timer, cld->tune_delay,
+ HRTIMER_MODE_REL);
cl_dvfs_set_force_out_min(cld);
}
break;
@@ -846,11 +847,12 @@ static void set_ol_config(struct tegra_cl_dvfs *cld)
cl_dvfs_writel(cld, val, CL_DVFS_FREQ_REQ);
}
-static void tune_timer_cb(unsigned long data)
+static enum hrtimer_restart tune_timer_cb(struct hrtimer *timer)
{
unsigned long flags;
u32 val, out_min, out_last;
- struct tegra_cl_dvfs *cld = (struct tegra_cl_dvfs *)data;
+ struct tegra_cl_dvfs *cld =
+ container_of(timer, struct tegra_cl_dvfs, tune_timer);
clk_lock_save(cld->dfll_clk, &flags);
@@ -868,10 +870,13 @@ static void tune_timer_cb(unsigned long data)
set_tune_state(cld, TEGRA_CL_DVFS_TUNE_HIGH);
tune_high(cld);
} else {
- mod_timer(&cld->tune_timer, jiffies + cld->tune_delay);
+ hrtimer_start(&cld->tune_timer, cld->tune_delay,
+ HRTIMER_MODE_REL);
}
}
clk_unlock_restore(cld->dfll_clk, &flags);
+
+ return HRTIMER_NORESTART;
}
static inline void calibration_timer_update(struct tegra_cl_dvfs *cld)
@@ -1621,10 +1626,9 @@ static int cl_dvfs_init(struct tegra_cl_dvfs *cld)
BUG_ON(!cld->ref_rate);
/* init tuning timer */
- init_timer(&cld->tune_timer);
+ hrtimer_init(&cld->tune_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
cld->tune_timer.function = tune_timer_cb;
- cld->tune_timer.data = (unsigned long)cld;
- cld->tune_delay = usecs_to_jiffies(CL_DVFS_TUNE_HIGH_DELAY);
+ cld->tune_delay = ktime_set(0, CL_DVFS_TUNE_HIGH_DELAY * 1000);
/* init calibration timer */
init_timer_deferrable(&cld->calibration_timer);