Re: [PATCH v2 2/2] drm/tegra: Do not implement runtime PM

2019-12-23 Thread Ulf Hansson
On Thu, 12 Dec 2019 at 17:48, Rafael J. Wysocki  wrote:
>
> On Thu, Dec 12, 2019 at 2:32 PM Ulf Hansson  wrote:
> >
> > On Thu, 12 Dec 2019 at 13:33, Thierry Reding  
> > wrote:
> > >
> > > On Thu, Dec 12, 2019 at 09:52:22AM +0100, Ulf Hansson wrote:
> > > > On Mon, 9 Dec 2019 at 14:03, Thierry Reding  
> > > > wrote:
> > > > >
> > > > > From: Thierry Reding 
> > > > >
> > > > > The Tegra DRM driver heavily relies on the implementations for runtime
> > > > > suspend/resume to be called at specific times. Unfortunately, there 
> > > > > are
> > > > > some cases where that doesn't work. One example is if the user 
> > > > > disables
> > > > > runtime PM for a given subdevice. Another example is that the PM core
> > > > > acquires a reference to runtime PM during system sleep, effectively
> > > > > preventing devices from going into low power modes. This is 
> > > > > intentional
> > > > > to avoid nasty race conditions, but it also causes system sleep to not
> > > > > function properly on all Tegra systems.
> > > >
> > > > Are the problems you refer to above, solely for system suspend/resume?
> > >
> > > No, this patch also fixes potential issues with regular operation of the
> > > display driver. The problem is that parts of the driver rely on being
> > > able to shut down the hardware during runtime operations, such as
> > > disabling an output. Under some circumstances part of this shutdown will
> > > imply a reset and, at least on some platforms, we rely on that reset to
> > > put the device into a known good state.
> > >
> > > So if a user decides to prevent the device from runtime suspending, we
> > > can potentially run into a situation where we can't properly set a
> > > display mode at runtime since we weren't allowed to reset the device.
> >
> > Thanks for clarifying!
> >
> > We have very similar issues for SDIO functional drivers (WiFi
> > drivers). Typically, at some point there needs to be a guarantee that
> > the power has been cut in between a "put" and "get", as to be able to
> > re-program a FW.
> >
> > My worry in regards to this, is that we may reinvent the wheel over
> > and over again, just because runtime PM today isn't a good fit.
> >
> > In principle, if you could, somehow forbid user-space from preventing
> > the device from being runtime suspended, that would do the trick,
> > wouldn't it?
>
> Treating pm_runtime_suspend() and pm_runtime_resume() as the low-level
> device power off and power on routines for the given platform is a
> mistake.  It has always been a mistake and I'm not going to accept
> changes trying to make it look like it isn't a mistake.

Of course you are right that it's a mistake. I am just pondering if
over how bad the mistake(s) really are and what we can do about them.

For example, on x86, the ACPI PM domain is used to power the SDIO card
and the SDIO func device (the SDIO card is the parent to the SDIO func
device) via runtime PM.

Honestly, I don't know how to fix this, unless we allow the drivers to
call the ACPI power on/off functions directly, but that doesn't sound
very nice either and kind of defeats the purpose of using the PM
domain.

>
> If any generic power off and power on helpers for DT-based platforms
> are needed, add them and make PM-runtime use them.  That should be
> straightforward enough.

That wouldn't help in the SDIO case as the power on/off thingy is
still relying on those runtime PM calls.

Kind regards
Uffe
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 2/2] drm/tegra: Do not implement runtime PM

2019-12-13 Thread Ulf Hansson
On Mon, 9 Dec 2019 at 14:03, Thierry Reding  wrote:
>
> From: Thierry Reding 
>
> The Tegra DRM driver heavily relies on the implementations for runtime
> suspend/resume to be called at specific times. Unfortunately, there are
> some cases where that doesn't work. One example is if the user disables
> runtime PM for a given subdevice. Another example is that the PM core
> acquires a reference to runtime PM during system sleep, effectively
> preventing devices from going into low power modes. This is intentional
> to avoid nasty race conditions, but it also causes system sleep to not
> function properly on all Tegra systems.

Are the problems you refer to above, solely for system suspend/resume?

