summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authortkasivajhula <tkasivajhula@nvidia.com>2010-04-19 19:13:21 -0700
committerGary King <gking@nvidia.com>2010-04-19 19:46:05 -0700
commitd76bfff19bc436f58fe97e906107dfc2878a236a (patch)
treec636b3f04e0c11f5d6b2e5865aa4aec42c1a3768 /arch
parent3685ff284c841c0af0b1caf6558cc4d142bfc4d1 (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.c15
-rw-r--r--arch/arm/mach-tegra/power-t2.c14
-rw-r--r--arch/arm/mach-tegra/power.h3
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)\