diff options
author | Ray Poudrier <rapoudrier@nvidia.com> | 2012-08-21 12:23:51 -0700 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2012-08-28 14:00:34 +0530 |
commit | 0a39f87f37c4f04697e8a155a3c0e27fe764ce90 (patch) | |
tree | 33b4da8451d4a477e64b9a54430b2521bd1c319e /arch | |
parent | 25a43cfab213ef1398973bceefb2c028aae4a0ce (diff) |
ARM:tegra:emc: scale latency allowance by tick len
Calculate the tick length of the EMC DFS table
and scale the latency allowance settings.
Bug 955082
Change-Id: Id7b1504c6854009ba7677c7ddebe0a8f62cbfb7e
Signed-off-by: Ray Poudrier <rapoudrier@nvidia.com>
Reviewed-on: http://git-master/r/124980
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/common-t3.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_emc.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_emc.h | 43 |
3 files changed, 102 insertions, 7 deletions
diff --git a/arch/arm/mach-tegra/common-t3.c b/arch/arm/mach-tegra/common-t3.c index 67122916f8fa..9bc49ef199a2 100644 --- a/arch/arm/mach-tegra/common-t3.c +++ b/arch/arm/mach-tegra/common-t3.c @@ -3,7 +3,7 @@ * * Tegra 3 SoC-specific initialization (memory controller, etc.) * - * Copyright (c) 2010-2012, NVIDIA Corporation. + * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +44,8 @@ ((MC_EMEM_ARB_TIMING_W2R - MC_EMEM_ARB_CFG) / 4 + 1) #define MC_TIMING_REG_NUM2 \ ((MC_EMEM_ARB_MISC1 - MC_EMEM_ARB_DA_TURNS) / 4 + 1) +#define MC_TIMING_REG_NUM3 \ + ((MC_LATENCY_ALLOWANCE_VI_2 - MC_LATENCY_ALLOWANCE_AFI) / 4 + 1) struct mc_client { const char *name; @@ -59,7 +61,8 @@ static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); #ifdef CONFIG_PM_SLEEP -static u32 mc_boot_timing[MC_TIMING_REG_NUM1 + MC_TIMING_REG_NUM2 + 4]; +static u32 mc_boot_timing[MC_TIMING_REG_NUM1 + MC_TIMING_REG_NUM2 + + MC_TIMING_REG_NUM3 + 4]; static void tegra_mc_timing_save(void) { @@ -76,7 +79,11 @@ static void tegra_mc_timing_save(void) *ctx++ = readl(mc + MC_EMEM_ARB_OVERRIDE); *ctx++ = readl(mc + MC_RESERVED_RSV); - *ctx++ = readl(mc + MC_INT_MASK); + for (off = MC_LATENCY_ALLOWANCE_AFI; off <= MC_LATENCY_ALLOWANCE_VI_2; + off += 4) + *ctx++ = readl((u32)mc + off); + + *ctx++ = readl((u32)mc + MC_INT_MASK); } void tegra_mc_timing_restore(void) @@ -94,8 +101,12 @@ void tegra_mc_timing_restore(void) __raw_writel(*ctx++, mc + MC_EMEM_ARB_OVERRIDE); __raw_writel(*ctx++, mc + MC_RESERVED_RSV); - writel(*ctx++, mc + MC_INT_MASK); - off = readl(mc + MC_INT_MASK); + for (off = MC_LATENCY_ALLOWANCE_AFI; off <= MC_LATENCY_ALLOWANCE_VI_2; + off += 4) + __raw_writel(*ctx++, (u32)mc + off); + + writel(*ctx++, (u32)mc + MC_INT_MASK); + off = readl((u32)mc + MC_INT_MASK); writel(0x1, mc + MC_TIMING_CONTROL); off = readl(mc + MC_TIMING_CONTROL); diff --git a/arch/arm/mach-tegra/tegra3_emc.c b/arch/arm/mach-tegra/tegra3_emc.c index 0a722e9aca83..f17ff2694fa4 100644 --- a/arch/arm/mach-tegra/tegra3_emc.c +++ b/arch/arm/mach-tegra/tegra3_emc.c @@ -1,7 +1,7 @@ /* * arch/arm/mach-tegra/tegra3_emc.c * - * Copyright (C) 2012 NVIDIA Corporation + * Copyright (C) 2011-2012, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ #include <asm/cacheflush.h> #include <mach/iomap.h> +#include <mach/latency_allowance.h> #include "clock.h" #include "dvfs.h" @@ -1018,6 +1019,31 @@ static struct notifier_block tegra_emc_resume_nb = { .priority = -1, }; +static int tegra_emc_get_table_ns_per_tick(unsigned int emc_rate, + unsigned int table_tick_len) +{ + unsigned int ns_per_tick = 0; + unsigned int mc_period_10ns = 0; + unsigned int reg; + + reg = mc_readl(MC_EMEM_ARB_MISC0) & MC_EMEM_ARB_MISC0_EMC_SAME_FREQ; + + mc_period_10ns = ((reg ? (NSEC_PER_MSEC * 10) : (20 * NSEC_PER_MSEC)) / + (emc_rate)); + ns_per_tick = ((table_tick_len & MC_EMEM_ARB_CFG_CYCLE_MASK) + * mc_period_10ns) / (10 * + (1 + ((table_tick_len & MC_EMEM_ARB_CFG_EXTRA_TICK_MASK) + >> MC_EMEM_ARB_CFG_EXTRA_TICK_SHIFT))); + + /* round new_ns_per_tick to 30/60 */ + if (ns_per_tick < 45) + ns_per_tick = 30; + else + ns_per_tick = 60; + + return ns_per_tick; +} + void tegra_init_emc(const struct tegra_emc_table *table, int table_size) { int i, mv; @@ -1025,6 +1051,8 @@ void tegra_init_emc(const struct tegra_emc_table *table, int table_size) bool max_entry = false; unsigned long boot_rate, max_rate; struct clk *cbus = tegra_get_clock_by_name("cbus"); + unsigned int ns_per_tick = 0; + unsigned int cur_ns_per_tick = 0; emc_stats.clkchange_count = 0; spin_lock_init(&emc_stats.spinlock); @@ -1085,6 +1113,19 @@ void tegra_init_emc(const struct tegra_emc_table *table, int table_size) if (table_rate == max_rate) max_entry = true; + + cur_ns_per_tick = tegra_emc_get_table_ns_per_tick(table_rate, + table[i].burst_regs[MC_EMEM_ARB_CFG_INDEX]); + + if (ns_per_tick == 0) { + ns_per_tick = cur_ns_per_tick; + } else if (ns_per_tick != cur_ns_per_tick) { + pr_err("tegra: invalid EMC DFS table: " + "mismatched DFS tick lengths " + "within table!\n"); + ns_per_tick = 0; + return; + } } /* Validate EMC rate and voltage limits */ @@ -1094,6 +1135,8 @@ void tegra_init_emc(const struct tegra_emc_table *table, int table_size) return; } + tegra_latency_allowance_update_tick_length(ns_per_tick); + tegra_emc_table = table; adjust_emc_dvfs_table(tegra_emc_table, tegra_emc_table_size); diff --git a/arch/arm/mach-tegra/tegra3_emc.h b/arch/arm/mach-tegra/tegra3_emc.h index 29b4556d749d..43ef636c613f 100644 --- a/arch/arm/mach-tegra/tegra3_emc.h +++ b/arch/arm/mach-tegra/tegra3_emc.h @@ -1,7 +1,7 @@ /* * arch/arm/mach-tegra/tegra3_emc.h * - * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. + * Copyright (C) 2011-2012, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -267,6 +267,10 @@ enum { #define MC_EMEM_ADR_CFG 0x54 #define MC_EMEM_ARB_CFG 0x90 +#define MC_EMEM_ARB_CFG_CYCLE_MASK 0x1ff +#define MC_EMEM_ARB_CFG_EXTRA_TICK_SHIFT 16 +#define MC_EMEM_ARB_CFG_EXTRA_TICK_MASK \ + (0x1f << MC_EMEM_ARB_CFG_EXTRA_TICK_SHIFT) #define MC_EMEM_ARB_OUTSTANDING_REQ 0x94 #define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_SHIFT 0 #define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK \ @@ -295,6 +299,43 @@ enum { #define MC_EMEM_ARB_OVERRIDE 0xe8 #define MC_EMEM_ARB_OVERRIDE_EACK_MASK (0x3 << 0) #define MC_TIMING_CONTROL 0xfc +#define MC_LATENCY_ALLOWANCE_AFI 0x2e0 +#define MC_LATENCY_ALLOWANCE_AVPC 0x2e4 +#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8 +#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec +#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0 +#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4 +#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8 +#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc +#define MC_LATENCY_ALLOWANCE_EPP_0 0x300 +#define MC_LATENCY_ALLOWANCE_EPP_1 0x304 +#define MC_LATENCY_ALLOWANCE_G2_0 0x308 +#define MC_LATENCY_ALLOWANCE_G2_1 0x30c +#define MC_LATENCY_ALLOWANCE_HC_0 0x310 +#define MC_LATENCY_ALLOWANCE_HC_1 0x314 +#define MC_LATENCY_ALLOWANCE_HDA 0x318 +#define MC_LATENCY_ALLOWANCE_ISP 0x31c +#define MC_LATENCY_ALLOWANCE_MPCORE 0x320 +#define MC_LATENCY_ALLOWANCE_MPCORELP 0x324 +#define MC_LATENCY_ALLOWANCE_MPE_0 0x328 +#define MC_LATENCY_ALLOWANCE_MPE_1 0x32c +#define MC_LATENCY_ALLOWANCE_MPE_2 0x330 +#define MC_LATENCY_ALLOWANCE_NV_0 0x334 +#define MC_LATENCY_ALLOWANCE_NV_1 0x338 +#define MC_LATENCY_ALLOWANCE_NV2_0 0x33c +#define MC_LATENCY_ALLOWANCE_NV2_1 0x340 +#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344 +#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348 +#define MC_LATENCY_ALLOWANCE_PTC 0x34c +#define MC_LATENCY_ALLOWANCE_SATA 0x350 +#define MC_LATENCY_ALLOWANCE_VDE_0 0x354 +#define MC_LATENCY_ALLOWANCE_VDE_1 0x358 +#define MC_LATENCY_ALLOWANCE_VDE_2 0x35c +#define MC_LATENCY_ALLOWANCE_VDE_3 0x360 +#define MC_LATENCY_ALLOWANCE_VI_0 0x364 +#define MC_LATENCY_ALLOWANCE_VI_1 0x368 +#define MC_LATENCY_ALLOWANCE_VI_2 0x36c + #define MC_RESERVED_RSV 0x3fc #endif |