From 420b84b69d206b523fcbd23fbc4b349a65c611cd Mon Sep 17 00:00:00 2001 From: Mainak Sen Date: Thu, 17 Aug 2023 09:06:57 +0000 Subject: [PATCH] drm/tegra: Stop channel DMA during suspend When channels are kept open over a suspend cycle, we need to re-initialize CDMA after resume. Bug 4133027 Change-Id: I9a2737b377a9ffb37e5f98703b7928bfceab58e3 Signed-off-by: Mainak Sen Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2963164 Reviewed-by: Mikko Perttunen GVS: Gerrit_Virtual_Submit --- drivers/gpu/host1x/channel.c | 17 +++++++++++++++++ drivers/gpu/host1x/channel.h | 1 + drivers/gpu/host1x/dev.c | 3 ++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c index e20c4844..847834b1 100644 --- a/drivers/gpu/host1x/channel.c +++ b/drivers/gpu/host1x/channel.c @@ -117,6 +117,23 @@ static struct host1x_channel *acquire_unused_channel(struct host1x *host) return &chlist->channels[index]; } +/** + * host1x_channel_list_stop() - disable cdma on allocated channels + * @chlist: list of host1x channels + * + * Stop DMA on the allocated channels during suspend + */ +void host1x_channel_list_stop(struct host1x_channel_list *chlist) +{ + struct host1x *host = container_of(chlist, struct host1x, channel_list); + int i; + for (i = 0; i < host->info->nb_channels; i++) { + if (!test_bit(i, chlist->allocated_channels)) + continue; + host1x_channel_stop(&chlist->channels[i]); + } +} + /** * host1x_channel_request() - Allocate a channel * @client: Host1x client this channel will be used to send commands to diff --git a/drivers/gpu/host1x/channel.h b/drivers/gpu/host1x/channel.h index 39044ff6..725b874c 100644 --- a/drivers/gpu/host1x/channel.h +++ b/drivers/gpu/host1x/channel.h @@ -37,5 +37,6 @@ int host1x_channel_list_init(struct host1x_channel_list *chlist, void host1x_channel_list_free(struct host1x_channel_list *chlist); struct host1x_channel *host1x_channel_get_index(struct host1x *host, unsigned int index); +void host1x_channel_list_stop(struct host1x_channel_list *chlist); #endif diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 2238bf40..55cd6dd4 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -1015,6 +1015,7 @@ static int __maybe_unused host1x_runtime_suspend(struct device *dev) int err; host1x_hw_intr_disable_all_general_intrs(host); + host1x_channel_list_stop(&host->channel_list); host1x_intr_stop(host); host1x_syncpt_save(host); @@ -1090,7 +1091,7 @@ release_reset: static const struct dev_pm_ops host1x_pm_ops = { SET_RUNTIME_PM_OPS(host1x_runtime_suspend, host1x_runtime_resume, NULL) - /* TODO: add system suspend-resume once driver will be ready for that */ + SET_SYSTEM_SLEEP_PM_OPS(host1x_runtime_suspend, host1x_runtime_resume) }; static struct platform_driver tegra_host1x_driver = {