summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorHyung Taek Ryoo <hryoo@nvidia.com>2012-05-11 11:19:00 -0700
committerLokesh Pathak <lpathak@nvidia.com>2012-05-14 03:35:02 -0700
commitfa2c352e1c7430f525265ea78301f41210555dcf (patch)
tree0e0146045784d102dd0eae1f5ff1dcbd622ed8b3 /drivers/media
parentdfa3daebbc8dbe3ccc8e72400359dfce29053222 (diff)
video: tegra: nvavp: Add a clock request ioctl
Add nvavp_force_clock_stay_on ioctl which provides way for user-mode driver to request the VDE/BSEV clocks. This change is to fix a hang during DRM session close. The AVP driver may have already turned the clocks off since playback was paused prior to session teardown. This situation can cause the OTF driver on secure side to hang if the VDE/BSEV clocks are not explicitly enabled prior to calling session terminate. Bug 960130 Bug 961015 Bug 979102 Change-Id: I3c09a6766f50a01ed04fbfd03e723ad9e978909f Reviewed-on: http://git-master/r/102024 Reviewed-by: Prajakta Gudadhe <pgudadhe@nvidia.com> Tested-by: Prajakta Gudadhe <pgudadhe@nvidia.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/tegra/nvavp/nvavp_dev.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/media/video/tegra/nvavp/nvavp_dev.c b/drivers/media/video/tegra/nvavp/nvavp_dev.c
index 14e4dc218241..4627c514622a 100644
--- a/drivers/media/video/tegra/nvavp/nvavp_dev.c
+++ b/drivers/media/video/tegra/nvavp/nvavp_dev.c
@@ -127,6 +127,7 @@ struct nvavp_clientctx {
struct nvmap_handle_ref *gather_mem;
int num_relocs;
struct nvavp_info *nvavp;
+ u32 clk_reqs;
};
static struct clk *nvavp_clk_get(struct nvavp_info *nvavp, int id)
@@ -1039,6 +1040,38 @@ static int nvavp_wake_avp_ioctl(struct file *filp, unsigned int cmd,
return 0;
}
+static int nvavp_force_clock_stay_on_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct nvavp_clientctx *clientctx = filp->private_data;
+ struct nvavp_info *nvavp = clientctx->nvavp;
+ struct nvavp_clock_stay_on_state_args clock;
+
+ if (copy_from_user(&clock, (void __user *)arg,
+ sizeof(struct nvavp_clock_stay_on_state_args)))
+ return -EFAULT;
+
+ dev_dbg(&nvavp->nvhost_dev->dev, "%s: state=%d\n",
+ __func__, clock.state);
+
+ if (clock.state != NVAVP_CLOCK_STAY_ON_DISABLED &&
+ clock.state != NVAVP_CLOCK_STAY_ON_ENABLED) {
+ dev_err(&nvavp->nvhost_dev->dev, "%s: invalid argument=%d\n",
+ __func__, clock.state);
+ return -EINVAL;
+ }
+
+ mutex_lock(&nvavp->open_lock);
+ if (clock.state) {
+ if (clientctx->clk_reqs++ == 0)
+ nvavp_clks_enable(nvavp);
+ } else {
+ if (--clientctx->clk_reqs == 0)
+ nvavp_clks_disable(nvavp);
+ }
+ mutex_unlock(&nvavp->open_lock);
+ return 0;
+}
static int tegra_nvavp_open(struct inode *inode, struct file *filp)
{
@@ -1092,6 +1125,10 @@ static int tegra_nvavp_release(struct inode *inode, struct file *filp)
goto out;
}
+ /* if this client had any requests, drop our clk ref */
+ if (clientctx->clk_reqs)
+ nvavp_clks_disable(nvavp);
+
if (nvavp->refcount > 0)
nvavp->refcount--;
if (!nvavp->refcount)
@@ -1133,6 +1170,9 @@ static long tegra_nvavp_ioctl(struct file *filp, unsigned int cmd,
case NVAVP_IOCTL_WAKE_AVP:
ret = nvavp_wake_avp_ioctl(filp, cmd, arg);
break;
+ case NVAVP_IOCTL_FORCE_CLOCK_STAY_ON:
+ ret = nvavp_force_clock_stay_on_ioctl(filp, cmd, arg);
+ break;
default:
ret = -EINVAL;
break;