Skip to content

Commit

Permalink
clk: tegra: emc: Support multiple RAM codes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dmitry Osipenko authored and Stephen Boyd committed Apr 25, 2019
1 parent 924ee3d commit 888ca40
Showing 1 changed file with 23 additions and 14 deletions.
37 changes: 23 additions & 14 deletions drivers/clk/tegra/clk-emc.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,23 @@ static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
struct tegra_clk_emc *tegra;
u8 ram_code = tegra_read_ram_code();
struct emc_timing *timing = NULL;
int i;
int i, k;

tegra = container_of(hw, struct tegra_clk_emc, hw);

for (i = 0; i < tegra->num_timings; i++) {
for (k = 0; k < tegra->num_timings; k++) {
if (tegra->timings[k].ram_code == ram_code)
break;
}

for (i = k; i < tegra->num_timings; i++) {
if (tegra->timings[i].ram_code != ram_code)
continue;
break;

timing = tegra->timings + i;

if (timing->rate > req->max_rate) {
i = max(i, 1);
i = max(i, k + 1);
req->rate = tegra->timings[i - 1].rate;
return 0;
}
Expand Down Expand Up @@ -282,7 +287,7 @@ static struct emc_timing *get_backup_timing(struct tegra_clk_emc *tegra,
for (i = timing_index+1; i < tegra->num_timings; i++) {
timing = tegra->timings + i;
if (timing->ram_code != ram_code)
continue;
break;

if (emc_parent_clk_sources[timing->parent_index] !=
emc_parent_clk_sources[
Expand All @@ -293,7 +298,7 @@ static struct emc_timing *get_backup_timing(struct tegra_clk_emc *tegra,
for (i = timing_index-1; i >= 0; --i) {
timing = tegra->timings + i;
if (timing->ram_code != ram_code)
continue;
break;

if (emc_parent_clk_sources[timing->parent_index] !=
emc_parent_clk_sources[
Expand Down Expand Up @@ -433,19 +438,23 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
struct device_node *node,
u32 ram_code)
{
struct emc_timing *timings_ptr;
struct device_node *child;
int child_count = of_get_child_count(node);
int i = 0, err;
size_t size;

size = (tegra->num_timings + child_count) * sizeof(struct emc_timing);

tegra->timings = kcalloc(child_count, sizeof(struct emc_timing),
GFP_KERNEL);
tegra->timings = krealloc(tegra->timings, size, GFP_KERNEL);
if (!tegra->timings)
return -ENOMEM;

tegra->num_timings = child_count;
timings_ptr = tegra->timings + tegra->num_timings;
tegra->num_timings += child_count;

for_each_child_of_node(node, child) {
struct emc_timing *timing = tegra->timings + (i++);
struct emc_timing *timing = timings_ptr + (i++);

err = load_one_timing_from_dt(tegra, timing, child);
if (err) {
Expand All @@ -456,7 +465,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
timing->ram_code = ram_code;
}

sort(tegra->timings, tegra->num_timings, sizeof(struct emc_timing),
sort(timings_ptr, child_count, sizeof(struct emc_timing),
cmp_timings, NULL);

return 0;
Expand Down Expand Up @@ -499,10 +508,10 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
* fuses until the apbmisc driver is loaded.
*/
err = load_timings_from_dt(tegra, node, node_ram_code);
of_node_put(node);
if (err)
if (err) {
of_node_put(node);
return ERR_PTR(err);
break;
}
}

if (tegra->num_timings == 0)
Expand Down

0 comments on commit 888ca40

Please sign in to comment.