mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
drm/tegra: Unify logic for suspend and resume
Two main changes for the suspend and resume: 1. Set clock to Fmin/Fmax in suspend/resume cycles 2. Reorder the code in suspend and resume functions and add recovering logic when error happens in between Bug 4224081 Signed-off-by: Johnny Liu <johnliu@nvidia.com> Change-Id: Iadb0b1f960ca8b9c80094d1769a2d90496263124 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2948452 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
61af983ca4
commit
69d9f479a4
@@ -577,12 +577,14 @@ static __maybe_unused int nvdec_runtime_resume(struct device *dev)
|
||||
goto disable;
|
||||
}
|
||||
|
||||
err = devfreq_resume_device(nvdec->devfreq);
|
||||
if (err < 0)
|
||||
goto disable;
|
||||
|
||||
nvdec_actmon_reg_init(nvdec);
|
||||
|
||||
host1x_actmon_enable(&nvdec->client.base);
|
||||
|
||||
devfreq_resume_device(nvdec->devfreq);
|
||||
|
||||
return 0;
|
||||
|
||||
disable:
|
||||
@@ -595,21 +597,29 @@ static __maybe_unused int nvdec_runtime_suspend(struct device *dev)
|
||||
struct nvdec *nvdec = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
devfreq_suspend_device(nvdec->devfreq);
|
||||
|
||||
host1x_actmon_disable(&nvdec->client.base);
|
||||
|
||||
host1x_channel_stop(nvdec->channel);
|
||||
|
||||
clk_bulk_disable_unprepare(nvdec->num_clks, nvdec->clks);
|
||||
err = devfreq_suspend_device(nvdec->devfreq);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (nvdec->icc_write) {
|
||||
err = icc_set_bw(nvdec->icc_write, 0, 0);
|
||||
if (err)
|
||||
if (err) {
|
||||
dev_warn(nvdec->dev, "failed to set icc bw: %d\n", err);
|
||||
goto devfreq_resume;
|
||||
}
|
||||
}
|
||||
|
||||
clk_bulk_disable_unprepare(nvdec->num_clks, nvdec->clks);
|
||||
|
||||
host1x_channel_stop(nvdec->channel);
|
||||
|
||||
host1x_actmon_disable(&nvdec->client.base);
|
||||
|
||||
return 0;
|
||||
|
||||
devfreq_resume:
|
||||
devfreq_resume_device(nvdec->devfreq);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nvdec_open_channel(struct tegra_drm_client *client,
|
||||
|
||||
@@ -467,12 +467,14 @@ static __maybe_unused int nvenc_runtime_resume(struct device *dev)
|
||||
if (err < 0)
|
||||
goto disable;
|
||||
|
||||
err = devfreq_resume_device(nvenc->devfreq);
|
||||
if (err < 0)
|
||||
goto disable;
|
||||
|
||||
nvenc_actmon_reg_init(nvenc);
|
||||
|
||||
host1x_actmon_enable(&nvenc->client.base);
|
||||
|
||||
devfreq_resume_device(nvenc->devfreq);
|
||||
|
||||
return 0;
|
||||
|
||||
disable:
|
||||
@@ -485,21 +487,29 @@ static __maybe_unused int nvenc_runtime_suspend(struct device *dev)
|
||||
struct nvenc *nvenc = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
devfreq_suspend_device(nvenc->devfreq);
|
||||
|
||||
host1x_actmon_disable(&nvenc->client.base);
|
||||
|
||||
host1x_channel_stop(nvenc->channel);
|
||||
|
||||
clk_disable_unprepare(nvenc->clk);
|
||||
err = devfreq_suspend_device(nvenc->devfreq);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (nvenc->icc_write) {
|
||||
err = icc_set_bw(nvenc->icc_write, 0, 0);
|
||||
if (err)
|
||||
if (err) {
|
||||
dev_warn(nvenc->dev, "failed to set icc bw: %d\n", err);
|
||||
goto devfreq_resume;
|
||||
}
|
||||
}
|
||||
|
||||
clk_disable_unprepare(nvenc->clk);
|
||||
|
||||
host1x_channel_stop(nvenc->channel);
|
||||
|
||||
host1x_actmon_disable(&nvenc->client.base);
|
||||
|
||||
return 0;
|
||||
|
||||
devfreq_resume:
|
||||
devfreq_resume_device(nvenc->devfreq);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nvenc_open_channel(struct tegra_drm_client *client,
|
||||
|
||||
@@ -466,12 +466,14 @@ static __maybe_unused int nvjpg_runtime_resume(struct device *dev)
|
||||
if (err < 0)
|
||||
goto disable;
|
||||
|
||||
err = devfreq_resume_device(nvjpg->devfreq);
|
||||
if (err < 0)
|
||||
goto disable;
|
||||
|
||||
nvjpg_actmon_reg_init(nvjpg);
|
||||
|
||||
host1x_actmon_enable(&nvjpg->client.base);
|
||||
|
||||
devfreq_resume_device(nvjpg->devfreq);
|
||||
|
||||
return 0;
|
||||
|
||||
disable:
|
||||
@@ -484,21 +486,29 @@ static __maybe_unused int nvjpg_runtime_suspend(struct device *dev)
|
||||
struct nvjpg *nvjpg = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
devfreq_suspend_device(nvjpg->devfreq);
|
||||
|
||||
host1x_actmon_disable(&nvjpg->client.base);
|
||||
|
||||
host1x_channel_stop(nvjpg->channel);
|
||||
|
||||
clk_disable_unprepare(nvjpg->clk);
|
||||
err = devfreq_suspend_device(nvjpg->devfreq);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (nvjpg->icc_write) {
|
||||
err = icc_set_bw(nvjpg->icc_write, 0, 0);
|
||||
if (err)
|
||||
if (err) {
|
||||
dev_warn(nvjpg->dev, "failed to set icc bw: %d\n", err);
|
||||
goto devfreq_resume;
|
||||
}
|
||||
}
|
||||
|
||||
clk_disable_unprepare(nvjpg->clk);
|
||||
|
||||
host1x_channel_stop(nvjpg->channel);
|
||||
|
||||
host1x_actmon_disable(&nvjpg->client.base);
|
||||
|
||||
return 0;
|
||||
|
||||
devfreq_resume:
|
||||
devfreq_resume_device(nvjpg->devfreq);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nvjpg_open_channel(struct tegra_drm_client *client,
|
||||
|
||||
@@ -524,18 +524,19 @@ static int __maybe_unused vic_runtime_resume(struct device *dev)
|
||||
if (err < 0)
|
||||
goto assert;
|
||||
|
||||
err = devfreq_resume_device(vic->devfreq);
|
||||
if (err < 0)
|
||||
goto assert;
|
||||
|
||||
vic_actmon_reg_init(vic);
|
||||
|
||||
host1x_actmon_enable(&vic->client.base);
|
||||
|
||||
devfreq_resume_device(vic->devfreq);
|
||||
|
||||
return 0;
|
||||
|
||||
assert:
|
||||
reset_control_assert(vic->rst);
|
||||
disable:
|
||||
devfreq_suspend_device(vic->devfreq);
|
||||
clk_disable_unprepare(vic->clk);
|
||||
return err;
|
||||
}
|
||||
@@ -545,27 +546,35 @@ static int __maybe_unused vic_runtime_suspend(struct device *dev)
|
||||
struct vic *vic = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
devfreq_suspend_device(vic->devfreq);
|
||||
err = devfreq_suspend_device(vic->devfreq);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
host1x_actmon_disable(&vic->client.base);
|
||||
|
||||
host1x_channel_stop(vic->channel);
|
||||
if (vic->icc_write) {
|
||||
err = icc_set_bw(vic->icc_write, 0, 0);
|
||||
if (err) {
|
||||
dev_warn(vic->dev, "failed to set icc bw: %d\n", err);
|
||||
goto devfreq_resume;
|
||||
}
|
||||
}
|
||||
|
||||
err = reset_control_assert(vic->rst);
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto devfreq_resume;
|
||||
|
||||
usleep_range(2000, 4000);
|
||||
|
||||
clk_disable_unprepare(vic->clk);
|
||||
|
||||
if (vic->icc_write) {
|
||||
err = icc_set_bw(vic->icc_write, 0, 0);
|
||||
if (err)
|
||||
dev_warn(vic->dev, "failed to set icc bw: %d\n", err);
|
||||
}
|
||||
host1x_channel_stop(vic->channel);
|
||||
|
||||
host1x_actmon_disable(&vic->client.base);
|
||||
|
||||
return 0;
|
||||
|
||||
devfreq_resume:
|
||||
devfreq_resume_device(vic->devfreq);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int vic_open_channel(struct tegra_drm_client *client,
|
||||
|
||||
Reference in New Issue
Block a user