diff options
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/clock.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-tegra/suspend.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_clocks.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_emc.c | 9 |
4 files changed, 18 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h index 95dcf48a4f78..46ada3ac50b1 100644 --- a/arch/arm/mach-tegra/clock.h +++ b/arch/arm/mach-tegra/clock.h @@ -196,8 +196,6 @@ struct tegra_sku_rate_limit { void tegra_soc_init_clocks(void); void tegra2_init_clocks(void); -void tegra2_periph_reset_deassert(struct clk *c); -void tegra2_periph_reset_assert(struct clk *c); void clk_init(struct clk *clk); struct clk *tegra_get_clock_by_name(const char *name); unsigned long clk_measure_input_freq(void); @@ -210,6 +208,7 @@ void tegra2_sdmmc_tap_delay(struct clk *c, int delay); int tegra_emc_set_rate(unsigned long rate); long tegra_emc_round_rate(unsigned long rate); struct clk *tegra_emc_predict_parent(unsigned long rate, u32 *div_value); +void tegra_emc_timing_invalidate(void); #ifdef CONFIG_CPU_FREQ struct cpufreq_frequency_table; diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c index 0839b861f9e6..77aa88c7ac18 100644 --- a/arch/arm/mach-tegra/suspend.c +++ b/arch/arm/mach-tegra/suspend.c @@ -771,7 +771,9 @@ static int tegra_suspend_enter(suspend_state_t state) { struct irq_desc *desc; void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); +#ifdef CONFIG_ARCH_TEGRA_2x_SOC void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE); +#endif unsigned long flags; u32 mc_data[3] = {0, 0, 0}; int irq; @@ -840,10 +842,10 @@ static int tegra_suspend_enter(suspend_state_t state) writel(mc_data[0], mc + MC_SECURITY_START); writel(mc_data[1], mc + MC_SECURITY_SIZE); writel(mc_data[2], mc + MC_SECURITY_CFG2); - +#ifdef CONFIG_ARCH_TEGRA_2x_SOC /* trigger emc mode write */ writel(EMC_MRW_DEV_NONE, emc + EMC_MRW_0); - +#endif tegra_clk_resume(); tegra_gpio_resume(); tegra_timer_resume(); diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c index 169124a6bef9..1af74d1c5655 100644 --- a/arch/arm/mach-tegra/tegra3_clocks.c +++ b/arch/arm/mach-tegra/tegra3_clocks.c @@ -3661,5 +3661,10 @@ void tegra_clk_resume(void) clk_writel(*ctx++, MISC_CLK_ENB); clk_writel(*ctx++, CLK_MASK_ARM); + + /* Since EMC clock is not restored update current state, and mark + EMC DFS as out of sync */ + tegra3_periph_clk_init(&tegra_clk_emc); + tegra_emc_timing_invalidate(); } #endif diff --git a/arch/arm/mach-tegra/tegra3_emc.c b/arch/arm/mach-tegra/tegra3_emc.c index 2335d90504b8..d4ee7d9f3af2 100644 --- a/arch/arm/mach-tegra/tegra3_emc.c +++ b/arch/arm/mach-tegra/tegra3_emc.c @@ -181,6 +181,7 @@ enum { static struct clk_mux_sel tegra_emc_clk_sel[TEGRA_EMC_TABLE_MAX_SIZE]; static int emc_last_sel; static struct tegra_emc_table start_timing; +static bool emc_timing_in_sync; static const struct tegra_emc_table *tegra_emc_table; static int tegra_emc_table_size; @@ -606,7 +607,7 @@ int tegra_emc_set_rate(unsigned long rate) if (i >= tegra_emc_table_size) return -EINVAL; - if (!emc_stats.clkchange_count) { + if (!emc_timing_in_sync) { /* can not assume that boot timing matches dfs table even if boot frequency matches one of the table nodes */ emc_get_timing(&start_timing); @@ -617,6 +618,7 @@ int tegra_emc_set_rate(unsigned long rate) clk_setting = tegra_emc_clk_sel[i].value; emc_set_clock(&tegra_emc_table[i], last_timing, clk_setting); + emc_timing_in_sync = true; emc_last_stats_update(i); pr_debug("%s: rate %lu setting 0x%x\n", __func__, rate, clk_setting); @@ -781,6 +783,11 @@ void tegra_init_emc(const struct tegra_emc_table *table, int table_size) tegra_emc_table = table; } +void tegra_emc_timing_invalidate(void) +{ + emc_timing_in_sync = false; +} + #ifdef CONFIG_DEBUG_FS static struct dentry *emc_debugfs_root; |