diff options
author | tkasivajhula <tkasivajhula@nvidia.com> | 2010-04-19 19:13:21 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-04-19 19:46:05 -0700 |
commit | d76bfff19bc436f58fe97e906107dfc2878a236a (patch) | |
tree | c636b3f04e0c11f5d6b2e5865aa4aec42c1a3768 /arch | |
parent | 3685ff284c841c0af0b1caf6558cc4d142bfc4d1 (diff) |
tegra power: Spurious KBC interrupt WAR. Explicitly disable KBC interrupt.
The interrupt flag in the 32KHz domain might not be getting cleared correctly.
Clear the kbc interrupt explicitly prior to LP0 to fix this.
Change-Id: I68c93cb3130fd123e28f1c697b9314b1bbcf4c6e
Reviewed-on: http://git-master/r/1154
Reviewed-by: Gary King <gking@nvidia.com>
Reviewed-by: Trivikram Kasivajhula <tkasivajhula@nvidia.com>
Tested-by: Trivikram Kasivajhula <tkasivajhula@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/idle-t2.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-t2.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power.h | 3 |
3 files changed, 31 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/idle-t2.c b/arch/arm/mach-tegra/idle-t2.c index 26c2bb7e3c8b..33625294df9f 100644 --- a/arch/arm/mach-tegra/idle-t2.c +++ b/arch/arm/mach-tegra/idle-t2.c @@ -57,6 +57,10 @@ extern struct wake_lock main_wake_lock; //Let Max LP2 time wait be 71 min (Almost a wrap around) #define LP2_MAX_WAIT_TIME_US (71*60*1000000ul) +#if NV_KBC_INTERRUPT_WORKAROUND +volatile void *g_pKBC; +#endif + // When non-zero, collects and prints aggregate statistics about idle times static volatile NvU8 *s_pFlowCtrl = NULL; @@ -222,6 +226,17 @@ void __init NvAp20InitFlowController(void) return; } +#if NV_KBC_INTERRUPT_WORKAROUND + NvRmModuleGetBaseAddress(s_hRmGlobal, + NVRM_MODULE_ID(NvRmModuleID_Kbc, 0), &pa, &len); + + if (NvRmPhysicalMemMap(pa, len, NVOS_MEM_READ_WRITE, + NvOsMemAttribute_Uncached, + (void**)&g_pKBC)!=NvSuccess) + { + return; + } +#endif s_pFlowCtrl = pTempFc; g_ArmPerif = (NvU32)pTempArmPerif; diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c index 04e65a6795a6..e340298cc5ae 100644 --- a/arch/arm/mach-tegra/power-t2.c +++ b/arch/arm/mach-tegra/power-t2.c @@ -23,6 +23,7 @@ #include "power.h" #include "linux/interrupt.h" #include "nvassert.h" +#include "ap20/arapbdev_kbc.h" extern int enter_power_state(PowerState state, unsigned int proc_id); extern void prepare_for_wb0(void); @@ -43,6 +44,10 @@ void shadow_lp0_scratch_regs(void); extern NvRmDeviceHandle s_hRmGlobal; +#if NV_KBC_INTERRUPT_WORKAROUND +extern volatile void *g_pKBC; +#endif + uintptr_t g_resume = 0, g_contextSavePA = 0, g_contextSaveVA = 0; uintptr_t g_iramContextSaveVA = 0; NvU32 g_modifiedPlls; @@ -99,6 +104,13 @@ void cpu_ap20_do_lp0(void) prepare_for_wb0(); shadow_lp0_scratch_regs(); printk("LP0: Entering...\n"); + +#if NV_KBC_INTERRUPT_WORKAROUND + //Forcibly clear the interrupt. This will clear + //the KBC interrupt that is probably pending in the + //32KHz domain. + NV_WRITE32(g_pKBC + APBDEV_KBC_INT_0, 0x1); +#endif enter_power_state(POWER_STATE_LP0, 0); //Re-initialize the L2 cache @@ -721,7 +733,7 @@ unsigned int check_for_cpu1_reset(void) CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET_0); reg = reg & 0x2; - + return reg; } diff --git a/arch/arm/mach-tegra/power.h b/arch/arm/mach-tegra/power.h index 81a1130fa2da..ddca6fa3ce49 100644 --- a/arch/arm/mach-tegra/power.h +++ b/arch/arm/mach-tegra/power.h @@ -50,6 +50,9 @@ extern NvRmDeviceHandle s_hRmGlobal; #define WAKE_PAD_MIN_LATCH_TIME_US 130 #define WAKE_PAD_MIN_SAMPLE_TIME_US 70 +//Workaround for spurious KBC wake event +#define NV_KBC_INTERRUPT_WORKAROUND 1 + #define NV_CAR_REGR(pBase, reg)\ NV_READ32( (((NvUPtr)(pBase)) + CLK_RST_CONTROLLER_##reg##_0)) #define NV_CAR_REGW(pBase, reg, val)\ |