summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorHyung Taek Ryoo <hryoo@nvidia.com>2012-04-16 11:33:49 -0700
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-04-23 07:40:24 -0700
commite929f231fb47ae745934386f53cfb7ea5b5a257b (patch)
treed7c52c85e00df4aed73cfc43c1980fb742650327 /drivers/media
parent4a8db663c62e6939e14386def1ac11b0e1777df2 (diff)
video: tegra: nvavp: Add force clock stay on API
Add nvavp_force_clock_stay_on ioctl which provides way for user-mode driver to stay on AVP clock state. This change is to fix LP0 resume fail during Widevine playback. Since VDE/BSEV clocks are used by OTF driver in secure world during closing sesssion, the change makes VDE/BSEV clocks running while entering LP0. Bug 960130 Bug 961015 Change-Id: I7eaaa9a33537a72b6ae0a016372bc513fef532e2 Reviewed-on: http://git-master/r/96302 Reviewed-by: Hyung Taek Ryoo <hryoo@nvidia.com> Tested-by: Hyung Taek Ryoo <hryoo@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Karan Jhavar <kjhavar@nvidia.com> Reviewed-by: Dan Willemsen <dwillemsen@nvidia.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/tegra/nvavp/nvavp_dev.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/media/video/tegra/nvavp/nvavp_dev.c b/drivers/media/video/tegra/nvavp/nvavp_dev.c
index d692be54c538..3741043eb1d2 100644
--- a/drivers/media/video/tegra/nvavp/nvavp_dev.c
+++ b/drivers/media/video/tegra/nvavp/nvavp_dev.c
@@ -117,6 +117,7 @@ struct nvavp_info {
struct nvhost_device *nvhost_dev;
struct miscdevice misc_dev;
+ atomic_t clock_stay_on_refcount;
};
struct nvavp_clientctx {
@@ -126,6 +127,7 @@ struct nvavp_clientctx {
struct nvmap_handle_ref *gather_mem;
int num_relocs;
struct nvavp_info *nvavp;
+ int clock_stay_on;
};
static struct clk *nvavp_clk_get(struct nvavp_info *nvavp, int id)
@@ -171,7 +173,8 @@ static void nvavp_clk_ctrl(struct nvavp_info *nvavp, u32 clk_en)
static u32 nvavp_check_idle(struct nvavp_info *nvavp)
{
struct nv_e276_control *control = nvavp->os_control;
- return (control->put == control->get) ? 1 : 0;
+ return ((control->put == control->get)
+ && (!atomic_read(&nvavp->clock_stay_on_refcount))) ? 1 : 0;
}
static void clock_disable_handler(struct work_struct *work)
@@ -1022,6 +1025,39 @@ 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;
+ }
+
+ if (clientctx->clock_stay_on == clock.state)
+ return 0;
+
+ clientctx->clock_stay_on = clock.state;
+
+ if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED)
+ atomic_inc(&nvavp->clock_stay_on_refcount);
+ else if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_DISABLED)
+ atomic_dec(&nvavp->clock_stay_on_refcount);
+
+ return 0;
+}
static int tegra_nvavp_open(struct inode *inode, struct file *filp)
{
@@ -1048,6 +1084,7 @@ static int tegra_nvavp_open(struct inode *inode, struct file *filp)
clientctx->nvmap = nvavp->nvmap;
clientctx->nvavp = nvavp;
+ clientctx->clock_stay_on = NVAVP_CLOCK_STAY_ON_DISABLED;
filp->private_data = clientctx;
@@ -1075,6 +1112,8 @@ static int tegra_nvavp_release(struct inode *inode, struct file *filp)
goto out;
}
+ if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED)
+ atomic_dec(&nvavp->clock_stay_on_refcount);
if (nvavp->refcount > 0)
nvavp->refcount--;
if (!nvavp->refcount)
@@ -1116,6 +1155,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;