summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhushan Rayrikar <brayrikar@nvidia.com>2011-08-30 14:36:12 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-09-15 12:33:54 -0700
commit0a36812d0f16ad242d62c4041a2980f8de435448 (patch)
tree79c0c1eb09a748a8b055dabcc6c9469bfdf5ec2c
parent828f6940cc2c3ed160b5528fdbe9763c9cde5fb7 (diff)
media: video: tegra: Powergate vi, csi and isp
Add powergating for vi, csi and isp in tegra_camera Bug 855758 Change-Id: Ibb026f71ea0623e0e8e21cb8c250f92728d0d60b Reviewed-on: http://git-master/r/52099 Reviewed-by: Bhushan Rayrikar <brayrikar@nvidia.com> Tested-by: Bhushan Rayrikar <brayrikar@nvidia.com> Reviewed-by: Narendra Damahe <ndamahe@nvidia.com> Reviewed-by: Dan Willemsen <dwillemsen@nvidia.com>
-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 95d477ee8cca..438e431fa033 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)
{
@@ -204,6 +206,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;
@@ -220,6 +235,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;
}
@@ -254,13 +278,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;
}
@@ -294,6 +327,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