aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2019-04-14 15:23:18 -0400
committerStephen Boyd <sboyd@kernel.org>2019-04-25 16:54:20 -0400
commit888ca40e2843a24d2d4830780a4a5705a3fb219a (patch)
treec86bc1c8a807f67eaa80d0c392a349f0bc566cb3
parent924ee3d551c9deb16090230b824988bd37e72aa8 (diff)
clk: tegra: emc: Support multiple RAM codes
The timings parser doesn't append timings, but instead it parses only the first timing and hence doesn't store all of the timings when device-tree has timings for multiple RAM codes. In a result EMC scaling doesn't work if timings are missing. Tested-by: Steev Klimaszewski <steev@kali.org> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r--drivers/clk/tegra/clk-emc.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
index 23416982e7c7..28068584ff6e 100644
--- a/drivers/clk/tegra/clk-emc.c
+++ b/drivers/clk/tegra/clk-emc.c
@@ -121,18 +121,23 @@ static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
121 struct tegra_clk_emc *tegra; 121 struct tegra_clk_emc *tegra;
122 u8 ram_code = tegra_read_ram_code(); 122 u8 ram_code = tegra_read_ram_code();
123 struct emc_timing *timing = NULL; 123 struct emc_timing *timing = NULL;
124 int i; 124 int i, k;
125 125
126 tegra = container_of(hw, struct tegra_clk_emc, hw); 126 tegra = container_of(hw, struct tegra_clk_emc, hw);
127 127
128 for (i = 0; i < tegra->num_timings; i++) { 128 for (k = 0; k < tegra->num_timings; k++) {
129 if (tegra->timings[k].ram_code == ram_code)
130 break;
131 }
132
133 for (i = k; i < tegra->num_timings; i++) {
129 if (tegra->timings[i].ram_code != ram_code) 134 if (tegra->timings[i].ram_code != ram_code)
130 continue; 135 break;
131 136
132 timing = tegra->timings + i; 137 timing = tegra->timings + i;
133 138
134 if (timing->rate > req->max_rate) { 139 if (timing->rate > req->max_rate) {
135 i = max(i, 1); 140 i = max(i, k + 1);
136 req->rate = tegra->timings[i - 1].rate; 141 req->rate = tegra->timings[i - 1].rate;
137 return 0; 142 return 0;
138 } 143 }
@@ -282,7 +287,7 @@ static struct emc_timing *get_backup_timing(struct tegra_clk_emc *tegra,
282 for (i = timing_index+1; i < tegra->num_timings; i++) { 287 for (i = timing_index+1; i < tegra->num_timings; i++) {
283 timing = tegra->timings + i; 288 timing = tegra->timings + i;
284 if (timing->ram_code != ram_code) 289 if (timing->ram_code != ram_code)
285 continue; 290 break;
286 291
287 if (emc_parent_clk_sources[timing->parent_index] != 292 if (emc_parent_clk_sources[timing->parent_index] !=
288 emc_parent_clk_sources[ 293 emc_parent_clk_sources[
@@ -293,7 +298,7 @@ static struct emc_timing *get_backup_timing(struct tegra_clk_emc *tegra,
293 for (i = timing_index-1; i >= 0; --i) { 298 for (i = timing_index-1; i >= 0; --i) {
294 timing = tegra->timings + i; 299 timing = tegra->timings + i;
295 if (timing->ram_code != ram_code) 300 if (timing->ram_code != ram_code)
296 continue; 301 break;
297 302
298 if (emc_parent_clk_sources[timing->parent_index] != 303 if (emc_parent_clk_sources[timing->parent_index] !=
299 emc_parent_clk_sources[ 304 emc_parent_clk_sources[
@@ -433,19 +438,23 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
433 struct device_node *node, 438 struct device_node *node,
434 u32 ram_code) 439 u32 ram_code)
435{ 440{
441 struct emc_timing *timings_ptr;
436 struct device_node *child; 442 struct device_node *child;
437 int child_count = of_get_child_count(node); 443 int child_count = of_get_child_count(node);
438 int i = 0, err; 444 int i = 0, err;
445 size_t size;
446
447 size = (tegra->num_timings + child_count) * sizeof(struct emc_timing);
439 448
440 tegra->timings = kcalloc(child_count, sizeof(struct emc_timing), 449 tegra->timings = krealloc(tegra->timings, size, GFP_KERNEL);
441 GFP_KERNEL);
442 if (!tegra->timings) 450 if (!tegra->timings)
443 return -ENOMEM; 451 return -ENOMEM;
444 452
445 tegra->num_timings = child_count; 453 timings_ptr = tegra->timings + tegra->num_timings;
454 tegra->num_timings += child_count;
446 455
447 for_each_child_of_node(node, child) { 456 for_each_child_of_node(node, child) {
448 struct emc_timing *timing = tegra->timings + (i++); 457 struct emc_timing *timing = timings_ptr + (i++);
449 458
450 err = load_one_timing_from_dt(tegra, timing, child); 459 err = load_one_timing_from_dt(tegra, timing, child);
451 if (err) { 460 if (err) {
@@ -456,7 +465,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
456 timing->ram_code = ram_code; 465 timing->ram_code = ram_code;
457 } 466 }
458 467
459 sort(tegra->timings, tegra->num_timings, sizeof(struct emc_timing), 468 sort(timings_ptr, child_count, sizeof(struct emc_timing),
460 cmp_timings, NULL); 469 cmp_timings, NULL);
461 470
462 return 0; 471 return 0;
@@ -499,10 +508,10 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
499 * fuses until the apbmisc driver is loaded. 508 * fuses until the apbmisc driver is loaded.
500 */ 509 */
501 err = load_timings_from_dt(tegra, node, node_ram_code); 510 err = load_timings_from_dt(tegra, node, node_ram_code);
502 of_node_put(node); 511 if (err) {
503 if (err) 512 of_node_put(node);
504 return ERR_PTR(err); 513 return ERR_PTR(err);
505 break; 514 }
506 } 515 }
507 516
508 if (tegra->num_timings == 0) 517 if (tegra->num_timings == 0)