summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/imagination/pvr_drv.c
diff options
context:
space:
mode:
authorSarah Walker <sarah.walker@imgtec.com>2023-11-22 19:34:33 +0300
committerMaxime Ripard <mripard@kernel.org>2023-11-23 11:01:46 +0300
commit727538a4bbff07736ecfd704efd7e21718fca3e4 (patch)
tree5eb5f5382274583f9f3fb5120b1d2eecce4ecfc6 /drivers/gpu/drm/imagination/pvr_drv.c
parentff5f643de0bf27874c4033cd57a0bd034b5c7d11 (diff)
downloadlinux-727538a4bbff07736ecfd704efd7e21718fca3e4.tar.xz
drm/imagination: Implement power management
Add power management to the driver, using runtime pm. The power off sequence depends on firmware commands which are not implemented in this patch. Changes since v8: - Corrected license identifiers Changes since v5: - Use RUNTIME_PM_OPS() to declare PM callbacks - Add Kconfig dependency on CONFIG_PM Changes since v4: - Suspend runtime PM before unplugging device on rmmod Changes since v3: - Don't power device when calling pvr_device_gpu_fini() - Documentation for pvr_dev->lost has been improved - pvr_power_init() renamed to pvr_watchdog_init() - Use drm_dev_{enter,exit} Changes since v2: - Use runtime PM - Implement watchdog Signed-off-by: Sarah Walker <sarah.walker@imgtec.com> Signed-off-by: Donald Robson <donald.robson@imgtec.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://lore.kernel.org/r/e09af4ef1ff514e1d6d7f97c7c5032c643c56f9c.1700668843.git.donald.robson@imgtec.com Signed-off-by: Maxime Ripard <mripard@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/imagination/pvr_drv.c')
-rw-r--r--drivers/gpu/drm/imagination/pvr_drv.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c
index 6d3bc886e1c3..12e136217c45 100644
--- a/drivers/gpu/drm/imagination/pvr_drv.c
+++ b/drivers/gpu/drm/imagination/pvr_drv.c
@@ -5,6 +5,7 @@
#include "pvr_drv.h"
#include "pvr_gem.h"
#include "pvr_mmu.h"
+#include "pvr_power.h"
#include "pvr_rogue_defs.h"
#include "pvr_rogue_fwif_client.h"
#include "pvr_rogue_fwif_shared.h"
@@ -1265,9 +1266,16 @@ pvr_probe(struct platform_device *plat_dev)
platform_set_drvdata(plat_dev, drm_dev);
+ devm_pm_runtime_enable(&plat_dev->dev);
+ pm_runtime_mark_last_busy(&plat_dev->dev);
+
+ pm_runtime_set_autosuspend_delay(&plat_dev->dev, 50);
+ pm_runtime_use_autosuspend(&plat_dev->dev);
+ pvr_watchdog_init(pvr_dev);
+
err = pvr_device_init(pvr_dev);
if (err)
- return err;
+ goto err_watchdog_fini;
err = drm_dev_register(drm_dev, 0);
if (err)
@@ -1278,6 +1286,9 @@ pvr_probe(struct platform_device *plat_dev)
err_device_fini:
pvr_device_fini(pvr_dev);
+err_watchdog_fini:
+ pvr_watchdog_fini(pvr_dev);
+
return err;
}
@@ -1287,8 +1298,10 @@ pvr_remove(struct platform_device *plat_dev)
struct drm_device *drm_dev = platform_get_drvdata(plat_dev);
struct pvr_device *pvr_dev = to_pvr_device(drm_dev);
+ pm_runtime_suspend(drm_dev->dev);
pvr_device_fini(pvr_dev);
drm_dev_unplug(drm_dev);
+ pvr_watchdog_fini(pvr_dev);
return 0;
}
@@ -1299,11 +1312,16 @@ static const struct of_device_id dt_match[] = {
};
MODULE_DEVICE_TABLE(of, dt_match);
+static const struct dev_pm_ops pvr_pm_ops = {
+ RUNTIME_PM_OPS(pvr_power_device_suspend, pvr_power_device_resume, pvr_power_device_idle)
+};
+
static struct platform_driver pvr_driver = {
.probe = pvr_probe,
.remove = pvr_remove,
.driver = {
.name = PVR_DRIVER_NAME,
+ .pm = &pvr_pm_ops,
.of_match_table = dt_match,
},
};