diff options
author | Alex Frid <afrid@nvidia.com> | 2013-07-16 12:43:15 -0700 |
---|---|---|
committer | Harshada Kale <hkale@nvidia.com> | 2013-09-12 02:22:14 -0700 |
commit | 4f8581ad501bb1f1cceb772d80f38fb4c3c2dfca (patch) | |
tree | 54a6d518ec535fa15bb9a437b7aedf96dee2f2c0 /arch | |
parent | dbb6882a58b47f6af22d964bf873fb427a951877 (diff) |
ARM: tegra11: clock: Add cbus fine granularity region
Added fine granularity region to cbus possible rates. In this region
requested cbus rate is not clipped to dvfs steps, but rounded to fine
granularity resolution. The latter is set as 12MHz, and the region is
defined as 5 resolution steps below the top dvfs rate, assuming this
top rate is reachable on the particular chip bin/sku.
Change-Id: If1096ae068367819e64c55172c1a1c0a46c38b86
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/250033
(cherry picked from commit 0c7b83bffdf79615bf15301f8643ac1dfabdefd9)
Reviewed-on: http://git-master/r/253673
Tested-by: Shaoming Feng <shaomingf@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/tegra11_clocks.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/tegra11_clocks.c b/arch/arm/mach-tegra/tegra11_clocks.c index bb7a0cabfd24..0e2d8d402590 100644 --- a/arch/arm/mach-tegra/tegra11_clocks.c +++ b/arch/arm/mach-tegra/tegra11_clocks.c @@ -4560,10 +4560,14 @@ static int tegra11_clk_cbus_enable(struct clk *c) return 0; } +/* select 5 steps below top rate as fine granularity region */ +#define CBUS_FINE_GRANULARITY 12000000 /* 12 MHz */ +#define CBUS_FINE_GRANULARITY_RANGE (5 * CBUS_FINE_GRANULARITY) + static long tegra11_clk_cbus_round_updown(struct clk *c, unsigned long rate, bool up) { - int i; + int i, n; if (!c->dvfs) { if (!c->min_rate) @@ -4585,6 +4589,24 @@ static long tegra11_clk_cbus_round_updown(struct clk *c, unsigned long rate, } rate = max(rate, c->min_rate); + /* for top rates in fine granularity region don't clip to dvfs table */ + n = c->dvfs->num_freqs; + if ((n >= 2) && (c->dvfs->millivolts[n-1] <= c->dvfs->max_millivolts) && + (rate > c->dvfs->freqs[n-2])) { + unsigned long threshold = max(c->dvfs->freqs[n-1], + c->dvfs->freqs[n-2] + CBUS_FINE_GRANULARITY_RANGE); + threshold -= CBUS_FINE_GRANULARITY_RANGE; + + if (rate <= threshold) + return up ? threshold : c->dvfs->freqs[n-2]; + + rate = (up ? DIV_ROUND_UP(rate, CBUS_FINE_GRANULARITY) : + rate / CBUS_FINE_GRANULARITY) * CBUS_FINE_GRANULARITY; + rate = clamp(rate, threshold, c->dvfs->freqs[n-1]); + return rate; + } + + /* clip rate to dvfs table steps */ for (i = 0; ; i++) { unsigned long f = c->dvfs->freqs[i]; int mv = c->dvfs->millivolts[i]; |