diff options
author | Bhushan Rayrikar <brayrikar@nvidia.com> | 2011-08-30 14:36:12 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:50:01 -0800 |
commit | f5881ad6ca97f9c7a6a9a78cb90380dfce1a8ff3 (patch) | |
tree | 1f445ff7eea03d0ad037ef39ce70f3c5dc2a65d6 | |
parent | 4dabb94c2369ad615dc71a07320e0b9486baa311 (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.c | 43 |
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 |