Add driver pm system and runtime hardware resume/suspend ops. Note this won't enable runtime pm of the device yet. v2: Do clock and power gating when suspend/resume. Signed-off-by: Qiang Yu <yuq825@xxxxxxxxx> --- drivers/gpu/drm/lima/lima_device.c | 90 ++++++++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_device.h | 3 + drivers/gpu/drm/lima/lima_drv.c | 7 +++ 3 files changed, 100 insertions(+) diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c index 281e05a8cd4b..8604b7994943 100644 --- a/drivers/gpu/drm/lima/lima_device.c +++ b/drivers/gpu/drm/lima/lima_device.c @@ -244,6 +244,27 @@ static void lima_fini_ip(struct lima_device *ldev, int index) desc->fini(ip); } +static int lima_resume_ip(struct lima_device *ldev, int index) +{ + struct lima_ip_desc *desc = lima_ip_desc + index; + struct lima_ip *ip = ldev->ip + index; + int ret = 0; + + if (ip->present) + ret = desc->resume(ip); + + return ret; +} + +static void lima_suspend_ip(struct lima_device *ldev, int index) +{ + struct lima_ip_desc *desc = lima_ip_desc + index; + struct lima_ip *ip = ldev->ip + index; + + if (ip->present) + desc->suspend(ip); +} + static int lima_init_gp_pipe(struct lima_device *dev) { struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; @@ -439,3 +460,72 @@ void lima_device_fini(struct lima_device *ldev) lima_clk_fini(ldev); } + +int lima_device_resume(struct device *dev) +{ + struct lima_device *ldev = dev_get_drvdata(dev); + int i, err; + + err = lima_clk_enable(ldev); + if (err) { + dev_err(dev, "resume clk fail %d\n", err); + return err; + } + + err = lima_regulator_enable(ldev); + if (err) { + dev_err(dev, "resume regulator fail %d\n", err); + goto err_out0; + } + + for (i = 0; i < lima_ip_num; i++) { + err = lima_resume_ip(ldev, i); + if (err) { + dev_err(dev, "resume ip %d fail\n", i); + goto err_out1; + } + } + + err = lima_devfreq_resume(&ldev->devfreq); + if (err) { + dev_err(dev, "devfreq resume fail\n"); + goto err_out1; + } + + return 0; + +err_out1: + while (--i >= 0) + lima_suspend_ip(ldev, i); + lima_regulator_disable(ldev); +err_out0: + lima_clk_disable(ldev); + return err; +} + +int lima_device_suspend(struct device *dev) +{ + struct lima_device *ldev = dev_get_drvdata(dev); + int i, err; + + /* check any task running */ + for (i = 0; i < lima_pipe_num; i++) { + if (atomic_read(&ldev->pipe[i].base.hw_rq_count)) + return -EBUSY; + } + + err = lima_devfreq_suspend(&ldev->devfreq); + if (err) { + dev_err(dev, "devfreq suspend fail\n"); + return err; + } + + for (i = lima_ip_num - 1; i >= 0; i--) + lima_suspend_ip(ldev, i); + + lima_regulator_disable(ldev); + + lima_clk_disable(ldev); + + return 0; +} diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h index 095a0b5f1703..e06d1955f4a3 100644 --- a/drivers/gpu/drm/lima/lima_device.h +++ b/drivers/gpu/drm/lima/lima_device.h @@ -141,4 +141,7 @@ static inline int lima_poll_timeout(struct lima_ip *ip, lima_poll_func_t func, return 0; } +int lima_device_suspend(struct device *dev); +int lima_device_resume(struct device *dev); + #endif diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index 91bf5b305e9d..639d1cd3268a 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -5,6 +5,7 @@ #include <linux/of_platform.h> #include <linux/uaccess.h> #include <linux/slab.h> +#include <linux/pm_runtime.h> #include <drm/drm_ioctl.h> #include <drm/drm_drv.h> #include <drm/drm_prime.h> @@ -452,11 +453,17 @@ static const struct of_device_id dt_match[] = { }; MODULE_DEVICE_TABLE(of, dt_match); +static const struct dev_pm_ops lima_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(lima_device_suspend, lima_device_resume, NULL) +}; + static struct platform_driver lima_platform_driver = { .probe = lima_pdev_probe, .remove = lima_pdev_remove, .driver = { .name = "lima", + .pm = &lima_pm_ops, .of_match_table = dt_match, }, }; -- 2.17.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel