drivers: media: CDI: Add Des's power control

Add the new IOCTL command to control the deserilaizer's PWDN signal
instead of enabling it when CDI root opens

Bug 3879569

Change-Id: Ia07c3b4266e1f137d197af130fb2bf12e52a1767
Signed-off-by: Junghyun Kim <juskim@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2835141
(cherry picked from commit 29fb31dad2e63d2669a6a6eb5c2751092b7097e2)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2847959
(cherry picked from commit bd9766952be10722f4cc6a17ff582005b3138b08)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2854722
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
Tested-by: Frank Chen <frankc@nvidia.com>
Reviewed-by: Frank Chen <frankc@nvidia.com>
Reviewed-by: Mohit Ingale <mohiti@nvidia.com>
Reviewed-by: Shiva Dubey <sdubey@nvidia.com>
This commit is contained in:
Junghyun Kim
2022-12-29 17:45:12 -08:00
committed by mobile promotions
parent 55cee03ee7
commit b8817415d5
2 changed files with 53 additions and 32 deletions

View File

@@ -45,6 +45,8 @@
#define TIMEOUT_US 2000000 /* 2 seconds */ #define TIMEOUT_US 2000000 /* 2 seconds */
static struct semaphore tca9539_sem;
/* CDI Dev Debugfs functions /* CDI Dev Debugfs functions
* *
* - cdi_mgr_debugfs_init * - cdi_mgr_debugfs_init
@@ -701,6 +703,48 @@ static int cdi_mgr_wait_err(
return err; return err;
} }
static int cdi_mgr_des_power(
struct cdi_mgr_priv *cdi_mgr, bool enable)
{
u8 val;
/* if runtime_pwrctrl_off is not true, power on all here */
if (!cdi_mgr->pdata->runtime_pwrctrl_off)
cdi_mgr_power_up(cdi_mgr, 0xffffffff);
cdi_mgr_mcdi_ctrl(cdi_mgr, enable);
if (cdi_mgr->tca9539.enable) {
if (down_timeout(&tca9539_sem,
usecs_to_jiffies(TIMEOUT_US)) != 0)
dev_err(cdi_mgr->dev,
"%s: failed to wait for the semaphore\n",
__func__);
if (cdi_mgr->cim_ver == 1U) { /* P3714 A01 */
if (tca9539_rd(cdi_mgr, 0x02, &val) != 0)
return -EFAULT;
if (enable)
val |= (0x10 << cdi_mgr->tca9539.power_port);
else
val &= ~(0x10 << cdi_mgr->tca9539.power_port);
if (tca9539_wr(cdi_mgr, 0x02, val) != 0)
return -EFAULT;
} else if (cdi_mgr->cim_ver == 2U) { /* P3714 A02 */
if (tca9539_rd(cdi_mgr, 0x03, &val) != 0)
return -EFAULT;
if (enable)
val |= (0x1 << cdi_mgr->tca9539.power_port);
else
val &= ~(0x1 << cdi_mgr->tca9539.power_port);
if (tca9539_wr(cdi_mgr, 0x03, val) != 0)
return -EFAULT;
}
up(&tca9539_sem);
}
return 0;
}
static long cdi_mgr_ioctl( static long cdi_mgr_ioctl(
struct file *file, unsigned int cmd, unsigned long arg) struct file *file, unsigned int cmd, unsigned long arg)
{ {
@@ -783,6 +827,12 @@ static long cdi_mgr_ioctl(
case CDI_MGR_IOCTL_GET_PWR_INFO: case CDI_MGR_IOCTL_GET_PWR_INFO:
err = cdi_mgr_get_pwr_ctrl_info(cdi_mgr, (void __user *)arg); err = cdi_mgr_get_pwr_ctrl_info(cdi_mgr, (void __user *)arg);
break; break;
case CDI_MGR_IOCTL_ENABLE_DES_POWER:
err = cdi_mgr_des_power(cdi_mgr, true);
break;
case CDI_MGR_IOCTL_DISABLE_DES_POWER:
err = cdi_mgr_des_power(cdi_mgr, false);
break;
default: default:
dev_err(cdi_mgr->pdev, "%s unsupported ioctl: %x\n", dev_err(cdi_mgr->pdev, "%s unsupported ioctl: %x\n",
__func__, cmd); __func__, cmd);
@@ -795,11 +845,8 @@ static long cdi_mgr_ioctl(
return err; return err;
} }
static struct semaphore tca9539_sem;
static int cdi_mgr_open(struct inode *inode, struct file *file) static int cdi_mgr_open(struct inode *inode, struct file *file)
{ {
u8 val;
struct cdi_mgr_priv *cdi_mgr = container_of(inode->i_cdev, struct cdi_mgr_priv *cdi_mgr = container_of(inode->i_cdev,
struct cdi_mgr_priv, cdev); struct cdi_mgr_priv, cdev);
@@ -812,34 +859,6 @@ static int cdi_mgr_open(struct inode *inode, struct file *file)
dev_dbg(cdi_mgr->pdev, "%s\n", __func__); dev_dbg(cdi_mgr->pdev, "%s\n", __func__);
file->private_data = cdi_mgr; file->private_data = cdi_mgr;
/* if runtime_pwrctrl_off is not true, power on all here */
if (!cdi_mgr->pdata->runtime_pwrctrl_off)
cdi_mgr_power_up(cdi_mgr, 0xffffffff);
cdi_mgr_mcdi_ctrl(cdi_mgr, true);
if (cdi_mgr->tca9539.enable) {
if (down_timeout(&tca9539_sem,
usecs_to_jiffies(TIMEOUT_US)) != 0)
dev_err(cdi_mgr->dev,
"%s: failed to wait for the semaphore\n",
__func__);
if (cdi_mgr->cim_ver == 1U) { /* P3714 A01 */
if (tca9539_rd(cdi_mgr, 0x02, &val) != 0)
return -EFAULT;
val |= (0x10 << cdi_mgr->tca9539.power_port);
if (tca9539_wr(cdi_mgr, 0x02, val) != 0)
return -EFAULT;
} else if (cdi_mgr->cim_ver == 2U) { /* P3714 A02 */
if (tca9539_rd(cdi_mgr, 0x03, &val) != 0)
return -EFAULT;
val |= (0x1 << cdi_mgr->tca9539.power_port);
if (tca9539_wr(cdi_mgr, 0x03, val) != 0)
return -EFAULT;
}
up(&tca9539_sem);
}
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // Copyright (c) 2020-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#ifndef __UAPI_TEGRA_CDI_MGR_H__ #ifndef __UAPI_TEGRA_CDI_MGR_H__
#define __UAPI_TEGRA_CDI_MGR_H__ #define __UAPI_TEGRA_CDI_MGR_H__
@@ -21,6 +21,8 @@
#define CDI_MGR_IOCTL_GET_EXT_PWR_CTRL _IOR('o', 12, __u8) #define CDI_MGR_IOCTL_GET_EXT_PWR_CTRL _IOR('o', 12, __u8)
#define CDI_MGR_IOCTL_ENABLE_ERROR_REPORT _IO('o', 13) #define CDI_MGR_IOCTL_ENABLE_ERROR_REPORT _IO('o', 13)
#define CDI_MGR_IOCTL_GET_PWR_INFO _IOW('o', 14, struct cdi_mgr_pwr_ctrl_info) #define CDI_MGR_IOCTL_GET_PWR_INFO _IOW('o', 14, struct cdi_mgr_pwr_ctrl_info)
#define CDI_MGR_IOCTL_ENABLE_DES_POWER _IO('o', 15)
#define CDI_MGR_IOCTL_DISABLE_DES_POWER _IO('o', 16)
#define CDI_MGR_POWER_ALL 5 #define CDI_MGR_POWER_ALL 5
#define MAX_CDI_NAME_LENGTH 32 #define MAX_CDI_NAME_LENGTH 32