@@ -73,6 +73,17 @@
};
MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
+static void mc_modifyl(struct tegra_mc *mc, u32 reg, u32 value, u8 shift,
+ u8 mask)
+{
+ u32 val;
+
+ val = readl(mc->regs + reg);
+ val &= ~(mask << shift);
+ val |= (value & mask) << shift;
+ writel(val, mc->regs + reg);
+}
+
static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
{
unsigned long long tick;
@@ -91,18 +102,14 @@ static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
/* write latency allowance defaults */
for (i = 0; i < mc->soc->num_clients; i++) {
const struct tegra_mc_la *la = &mc->soc->clients[i].la;
- u32 value;
-
- value = readl(mc->regs + la->reg);
- value &= ~(la->mask << la->shift);
- value |= (la->def & la->mask) << la->shift;
- writel(value, mc->regs + la->reg);
+ mc_modifyl(mc, la->reg, la->def, la->shift, la->mask);
}
return 0;
}
-void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
+static struct tegra_mc_timing *find_mc_timing(struct tegra_mc *mc,
+ unsigned long rate)
{
unsigned int i;
struct tegra_mc_timing *timing = NULL;
@@ -114,6 +121,15 @@ void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
}
}
+ return timing;
+}
+
+void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
+{
+ unsigned int i;
+ struct tegra_mc_timing *timing = NULL;
+
+ timing = find_mc_timing(mc, rate);
if (!timing) {
dev_err(mc->dev, "no memory timing registered for rate %lu\n",
rate);
Introduce a few helper functions to lookup a timing for a given rate and modify MC register field. These will be useful when adding support for updating the latency allowance (LA) registers when scaling the EMC clock. Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> --- drivers/memory/tegra/mc.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-)