aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu.vizoso@collabora.com>2015-03-17 05:36:13 -0400
committerThierry Reding <treding@nvidia.com>2015-05-13 09:17:13 -0400
commit890d6a54ead9dafdfdeebe65cbb10056e14c835a (patch)
tree67648b87c70a13dac5ce6c9395af26017e7485fd
parentac67477f8f4163a6e7678f252030051f4eef2d5f (diff)
clk: tegra: Have EMC clock implement determine_rate()
As opposed to round_rate(), determine_rate() can take rate constraints into account when choosing the best rate. Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/clk/tegra/clk-emc.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
index 32e5563711ac..7649685c86bc 100644
--- a/drivers/clk/tegra/clk-emc.c
+++ b/drivers/clk/tegra/clk-emc.c
@@ -116,8 +116,11 @@ static unsigned long emc_recalc_rate(struct clk_hw *hw,
116 * safer since things have EMC rate floors. Also don't touch parent_rate 116 * safer since things have EMC rate floors. Also don't touch parent_rate
117 * since we don't want the CCF to play with our parent clocks. 117 * since we don't want the CCF to play with our parent clocks.
118 */ 118 */
119static long emc_round_rate(struct clk_hw *hw, unsigned long rate, 119static long emc_determine_rate(struct clk_hw *hw, unsigned long rate,
120 unsigned long *parent_rate) 120 unsigned long min_rate,
121 unsigned long max_rate,
122 unsigned long *best_parent_rate,
123 struct clk_hw **best_parent_hw)
121{ 124{
122 struct tegra_clk_emc *tegra; 125 struct tegra_clk_emc *tegra;
123 u8 ram_code = tegra_read_ram_code(); 126 u8 ram_code = tegra_read_ram_code();
@@ -126,18 +129,26 @@ static long emc_round_rate(struct clk_hw *hw, unsigned long rate,
126 129
127 tegra = container_of(hw, struct tegra_clk_emc, hw); 130 tegra = container_of(hw, struct tegra_clk_emc, hw);
128 131
129 for (i = 0; i < tegra->num_timings; i++) { 132 for (i = 0; i < tegra->num_timings; i++) {
130 if (tegra->timings[i].ram_code != ram_code) 133 if (tegra->timings[i].ram_code != ram_code)
131 continue; 134 continue;
135
136 timing = tegra->timings + i;
132 137
133 timing = tegra->timings + i; 138 if (timing->rate > max_rate) {
139 i = min(i, 1);
140 return tegra->timings[i - 1].rate;
141 }
142
143 if (timing->rate < min_rate)
144 continue;
134 145
135 if (timing->rate >= rate) 146 if (timing->rate >= rate)
136 return timing->rate; 147 return timing->rate;
137 } 148 }
138 149
139 if (timing) 150 if (timing)
140 return timing->rate; 151 return timing->rate;
141 152
142 return __clk_get_rate(hw->clk); 153 return __clk_get_rate(hw->clk);
143} 154}
@@ -451,7 +462,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
451 462
452static const struct clk_ops tegra_clk_emc_ops = { 463static const struct clk_ops tegra_clk_emc_ops = {
453 .recalc_rate = emc_recalc_rate, 464 .recalc_rate = emc_recalc_rate,
454 .round_rate = emc_round_rate, 465 .determine_rate = emc_determine_rate,
455 .set_rate = emc_set_rate, 466 .set_rate = emc_set_rate,
456 .get_parent = emc_get_parent, 467 .get_parent = emc_get_parent,
457}; 468};