From 627fa473f742cf141a70298a9c366df07935fa2d Mon Sep 17 00:00:00 2001 From: tkasivajhula Date: Tue, 22 Jun 2010 17:04:22 -0700 Subject: [ARM/tegra] Various Fixes for the LP0 power state. - Fix the AVP suspend/restore path. - KBC is currently broken as a wake up source, so disable that and enable rtc - Fix warmboot sequence. - Various other PMC issues Change-Id: Ifa70b66253f3a30f85822ef6c0eecac29b1fc8d1 Reviewed-on: http://git-master/r/3019 Reviewed-by: Trivikram Kasivajhula Tested-by: Trivikram Kasivajhula Reviewed-by: Yu-Huan Hsu --- .../odm_kit/query/whistler/nvodm_query.c | 4 +-- arch/arm/mach-tegra/suspend-t2.c | 23 ++++++++++++++ arch/arm/mach-tegra/suspend.c | 37 ++++++++++++++++++---- arch/arm/mach-tegra/tegra2_save.S | 30 ++++++++++++++++++ 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c index fab62d92bfcd..841798ed9d73 100644 --- a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c @@ -581,8 +581,8 @@ static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] = {NV_FALSE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1 {NV_FALSE, 14, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 14 - gp3_pv[6] (WLAN_INT) {NV_FALSE, 15, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 15 - gmi_ad16 (SPI3_DOUT, DTV_SPI4_CS1) - {NV_FALSE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq - {NV_TRUE, 17, NvOdmWakeupPadPolarity_High}, // Wake Event 17 - kbc_interrupt + {NV_TRUE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq + {NV_FALSE, 17, NvOdmWakeupPadPolarity_High}, // Wake Event 17 - kbc_interrupt {NV_FALSE, 18, NvOdmWakeupPadPolarity_Low}, // Wake Event 18 - pwr_int (PMIC_INT) {NV_FALSE, 19, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 19 - usb_vbus_wakeup[0] {NV_FALSE, 20, NvOdmWakeupPadPolarity_High}, // Wake Event 20 - usb_vbus_wakeup[1] diff --git a/arch/arm/mach-tegra/suspend-t2.c b/arch/arm/mach-tegra/suspend-t2.c index ed1055687baf..1cff68f878e9 100644 --- a/arch/arm/mach-tegra/suspend-t2.c +++ b/arch/arm/mach-tegra/suspend-t2.c @@ -24,6 +24,8 @@ #include #include #include +#include "nvbootargs.h" +#include #define PMC_SCRATCH3 0x5c #define PMC_SCRATCH5 0x64 @@ -49,6 +51,7 @@ #define PMC_SCRATCH35 0x128 #define PMC_SCRATCH36 0x12c #define PMC_SCRATCH40 0x13c +#define PMC_SCRATCH41 0x140 struct pmc_scratch_field { void __iomem *addr; @@ -328,9 +331,16 @@ static const struct pmc_scratch_reg scratch[] __initdata = { scratch(PMC_SCRATCH40, xm2_cfgd), }; +extern void tegra_lp2_startup(void); +extern NvRmDeviceHandle s_hRmGlobal; +unsigned int s_AvpWarmbootEntry; +static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); + void __init lp0_suspend_init(void) { int i; + NvBootArgsWarmboot WarmbootArgs; + NvRmMemHandle s_hWarmboot = NULL; for (i=0; iwake_high; lvl ^= status; - writel(lvl, PMC_WAKE_LEVEL); - writel(pdata->wake_enb, PMC_WAKE_MASK); + writel(lvl, pmc + PMC_WAKE_LEVEL); + writel(pdata->wake_enb, pmc + PMC_WAKE_MASK); } extern void __tegra_lp1_reset(void); @@ -314,6 +328,7 @@ extern void __tegra_iram_end(void); static u8 *iram_save = NULL; static unsigned int iram_save_size = 0; static void __iomem *iram_code = IO_ADDRESS(TEGRA_IRAM_CODE_AREA); +static void __iomem *iram_avp_resume = IO_ADDRESS(TEGRA_IRAM_BASE); static void tegra_suspend_dram(bool lp0_ok) { @@ -344,6 +359,7 @@ static void tegra_suspend_dram(bool lp0_ok) } else { NvRmPrivPowerSetState(s_hRmGlobal, NvRmPowerState_LP0); set_power_timers(pdata->cpu_timer, pdata->cpu_off_timer); + tegra_setup_warmboot(); mode |= TEGRA_POWER_SYSCLK_OE; mode |= TEGRA_POWER_PWRREQ_OE; mode |= TEGRA_POWER_EFFECT_LP0; @@ -365,6 +381,8 @@ static void tegra_suspend_dram(bool lp0_ok) reg |= ((mode & TEGRA_POWER_PMC_MASK) << TEGRA_POWER_PMC_SHIFT); pmc_32kwritel(reg, PMC_CTRL); } + else + mode |= TEGRA_POWER_CPU_PWRREQ_OE; tegra_setup_wakepads(lp0_ok); suspend_cpu_complex(); @@ -390,7 +408,9 @@ static void tegra_suspend_dram(bool lp0_ok) } else if (!lp0_ok) writel(lp2_timer, pmc + PMC_CPUPWRGOOD_TIMER); - memcpy(iram_code, iram_save, iram_save_size); + if (!lp0_ok) + memcpy(iram_code, iram_save, iram_save_size); + wmb(); } @@ -489,6 +509,11 @@ static int tegra_suspend_prepare_late(void) __func__, e); return -EIO; } + + //The AVP stores its resume address in the first word of IRAM + //Write this resume address to SCRATCH39, where the warmboot + //code can later find it + writel(*(volatile unsigned int *)iram_avp_resume, pmc + PMC_SCRATCH39); #endif disable_irq(INT_SYS_STATS_MON); return tegra_iovmm_suspend(); diff --git a/arch/arm/mach-tegra/tegra2_save.S b/arch/arm/mach-tegra/tegra2_save.S index 6f7fd086a366..b5353803e0b5 100644 --- a/arch/arm/mach-tegra/tegra2_save.S +++ b/arch/arm/mach-tegra/tegra2_save.S @@ -69,6 +69,9 @@ #define FLOW_CTRL_HALT_CPU_EVENTS 0x0 +#define DEBUG_FORCE_RTC_WAKEUP_SEC 0 +#define RTC_PA_BASE 0x7000e000 + #include "power-macros.S" .macro emc_device_mask, rd, base @@ -366,6 +369,33 @@ __tear_down_master_pll_cpu: bic r0, r0, #(1<<30) str r0, [r5, #CLK_RESET_PLLC_BASE] +#if DEBUG_FORCE_RTC_WAKEUP_SEC + //r0 = RTC_BASE + mov32 r0, RTC_PA_BASE + //setup rtc wake + ldr r2, [r0, #0x10] /* milli */ + ldr r2, [r0, #0x8] /* shadow */ + + add r2, r2, #DEBUG_FORCE_RTC_WAKEUP_SEC +rtc_idle1: + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle1 + str r2, [r0, #0x14] +rtc_idle2: + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle2 + /* intr mask alarm0 */ + mov r2, #1 + str r2, [r0, #0x28] + str r2, [r0, #0x2c] +rtc_idle3: + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle3 +#endif + __cclk_burst_set: mov r0, #(4<<29) /* STOP_UNTIL_IRQ */ orr r0, r0, #(1<<10) | (1<<8) /* IRQ_0, FIQ_0 */ -- cgit v1.2.3