aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_buffer.c2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.c12
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.h11
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c37
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.h12
5 files changed, 21 insertions, 53 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
index 7fea74861a87..160ce3c060a5 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
@@ -439,6 +439,4 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
439 439
440 if (drm_debug & DRM_UT_DRIVER) 440 if (drm_debug & DRM_UT_DRIVER)
441 etnaviv_buffer_dump(gpu, buffer, 0, 0x50); 441 etnaviv_buffer_dump(gpu, buffer, 0, 0x50);
442
443 gpu->lastctx = cmdbuf->ctx;
444} 442}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 52802e6049e0..96efc84396bf 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -72,14 +72,8 @@ static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file)
72 for (i = 0; i < ETNA_MAX_PIPES; i++) { 72 for (i = 0; i < ETNA_MAX_PIPES; i++) {
73 struct etnaviv_gpu *gpu = priv->gpu[i]; 73 struct etnaviv_gpu *gpu = priv->gpu[i];
74 74
75 if (gpu) { 75 if (gpu)
76 mutex_lock(&gpu->lock);
77 if (gpu->lastctx == ctx)
78 gpu->lastctx = NULL;
79 mutex_unlock(&gpu->lock);
80
81 drm_sched_entity_destroy(&ctx->sched_entity[i]); 76 drm_sched_entity_destroy(&ctx->sched_entity[i]);
82 }
83 } 77 }
84 78
85 kfree(ctx); 79 kfree(ctx);
@@ -523,7 +517,7 @@ static int etnaviv_bind(struct device *dev)
523 if (!priv) { 517 if (!priv) {
524 dev_err(dev, "failed to allocate private data\n"); 518 dev_err(dev, "failed to allocate private data\n");
525 ret = -ENOMEM; 519 ret = -ENOMEM;
526 goto out_unref; 520 goto out_put;
527 } 521 }
528 drm->dev_private = priv; 522 drm->dev_private = priv;
529 523
@@ -549,7 +543,7 @@ out_register:
549 component_unbind_all(dev, drm); 543 component_unbind_all(dev, drm);
550out_bind: 544out_bind:
551 kfree(priv); 545 kfree(priv);
552out_unref: 546out_put:
553 drm_dev_put(drm); 547 drm_dev_put(drm);
554 548
555 return ret; 549 return ret;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index 8d02d1b7dcf5..4bf698de5996 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -107,17 +107,6 @@ static inline size_t size_vstruct(size_t nelem, size_t elem_size, size_t base)
107 return base + nelem * elem_size; 107 return base + nelem * elem_size;
108} 108}
109 109
110/* returns true if fence a comes after fence b */
111static inline bool fence_after(u32 a, u32 b)
112{
113 return (s32)(a - b) > 0;
114}
115
116static inline bool fence_after_eq(u32 a, u32 b)
117{
118 return (s32)(a - b) >= 0;
119}
120
121/* 110/*
122 * Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies. 111 * Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies.
123 * We need to calculate the timeout in terms of number of jiffies 112 * We need to calculate the timeout in terms of number of jiffies
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index f225fbc6edd2..6904535475de 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -3,10 +3,12 @@
3 * Copyright (C) 2015-2018 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
4 */ 4 */
5 5
6#include <linux/clk.h>
6#include <linux/component.h> 7#include <linux/component.h>
7#include <linux/dma-fence.h> 8#include <linux/dma-fence.h>
8#include <linux/moduleparam.h> 9#include <linux/moduleparam.h>
9#include <linux/of_device.h> 10#include <linux/of_device.h>
11#include <linux/regulator/consumer.h>
10#include <linux/thermal.h> 12#include <linux/thermal.h>
11 13
12#include "etnaviv_cmdbuf.h" 14#include "etnaviv_cmdbuf.h"
@@ -976,7 +978,6 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
976 978
977void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu) 979void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
978{ 980{
979 unsigned long flags;
980 unsigned int i = 0; 981 unsigned int i = 0;
981 982
982 dev_err(gpu->dev, "recover hung GPU!\n"); 983 dev_err(gpu->dev, "recover hung GPU!\n");
@@ -989,15 +990,13 @@ void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
989 etnaviv_hw_reset(gpu); 990 etnaviv_hw_reset(gpu);
990 991
991 /* complete all events, the GPU won't do it after the reset */ 992 /* complete all events, the GPU won't do it after the reset */
992 spin_lock_irqsave(&gpu->event_spinlock, flags); 993 spin_lock(&gpu->event_spinlock);
993 for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS) 994 for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS)
994 complete(&gpu->event_free); 995 complete(&gpu->event_free);
995 bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS); 996 bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS);
996 spin_unlock_irqrestore(&gpu->event_spinlock, flags); 997 spin_unlock(&gpu->event_spinlock);
997 gpu->completed_fence = gpu->active_fence;
998 998
999 etnaviv_gpu_hw_init(gpu); 999 etnaviv_gpu_hw_init(gpu);
1000 gpu->lastctx = NULL;
1001 gpu->exec_state = -1; 1000 gpu->exec_state = -1;
1002 1001
1003 mutex_unlock(&gpu->lock); 1002 mutex_unlock(&gpu->lock);
@@ -1032,7 +1031,7 @@ static bool etnaviv_fence_signaled(struct dma_fence *fence)
1032{ 1031{
1033 struct etnaviv_fence *f = to_etnaviv_fence(fence); 1032 struct etnaviv_fence *f = to_etnaviv_fence(fence);
1034 1033
1035 return fence_completed(f->gpu, f->base.seqno); 1034 return (s32)(f->gpu->completed_fence - f->base.seqno) >= 0;
1036} 1035}
1037 1036
1038static void etnaviv_fence_release(struct dma_fence *fence) 1037static void etnaviv_fence_release(struct dma_fence *fence)
@@ -1071,6 +1070,12 @@ static struct dma_fence *etnaviv_gpu_fence_alloc(struct etnaviv_gpu *gpu)
1071 return &f->base; 1070 return &f->base;
1072} 1071}
1073 1072
1073/* returns true if fence a comes after fence b */
1074static inline bool fence_after(u32 a, u32 b)
1075{
1076 return (s32)(a - b) > 0;
1077}
1078
1074/* 1079/*
1075 * event management: 1080 * event management:
1076 */ 1081 */
@@ -1078,7 +1083,7 @@ static struct dma_fence *etnaviv_gpu_fence_alloc(struct etnaviv_gpu *gpu)
1078static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events, 1083static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
1079 unsigned int *events) 1084 unsigned int *events)
1080{ 1085{
1081 unsigned long flags, timeout = msecs_to_jiffies(10 * 10000); 1086 unsigned long timeout = msecs_to_jiffies(10 * 10000);
1082 unsigned i, acquired = 0; 1087 unsigned i, acquired = 0;
1083 1088
1084 for (i = 0; i < nr_events; i++) { 1089 for (i = 0; i < nr_events; i++) {
@@ -1095,7 +1100,7 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
1095 timeout = ret; 1100 timeout = ret;
1096 } 1101 }
1097 1102
1098 spin_lock_irqsave(&gpu->event_spinlock, flags); 1103 spin_lock(&gpu->event_spinlock);
1099 1104
1100 for (i = 0; i < nr_events; i++) { 1105 for (i = 0; i < nr_events; i++) {
1101 int event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS); 1106 int event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS);
@@ -1105,7 +1110,7 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
1105 set_bit(event, gpu->event_bitmap); 1110 set_bit(event, gpu->event_bitmap);
1106 } 1111 }
1107 1112
1108 spin_unlock_irqrestore(&gpu->event_spinlock, flags); 1113 spin_unlock(&gpu->event_spinlock);
1109 1114
1110 return 0; 1115 return 0;
1111 1116
@@ -1118,18 +1123,11 @@ out:
1118 1123
1119static void event_free(struct etnaviv_gpu *gpu, unsigned int event) 1124static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
1120{ 1125{
1121 unsigned long flags;
1122
1123 spin_lock_irqsave(&gpu->event_spinlock, flags);
1124
1125 if (!test_bit(event, gpu->event_bitmap)) { 1126 if (!test_bit(event, gpu->event_bitmap)) {
1126 dev_warn(gpu->dev, "event %u is already marked as free", 1127 dev_warn(gpu->dev, "event %u is already marked as free",
1127 event); 1128 event);
1128 spin_unlock_irqrestore(&gpu->event_spinlock, flags);
1129 } else { 1129 } else {
1130 clear_bit(event, gpu->event_bitmap); 1130 clear_bit(event, gpu->event_bitmap);
1131 spin_unlock_irqrestore(&gpu->event_spinlock, flags);
1132
1133 complete(&gpu->event_free); 1131 complete(&gpu->event_free);
1134 } 1132 }
1135} 1133}
@@ -1306,8 +1304,6 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit)
1306 goto out_unlock; 1304 goto out_unlock;
1307 } 1305 }
1308 1306
1309 gpu->active_fence = gpu_fence->seqno;
1310
1311 if (submit->nr_pmrs) { 1307 if (submit->nr_pmrs) {
1312 gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre; 1308 gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre;
1313 kref_get(&submit->refcount); 1309 kref_get(&submit->refcount);
@@ -1549,7 +1545,6 @@ static int etnaviv_gpu_hw_resume(struct etnaviv_gpu *gpu)
1549 etnaviv_gpu_update_clock(gpu); 1545 etnaviv_gpu_update_clock(gpu);
1550 etnaviv_gpu_hw_init(gpu); 1546 etnaviv_gpu_hw_init(gpu);
1551 1547
1552 gpu->lastctx = NULL;
1553 gpu->exec_state = -1; 1548 gpu->exec_state = -1;
1554 1549
1555 mutex_unlock(&gpu->lock); 1550 mutex_unlock(&gpu->lock);
@@ -1806,8 +1801,8 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev)
1806 struct etnaviv_gpu *gpu = dev_get_drvdata(dev); 1801 struct etnaviv_gpu *gpu = dev_get_drvdata(dev);
1807 u32 idle, mask; 1802 u32 idle, mask;
1808 1803
1809 /* If we have outstanding fences, we're not idle */ 1804 /* If there are any jobs in the HW queue, we're not idle */
1810 if (gpu->completed_fence != gpu->active_fence) 1805 if (atomic_read(&gpu->sched.hw_rq_count))
1811 return -EBUSY; 1806 return -EBUSY;
1812 1807
1813 /* Check whether the hardware (except FE) is idle */ 1808 /* Check whether the hardware (except FE) is idle */
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index 9a75a6937268..9bcf151f706b 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -6,9 +6,6 @@
6#ifndef __ETNAVIV_GPU_H__ 6#ifndef __ETNAVIV_GPU_H__
7#define __ETNAVIV_GPU_H__ 7#define __ETNAVIV_GPU_H__
8 8
9#include <linux/clk.h>
10#include <linux/regulator/consumer.h>
11
12#include "etnaviv_cmdbuf.h" 9#include "etnaviv_cmdbuf.h"
13#include "etnaviv_drv.h" 10#include "etnaviv_drv.h"
14 11
@@ -88,6 +85,8 @@ struct etnaviv_event {
88 85
89struct etnaviv_cmdbuf_suballoc; 86struct etnaviv_cmdbuf_suballoc;
90struct etnaviv_cmdbuf; 87struct etnaviv_cmdbuf;
88struct regulator;
89struct clk;
91 90
92#define ETNA_NR_EVENTS 30 91#define ETNA_NR_EVENTS 30
93 92
@@ -98,7 +97,6 @@ struct etnaviv_gpu {
98 struct mutex lock; 97 struct mutex lock;
99 struct etnaviv_chip_identity identity; 98 struct etnaviv_chip_identity identity;
100 enum etnaviv_sec_mode sec_mode; 99 enum etnaviv_sec_mode sec_mode;
101 struct etnaviv_file_private *lastctx;
102 struct workqueue_struct *wq; 100 struct workqueue_struct *wq;
103 struct drm_gpu_scheduler sched; 101 struct drm_gpu_scheduler sched;
104 102
@@ -121,7 +119,6 @@ struct etnaviv_gpu {
121 struct mutex fence_lock; 119 struct mutex fence_lock;
122 struct idr fence_idr; 120 struct idr fence_idr;
123 u32 next_fence; 121 u32 next_fence;
124 u32 active_fence;
125 u32 completed_fence; 122 u32 completed_fence;
126 wait_queue_head_t fence_event; 123 wait_queue_head_t fence_event;
127 u64 fence_context; 124 u64 fence_context;
@@ -161,11 +158,6 @@ static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg)
161 return readl(gpu->mmio + reg); 158 return readl(gpu->mmio + reg);
162} 159}
163 160
164static inline bool fence_completed(struct etnaviv_gpu *gpu, u32 fence)
165{
166 return fence_after_eq(gpu->completed_fence, fence);
167}
168
169int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); 161int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value);
170 162
171int etnaviv_gpu_init(struct etnaviv_gpu *gpu); 163int etnaviv_gpu_init(struct etnaviv_gpu *gpu);