[PATCH 3/3] ARM: EXYNOS5: save CLK_TOP_SRC3 register before powergating

Prasanna Kumar prasanna.ps at samsung.com
Tue Nov 27 07:22:37 EST 2012


From: Prasanna Kumar <prasanna.ps at samsung.com>

This patch adds a software workaround to the hardware
problem found in exynos5 while powergating.

It is observed that CLK_TOP_SRC3 register gets modified if
the G-Scaler/MFC devices are power gated. The clock for G-Scaler gets
set to XXTI which results in the device running very slow .
A big drop in performance is noticed whilerunning the video.
This issue also occurs while powergating MFC.

The value of clock source register is restored once the powergating
operation is completed.

Signed-off-by: Prasanna Kumar <prasanna.ps at samsung.com>
---
 arch/arm/mach-exynos/pm_domains.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index 9f1351d..955cbe3 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -24,6 +24,8 @@
 
 #include <mach/regs-pmu.h>
 #include <plat/devs.h>
+#include <mach/regs-clock.h>
+#include <plat/cpu.h>
 
 /*
  * Exynos specific wrapper around the generic power domain
@@ -41,6 +43,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
 	void __iomem *base;
 	u32 timeout, pwr;
 	char *op;
+	u32 tmp = 0;
 
 	pd = container_of(domain, struct exynos_pm_domain, pd);
 	base = pd->base;
@@ -48,6 +51,23 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
 	pwr = power_on ? S5P_INT_LOCAL_PWR_EN : 0;
 	__raw_writel(pwr, base);
 
+	/*
+	 *It is found that the CLK SRC register in exynos5
+	 *gets modified when power domain of gsc/mfc/isp/disp1
+	 *is powered off.This happens only after the system is
+	 *suspended and resumed and not before that.
+	 *The following fix adresses this hardware issue.
+	 *It saves the value of clock source register and
+	 *resores it later
+	 */
+
+	if (soc_is_exynos5250()) {
+		if (!power_on) {
+			/* save clock source register */
+			tmp = __raw_readl(EXYNOS5_CLKSRC_TOP3);
+		}
+	}
+
 	/* Wait max 1ms */
 	timeout = 10;
 
@@ -61,6 +81,13 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
 		cpu_relax();
 		usleep_range(80, 100);
 	}
+
+	if (soc_is_exynos5250()) {
+		if (!power_on) {
+			/* restore clock source register */
+			__raw_writel(tmp, EXYNOS5_CLKSRC_TOP3);
+		}
+	}
 	return 0;
 }
 
-- 
1.7.0.4




More information about the linux-arm-kernel mailing list