From 9fa11c36c178978b1b6b4f719fa25e280f63ecfe Mon Sep 17 00:00:00 2001 From: Johnny Liu Date: Wed, 13 Sep 2023 14:27:21 +0000 Subject: [PATCH] vi5: follow RPM framework for suspend and resume When poweron and poweroff the device, runtime reusme and suspend callbacks should be called respectively so that the device can prepare and teardown the runtime environment properly. For example, requesting proper ICC memory bandwidth requests in resume and suspend cycles. Bug 4199055 Signed-off-by: Johnny Liu Change-Id: I67a77c58b3c05f67caf1fe83bcc0edd1da376768 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2979911 Reviewed-by: Anubhav Rai Reviewed-by: Bibek Basu GVS: Gerrit_Virtual_Submit --- .../media/platform/tegra/camera/vi/vi5_fops.c | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/tegra/camera/vi/vi5_fops.c b/drivers/media/platform/tegra/camera/vi/vi5_fops.c index fc4403ed..be0c8503 100644 --- a/drivers/media/platform/tegra/camera/vi/vi5_fops.c +++ b/drivers/media/platform/tegra/camera/vi/vi5_fops.c @@ -5,23 +5,25 @@ * Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ -#include -#include +#include #include +#include #include #include -#include +#include #include -#include -#include -#include +#include #include #include +#include +#include +#include #include -#include "vi5_formats.h" -#include "vi5_fops.h" #include +#include "vi5_fops.h" +#include "vi5_formats.h" + #define DEFAULT_FRAMERATE 30 #define BPP_MEM 2 #define VI_CSI_CLK_SCALE 110 @@ -998,11 +1000,21 @@ void tegra_vi5_disable(struct tegra_mc_vi *vi) static int vi5_power_on(struct tegra_channel *chan) { int ret = 0; + struct device *dev; struct tegra_mc_vi *vi; struct tegra_csi_device *csi; vi = chan->vi; csi = vi->csi; + vi5_unit_get_device_handle(vi->ndev, chan->port[0], &dev); + + /* Resume VI5 to set ICC bandwidth with maximum value */ + if (pm_runtime_enabled(dev)) { + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { + return ret; + } + } ret = tegra_vi5_enable(vi); if (ret < 0) @@ -1020,17 +1032,25 @@ static int vi5_power_on(struct tegra_channel *chan) static void vi5_power_off(struct tegra_channel *chan) { int ret = 0; + struct device *dev; struct tegra_mc_vi *vi; struct tegra_csi_device *csi; vi = chan->vi; csi = vi->csi; + vi5_unit_get_device_handle(vi->ndev, chan->port[0], &dev); ret = tegra_channel_set_power(chan, 0); if (ret < 0) dev_err(vi->dev, "Failed to power off subdevices\n"); tegra_vi5_disable(vi); + + /* Suspend VI5 to reset ICC bandwidth request */ + if (pm_runtime_enabled(dev)) { + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + } } struct tegra_vi_fops vi5_fops = {