diff mbox series

[2/3] gpu: host1x: Stop CDMA before suspending

Message ID 20230901111510.663401-2-cyndis@kapsi.fi
State Accepted
Headers show
Series [1/3] gpu: host1x: Add locking in channel allocation | expand

Commit Message

Mikko Perttunen Sept. 1, 2023, 11:15 a.m. UTC
From: Mikko Perttunen <mperttunen@nvidia.com>

Before going into suspend, wait all CDMA to go idle and stop it.
This will ensure no channel is still active while we enter
suspend, and ensures the driver doesn't think that CDMA is still
active when coming back from suspend (as HW state has been reset).

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 drivers/gpu/host1x/channel.c | 19 +++++++++++++++++++
 drivers/gpu/host1x/channel.h |  1 +
 drivers/gpu/host1x/dev.c     |  1 +
 3 files changed, 21 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c
index 79501c957532..08077afe4cde 100644
--- a/drivers/gpu/host1x/channel.c
+++ b/drivers/gpu/host1x/channel.c
@@ -81,6 +81,25 @@  void host1x_channel_stop(struct host1x_channel *channel)
 }
 EXPORT_SYMBOL(host1x_channel_stop);
 
+/**
+ * host1x_channel_stop_all() - disable CDMA on allocated channels
+ * @host: host1x instance
+ *
+ * Stop CDMA on allocated channels
+ */
+void host1x_channel_stop_all(struct host1x *host)
+{
+	struct host1x_channel_list *chlist = &host->channel_list;
+	int bit;
+
+	mutex_lock(&chlist->lock);
+
+	for_each_set_bit(bit, chlist->allocated_channels, host->info->nb_channels)
+		host1x_channel_stop(&chlist->channels[bit]);
+
+	mutex_unlock(&chlist->lock);
+}
+
 static void release_channel(struct kref *kref)
 {
 	struct host1x_channel *channel =
diff --git a/drivers/gpu/host1x/channel.h b/drivers/gpu/host1x/channel.h
index b23a8071fbd0..d7aede204d83 100644
--- a/drivers/gpu/host1x/channel.h
+++ b/drivers/gpu/host1x/channel.h
@@ -40,5 +40,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_stop_all(struct host1x *host);
 
 #endif
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 7c6699aed7d2..6501bee9e8c1 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -655,6 +655,7 @@  static int __maybe_unused host1x_runtime_suspend(struct device *dev)
 	struct host1x *host = dev_get_drvdata(dev);
 	int err;
 
+	host1x_channel_stop_all(host);
 	host1x_intr_stop(host);
 	host1x_syncpt_save(host);