diff options
Diffstat (limited to 'drivers/memory/tegra')
-rw-r--r-- | drivers/memory/tegra/mc.c | 13 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra124-emc.c | 9 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra124.c | 2 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra186-emc.c | 9 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra20-emc.c | 17 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra20.c | 2 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra210-emc-cc-r21021.c | 429 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra210-emc-core.c | 2 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra234.c | 48 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra30-emc.c | 9 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra30.c | 2 |
11 files changed, 148 insertions, 394 deletions
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c index a083921a8968..bd5b58f1fd42 100644 --- a/drivers/memory/tegra/mc.c +++ b/drivers/memory/tegra/mc.c @@ -450,7 +450,6 @@ static int load_one_timing(struct tegra_mc *mc, static int load_timings(struct tegra_mc *mc, struct device_node *node) { - struct device_node *child; struct tegra_mc_timing *timing; int child_count = of_get_child_count(node); int i = 0, err; @@ -462,14 +461,12 @@ static int load_timings(struct tegra_mc *mc, struct device_node *node) mc->num_timings = child_count; - for_each_child_of_node(node, child) { + for_each_child_of_node_scoped(node, child) { timing = &mc->timings[i++]; err = load_one_timing(mc, timing, child); - if (err) { - of_node_put(child); + if (err) return err; - } } return 0; @@ -477,7 +474,6 @@ static int load_timings(struct tegra_mc *mc, struct device_node *node) static int tegra_mc_setup_timings(struct tegra_mc *mc) { - struct device_node *node; u32 ram_code, node_ram_code; int err; @@ -485,14 +481,13 @@ static int tegra_mc_setup_timings(struct tegra_mc *mc) mc->num_timings = 0; - for_each_child_of_node(mc->dev->of_node, node) { + for_each_child_of_node_scoped(mc->dev->of_node, node) { err = of_property_read_u32(node, "nvidia,ram-code", &node_ram_code); if (err || (node_ram_code != ram_code)) continue; err = load_timings(mc, node); - of_node_put(node); if (err) return err; break; @@ -755,7 +750,7 @@ const char *const tegra_mc_error_names[8] = { [6] = "SMMU translation error", }; -struct icc_node *tegra_mc_icc_xlate(struct of_phandle_args *spec, void *data) +struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec, void *data) { struct tegra_mc *mc = icc_provider_to_tegra_mc(data); struct icc_node *node; diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index 00ed2b6a0d1b..03f1daa2d132 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -992,7 +992,6 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, struct device_node *node) { int child_count = of_get_child_count(node); - struct device_node *child; struct emc_timing *timing; unsigned int i = 0; int err; @@ -1004,14 +1003,12 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, emc->num_timings = child_count; - for_each_child_of_node(node, child) { + for_each_child_of_node_scoped(node, child) { timing = &emc->timings[i++]; err = load_one_timing_from_dt(emc, timing, child); - if (err) { - of_node_put(child); + if (err) return err; - } } sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings, @@ -1285,7 +1282,7 @@ to_tegra_emc_provider(struct icc_provider *provider) } static struct icc_node_data * -emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data) +emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) { struct icc_provider *provider = data; struct icc_node_data *ndata; diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c index 470b7dbab2c2..9d7393e19f12 100644 --- a/drivers/memory/tegra/tegra124.c +++ b/drivers/memory/tegra/tegra124.c @@ -1170,7 +1170,7 @@ static int tegra124_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw, } static struct icc_node_data * -tegra124_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data) +tegra124_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) { struct tegra_mc *mc = icc_provider_to_tegra_mc(data); const struct tegra_mc_client *client; diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c index fcd4aea48bda..bc807d7fcd4e 100644 --- a/drivers/memory/tegra/tegra186-emc.c +++ b/drivers/memory/tegra/tegra186-emc.c @@ -35,11 +35,6 @@ struct tegra186_emc { struct icc_provider provider; }; -static inline struct tegra186_emc *to_tegra186_emc(struct icc_provider *provider) -{ - return container_of(provider, struct tegra186_emc, provider); -} - /* * debugfs interface * @@ -236,7 +231,7 @@ static int tegra_emc_icc_set_bw(struct icc_node *src, struct icc_node *dst) } static struct icc_node * -tegra_emc_of_icc_xlate(struct of_phandle_args *spec, void *data) +tegra_emc_of_icc_xlate(const struct of_phandle_args *spec, void *data) { struct icc_provider *provider = data; struct icc_node *node; @@ -411,7 +406,7 @@ static struct platform_driver tegra186_emc_driver = { .sync_state = icc_sync_state, }, .probe = tegra186_emc_probe, - .remove_new = tegra186_emc_remove, + .remove = tegra186_emc_remove, }; module_platform_driver(tegra186_emc_driver); diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index fd595c851a27..9b7d30a21a5b 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -410,7 +410,6 @@ static int cmp_timings(const void *_a, const void *_b) static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, struct device_node *node) { - struct device_node *child; struct emc_timing *timing; int child_count; int err; @@ -428,15 +427,13 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, timing = emc->timings; - for_each_child_of_node(node, child) { + for_each_child_of_node_scoped(node, child) { if (of_node_name_eq(child, "lpddr2")) continue; err = load_one_timing_from_dt(emc, timing++, child); - if (err) { - of_node_put(child); + if (err) return err; - } emc->num_timings++; } @@ -477,14 +474,15 @@ tegra_emc_find_node_by_ram_code(struct tegra_emc *emc) ram_code = tegra_read_ram_code(); - for (np = of_find_node_by_name(dev->of_node, "emc-tables"); np; - np = of_find_node_by_name(np, "emc-tables")) { + for_each_child_of_node(dev->of_node, np) { + if (!of_node_name_eq(np, "emc-tables")) + continue; err = of_property_read_u32(np, "nvidia,ram-code", &value); if (err || value != ram_code) { struct device_node *lpddr2_np; bool cfg_mismatches = false; - lpddr2_np = of_find_node_by_name(np, "lpddr2"); + lpddr2_np = of_get_child_by_name(np, "lpddr2"); if (lpddr2_np) { const struct lpddr2_info *info; @@ -521,7 +519,6 @@ tegra_emc_find_node_by_ram_code(struct tegra_emc *emc) } if (cfg_mismatches) { - of_node_put(np); continue; } } @@ -950,7 +947,7 @@ to_tegra_emc_provider(struct icc_provider *provider) } static struct icc_node_data * -emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data) +emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) { struct icc_provider *provider = data; struct icc_node_data *ndata; diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c index aa4b97d5e732..a3022e715dee 100644 --- a/drivers/memory/tegra/tegra20.c +++ b/drivers/memory/tegra/tegra20.c @@ -390,7 +390,7 @@ static int tegra20_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw, } static struct icc_node_data * -tegra20_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data) +tegra20_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) { struct tegra_mc *mc = icc_provider_to_tegra_mc(data); unsigned int i, idx = spec->args[0]; diff --git a/drivers/memory/tegra/tegra210-emc-cc-r21021.c b/drivers/memory/tegra/tegra210-emc-cc-r21021.c index 4cb608c71ead..a30a646ec468 100644 --- a/drivers/memory/tegra/tegra210-emc-cc-r21021.c +++ b/drivers/memory/tegra/tegra210-emc-cc-r21021.c @@ -75,29 +75,29 @@ enum { * The division portion of the average operation. */ #define __AVERAGE_PTFV(dev) \ - ({ next->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX] = \ - next->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX] / \ + ({ next->ptfv_list[(dev)] = \ + next->ptfv_list[(dev)] / \ next->ptfv_list[PTFV_DVFS_SAMPLES_INDEX]; }) /* * Convert val to fixed point and add it to the temporary average. */ #define __INCREMENT_PTFV(dev, val) \ - ({ next->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX] += \ + ({ next->ptfv_list[(dev)] += \ ((val) * MOVAVG_PRECISION_FACTOR); }) /* * Convert a moving average back to integral form and return the value. */ #define __MOVAVG_AC(timing, dev) \ - ((timing)->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX] / \ + ((timing)->ptfv_list[(dev)] / \ MOVAVG_PRECISION_FACTOR) /* Weighted update. */ #define __WEIGHTED_UPDATE_PTFV(dev, nval) \ do { \ int w = PTFV_MOVAVG_WEIGHT_INDEX; \ - int dqs = PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX; \ + int dqs = (dev); \ \ next->ptfv_list[dqs] = \ ((nval * MOVAVG_PRECISION_FACTOR) + \ @@ -105,315 +105,91 @@ enum { next->ptfv_list[w])) / \ (next->ptfv_list[w] + 1); \ \ - emc_dbg(emc, EMA_UPDATES, "%s: (s=%lu) EMA: %u\n", \ + emc_dbg(emc, EMA_UPDATES, "%s: (s=%u) EMA: %u\n", \ __stringify(dev), nval, next->ptfv_list[dqs]); \ } while (0) /* Access a particular average. */ #define __MOVAVG(timing, dev) \ - ((timing)->ptfv_list[PTFV_DQSOSC_MOVAVG_ ## dev ## _INDEX]) + ((timing)->ptfv_list[(dev)]) -static u32 update_clock_tree_delay(struct tegra210_emc *emc, int type) +static bool tegra210_emc_compare_update_delay(struct tegra210_emc_timing *timing, + u32 measured, u32 idx) { - bool periodic_training_update = type == PERIODIC_TRAINING_UPDATE; - struct tegra210_emc_timing *last = emc->last; - struct tegra210_emc_timing *next = emc->next; - u32 last_timing_rate_mhz = last->rate / 1000; - u32 next_timing_rate_mhz = next->rate / 1000; - bool dvfs_update = type == DVFS_UPDATE; - s32 tdel = 0, tmdel = 0, adel = 0; - bool dvfs_pt1 = type == DVFS_PT1; - unsigned long cval = 0; - u32 temp[2][2], value; - unsigned int i; - - /* - * Dev0 MSB. - */ - if (dvfs_pt1 || periodic_training_update) { - value = tegra210_emc_mrr_read(emc, 2, 19); - - for (i = 0; i < emc->num_channels; i++) { - temp[i][0] = (value & 0x00ff) << 8; - temp[i][1] = (value & 0xff00) << 0; - value >>= 16; - } - - /* - * Dev0 LSB. - */ - value = tegra210_emc_mrr_read(emc, 2, 18); - - for (i = 0; i < emc->num_channels; i++) { - temp[i][0] |= (value & 0x00ff) >> 0; - temp[i][1] |= (value & 0xff00) >> 8; - value >>= 16; - } - } - - if (dvfs_pt1 || periodic_training_update) { - cval = tegra210_emc_actual_osc_clocks(last->run_clocks); - cval *= 1000000; - cval /= last_timing_rate_mhz * 2 * temp[0][0]; - } + u32 *curr = &timing->current_dram_clktree[idx]; + u32 rate_mhz = timing->rate / 1000; + u32 tmdel; - if (dvfs_pt1) - __INCREMENT_PTFV(C0D0U0, cval); - else if (dvfs_update) - __AVERAGE_PTFV(C0D0U0); - else if (periodic_training_update) - __WEIGHTED_UPDATE_PTFV(C0D0U0, cval); - - if (dvfs_update || periodic_training_update) { - tdel = next->current_dram_clktree[C0D0U0] - - __MOVAVG_AC(next, C0D0U0); - tmdel = (tdel < 0) ? -1 * tdel : tdel; - adel = tmdel; - - if (tmdel * 128 * next_timing_rate_mhz / 1000000 > - next->tree_margin) - next->current_dram_clktree[C0D0U0] = - __MOVAVG_AC(next, C0D0U0); - } + tmdel = abs(*curr - measured); - if (dvfs_pt1 || periodic_training_update) { - cval = tegra210_emc_actual_osc_clocks(last->run_clocks); - cval *= 1000000; - cval /= last_timing_rate_mhz * 2 * temp[0][1]; + if (tmdel * 128 * rate_mhz / 1000000 > timing->tree_margin) { + *curr = measured; + return true; } - if (dvfs_pt1) - __INCREMENT_PTFV(C0D0U1, cval); - else if (dvfs_update) - __AVERAGE_PTFV(C0D0U1); - else if (periodic_training_update) - __WEIGHTED_UPDATE_PTFV(C0D0U1, cval); - - if (dvfs_update || periodic_training_update) { - tdel = next->current_dram_clktree[C0D0U1] - - __MOVAVG_AC(next, C0D0U1); - tmdel = (tdel < 0) ? -1 * tdel : tdel; - - if (tmdel > adel) - adel = tmdel; - - if (tmdel * 128 * next_timing_rate_mhz / 1000000 > - next->tree_margin) - next->current_dram_clktree[C0D0U1] = - __MOVAVG_AC(next, C0D0U1); - } - - if (emc->num_channels > 1) { - if (dvfs_pt1 || periodic_training_update) { - cval = tegra210_emc_actual_osc_clocks(last->run_clocks); - cval *= 1000000; - cval /= last_timing_rate_mhz * 2 * temp[1][0]; - } - - if (dvfs_pt1) - __INCREMENT_PTFV(C1D0U0, cval); - else if (dvfs_update) - __AVERAGE_PTFV(C1D0U0); - else if (periodic_training_update) - __WEIGHTED_UPDATE_PTFV(C1D0U0, cval); - - if (dvfs_update || periodic_training_update) { - tdel = next->current_dram_clktree[C1D0U0] - - __MOVAVG_AC(next, C1D0U0); - tmdel = (tdel < 0) ? -1 * tdel : tdel; - - if (tmdel > adel) - adel = tmdel; - - if (tmdel * 128 * next_timing_rate_mhz / 1000000 > - next->tree_margin) - next->current_dram_clktree[C1D0U0] = - __MOVAVG_AC(next, C1D0U0); - } - - if (dvfs_pt1 || periodic_training_update) { - cval = tegra210_emc_actual_osc_clocks(last->run_clocks); - cval *= 1000000; - cval /= last_timing_rate_mhz * 2 * temp[1][1]; - } - - if (dvfs_pt1) - __INCREMENT_PTFV(C1D0U1, cval); - else if (dvfs_update) - __AVERAGE_PTFV(C1D0U1); - else if (periodic_training_update) - __WEIGHTED_UPDATE_PTFV(C1D0U1, cval); - - if (dvfs_update || periodic_training_update) { - tdel = next->current_dram_clktree[C1D0U1] - - __MOVAVG_AC(next, C1D0U1); - tmdel = (tdel < 0) ? -1 * tdel : tdel; - - if (tmdel > adel) - adel = tmdel; - - if (tmdel * 128 * next_timing_rate_mhz / 1000000 > - next->tree_margin) - next->current_dram_clktree[C1D0U1] = - __MOVAVG_AC(next, C1D0U1); - } - } - - if (emc->num_devices < 2) - goto done; - - /* - * Dev1 MSB. - */ - if (dvfs_pt1 || periodic_training_update) { - value = tegra210_emc_mrr_read(emc, 1, 19); + return false; +} - for (i = 0; i < emc->num_channels; i++) { - temp[i][0] = (value & 0x00ff) << 8; - temp[i][1] = (value & 0xff00) << 0; - value >>= 16; - } +static void tegra210_emc_get_clktree_delay(struct tegra210_emc *emc, + u32 delay[DRAM_CLKTREE_NUM]) +{ + struct tegra210_emc_timing *curr = emc->last; + u32 rate_mhz = curr->rate / 1000; + u32 msb, lsb, dqsosc, delay_us; + unsigned int c, d, idx; + unsigned long clocks; - /* - * Dev1 LSB. - */ - value = tegra210_emc_mrr_read(emc, 1, 18); + clocks = tegra210_emc_actual_osc_clocks(curr->run_clocks); + delay_us = 2 + (clocks / rate_mhz); - for (i = 0; i < emc->num_channels; i++) { - temp[i][0] |= (value & 0x00ff) >> 0; - temp[i][1] |= (value & 0xff00) >> 8; - value >>= 16; - } - } + tegra210_emc_start_periodic_compensation(emc); + udelay(delay_us); - if (dvfs_pt1 || periodic_training_update) { - cval = tegra210_emc_actual_osc_clocks(last->run_clocks); - cval *= 1000000; - cval /= last_timing_rate_mhz * 2 * temp[0][0]; - } + for (d = 0; d < emc->num_devices; d++) { + /* Read DQSOSC from MRR18/19 */ + msb = tegra210_emc_mrr_read(emc, 2 - d, 19); + lsb = tegra210_emc_mrr_read(emc, 2 - d, 18); - if (dvfs_pt1) - __INCREMENT_PTFV(C0D1U0, cval); - else if (dvfs_update) - __AVERAGE_PTFV(C0D1U0); - else if (periodic_training_update) - __WEIGHTED_UPDATE_PTFV(C0D1U0, cval); - - if (dvfs_update || periodic_training_update) { - tdel = next->current_dram_clktree[C0D1U0] - - __MOVAVG_AC(next, C0D1U0); - tmdel = (tdel < 0) ? -1 * tdel : tdel; - - if (tmdel > adel) - adel = tmdel; - - if (tmdel * 128 * next_timing_rate_mhz / 1000000 > - next->tree_margin) - next->current_dram_clktree[C0D1U0] = - __MOVAVG_AC(next, C0D1U0); - } + for (c = 0; c < emc->num_channels; c++) { + /* C[c]D[d]U[0] */ + idx = c * 4 + d * 2; - if (dvfs_pt1 || periodic_training_update) { - cval = tegra210_emc_actual_osc_clocks(last->run_clocks); - cval *= 1000000; - cval /= last_timing_rate_mhz * 2 * temp[0][1]; - } + dqsosc = (msb & 0x00ff) << 8; + dqsosc |= (lsb & 0x00ff) >> 0; - if (dvfs_pt1) - __INCREMENT_PTFV(C0D1U1, cval); - else if (dvfs_update) - __AVERAGE_PTFV(C0D1U1); - else if (periodic_training_update) - __WEIGHTED_UPDATE_PTFV(C0D1U1, cval); - - if (dvfs_update || periodic_training_update) { - tdel = next->current_dram_clktree[C0D1U1] - - __MOVAVG_AC(next, C0D1U1); - tmdel = (tdel < 0) ? -1 * tdel : tdel; - - if (tmdel > adel) - adel = tmdel; - - if (tmdel * 128 * next_timing_rate_mhz / 1000000 > - next->tree_margin) - next->current_dram_clktree[C0D1U1] = - __MOVAVG_AC(next, C0D1U1); - } + /* Check for unpopulated channels */ + if (dqsosc) + delay[idx] = (clocks * 1000000) / + (rate_mhz * 2 * dqsosc); - if (emc->num_channels > 1) { - if (dvfs_pt1 || periodic_training_update) { - cval = tegra210_emc_actual_osc_clocks(last->run_clocks); - cval *= 1000000; - cval /= last_timing_rate_mhz * 2 * temp[1][0]; - } + /* C[c]D[d]U[1] */ + idx++; - if (dvfs_pt1) - __INCREMENT_PTFV(C1D1U0, cval); - else if (dvfs_update) - __AVERAGE_PTFV(C1D1U0); - else if (periodic_training_update) - __WEIGHTED_UPDATE_PTFV(C1D1U0, cval); - - if (dvfs_update || periodic_training_update) { - tdel = next->current_dram_clktree[C1D1U0] - - __MOVAVG_AC(next, C1D1U0); - tmdel = (tdel < 0) ? -1 * tdel : tdel; - - if (tmdel > adel) - adel = tmdel; - - if (tmdel * 128 * next_timing_rate_mhz / 1000000 > - next->tree_margin) - next->current_dram_clktree[C1D1U0] = - __MOVAVG_AC(next, C1D1U0); - } + dqsosc = (msb & 0xff00) << 0; + dqsosc |= (lsb & 0xff00) >> 8; - if (dvfs_pt1 || periodic_training_update) { - cval = tegra210_emc_actual_osc_clocks(last->run_clocks); - cval *= 1000000; - cval /= last_timing_rate_mhz * 2 * temp[1][1]; - } + /* Check for unpopulated channels */ + if (dqsosc) + delay[idx] = (clocks * 1000000) / + (rate_mhz * 2 * dqsosc); - if (dvfs_pt1) - __INCREMENT_PTFV(C1D1U1, cval); - else if (dvfs_update) - __AVERAGE_PTFV(C1D1U1); - else if (periodic_training_update) - __WEIGHTED_UPDATE_PTFV(C1D1U1, cval); - - if (dvfs_update || periodic_training_update) { - tdel = next->current_dram_clktree[C1D1U1] - - __MOVAVG_AC(next, C1D1U1); - tmdel = (tdel < 0) ? -1 * tdel : tdel; - - if (tmdel > adel) - adel = tmdel; - - if (tmdel * 128 * next_timing_rate_mhz / 1000000 > - next->tree_margin) - next->current_dram_clktree[C1D1U1] = - __MOVAVG_AC(next, C1D1U1); + msb >>= 16; + lsb >>= 16; } } - -done: - return adel; } -static u32 periodic_compensation_handler(struct tegra210_emc *emc, u32 type, - struct tegra210_emc_timing *last, - struct tegra210_emc_timing *next) +static bool periodic_compensation_handler(struct tegra210_emc *emc, u32 type, + struct tegra210_emc_timing *last, + struct tegra210_emc_timing *next) { #define __COPY_EMA(nt, lt, dev) \ ({ __MOVAVG(nt, dev) = __MOVAVG(lt, dev) * \ (nt)->ptfv_list[PTFV_DVFS_SAMPLES_INDEX]; }) - u32 i, adel = 0, samples = next->ptfv_list[PTFV_DVFS_SAMPLES_INDEX]; - u32 delay; - - delay = tegra210_emc_actual_osc_clocks(last->run_clocks); - delay *= 1000; - delay = 2 + (delay / last->rate); + u32 i, samples = next->ptfv_list[PTFV_DVFS_SAMPLES_INDEX]; + u32 delay[DRAM_CLKTREE_NUM], idx; + bool over = false; if (!next->periodic_training) return 0; @@ -427,57 +203,46 @@ static u32 periodic_compensation_handler(struct tegra210_emc *emc, u32 type, * calibration then we can reuse the previous * frequencies EMA data. */ - __COPY_EMA(next, last, C0D0U0); - __COPY_EMA(next, last, C0D0U1); - __COPY_EMA(next, last, C1D0U0); - __COPY_EMA(next, last, C1D0U1); - __COPY_EMA(next, last, C0D1U0); - __COPY_EMA(next, last, C0D1U1); - __COPY_EMA(next, last, C1D1U0); - __COPY_EMA(next, last, C1D1U1); + for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++) + __COPY_EMA(next, last, idx); } else { /* Reset the EMA.*/ - __MOVAVG(next, C0D0U0) = 0; - __MOVAVG(next, C0D0U1) = 0; - __MOVAVG(next, C1D0U0) = 0; - __MOVAVG(next, C1D0U1) = 0; - __MOVAVG(next, C0D1U0) = 0; - __MOVAVG(next, C0D1U1) = 0; - __MOVAVG(next, C1D1U0) = 0; - __MOVAVG(next, C1D1U1) = 0; + for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++) + __MOVAVG(next, idx) = 0; for (i = 0; i < samples; i++) { - tegra210_emc_start_periodic_compensation(emc); - udelay(delay); + /* Generate next sample of data. */ + tegra210_emc_get_clktree_delay(emc, delay); - /* - * Generate next sample of data. - */ - adel = update_clock_tree_delay(emc, DVFS_PT1); + for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++) + __INCREMENT_PTFV(idx, delay[idx]); } } - /* - * Seems like it should be part of the - * 'if (last_timing->periodic_training)' conditional - * since is already done for the else clause. - */ - adel = update_clock_tree_delay(emc, DVFS_UPDATE); + for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++) { + /* Do the division part of the moving average */ + __AVERAGE_PTFV(idx); + over |= tegra210_emc_compare_update_delay(next, + __MOVAVG_AC(next, idx), idx); + } } if (type == PERIODIC_TRAINING_SEQUENCE) { - tegra210_emc_start_periodic_compensation(emc); - udelay(delay); + tegra210_emc_get_clktree_delay(emc, delay); - adel = update_clock_tree_delay(emc, PERIODIC_TRAINING_UPDATE); + for (idx = 0; idx < DRAM_CLKTREE_NUM; idx++) { + __WEIGHTED_UPDATE_PTFV(idx, delay[idx]); + over |= tegra210_emc_compare_update_delay(next, + __MOVAVG_AC(next, idx), idx); + } } - return adel; + return over; } static u32 tegra210_emc_r21021_periodic_compensation(struct tegra210_emc *emc) { - u32 emc_cfg, emc_cfg_o, emc_cfg_update, del, value; + u32 emc_cfg, emc_cfg_o, emc_cfg_update, value; static const u32 list[] = { EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1, @@ -492,7 +257,6 @@ static u32 tegra210_emc_r21021_periodic_compensation(struct tegra210_emc *emc) }; struct tegra210_emc_timing *last = emc->last; unsigned int items = ARRAY_SIZE(list), i; - unsigned long delay; if (last->periodic_training) { emc_dbg(emc, PER_TRAIN, "Periodic training starting\n"); @@ -530,30 +294,18 @@ static u32 tegra210_emc_r21021_periodic_compensation(struct tegra210_emc *emc) /* * 2. osc kick off - this assumes training and dvfs have set * correct MR23. - */ - tegra210_emc_start_periodic_compensation(emc); - - /* + * * 3. Let dram capture its clock tree delays. - */ - delay = tegra210_emc_actual_osc_clocks(last->run_clocks); - delay *= 1000; - delay /= last->rate + 1; - udelay(delay); - - /* + * * 4. Check delta wrt previous values (save value if margin * exceeds what is set in table). */ - del = periodic_compensation_handler(emc, - PERIODIC_TRAINING_SEQUENCE, - last, last); - + if (periodic_compensation_handler(emc, PERIODIC_TRAINING_SEQUENCE, + last, last)) { /* * 5. Apply compensation w.r.t. trained values (if clock tree * has drifted more than the set margin). */ - if (last->tree_margin < ((del * 128 * (last->rate / 1000)) / 1000000)) { for (i = 0; i < items; i++) { value = tegra210_emc_compensate(last, list[i]); emc_dbg(emc, EMA_WRITES, "0x%08x <= 0x%08x\n", @@ -734,16 +486,7 @@ static void tegra210_emc_r21021_set_clock(struct tegra210_emc *emc, u32 clksrc) EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_MASK, 0); - tegra210_emc_start_periodic_compensation(emc); - - delay = 1000 * tegra210_emc_actual_osc_clocks(last->run_clocks); - udelay((delay / last->rate) + 2); - - value = periodic_compensation_handler(emc, DVFS_SEQUENCE, fake, - next); - value = (value * 128 * next->rate / 1000) / 1000000; - - if (next->periodic_training && value > next->tree_margin) + if (periodic_compensation_handler(emc, DVFS_SEQUENCE, fake, next)) compensate_trimmer_applicable = true; } diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c index 78ca1d6c0977..2d5d8245a1d3 100644 --- a/drivers/memory/tegra/tegra210-emc-core.c +++ b/drivers/memory/tegra/tegra210-emc-core.c @@ -2051,7 +2051,7 @@ static struct platform_driver tegra210_emc_driver = { .pm = &tegra210_emc_pm_ops, }, .probe = tegra210_emc_probe, - .remove_new = tegra210_emc_remove, + .remove = tegra210_emc_remove, }; module_platform_driver(tegra210_emc_driver); diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c index abff87f917cb..5f57cea48b62 100644 --- a/drivers/memory/tegra/tegra234.c +++ b/drivers/memory/tegra/tegra234.c @@ -92,6 +92,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_DLA0RDB, .name = "dla0rdb", + .bpmp_id = TEGRA_ICC_BPMP_DLA_0, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA0, .regs = { .sid = { @@ -102,6 +104,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_DLA0RDB1, .name = "dla0rdb1", + .bpmp_id = TEGRA_ICC_BPMP_DLA_0, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA0, .regs = { .sid = { @@ -112,6 +116,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_DLA0WRB, .name = "dla0wrb", + .bpmp_id = TEGRA_ICC_BPMP_DLA_0, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA0, .regs = { .sid = { @@ -121,7 +127,9 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA1RDB, - .name = "dla0rdb", + .name = "dla1rdb", + .bpmp_id = TEGRA_ICC_BPMP_DLA_1, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA1, .regs = { .sid = { @@ -407,7 +415,9 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA1RDB1, - .name = "dla0rdb1", + .name = "dla1rdb1", + .bpmp_id = TEGRA_ICC_BPMP_DLA_1, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA1, .regs = { .sid = { @@ -417,7 +427,9 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA1WRB, - .name = "dla0wrb", + .name = "dla1wrb", + .bpmp_id = TEGRA_ICC_BPMP_DLA_1, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA1, .regs = { .sid = { @@ -539,7 +551,7 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { .bpmp_id = TEGRA_ICC_BPMP_NVJPG_0, .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVJPG, - .regs = { + .regs = { .sid = { .override = 0x3f8, .security = 0x3fc, @@ -660,6 +672,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_DLA0RDA, .name = "dla0rda", + .bpmp_id = TEGRA_ICC_BPMP_DLA_0, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA0, .regs = { .sid = { @@ -670,6 +684,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_DLA0FALRDB, .name = "dla0falrdb", + .bpmp_id = TEGRA_ICC_BPMP_DLA_0, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA0, .regs = { .sid = { @@ -680,6 +696,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_DLA0WRA, .name = "dla0wra", + .bpmp_id = TEGRA_ICC_BPMP_DLA_0, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA0, .regs = { .sid = { @@ -690,6 +708,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_DLA0FALWRB, .name = "dla0falwrb", + .bpmp_id = TEGRA_ICC_BPMP_DLA_0, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA0, .regs = { .sid = { @@ -699,7 +719,9 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA1RDA, - .name = "dla0rda", + .name = "dla1rda", + .bpmp_id = TEGRA_ICC_BPMP_DLA_1, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA1, .regs = { .sid = { @@ -709,7 +731,9 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA1FALRDB, - .name = "dla0falrdb", + .name = "dla1falrdb", + .bpmp_id = TEGRA_ICC_BPMP_DLA_1, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA1, .regs = { .sid = { @@ -719,7 +743,9 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA1WRA, - .name = "dla0wra", + .name = "dla1wra", + .bpmp_id = TEGRA_ICC_BPMP_DLA_1, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA1, .regs = { .sid = { @@ -729,7 +755,9 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA1FALWRB, - .name = "dla0falwrb", + .name = "dla1falwrb", + .bpmp_id = TEGRA_ICC_BPMP_DLA_1, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA1, .regs = { .sid = { @@ -908,6 +936,8 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, { .id = TEGRA234_MEMORY_CLIENT_DLA0RDA1, .name = "dla0rda1", + .bpmp_id = TEGRA_ICC_BPMP_DLA_0, + .type = TEGRA_ICC_NISO, .sid = TEGRA234_SID_NVDLA0, .regs = { .sid = { @@ -917,7 +947,7 @@ static const struct tegra_mc_client tegra234_mc_clients[] = { }, }, { .id = TEGRA234_MEMORY_CLIENT_DLA1RDA1, - .name = "dla0rda1", + .name = "dla1rda1", .sid = TEGRA234_SID_NVDLA1, .regs = { .sid = { diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index 9eae25c57ec6..921dce1b8bc6 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -979,7 +979,6 @@ static int emc_check_mc_timings(struct tegra_emc *emc) static int emc_load_timings_from_dt(struct tegra_emc *emc, struct device_node *node) { - struct device_node *child; struct emc_timing *timing; int child_count; int err; @@ -998,12 +997,10 @@ static int emc_load_timings_from_dt(struct tegra_emc *emc, emc->num_timings = child_count; timing = emc->timings; - for_each_child_of_node(node, child) { + for_each_child_of_node_scoped(node, child) { err = load_one_timing_from_dt(emc, timing++, child); - if (err) { - of_node_put(child); + if (err) return err; - } } sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings, @@ -1468,7 +1465,7 @@ to_tegra_emc_provider(struct icc_provider *provider) } static struct icc_node_data * -emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data) +emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) { struct icc_provider *provider = data; struct icc_node_data *ndata; diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c index 06f8b35e0a14..d3e685c8431f 100644 --- a/drivers/memory/tegra/tegra30.c +++ b/drivers/memory/tegra/tegra30.c @@ -1332,7 +1332,7 @@ static int tegra30_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw, } static struct icc_node_data * -tegra30_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data) +tegra30_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) { struct tegra_mc *mc = icc_provider_to_tegra_mc(data); const struct tegra_mc_client *client; |