>
> Fix this by not implementing runtime PM at all. Instead, a minimal,
> reference-counted suspend/resume infrastructure is added to the host1x
> bus. This has the benefit that it can be used regardless of the system
> power state (or any transitions we might be in), or whether or not the
> user allows runtime PM.
>
> Atomic modesetting guarantees that these functions will end up being
> called at the right point in time, so the pitfalls for the more generic
> runtime PM do not apply here.

Before I go on a look more closely to the code...

How do these changes affect the control of the power-rails for the
related devices? We should strive towards using PM domain(s), that
gets attached to the device.

Is that still the case or are these changes causing more calls to
shortcut that path, which means more calls into SoC specific code
directly from the drivers?

Kind regards
Uffe

>
> Signed-off-by: Thierry Reding 
> ---
> Changes in v2:
> - keep runtime PM for VIC
>
>  drivers/gpu/drm/tegra/dc.c| 141 ++--
>  drivers/gpu/drm/tegra/dpaux.c |   2 +-
>  drivers/gpu/drm/tegra/drm.h   |   2 +
>  drivers/gpu/drm/tegra/dsi.c   | 175 --
>  drivers/gpu/drm/tegra/hdmi.c  | 116 +++-
>  drivers/gpu/drm/tegra/hub.c   | 194 --
>  drivers/gpu/drm/tegra/hub.h   |   2 +-
>  drivers/gpu/drm/tegra/sor.c   | 154 +++
>  drivers/gpu/host1x/bus.c  |  75 +
>  include/linux/host1x.h|  11 ++
>  10 files changed, 541 insertions(+), 331 deletions(-)
>
> diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> index 2983eb33f2be..871046f3f469 100644
> --- a/drivers/gpu/drm/tegra/dc.c
> +++ b/drivers/gpu/drm/tegra/dc.c
> @@ -1737,6 +1737,7 @@ static void tegra_crtc_atomic_disable(struct drm_crtc 
> *crtc,
>  {
> struct tegra_dc *dc = to_tegra_dc(crtc);
> u32 value;
> +   int err;
>
> if (!tegra_dc_idle(dc)) {
> tegra_dc_stop(dc);
> @@ -1783,7 +1784,9 @@ static void tegra_crtc_atomic_disable(struct drm_crtc 
> *crtc,
>
> spin_unlock_irq(>dev->event_lock);
>
> -   pm_runtime_put_sync(dc->dev);
> +   err = host1x_client_suspend(>client);
> +   if (err < 0)
> +   dev_err(dc->dev, "failed to suspend: %d\n", err);
>  }
>
>  static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
> @@ -1793,8 +1796,13 @@ static void tegra_crtc_atomic_enable(struct drm_crtc 
> *crtc,
> struct tegra_dc_state *state = to_dc_state(crtc->state);
> struct tegra_dc *dc = to_tegra_dc(crtc);
> u32 value;
> +   int err;
>
> -   pm_runtime_get_sync(dc->dev);
> +   err = host1x_client_resume(>client);
> +   if (err < 0) {
> +   dev_err(dc->dev, "failed to resume: %d\n", err);
> +   return;
> +   }
>
> /* initialize display controller */
> if (dc->syncpt) {
> @@ -2022,6 +2030,15 @@ static int tegra_dc_init(struct host1x_client *client)
> if (!tegra_dc_has_window_groups(dc))
> return 0;
>
> +   /*
> +* Set the display hub as the host1x client parent for the display
> +* controller. This is needed for the runtime reference counting that
> +* ensures the display hub is always powered when any of the display
> +* controllers are.
> +*/
> +   if (dc->soc->has_nvdisplay)
> +   client->parent = >hub->client;
> +
> dc->syncpt = host1x_syncpt_request(client, flags);
> if (!dc->syncpt)
> dev_warn(dc->dev, "failed to allocate syncpoint\n");
> @@ -2131,9 +2148,74 @@ static int tegra_dc_exit(struct host1x_client *client)
> return 0;
>  }
>
> +static int tegra_dc_runtime_suspend(struct host1x_client *client)
> +{
> +   struct tegra_dc *dc = host1x_client_to_dc(client);
> +   struct device *dev = client->dev;
> +   int err;
> +
> +   err = reset_control_assert(dc->rst);
> +   if (err < 0) {
> +   dev_err(dev, "failed to assert reset: %d\n", err);
> +   return err;
> +   }
> +
> +   if (dc->soc->has_powergate)
> +   tegra_powergate_power_off(dc->powergate);
> +
> +   

Re: [PATCH v2 2/2] drm/tegra: Do not implement runtime PM

2019-12-13 Thread Ulf Hansson
On Thu, 12 Dec 2019 at 13:33, Thierry Reding  wrote:
>
> On Thu, Dec 12, 2019 at 09:52:22AM +0100, Ulf Hansson wrote:
> > On Mon, 9 Dec 2019 at 14:03, Thierry Reding  
> > wrote:
> > >
> > > From: Thierry Reding 
> > >
> > > The Tegra DRM driver heavily relies on the implementations for runtime
> > > suspend/resume to be called at specific times. Unfortunately, there are
> > > some cases where that doesn't work. One example is if the user disables
> > > runtime PM for a given subdevice. Another example is that the PM core
> > > acquires a reference to runtime PM during system sleep, effectively
> > > preventing devices from going into low power modes. This is intentional
> > > to avoid nasty race conditions, but it also causes system sleep to not
> > > function properly on all Tegra systems.
> >
> > Are the problems you refer to above, solely for system suspend/resume?
>
> No, this patch also fixes potential issues with regular operation of the
> display driver. The problem is that parts of the driver rely on being
> able to shut down the hardware during runtime operations, such as
> disabling an output. Under some circumstances part of this shutdown will
> imply a reset and, at least on some platforms, we rely on that reset to
> put the device into a known good state.
>
> So if a user decides to prevent the device from runtime suspending, we
> can potentially run into a situation where we can't properly set a
> display mode at runtime since we weren't allowed to reset the device.

Thanks for clarifying!

We have very similar issues for SDIO functional drivers (WiFi
drivers). Typically, at some point there needs to be a guarantee that
the power has been cut in between a "put" and "get", as to be able to
re-program a FW.

My worry in regards to this, is that we may reinvent the wheel over
and over again, just because runtime PM today isn't a good fit.

In principle, if you could, somehow forbid user-space from preventing
the device from being runtime suspended, that would do the trick,
wouldn't it?

When it comes to system suspend/resume I am less concerned, as we have
a couple of different methods to address this problem.

>
> > > Fix this by not implementing runtime PM at all. Instead, a minimal,
> > > reference-counted suspend/resume infrastructure is added to the host1x
> > > bus. This has the benefit that it can be used regardless of the system
> > > power state (or any transitions we might be in), or whether or not the
> > > user allows runtime PM.
> > >
> > > Atomic modesetting guarantees that these functions will end up being
> > > called at the right point in time, so the pitfalls for the more generic
> > > runtime PM do not apply here.
> >
> > Before I go on a look more closely to the code...
> >
> > How do these changes affect the control of the power-rails for the
> > related devices? We should strive towards using PM domain(s), that
> > gets attached to the device.
> >
> > Is that still the case or are these changes causing more calls to
> > shortcut that path, which means more calls into SoC specific code
> > directly from the drivers?
>
> This shouldn't change anything with regards to power domains. We still
> attach to those and use generic PM domains if they are available. If you
> look at the implementations for these "runtime" suspend/resume
> operations, they will in fact release/acquire a runtime PM reference,
> respectively. This is done to make sure that generic PM domain
> references are properly balanced, so that the power domains get turned
> off when none of the devices are using them anymore.
>
> The only calls to SoC specific code is the same that we used to have
> before, which we need for backwards-compatibility with old device trees.
> In practice we never hit those code paths anymore because all Tegra
> devices allow updating the DTB at the same time as the kernel. But users
> could technically be running a really old device tree against a recent
> kernel and then they'd need those legacy code paths to ensure the
> devices are powered on.

Great, this makes me comfortable with this approach!

Kind regards
Uffe

>
> Thierry
>
> > > Signed-off-by: Thierry Reding 
> > > ---
> > > Changes in v2:
> > > - keep runtime PM for VIC
> > >
> > >  drivers/gpu/drm/tegra/dc.c| 141 ++--
> > >  drivers/gpu/drm/tegra/dpaux.c |   2 +-
> > >  drivers/gpu/drm/tegra/drm.h   |   2 +
> > >  drivers/gpu/drm/tegra/dsi.c   | 175 --
> > >  drivers/gpu/drm/tegra/hdmi.c  | 116 +++-
> > >  drivers/gpu/drm/tegra/hub.c   | 194 --
> > >  drivers/gpu/drm/tegra/hub.h   |   2 +-
> > >  drivers/gpu/drm/tegra/sor.c   | 154 +++
> > >  drivers/gpu/host1x/bus.c  |  75 +
> > >  include/linux/host1x.h|  11 ++
> > >  10 files changed, 541 insertions(+), 331 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> > > index 

Re: [PATCH v2 2/2] drm/tegra: Do not implement runtime PM

2019-12-12 Thread Rafael J. Wysocki
On Thu, Dec 12, 2019 at 2:32 PM Ulf Hansson  wrote:
>
> On Thu, 12 Dec 2019 at 13:33, Thierry Reding  wrote:
> >
> > On Thu, Dec 12, 2019 at 09:52:22AM +0100, Ulf Hansson wrote:
> > > On Mon, 9 Dec 2019 at 14:03, Thierry Reding  
> > > wrote:
> > > >
> > > > From: Thierry Reding 
> > > >
> > > > The Tegra DRM driver heavily relies on the implementations for runtime
> > > > suspend/resume to be called at specific times. Unfortunately, there are
> > > > some cases where that doesn't work. One example is if the user disables
> > > > runtime PM for a given subdevice. Another example is that the PM core
> > > > acquires a reference to runtime PM during system sleep, effectively
> > > > preventing devices from going into low power modes. This is intentional
> > > > to avoid nasty race conditions, but it also causes system sleep to not
> > > > function properly on all Tegra systems.
> > >
> > > Are the problems you refer to above, solely for system suspend/resume?
> >
> > No, this patch also fixes potential issues with regular operation of the
> > display driver. The problem is that parts of the driver rely on being
> > able to shut down the hardware during runtime operations, such as
> > disabling an output. Under some circumstances part of this shutdown will
> > imply a reset and, at least on some platforms, we rely on that reset to
> > put the device into a known good state.
> >
> > So if a user decides to prevent the device from runtime suspending, we
> > can potentially run into a situation where we can't properly set a
> > display mode at runtime since we weren't allowed to reset the device.
>
> Thanks for clarifying!
>
> We have very similar issues for SDIO functional drivers (WiFi
> drivers). Typically, at some point there needs to be a guarantee that
> the power has been cut in between a "put" and "get", as to be able to
> re-program a FW.
>
> My worry in regards to this, is that we may reinvent the wheel over
> and over again, just because runtime PM today isn't a good fit.
>
> In principle, if you could, somehow forbid user-space from preventing
> the device from being runtime suspended, that would do the trick,
> wouldn't it?

Treating pm_runtime_suspend() and pm_runtime_resume() as the low-level
device power off and power on routines for the given platform is a
mistake.  It has always been a mistake and I'm not going to accept
changes trying to make it look like it isn't a mistake.

If any generic power off and power on helpers for DT-based platforms
are needed, add them and make PM-runtime use them.  That should be
straightforward enough.

Thanks!
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 2/2] drm/tegra: Do not implement runtime PM

2019-12-12 Thread Thierry Reding
On Thu, Dec 12, 2019 at 09:52:22AM +0100, Ulf Hansson wrote:
> On Mon, 9 Dec 2019 at 14:03, Thierry Reding  wrote:
> >
> > From: Thierry Reding 
> >
> > The Tegra DRM driver heavily relies on the implementations for runtime
> > suspend/resume to be called at specific times. Unfortunately, there are
> > some cases where that doesn't work. One example is if the user disables
> > runtime PM for a given subdevice. Another example is that the PM core
> > acquires a reference to runtime PM during system sleep, effectively
> > preventing devices from going into low power modes. This is intentional
> > to avoid nasty race conditions, but it also causes system sleep to not
> > function properly on all Tegra systems.
> 
> Are the problems you refer to above, solely for system suspend/resume?

No, this patch also fixes potential issues with regular operation of the
display driver. The problem is that parts of the driver rely on being
able to shut down the hardware during runtime operations, such as
disabling an output. Under some circumstances part of this shutdown will
imply a reset and, at least on some platforms, we rely on that reset to
put the device into a known good state.

So if a user decides to prevent the device from runtime suspending, we
can potentially run into a situation where we can't properly set a
display mode at runtime since we weren't allowed to reset the device.

> > Fix this by not implementing runtime PM at all. Instead, a minimal,
> > reference-counted suspend/resume infrastructure is added to the host1x
> > bus. This has the benefit that it can be used regardless of the system
> > power state (or any transitions we might be in), or whether or not the
> > user allows runtime PM.
> >
> > Atomic modesetting guarantees that these functions will end up being
> > called at the right point in time, so the pitfalls for the more generic
> > runtime PM do not apply here.
> 
> Before I go on a look more closely to the code...
> 
> How do these changes affect the control of the power-rails for the
> related devices? We should strive towards using PM domain(s), that
> gets attached to the device.
> 
> Is that still the case or are these changes causing more calls to
> shortcut that path, which means more calls into SoC specific code
> directly from the drivers?

This shouldn't change anything with regards to power domains. We still
attach to those and use generic PM domains if they are available. If you
look at the implementations for these "runtime" suspend/resume
operations, they will in fact release/acquire a runtime PM reference,
respectively. This is done to make sure that generic PM domain
references are properly balanced, so that the power domains get turned
off when none of the devices are using them anymore.

The only calls to SoC specific code is the same that we used to have
before, which we need for backwards-compatibility with old device trees.
In practice we never hit those code paths anymore because all Tegra
devices allow updating the DTB at the same time as the kernel. But users
could technically be running a really old device tree against a recent
kernel and then they'd need those legacy code paths to ensure the
devices are powered on.

Thierry

> > Signed-off-by: Thierry Reding 
> > ---
> > Changes in v2:
> > - keep runtime PM for VIC
> >
> >  drivers/gpu/drm/tegra/dc.c| 141 ++--
> >  drivers/gpu/drm/tegra/dpaux.c |   2 +-
> >  drivers/gpu/drm/tegra/drm.h   |   2 +
> >  drivers/gpu/drm/tegra/dsi.c   | 175 --
> >  drivers/gpu/drm/tegra/hdmi.c  | 116 +++-
> >  drivers/gpu/drm/tegra/hub.c   | 194 --
> >  drivers/gpu/drm/tegra/hub.h   |   2 +-
> >  drivers/gpu/drm/tegra/sor.c   | 154 +++
> >  drivers/gpu/host1x/bus.c  |  75 +
> >  include/linux/host1x.h|  11 ++
> >  10 files changed, 541 insertions(+), 331 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> > index 2983eb33f2be..871046f3f469 100644
> > --- a/drivers/gpu/drm/tegra/dc.c
> > +++ b/drivers/gpu/drm/tegra/dc.c
> > @@ -1737,6 +1737,7 @@ static void tegra_crtc_atomic_disable(struct drm_crtc 
> > *crtc,
> >  {
> > struct tegra_dc *dc = to_tegra_dc(crtc);
> > u32 value;
> > +   int err;
> >
> > if (!tegra_dc_idle(dc)) {
> > tegra_dc_stop(dc);
> > @@ -1783,7 +1784,9 @@ static void tegra_crtc_atomic_disable(struct drm_crtc 
> > *crtc,
> >
> > spin_unlock_irq(>dev->event_lock);
> >
> > -   pm_runtime_put_sync(dc->dev);
> > +   err = host1x_client_suspend(>client);
> > +   if (err < 0)
> > +   dev_err(dc->dev, "failed to suspend: %d\n", err);
> >  }
> >
> >  static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
> > @@ -1793,8 +1796,13 @@ static void tegra_crtc_atomic_enable(struct drm_crtc 
> > *crtc,
> > struct tegra_dc_state *state = to_dc_state(crtc->state);

[PATCH v2 2/2] drm/tegra: Do not implement runtime PM

2019-12-09 Thread Thierry Reding
From: Thierry Reding 

The Tegra DRM driver heavily relies on the implementations for runtime
suspend/resume to be called at specific times. Unfortunately, there are
some cases where that doesn't work. One example is if the user disables
runtime PM for a given subdevice. Another example is that the PM core
acquires a reference to runtime PM during system sleep, effectively
preventing devices from going into low power modes. This is intentional
to avoid nasty race conditions, but it also causes system sleep to not
function properly on all Tegra systems.

Fix this by not implementing runtime PM at all. Instead, a minimal,
reference-counted suspend/resume infrastructure is added to the host1x
bus. This has the benefit that it can be used regardless of the system
power state (or any transitions we might be in), or whether or not the
user allows runtime PM.

Atomic modesetting guarantees that these functions will end up being
called at the right point in time, so the pitfalls for the more generic
runtime PM do not apply here.

Signed-off-by: Thierry Reding 
---
Changes in v2:
- keep runtime PM for VIC

 drivers/gpu/drm/tegra/dc.c| 141 ++--
 drivers/gpu/drm/tegra/dpaux.c |   2 +-
 drivers/gpu/drm/tegra/drm.h   |   2 +
 drivers/gpu/drm/tegra/dsi.c   | 175 --
 drivers/gpu/drm/tegra/hdmi.c  | 116 +++-
 drivers/gpu/drm/tegra/hub.c   | 194 --
 drivers/gpu/drm/tegra/hub.h   |   2 +-
 drivers/gpu/drm/tegra/sor.c   | 154 +++
 drivers/gpu/host1x/bus.c  |  75 +
 include/linux/host1x.h|  11 ++
 10 files changed, 541 insertions(+), 331 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 2983eb33f2be..871046f3f469 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1737,6 +1737,7 @@ static void tegra_crtc_atomic_disable(struct drm_crtc 
*crtc,
 {
struct tegra_dc *dc = to_tegra_dc(crtc);
u32 value;
+   int err;
 
if (!tegra_dc_idle(dc)) {
tegra_dc_stop(dc);
@@ -1783,7 +1784,9 @@ static void tegra_crtc_atomic_disable(struct drm_crtc 
*crtc,
 
spin_unlock_irq(>dev->event_lock);
 
-   pm_runtime_put_sync(dc->dev);
+   err = host1x_client_suspend(>client);
+   if (err < 0)
+   dev_err(dc->dev, "failed to suspend: %d\n", err);
 }
 
 static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
@@ -1793,8 +1796,13 @@ static void tegra_crtc_atomic_enable(struct drm_crtc 
*crtc,
struct tegra_dc_state *state = to_dc_state(crtc->state);
struct tegra_dc *dc = to_tegra_dc(crtc);
u32 value;
+   int err;
 
-   pm_runtime_get_sync(dc->dev);
+   err = host1x_client_resume(>client);
+   if (err < 0) {
+   dev_err(dc->dev, "failed to resume: %d\n", err);
+   return;
+   }
 
/* initialize display controller */
if (dc->syncpt) {
@@ -2022,6 +2030,15 @@ static int tegra_dc_init(struct host1x_client *client)
if (!tegra_dc_has_window_groups(dc))
return 0;
 
+   /*
+* Set the display hub as the host1x client parent for the display
+* controller. This is needed for the runtime reference counting that
+* ensures the display hub is always powered when any of the display
+* controllers are.
+*/
+   if (dc->soc->has_nvdisplay)
+   client->parent = >hub->client;
+
dc->syncpt = host1x_syncpt_request(client, flags);
if (!dc->syncpt)
dev_warn(dc->dev, "failed to allocate syncpoint\n");
@@ -2131,9 +2148,74 @@ static int tegra_dc_exit(struct host1x_client *client)
return 0;
 }
 
+static int tegra_dc_runtime_suspend(struct host1x_client *client)
+{
+   struct tegra_dc *dc = host1x_client_to_dc(client);
+   struct device *dev = client->dev;
+   int err;
+
+   err = reset_control_assert(dc->rst);
+   if (err < 0) {
+   dev_err(dev, "failed to assert reset: %d\n", err);
+   return err;
+   }
+
+   if (dc->soc->has_powergate)
+   tegra_powergate_power_off(dc->powergate);
+
+   clk_disable_unprepare(dc->clk);
+   pm_runtime_put_sync(dev);
+
+   return 0;
+}
+
+static int tegra_dc_runtime_resume(struct host1x_client *client)
+{
+   struct tegra_dc *dc = host1x_client_to_dc(client);
+   struct device *dev = client->dev;
+   int err;
+
+   err = pm_runtime_get_sync(dev);
+   if (err < 0) {
+   dev_err(dev, "failed to get runtime PM: %d\n", err);
+   return err;
+   }
+
+   if (dc->soc->has_powergate) {
+   err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk,
+   dc->rst);
+   if (err < 0) {
+   dev_err(dev, "failed to power partition: %d\n", err);
+