From f9288476cff96063d0c8aa2fd6397d143e85f433 Mon Sep 17 00:00:00 2001 From: Bitan Biswas Date: Thu, 12 Jul 2012 18:33:37 +0530 Subject: ARM: tegra: reset io dpd mode Bootloader io dpd settings are cleared during kernel initialization bug 758856 Change-Id: Ic6d5250a5ae127bb45ab37b9200ca06c8d1f11a2 Signed-off-by: Bitan Biswas Reviewed-on: http://git-master/r/115395 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/pm-t2.c | 6 ++++++ arch/arm/mach-tegra/pm-t3.c | 43 ++++++++++++++++++++++++++++++++++++++++--- arch/arm/mach-tegra/pm.c | 4 ++++ arch/arm/mach-tegra/pm.h | 3 +++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-tegra/pm-t2.c b/arch/arm/mach-tegra/pm-t2.c index 3ecd27167883..6b8515ab2e3e 100644 --- a/arch/arm/mach-tegra/pm-t2.c +++ b/arch/arm/mach-tegra/pm-t2.c @@ -384,3 +384,9 @@ int tegra_io_dpd_init(void) return 0; } EXPORT_SYMBOL(tegra_io_dpd_init); + +void tegra_bl_io_dpd_cleanup() +{ +} +EXPORT_SYMBOL(tegra_bl_io_dpd_cleanup); + diff --git a/arch/arm/mach-tegra/pm-t3.c b/arch/arm/mach-tegra/pm-t3.c index 89f2bb5f0731..939a9b8ad404 100644 --- a/arch/arm/mach-tegra/pm-t3.c +++ b/arch/arm/mach-tegra/pm-t3.c @@ -483,14 +483,16 @@ struct tegra_io_dpd tegra_list_io_dpd[] = { IO_DPD_INFO("sdhci-tegra.3", 1, 3), /* SDMMC4 */ }; +/* we want to cleanup bootloader io dpd setting in kernel */ +static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); + #ifdef CONFIG_PM_SLEEP struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev) { int i; const char *name = dev ? dev_name(dev) : NULL; if (name) { - for (i = 0; i < (sizeof(tegra_list_io_dpd) / - sizeof(struct tegra_io_dpd)); i++) { + for (i = 0; i < ARRAY_SIZE(tegra_list_io_dpd); i++) { if (!(strncmp(tegra_list_io_dpd[i].name, name, strlen(name)))) { return &tegra_list_io_dpd[i]; @@ -502,7 +504,6 @@ struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev) return NULL; } -static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); static DEFINE_SPINLOCK(tegra_io_dpd_lock); void tegra_io_dpd_enable(struct tegra_io_dpd *hnd) @@ -608,3 +609,39 @@ EXPORT_SYMBOL(tegra_io_dpd_get); EXPORT_SYMBOL(tegra_io_dpd_enable); EXPORT_SYMBOL(tegra_io_dpd_disable); EXPORT_SYMBOL(tegra_io_dpd_init); + +struct io_dpd_reg_info { + u32 req_reg_off; + u8 dpd_code_lsb; +}; + +static struct io_dpd_reg_info t3_io_dpd_req_regs[] = { + {0x1b8, 30}, + {0x1c0, 5}, +}; + +/* io dpd off request code */ +#define IO_DPD_CODE_OFF 1 + +/* cleans io dpd settings from bootloader during kernel init */ +void tegra_bl_io_dpd_cleanup() +{ + int i; + unsigned int dpd_mask; + unsigned int dpd_status; + + pr_info("Clear bootloader IO dpd settings\n"); + /* clear all dpd requests from bootloader */ + for (i = 0; i < ARRAY_SIZE(t3_io_dpd_req_regs); i++) { + dpd_mask = ((1 << t3_io_dpd_req_regs[i].dpd_code_lsb) - 1); + dpd_mask |= (IO_DPD_CODE_OFF << + t3_io_dpd_req_regs[i].dpd_code_lsb); + writel(dpd_mask, pmc + t3_io_dpd_req_regs[i].req_reg_off); + /* dpd status register is next to req reg in tegra3 */ + dpd_status = readl(pmc + + (t3_io_dpd_req_regs[i].req_reg_off + 4)); + } + return; +} +EXPORT_SYMBOL(tegra_bl_io_dpd_cleanup); + diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 85a6cf19234a..9049e37ca05a 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c @@ -1231,6 +1231,10 @@ out: iram_cpu_lp2_mask = tegra_cpu_lp2_mask; iram_cpu_lp1_mask = tegra_cpu_lp1_mask; + + /* clear io dpd settings before kernel */ + tegra_bl_io_dpd_cleanup(); + fail: #endif if (plat->suspend_mode == TEGRA_SUSPEND_NONE) diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h index 65e816c7abc0..498170648819 100644 --- a/arch/arm/mach-tegra/pm.h +++ b/arch/arm/mach-tegra/pm.h @@ -67,6 +67,9 @@ struct tegra_suspend_platform_data { unsigned int cpu_resume_boost; /* CPU frequency resume boost in kHz */ }; +/* clears io dpd settings before kernel code */ +void tegra_bl_io_dpd_cleanup(void); + unsigned long tegra_cpu_power_good_time(void); unsigned long tegra_cpu_power_off_time(void); unsigned long tegra_cpu_lp2_min_residency(void); -- cgit v1.2.3