summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/powergate-t12x.c
diff options
context:
space:
mode:
authorPablo Ceballos <pceballos@nvidia.com>2013-10-09 14:01:48 -0700
committerMitch Luban <mluban@nvidia.com>2013-10-17 09:57:23 -0700
commitc169f3f2fcc55422dd319a620b26654effe2aed1 (patch)
treeb3947e774879ac52c010417eadf317a275a691fd /arch/arm/mach-tegra/powergate-t12x.c
parentfcbe240c620dc16abe8b09092c23f385c9ca49c2 (diff)
arm: tegra: T124 DIS and VE powergate dependency
The DIS partition cannot be powergated without the VE partition first being powergated. Implement this dependency using the ref-counts. Bug 1310335 Bug 1350333 Change-Id: I4686816260e7e966635dc4786d07d7d390254c59 Signed-off-by: Pablo Ceballos <pceballos@nvidia.com> Reviewed-on: http://git-master/r/288574 Reviewed-on: http://git-master/r/298773 Reviewed-by: Mitch Luban <mluban@nvidia.com> Tested-by: Mitch Luban <mluban@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/powergate-t12x.c')
-rw-r--r--arch/arm/mach-tegra/powergate-t12x.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/arch/arm/mach-tegra/powergate-t12x.c b/arch/arm/mach-tegra/powergate-t12x.c
index 7c602a944e71..43087a9f4b94 100644
--- a/arch/arm/mach-tegra/powergate-t12x.c
+++ b/arch/arm/mach-tegra/powergate-t12x.c
@@ -489,58 +489,24 @@ static inline int tegra12x_unpowergate(int id)
return 0;
}
-static int tegra12x_venc_powergate(int id)
-{
- int ret = 0;
- int ref_count = atomic_read(&ref_count_venc);
-
- if (!TEGRA_IS_VENC_POWERGATE_ID(id))
- return -EINVAL;
-
- ref_count = atomic_dec_return(&ref_count_venc);
-
- if (ref_count > 0)
- return ret;
-
- if (ref_count <= 0)
- ret = tegra12x_powergate(id);
-
- return ret;
-}
-
-static int tegra12x_venc_unpowergate(int id)
-{
- int ret = 0;
-
- if (!TEGRA_IS_VENC_POWERGATE_ID(id))
- return -EINVAL;
-
- atomic_inc(&ref_count_venc);
- ret = tegra12x_unpowergate(id);
-
- return ret;
-}
-
static int tegra12x_disp_powergate(int id)
{
int ret = 0;
int ref_counta = atomic_read(&ref_count_dispa);
int ref_countb = atomic_read(&ref_count_dispb);
-
- if (!TEGRA_IS_DISP_POWERGATE_ID(id))
- return -EINVAL;
+ int ref_countve = atomic_read(&ref_count_venc);
if (id == TEGRA_POWERGATE_DISA) {
ref_counta = atomic_dec_return(&ref_count_dispa);
WARN_ONCE(ref_counta < 0, "DISPA ref count underflow");
- } else {
+ } else if (id == TEGRA_POWERGATE_DISB) {
if (ref_countb > 0)
ref_countb = atomic_dec_return(&ref_count_dispb);
if (ref_countb <= 0)
CHECK_RET(tegra12x_powergate(TEGRA_POWERGATE_DISB));
}
- if ((ref_counta <= 0) && (ref_countb <= 0)) {
+ if ((ref_counta <= 0) && (ref_countb <= 0) && (ref_countve <= 0)) {
CHECK_RET(tegra12x_powergate(TEGRA_POWERGATE_SOR));
CHECK_RET(tegra12x_powergate(TEGRA_POWERGATE_DISA));
}
@@ -551,16 +517,13 @@ static int tegra12x_disp_unpowergate(int id)
{
int ret;
- if (!TEGRA_IS_DISP_POWERGATE_ID(id))
- return -EINVAL;
-
/* always unpowergate dispA and SOR partition */
CHECK_RET(tegra12x_unpowergate(TEGRA_POWERGATE_DISA));
CHECK_RET(tegra12x_unpowergate(TEGRA_POWERGATE_SOR));
if (id == TEGRA_POWERGATE_DISA)
atomic_inc(&ref_count_dispa);
- else {
+ else if (id == TEGRA_POWERGATE_DISB) {
atomic_inc(&ref_count_dispb);
ret = tegra12x_unpowergate(TEGRA_POWERGATE_DISB);
}
@@ -568,6 +531,41 @@ static int tegra12x_disp_unpowergate(int id)
return ret;
}
+static int tegra12x_venc_powergate(int id)
+{
+ int ret = 0;
+ int ref_count = atomic_read(&ref_count_venc);
+
+ if (!TEGRA_IS_VENC_POWERGATE_ID(id))
+ return -EINVAL;
+
+ ref_count = atomic_dec_return(&ref_count_venc);
+
+ if (ref_count > 0)
+ return ret;
+
+ if (ref_count <= 0) {
+ CHECK_RET(tegra12x_powergate(id));
+ CHECK_RET(tegra12x_disp_powergate(id));
+ }
+
+ return ret;
+}
+
+static int tegra12x_venc_unpowergate(int id)
+{
+ int ret = 0;
+
+ if (!TEGRA_IS_VENC_POWERGATE_ID(id))
+ return -EINVAL;
+
+ CHECK_RET(tegra12x_disp_unpowergate(id));
+
+ atomic_inc(&ref_count_venc);
+ CHECK_RET(tegra12x_unpowergate(id));
+
+ return ret;
+}
int tegra12x_powergate_partition(int id)
{