Skip to content

Commit 63945d5

Browse files
committed
drm/lima: add pm resume/suspend ops
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. Tested-by: Bhushan Shah <bshah@kde.org> Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com> Signed-off-by: Qiang Yu <yuq825@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-10-yuq825@gmail.com
1 parent 7a475eb commit 63945d5

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

drivers/gpu/drm/lima/lima_device.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,27 @@ static void lima_fini_ip(struct lima_device *ldev, int index)
247247
desc->fini(ip);
248248
}
249249

250+
static int lima_resume_ip(struct lima_device *ldev, int index)
251+
{
252+
struct lima_ip_desc *desc = lima_ip_desc + index;
253+
struct lima_ip *ip = ldev->ip + index;
254+
int ret = 0;
255+
256+
if (ip->present)
257+
ret = desc->resume(ip);
258+
259+
return ret;
260+
}
261+
262+
static void lima_suspend_ip(struct lima_device *ldev, int index)
263+
{
264+
struct lima_ip_desc *desc = lima_ip_desc + index;
265+
struct lima_ip *ip = ldev->ip + index;
266+
267+
if (ip->present)
268+
desc->suspend(ip);
269+
}
270+
250271
static int lima_init_gp_pipe(struct lima_device *dev)
251272
{
252273
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp;
@@ -441,3 +462,72 @@ void lima_device_fini(struct lima_device *ldev)
441462

442463
lima_clk_fini(ldev);
443464
}
465+
466+
int lima_device_resume(struct device *dev)
467+
{
468+
struct lima_device *ldev = dev_get_drvdata(dev);
469+
int i, err;
470+
471+
err = lima_clk_enable(ldev);
472+
if (err) {
473+
dev_err(dev, "resume clk fail %d\n", err);
474+
return err;
475+
}
476+
477+
err = lima_regulator_enable(ldev);
478+
if (err) {
479+
dev_err(dev, "resume regulator fail %d\n", err);
480+
goto err_out0;
481+
}
482+
483+
for (i = 0; i < lima_ip_num; i++) {
484+
err = lima_resume_ip(ldev, i);
485+
if (err) {
486+
dev_err(dev, "resume ip %d fail\n", i);
487+
goto err_out1;
488+
}
489+
}
490+
491+
err = lima_devfreq_resume(&ldev->devfreq);
492+
if (err) {
493+
dev_err(dev, "devfreq resume fail\n");
494+
goto err_out1;
495+
}
496+
497+
return 0;
498+
499+
err_out1:
500+
while (--i >= 0)
501+
lima_suspend_ip(ldev, i);
502+
lima_regulator_disable(ldev);
503+
err_out0:
504+
lima_clk_disable(ldev);
505+
return err;
506+
}
507+
508+
int lima_device_suspend(struct device *dev)
509+
{
510+
struct lima_device *ldev = dev_get_drvdata(dev);
511+
int i, err;
512+
513+
/* check any task running */
514+
for (i = 0; i < lima_pipe_num; i++) {
515+
if (atomic_read(&ldev->pipe[i].base.hw_rq_count))
516+
return -EBUSY;
517+
}
518+
519+
err = lima_devfreq_suspend(&ldev->devfreq);
520+
if (err) {
521+
dev_err(dev, "devfreq suspend fail\n");
522+
return err;
523+
}
524+
525+
for (i = lima_ip_num - 1; i >= 0; i--)
526+
lima_suspend_ip(ldev, i);
527+
528+
lima_regulator_disable(ldev);
529+
530+
lima_clk_disable(ldev);
531+
532+
return 0;
533+
}

drivers/gpu/drm/lima/lima_device.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,7 @@ static inline int lima_poll_timeout(struct lima_ip *ip, lima_poll_func_t func,
140140
return 0;
141141
}
142142

143+
int lima_device_suspend(struct device *dev);
144+
int lima_device_resume(struct device *dev);
145+
143146
#endif

drivers/gpu/drm/lima/lima_drv.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/of_platform.h>
66
#include <linux/uaccess.h>
77
#include <linux/slab.h>
8+
#include <linux/pm_runtime.h>
89
#include <drm/drm_ioctl.h>
910
#include <drm/drm_drv.h>
1011
#include <drm/drm_prime.h>
@@ -451,11 +452,17 @@ static const struct of_device_id dt_match[] = {
451452
};
452453
MODULE_DEVICE_TABLE(of, dt_match);
453454

455+
static const struct dev_pm_ops lima_pm_ops = {
456+
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
457+
SET_RUNTIME_PM_OPS(lima_device_suspend, lima_device_resume, NULL)
458+
};
459+
454460
static struct platform_driver lima_platform_driver = {
455461
.probe = lima_pdev_probe,
456462
.remove = lima_pdev_remove,
457463
.driver = {
458464
.name = "lima",
465+
.pm = &lima_pm_ops,
459466
.of_match_table = dt_match,
460467
},
461468
};

0 commit comments

Comments
 (0)