diff options
author | Alex Frid <afrid@nvidia.com> | 2013-09-28 23:22:39 -0700 |
---|---|---|
committer | Yu-Huan Hsu <yhsu@nvidia.com> | 2013-10-11 14:33:06 -0700 |
commit | 52896670d023912bb04189a1b5c0dbcd85303240 (patch) | |
tree | 11edec05eeb9c64809a5180c04386941e9ec88bd /arch/arm/mach-tegra/tegra12_emc.c | |
parent | d1d4ca66a469a746c644be76fb10f754400d9a5a (diff) |
ARM: tegra12: clock: Separate EMC DVFS voltage steps
Separated EMC DVFS voltage steps from all other VDD_CORE clock
domains, since EMC steps are, in fact, different, and can very for
different board and DDR manufacturer combinations.
Change-Id: I6f01e664ba70dbd105124e31dee8c805d3823217
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/289510
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Xue Dong <xdong@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra12_emc.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra12_emc.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/arch/arm/mach-tegra/tegra12_emc.c b/arch/arm/mach-tegra/tegra12_emc.c index cfb9ccba635f..77ca7844d133 100644 --- a/arch/arm/mach-tegra/tegra12_emc.c +++ b/arch/arm/mach-tegra/tegra12_emc.c @@ -1020,30 +1020,38 @@ static int find_matching_input(const struct tegra12_emc_table *table, return 0; } + +static int emc_core_millivolts[MAX_DVFS_FREQS]; + static void adjust_emc_dvfs_table(const struct tegra12_emc_table *table, int table_size) { - int i, j; + int i, j, mv; unsigned long rate; - for (i = 0; i < MAX_DVFS_FREQS; i++) { - int mv = emc->dvfs->millivolts[i]; - if (!mv) - break; + BUG_ON(table_size > MAX_DVFS_FREQS); - /* For each dvfs voltage find maximum supported rate; - use 1MHz placeholder if not found */ - for (rate = 1000, j = 0; j < table_size; j++) { - if (tegra_emc_clk_sel[j].input == NULL) - continue; /* invalid entry */ + for (i = 0, j = 0; j < table_size; j++) { + if (tegra_emc_clk_sel[j].input == NULL) + continue; /* invalid entry */ - if ((mv >= table[j].emc_min_mv) && - (rate < table[j].rate)) - rate = table[j].rate; + rate = table[j].rate * 1000; + mv = table[j].emc_min_mv; + + if ((i == 0) || (mv > emc_core_millivolts[i-1])) { + /* advance: either regular or ll voltage increased - + assure the same set of dvfs freqs in both modes */ + emc->dvfs->freqs[i] = rate; + emc_core_millivolts[i] = mv; + i++; + } else { + /* squash: voltage has not increased */ + emc->dvfs->freqs[i-1] = rate; } - /* Table entries specify rate in kHz */ - emc->dvfs->freqs[i] = rate * 1000; } + + emc->dvfs->millivolts = emc_core_millivolts; + emc->dvfs->num_freqs = i; } #ifdef CONFIG_TEGRA_PLLM_SCALED @@ -1126,10 +1134,13 @@ static int init_emc_table(const struct tegra12_emc_table *table, int table_size) for (i = 0; i < tegra_emc_table_size; i++) { unsigned long table_rate = table[i].rate; - /* Skip "no-rate" entry, or entry violating ascending order */ - if (!table_rate || - (i && (table_rate <= table[i-1].rate))) - continue; + /* Stop: "no-rate" entry, or entry violating ascending order */ + if (!table_rate || (i && ((table_rate <= table[i-1].rate) || + (table[i].emc_min_mv < table[i-1].emc_min_mv)))) { + pr_warn("tegra: EMC rate entry %lu is not ascending\n", + table_rate); + break; + } BUG_ON(table[i].rev != table[0].rev); |