From 62370157ebb71a150877ce13a2d3a94b0ab84526 Mon Sep 17 00:00:00 2001 From: Gary King Date: Mon, 12 Jul 2010 19:17:49 -0700 Subject: [ARM/tegra] suspend: unconditionally configure PMC inverters change 8cb11a7a introduced a read-modify-write dependency in the LP2 entry sequence, and unconditionally enabled the core voltage request for platforms with separate requests for CPU & core voltage this caused harmony to immediately shutdown when entering LP2, since configuration of the PMC inverters was only being performed for systems that supported core voltage off (a.k.a., LP0). fix this by unconditionally configuring the inverters and other PMC state so that core_oe can be enabled safely Change-Id: I8fd11585ba511d6d13365250f80903bc0d71d0a4 Reviewed-on: http://git-master/r/3849 Reviewed-by: Aleksandr Frid Tested-by: Aleksandr Frid Reviewed-by: Gary King Tested-by: Gary King --- arch/arm/mach-tegra/suspend.c | 59 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c index bed16c47d4e3..2bd93273b33b 100644 --- a/arch/arm/mach-tegra/suspend.c +++ b/arch/arm/mach-tegra/suspend.c @@ -300,12 +300,12 @@ static void tegra_setup_warmboot(void) { u32 scratch0; - //Turn the WARMBOOT flag on in scratch0 + /* Turn the WARMBOOT flag on in scratch0 */ scratch0 = readl(pmc + PMC_SCRATCH0); scratch0 |= 1; pmc_32kwritel(scratch0, PMC_SCRATCH0); - //Write the AVP warmboot entry address in SCRATCH1 + /* Write the AVP warmboot entry address in SCRATCH1 */ pmc_32kwritel(s_AvpWarmbootEntry, PMC_SCRATCH1); } @@ -553,9 +553,9 @@ static int tegra_suspend_prepare_late(void) 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 + /* 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); @@ -669,12 +669,13 @@ extern void __init lp0_suspend_init(void); void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat) { -#ifdef CONFIG_PM - u32 reg; -#endif + u32 reg, mode; + tegra_pclk = clk_get_sys(NULL, "pclk"); BUG_ON(!tegra_pclk); pdata = plat; + (void)reg; + (void)mode; #ifdef CONFIG_PM iram_save_size = (unsigned long)__tegra_iram_end; @@ -695,34 +696,32 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat) /* Configure core power request and system clock control if LP0 is supported */ - if (pdata->core_off) { - u32 mode; - - writel(pdata->core_timer, pmc + PMC_COREPWRGOOD_TIMER); - writel(pdata->core_off_timer, pmc + PMC_COREPWROFF_TIMER); - reg = readl(pmc + PMC_CTRL); - mode = (reg >> TEGRA_POWER_PMC_SHIFT) & TEGRA_POWER_PMC_MASK; + writel(pdata->core_timer, pmc + PMC_COREPWRGOOD_TIMER); + writel(pdata->core_off_timer, pmc + PMC_COREPWROFF_TIMER); + reg = readl(pmc + PMC_CTRL); + mode = (reg >> TEGRA_POWER_PMC_SHIFT) & TEGRA_POWER_PMC_MASK; - mode &= ~TEGRA_POWER_SYSCLK_POLARITY; - mode &= ~TEGRA_POWER_PWRREQ_POLARITY; + mode &= ~TEGRA_POWER_SYSCLK_POLARITY; + mode &= ~TEGRA_POWER_PWRREQ_POLARITY; - if (!pdata->sysclkreq_high) - mode |= TEGRA_POWER_SYSCLK_POLARITY; - if (!pdata->corereq_high) - mode |= TEGRA_POWER_PWRREQ_POLARITY; + if (!pdata->sysclkreq_high) + mode |= TEGRA_POWER_SYSCLK_POLARITY; + if (!pdata->corereq_high) + mode |= TEGRA_POWER_PWRREQ_POLARITY; - /* configure output inverters while the request is tristated */ - reg |= (mode << TEGRA_POWER_PMC_SHIFT); - pmc_32kwritel(reg, PMC_CTRL); + /* configure output inverters while the request is tristated */ + reg |= (mode << TEGRA_POWER_PMC_SHIFT); + pmc_32kwritel(reg, PMC_CTRL); - /* now enable requests */ - reg |= (TEGRA_POWER_SYSCLK_OE << TEGRA_POWER_PMC_SHIFT); - if (pdata->separate_req) - reg |= (TEGRA_POWER_PWRREQ_OE << TEGRA_POWER_PMC_SHIFT); - writel(reg, pmc + PMC_CTRL); + /* now enable requests */ + reg |= (TEGRA_POWER_SYSCLK_OE << TEGRA_POWER_PMC_SHIFT); + if (pdata->separate_req) + reg |= (TEGRA_POWER_PWRREQ_OE << TEGRA_POWER_PMC_SHIFT); + writel(reg, pmc + PMC_CTRL); + if (pdata->core_off) lp0_suspend_init(); - } + suspend_set_ops(&tegra_suspend_ops); #endif } -- cgit v1.2.3