summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhushan Rayrikar <brayrikar@nvidia.com>2011-08-30 14:36:12 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:50:01 -0800
commitf5881ad6ca97f9c7a6a9a78cb90380dfce1a8ff3 (patch)
tree1f445ff7eea03d0ad037ef39ce70f3c5dc2a65d6
parent4dabb94c2369ad615dc71a07320e0b9486baa311 (diff)
media: video: tegra: Powergate vi, csi and isp
Add powergating for vi, csi and isp in tegra_camera Bug 855758 Reviewed-on: http://git-master/r/49923 (cherry picked from commit ea930f4477408724dea95d9c2f6d612e0e3d11a4) Change-Id: I67a9be5322c3d9fa4a372c1e4338843277086dfe Reviewed-on: http://git-master/r/60278 Reviewed-by: Jihoon Bang <jbang@nvidia.com> Tested-by: Jihoon Bang <jbang@nvidia.com> Reviewed-by: Ruicheng Dai <rdai@nvidia.com> Tested-by: Ruicheng Dai <rdai@nvidia.com> Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: R4319a27f885e83efdc2cfcfe8c195d1ac0cc4643
-rw-r--r--drivers/media/video/tegra/tegra_camera.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/drivers/media/video/tegra/tegra_camera.c b/drivers/media/video/tegra/tegra_camera.c
index a21051690f84..c0786cdb8636 100644
--- a/drivers/media/video/tegra/tegra_camera.c
+++ b/drivers/media/video/tegra/tegra_camera.c
@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <mach/iomap.h>
#include <mach/clk.h>
+#include <mach/powergate.h>
#include <media/tegra_camera.h>
@@ -47,6 +48,7 @@ static struct clk *vi_sensor_clk;
static struct clk *csus_clk;
static struct clk *csi_clk;
static struct regulator *tegra_camera_regulator_csi;
+static int tegra_camera_powergate;
static int tegra_camera_enable_isp(void)
{
@@ -216,6 +218,19 @@ static long tegra_camera_ioctl(struct file *file,
int ret = 0;
mutex_lock(&tegra_camera_lock);
+ /* Unpowergate camera blocks (vi, csi and isp)
+ before enabling clocks */
+ if (tegra_camera_powergate++ == 0) {
+ ret = tegra_unpowergate_partition(TEGRA_POWERGATE_VENC);
+ if (ret) {
+ tegra_powergate_partition(TEGRA_POWERGATE_VENC);
+ pr_err("%s: Unpowergating failed.\n", __func__);
+ tegra_camera_powergate = 0;
+ mutex_unlock(&tegra_camera_lock);
+ return ret;
+ }
+ }
+
if (!tegra_camera_block[id].is_enabled) {
ret = tegra_camera_block[id].enable();
tegra_camera_block[id].is_enabled = true;
@@ -232,6 +247,15 @@ static long tegra_camera_ioctl(struct file *file,
ret = tegra_camera_block[id].disable();
tegra_camera_block[id].is_enabled = false;
}
+ /* Powergate camera blocks (vi, csi and isp)
+ after disabling all the clocks */
+ if (!ret) {
+ if (--tegra_camera_powergate == 0) {
+ ret = tegra_powergate_partition(TEGRA_POWERGATE_VENC);
+ if (ret)
+ pr_err("%s: Powergating failed.\n", __func__);
+ }
+ }
mutex_unlock(&tegra_camera_lock);
return ret;
}
@@ -266,13 +290,22 @@ static long tegra_camera_ioctl(struct file *file,
static int tegra_camera_release(struct inode *inode, struct file *file)
{
- int i;
+ int i, err = 0;
for (i = 0; i < ARRAY_SIZE(tegra_camera_block); i++)
if (tegra_camera_block[i].is_enabled) {
tegra_camera_block[i].disable();
tegra_camera_block[i].is_enabled = false;
}
+ /* If camera blocks are not powergated yet, do it now */
+ if (tegra_camera_powergate > 0) {
+ mutex_lock(&tegra_camera_lock);
+ tegra_camera_powergate = 0;
+ err = tegra_powergate_partition(TEGRA_POWERGATE_VENC);
+ if (err)
+ pr_err("%s: Powergating failed.\n", __func__);
+ mutex_unlock(&tegra_camera_lock);
+ }
return 0;
}
@@ -306,6 +339,14 @@ static int tegra_camera_probe(struct platform_device *pdev)
int err;
pr_info("%s: probe\n", TEGRA_CAMERA_NAME);
+
+ mutex_lock(&tegra_camera_lock);
+ tegra_camera_powergate = 0;
+ err = tegra_powergate_partition(TEGRA_POWERGATE_VENC);
+ if (err)
+ pr_err("%s: Powergating failed.\n", __func__);
+ mutex_unlock(&tegra_camera_lock);
+
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
tegra_camera_regulator_csi = regulator_get(&pdev->dev, "vcsi");
#else