diff options
-rw-r--r-- | MAINTAINERS | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_drv.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_sched.c | 24 |
4 files changed, 49 insertions, 6 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 19f2d12ace6b..13fef810e3fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -581,7 +581,7 @@ W: https://www.infradead.org/~dhowells/kafs/ | |||
581 | 581 | ||
582 | AGPGART DRIVER | 582 | AGPGART DRIVER |
583 | M: David Airlie <airlied@linux.ie> | 583 | M: David Airlie <airlied@linux.ie> |
584 | T: git git://people.freedesktop.org/~airlied/linux (part of drm maint) | 584 | T: git git://anongit.freedesktop.org/drm/drm |
585 | S: Maintained | 585 | S: Maintained |
586 | F: drivers/char/agp/ | 586 | F: drivers/char/agp/ |
587 | F: include/linux/agp* | 587 | F: include/linux/agp* |
@@ -4630,7 +4630,7 @@ F: include/uapi/drm/vmwgfx_drm.h | |||
4630 | DRM DRIVERS | 4630 | DRM DRIVERS |
4631 | M: David Airlie <airlied@linux.ie> | 4631 | M: David Airlie <airlied@linux.ie> |
4632 | L: dri-devel@lists.freedesktop.org | 4632 | L: dri-devel@lists.freedesktop.org |
4633 | T: git git://people.freedesktop.org/~airlied/linux | 4633 | T: git git://anongit.freedesktop.org/drm/drm |
4634 | B: https://bugs.freedesktop.org/ | 4634 | B: https://bugs.freedesktop.org/ |
4635 | C: irc://chat.freenode.net/dri-devel | 4635 | C: irc://chat.freenode.net/dri-devel |
4636 | S: Maintained | 4636 | S: Maintained |
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index e5013a999147..540b59fb4103 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c | |||
@@ -631,8 +631,11 @@ static struct platform_driver etnaviv_platform_driver = { | |||
631 | }, | 631 | }, |
632 | }; | 632 | }; |
633 | 633 | ||
634 | static struct platform_device *etnaviv_drm; | ||
635 | |||
634 | static int __init etnaviv_init(void) | 636 | static int __init etnaviv_init(void) |
635 | { | 637 | { |
638 | struct platform_device *pdev; | ||
636 | int ret; | 639 | int ret; |
637 | struct device_node *np; | 640 | struct device_node *np; |
638 | 641 | ||
@@ -644,7 +647,7 @@ static int __init etnaviv_init(void) | |||
644 | 647 | ||
645 | ret = platform_driver_register(&etnaviv_platform_driver); | 648 | ret = platform_driver_register(&etnaviv_platform_driver); |
646 | if (ret != 0) | 649 | if (ret != 0) |
647 | platform_driver_unregister(&etnaviv_gpu_driver); | 650 | goto unregister_gpu_driver; |
648 | 651 | ||
649 | /* | 652 | /* |
650 | * If the DT contains at least one available GPU device, instantiate | 653 | * If the DT contains at least one available GPU device, instantiate |
@@ -653,20 +656,33 @@ static int __init etnaviv_init(void) | |||
653 | for_each_compatible_node(np, NULL, "vivante,gc") { | 656 | for_each_compatible_node(np, NULL, "vivante,gc") { |
654 | if (!of_device_is_available(np)) | 657 | if (!of_device_is_available(np)) |
655 | continue; | 658 | continue; |
656 | 659 | pdev = platform_device_register_simple("etnaviv", -1, | |
657 | platform_device_register_simple("etnaviv", -1, NULL, 0); | 660 | NULL, 0); |
661 | if (IS_ERR(pdev)) { | ||
662 | ret = PTR_ERR(pdev); | ||
663 | of_node_put(np); | ||
664 | goto unregister_platform_driver; | ||
665 | } | ||
666 | etnaviv_drm = pdev; | ||
658 | of_node_put(np); | 667 | of_node_put(np); |
659 | break; | 668 | break; |
660 | } | 669 | } |
661 | 670 | ||
671 | return 0; | ||
672 | |||
673 | unregister_platform_driver: | ||
674 | platform_driver_unregister(&etnaviv_platform_driver); | ||
675 | unregister_gpu_driver: | ||
676 | platform_driver_unregister(&etnaviv_gpu_driver); | ||
662 | return ret; | 677 | return ret; |
663 | } | 678 | } |
664 | module_init(etnaviv_init); | 679 | module_init(etnaviv_init); |
665 | 680 | ||
666 | static void __exit etnaviv_exit(void) | 681 | static void __exit etnaviv_exit(void) |
667 | { | 682 | { |
668 | platform_driver_unregister(&etnaviv_gpu_driver); | 683 | platform_device_unregister(etnaviv_drm); |
669 | platform_driver_unregister(&etnaviv_platform_driver); | 684 | platform_driver_unregister(&etnaviv_platform_driver); |
685 | platform_driver_unregister(&etnaviv_gpu_driver); | ||
670 | } | 686 | } |
671 | module_exit(etnaviv_exit); | 687 | module_exit(etnaviv_exit); |
672 | 688 | ||
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index dd430f0f8ff5..90f17ff7888e 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h | |||
@@ -131,6 +131,9 @@ struct etnaviv_gpu { | |||
131 | struct work_struct sync_point_work; | 131 | struct work_struct sync_point_work; |
132 | int sync_point_event; | 132 | int sync_point_event; |
133 | 133 | ||
134 | /* hang detection */ | ||
135 | u32 hangcheck_dma_addr; | ||
136 | |||
134 | void __iomem *mmio; | 137 | void __iomem *mmio; |
135 | int irq; | 138 | int irq; |
136 | 139 | ||
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c index a74eb57af15b..50d6b88cb7aa 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include "etnaviv_gem.h" | 10 | #include "etnaviv_gem.h" |
11 | #include "etnaviv_gpu.h" | 11 | #include "etnaviv_gpu.h" |
12 | #include "etnaviv_sched.h" | 12 | #include "etnaviv_sched.h" |
13 | #include "state.xml.h" | ||
13 | 14 | ||
14 | static int etnaviv_job_hang_limit = 0; | 15 | static int etnaviv_job_hang_limit = 0; |
15 | module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444); | 16 | module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444); |
@@ -85,6 +86,29 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job) | |||
85 | { | 86 | { |
86 | struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); | 87 | struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); |
87 | struct etnaviv_gpu *gpu = submit->gpu; | 88 | struct etnaviv_gpu *gpu = submit->gpu; |
89 | u32 dma_addr; | ||
90 | int change; | ||
91 | |||
92 | /* | ||
93 | * If the GPU managed to complete this jobs fence, the timout is | ||
94 | * spurious. Bail out. | ||
95 | */ | ||
96 | if (fence_completed(gpu, submit->out_fence->seqno)) | ||
97 | return; | ||
98 | |||
99 | /* | ||
100 | * If the GPU is still making forward progress on the front-end (which | ||
101 | * should never loop) we shift out the timeout to give it a chance to | ||
102 | * finish the job. | ||
103 | */ | ||
104 | dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS); | ||
105 | change = dma_addr - gpu->hangcheck_dma_addr; | ||
106 | if (change < 0 || change > 16) { | ||
107 | gpu->hangcheck_dma_addr = dma_addr; | ||
108 | schedule_delayed_work(&sched_job->work_tdr, | ||
109 | sched_job->sched->timeout); | ||
110 | return; | ||
111 | } | ||
88 | 112 | ||
89 | /* block scheduler */ | 113 | /* block scheduler */ |
90 | kthread_park(gpu->sched.thread); | 114 | kthread_park(gpu->sched.thread); |