diff options
author | Bhushan Rayrikar <brayrikar@nvidia.com> | 2011-08-30 14:36:12 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-09-15 12:33:54 -0700 |
commit | 0a36812d0f16ad242d62c4041a2980f8de435448 (patch) | |
tree | 79c0c1eb09a748a8b055dabcc6c9469bfdf5ec2c /drivers/media/video | |
parent | 828f6940cc2c3ed160b5528fdbe9763c9cde5fb7 (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>
Diffstat (limited to 'drivers/media/video')
-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 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 |