From 3eeffbc3d34d05b668234306a7de2e157db9b8db Mon Sep 17 00:00:00 2001 From: Alex Frid Date: Fri, 22 Jun 2012 14:13:41 -0700 Subject: ARM: tegra: clock: Record EMC clock source rate On Tegra3 added source rate to EMC clock source selection structure, and re-factored EMC DVFS initialization accordingly. Bug 1005576 Change-Id: I155e982bef2431a76cf5e5085070d4e654a7b49b Signed-off-by: Alex Frid Reviewed-on: http://git-master/r/110935 Reviewed-by: Rohan Somvanshi Tested-by: Rohan Somvanshi (cherry picked from commit bf52c26c532a9ebabc4fc8a1fb5fc9d88be85e66) Reviewed-on: http://git-master/r/114758 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Jihoon Bang Reviewed-by: Yu-Huan Hsu --- arch/arm/mach-tegra/tegra3_emc.c | 60 ++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 27 deletions(-) (limited to 'arch/arm/mach-tegra/tegra3_emc.c') diff --git a/arch/arm/mach-tegra/tegra3_emc.c b/arch/arm/mach-tegra/tegra3_emc.c index 6d430b0a99e3..997507b50843 100644 --- a/arch/arm/mach-tegra/tegra3_emc.c +++ b/arch/arm/mach-tegra/tegra3_emc.c @@ -189,7 +189,13 @@ enum { static int emc_num_burst_regs; -static struct clk_mux_sel tegra_emc_clk_sel[TEGRA_EMC_TABLE_MAX_SIZE]; +struct emc_sel { + struct clk *input; + u32 value; + unsigned long input_rate; +}; + +static struct emc_sel tegra_emc_clk_sel[TEGRA_EMC_TABLE_MAX_SIZE]; static struct tegra_emc_table start_timing; static const struct tegra_emc_table *emc_timing; static unsigned long dram_over_temp_state = DRAM_OVER_TEMP_NONE; @@ -820,24 +826,37 @@ struct clk *tegra_emc_predict_parent(unsigned long rate, u32 *div_value) return NULL; } -static const struct clk_mux_sel *find_matching_input( - unsigned long table_rate, - u32 *div_value) +int find_matching_input(unsigned long table_rate, struct emc_sel *emc_clk_sel) { - unsigned long inp_rate; + u32 div_value; + unsigned long input_rate; const struct clk_mux_sel *sel; + /* Table entries specify rate in kHz */ + table_rate *= 1000; + for (sel = emc->inputs; sel->input != NULL; sel++) { - /* Table entries specify rate in kHz */ - inp_rate = clk_get_rate(sel->input) / 1000; + input_rate = clk_get_rate(sel->input); - if ((inp_rate >= table_rate) && - (inp_rate % table_rate == 0)) { - *div_value = 2 * inp_rate / table_rate - 2; - return sel; + if ((input_rate >= table_rate) && + (input_rate % table_rate == 0)) { + div_value = 2 * input_rate / table_rate - 2; + break; } } - return NULL; + + if (sel->input) { + emc_clk_sel->input = sel->input; + emc_clk_sel->input_rate = input_rate; + + /* Get ready emc clock selection settings for this table rate */ + emc_clk_sel->value = sel->value << EMC_CLK_SOURCE_SHIFT; + emc_clk_sel->value |= (div_value << EMC_CLK_DIV_SHIFT); + if ((div_value == 0) && (emc_clk_sel->input == emc->parent)) + emc_clk_sel->value |= EMC_CLK_LOW_JITTER_ENABLE; + return 0; + } + return -EINVAL; } static void adjust_emc_dvfs_table(const struct tegra_emc_table *table, @@ -941,10 +960,9 @@ static struct notifier_block tegra_emc_resume_nb = { void tegra_init_emc(const struct tegra_emc_table *table, int table_size) { int i, mv; - u32 reg, div_value; + u32 reg; bool max_entry = false; unsigned long boot_rate, max_rate; - const struct clk_mux_sel *sel; emc_stats.clkchange_count = 0; spin_lock_init(&emc_stats.spinlock); @@ -994,8 +1012,7 @@ void tegra_init_emc(const struct tegra_emc_table *table, int table_size) BUG_ON(table[i].rev != table[0].rev); - sel = find_matching_input(table_rate, &div_value); - if (!sel) + if (find_matching_input(table_rate, &tegra_emc_clk_sel[i])) continue; if (table_rate == boot_rate) @@ -1004,17 +1021,6 @@ void tegra_init_emc(const struct tegra_emc_table *table, int table_size) if (table_rate == max_rate) max_entry = true; - tegra_emc_clk_sel[i] = *sel; - BUG_ON(div_value > - (EMC_CLK_DIV_MASK >> EMC_CLK_DIV_SHIFT)); - tegra_emc_clk_sel[i].value <<= EMC_CLK_SOURCE_SHIFT; - tegra_emc_clk_sel[i].value |= (div_value << EMC_CLK_DIV_SHIFT); - - if ((div_value == 0) && - (tegra_emc_clk_sel[i].input == emc->parent)) { - tegra_emc_clk_sel[i].value |= EMC_CLK_LOW_JITTER_ENABLE; - } - if (table[i].burst_regs[MC_EMEM_ARB_MISC0_INDEX] & MC_EMEM_ARB_MISC0_EMC_SAME_FREQ) tegra_emc_clk_sel[i].value |= EMC_CLK_MC_SAME_FREQ; -- cgit v1.2.3