From b8817415d59f3e1f5bb2cd49b709e974f37d813f Mon Sep 17 00:00:00 2001 From: Junghyun Kim Date: Thu, 29 Dec 2022 17:45:12 -0800 Subject: [PATCH] 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 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 Tested-by: Frank Chen Reviewed-by: Frank Chen Reviewed-by: Mohit Ingale Reviewed-by: Shiva Dubey --- drivers/media/platform/tegra/cdi/cdi_mgr.c | 81 +++++++++++++--------- include/uapi/media/cdi-mgr.h | 4 +- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/drivers/media/platform/tegra/cdi/cdi_mgr.c b/drivers/media/platform/tegra/cdi/cdi_mgr.c index 85b3d01c..81f36354 100644 --- a/drivers/media/platform/tegra/cdi/cdi_mgr.c +++ b/drivers/media/platform/tegra/cdi/cdi_mgr.c @@ -45,6 +45,8 @@ #define TIMEOUT_US 2000000 /* 2 seconds */ +static struct semaphore tca9539_sem; + /* CDI Dev Debugfs functions * * - cdi_mgr_debugfs_init @@ -701,6 +703,48 @@ static int cdi_mgr_wait_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( 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: err = cdi_mgr_get_pwr_ctrl_info(cdi_mgr, (void __user *)arg); 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: dev_err(cdi_mgr->pdev, "%s unsupported ioctl: %x\n", __func__, cmd); @@ -795,11 +845,8 @@ static long cdi_mgr_ioctl( return err; } -static struct semaphore tca9539_sem; - 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, cdev); @@ -812,34 +859,6 @@ static int cdi_mgr_open(struct inode *inode, struct file *file) dev_dbg(cdi_mgr->pdev, "%s\n", __func__); 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; } diff --git a/include/uapi/media/cdi-mgr.h b/include/uapi/media/cdi-mgr.h index 3085c766..0e87d2ca 100644 --- a/include/uapi/media/cdi-mgr.h +++ b/include/uapi/media/cdi-mgr.h @@ -1,5 +1,5 @@ // 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__ #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_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_ENABLE_DES_POWER _IO('o', 15) +#define CDI_MGR_IOCTL_DISABLE_DES_POWER _IO('o', 16) #define CDI_MGR_POWER_ALL 5 #define MAX_CDI_NAME_LENGTH 32