drm/panfrost: Add PM runtime flag
authorPhilippe Simons <simons.philippe@gmail.com>
Thu, 3 Apr 2025 05:52:08 +0000 (07:52 +0200)
committerSteven Price <steven.price@arm.com>
Mon, 28 Apr 2025 09:23:48 +0000 (10:23 +0100)
When the GPU is the only device attached to a single power domain,
core genpd disable and enable it when gpu enter and leave runtime suspend.

Some power-domain requires a sequence before disabled,
and the reverse when enabled.

Add GPU_PM_RT flag, and implement in
panfrost_device_runtime_suspend/resume.

Reviewed-by: Steven Price <steven.price@arm.com>
Signed-off-by: Philippe Simons <simons.philippe@gmail.com>
Signed-off-by: Steven Price <steven.price@arm.com>
Link: https://lore.kernel.org/r/20250403055210.54486-2-simons.philippe@gmail.com
drivers/gpu/drm/panfrost/panfrost_device.c
drivers/gpu/drm/panfrost/panfrost_device.h

index a45e4addcc19a391c74c6a0c084b2be7a0f61373..93d48e97ce102dba8cf6eac0445d87a3c4085b98 100644 (file)
@@ -406,11 +406,36 @@ void panfrost_device_reset(struct panfrost_device *pfdev)
 static int panfrost_device_runtime_resume(struct device *dev)
 {
        struct panfrost_device *pfdev = dev_get_drvdata(dev);
+       int ret;
+
+       if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) {
+               ret = reset_control_deassert(pfdev->rstc);
+               if (ret)
+                       return ret;
+
+               ret = clk_enable(pfdev->clock);
+               if (ret)
+                       goto err_clk;
+
+               if (pfdev->bus_clock) {
+                       ret = clk_enable(pfdev->bus_clock);
+                       if (ret)
+                               goto err_bus_clk;
+               }
+       }
 
        panfrost_device_reset(pfdev);
        panfrost_devfreq_resume(pfdev);
 
        return 0;
+
+err_bus_clk:
+       if (pfdev->comp->pm_features & BIT(GPU_PM_RT))
+               clk_disable(pfdev->clock);
+err_clk:
+       if (pfdev->comp->pm_features & BIT(GPU_PM_RT))
+               reset_control_assert(pfdev->rstc);
+       return ret;
 }
 
 static int panfrost_device_runtime_suspend(struct device *dev)
@@ -426,6 +451,14 @@ static int panfrost_device_runtime_suspend(struct device *dev)
        panfrost_gpu_suspend_irq(pfdev);
        panfrost_gpu_power_off(pfdev);
 
+       if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) {
+               if (pfdev->bus_clock)
+                       clk_disable(pfdev->bus_clock);
+
+               clk_disable(pfdev->clock);
+               reset_control_assert(pfdev->rstc);
+       }
+
        return 0;
 }
 
index ad95f2ed31d9ad0b1a3fa0e2afa1def6cefdb0a3..dcff70f905cd227e7cdf9672e9388564bd92cfff 100644 (file)
@@ -36,10 +36,13 @@ enum panfrost_drv_comp_bits {
  * enum panfrost_gpu_pm - Supported kernel power management features
  * @GPU_PM_CLK_DIS:  Allow disabling clocks during system suspend
  * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend
+ * @GPU_PM_RT: Allow disabling clocks and asserting the reset control during
+ *  system runtime suspend
  */
 enum panfrost_gpu_pm {
        GPU_PM_CLK_DIS,
        GPU_PM_VREG_OFF,
+       GPU_PM_RT
 };
 
 /**