aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2017-09-24 09:15:19 -0400
committerLucas Stach <l.stach@pengutronix.de>2017-10-10 05:45:39 -0400
commit355502e03ad26e3c872a0f5c408a4accca57ba7e (patch)
treec1327e81702aa186a5ea6be0a9279f0667315cc4
parent6eb3ecc33a6aaedda5ceb0824cafe34c47af2f55 (diff)
drm/etnaviv: use bitmap to keep track of events
This is prep work to be able to allocate multiple events in one go. Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c31
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.h6
2 files changed, 17 insertions, 20 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index de34e221c2fe..3b02814b9c52 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -744,10 +744,9 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
744 /* Setup event management */ 744 /* Setup event management */
745 spin_lock_init(&gpu->event_spinlock); 745 spin_lock_init(&gpu->event_spinlock);
746 init_completion(&gpu->event_free); 746 init_completion(&gpu->event_free);
747 for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { 747 bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS);
748 gpu->event[i].used = false; 748 for (i = 0; i < ARRAY_SIZE(gpu->event); i++)
749 complete(&gpu->event_free); 749 complete(&gpu->event_free);
750 }
751 750
752 /* Now program the hardware */ 751 /* Now program the hardware */
753 mutex_lock(&gpu->lock); 752 mutex_lock(&gpu->lock);
@@ -931,7 +930,7 @@ static void recover_worker(struct work_struct *work)
931 struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu, 930 struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu,
932 recover_work); 931 recover_work);
933 unsigned long flags; 932 unsigned long flags;
934 unsigned int i; 933 unsigned int i = 0;
935 934
936 dev_err(gpu->dev, "hangcheck recover!\n"); 935 dev_err(gpu->dev, "hangcheck recover!\n");
937 936
@@ -950,14 +949,12 @@ static void recover_worker(struct work_struct *work)
950 949
951 /* complete all events, the GPU won't do it after the reset */ 950 /* complete all events, the GPU won't do it after the reset */
952 spin_lock_irqsave(&gpu->event_spinlock, flags); 951 spin_lock_irqsave(&gpu->event_spinlock, flags);
953 for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { 952 for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS) {
954 if (!gpu->event[i].used)
955 continue;
956 dma_fence_signal(gpu->event[i].fence); 953 dma_fence_signal(gpu->event[i].fence);
957 gpu->event[i].fence = NULL; 954 gpu->event[i].fence = NULL;
958 gpu->event[i].used = false;
959 complete(&gpu->event_free); 955 complete(&gpu->event_free);
960 } 956 }
957 bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS);
961 spin_unlock_irqrestore(&gpu->event_spinlock, flags); 958 spin_unlock_irqrestore(&gpu->event_spinlock, flags);
962 gpu->completed_fence = gpu->active_fence; 959 gpu->completed_fence = gpu->active_fence;
963 960
@@ -1148,7 +1145,7 @@ int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj,
1148static unsigned int event_alloc(struct etnaviv_gpu *gpu) 1145static unsigned int event_alloc(struct etnaviv_gpu *gpu)
1149{ 1146{
1150 unsigned long ret, flags; 1147 unsigned long ret, flags;
1151 unsigned int i, event = ~0U; 1148 unsigned int event;
1152 1149
1153 ret = wait_for_completion_timeout(&gpu->event_free, 1150 ret = wait_for_completion_timeout(&gpu->event_free,
1154 msecs_to_jiffies(10 * 10000)); 1151 msecs_to_jiffies(10 * 10000));
@@ -1158,13 +1155,11 @@ static unsigned int event_alloc(struct etnaviv_gpu *gpu)
1158 spin_lock_irqsave(&gpu->event_spinlock, flags); 1155 spin_lock_irqsave(&gpu->event_spinlock, flags);
1159 1156
1160 /* find first free event */ 1157 /* find first free event */
1161 for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { 1158 event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS);
1162 if (gpu->event[i].used == false) { 1159 if (event < ETNA_NR_EVENTS)
1163 gpu->event[i].used = true; 1160 set_bit(event, gpu->event_bitmap);
1164 event = i; 1161 else
1165 break; 1162 event = ~0U;
1166 }
1167 }
1168 1163
1169 spin_unlock_irqrestore(&gpu->event_spinlock, flags); 1164 spin_unlock_irqrestore(&gpu->event_spinlock, flags);
1170 1165
@@ -1177,12 +1172,12 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
1177 1172
1178 spin_lock_irqsave(&gpu->event_spinlock, flags); 1173 spin_lock_irqsave(&gpu->event_spinlock, flags);
1179 1174
1180 if (gpu->event[event].used == false) { 1175 if (!test_bit(event, gpu->event_bitmap)) {
1181 dev_warn(gpu->dev, "event %u is already marked as free", 1176 dev_warn(gpu->dev, "event %u is already marked as free",
1182 event); 1177 event);
1183 spin_unlock_irqrestore(&gpu->event_spinlock, flags); 1178 spin_unlock_irqrestore(&gpu->event_spinlock, flags);
1184 } else { 1179 } else {
1185 gpu->event[event].used = false; 1180 clear_bit(event, gpu->event_bitmap);
1186 spin_unlock_irqrestore(&gpu->event_spinlock, flags); 1181 spin_unlock_irqrestore(&gpu->event_spinlock, flags);
1187 1182
1188 complete(&gpu->event_free); 1183 complete(&gpu->event_free);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index 689cb8f3680c..70e6590aacdf 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -88,13 +88,14 @@ struct etnaviv_chip_identity {
88}; 88};
89 89
90struct etnaviv_event { 90struct etnaviv_event {
91 bool used;
92 struct dma_fence *fence; 91 struct dma_fence *fence;
93}; 92};
94 93
95struct etnaviv_cmdbuf_suballoc; 94struct etnaviv_cmdbuf_suballoc;
96struct etnaviv_cmdbuf; 95struct etnaviv_cmdbuf;
97 96
97#define ETNA_NR_EVENTS 30
98
98struct etnaviv_gpu { 99struct etnaviv_gpu {
99 struct drm_device *drm; 100 struct drm_device *drm;
100 struct thermal_cooling_device *cooling; 101 struct thermal_cooling_device *cooling;
@@ -112,7 +113,8 @@ struct etnaviv_gpu {
112 u32 memory_base; 113 u32 memory_base;
113 114
114 /* event management: */ 115 /* event management: */
115 struct etnaviv_event event[30]; 116 DECLARE_BITMAP(event_bitmap, ETNA_NR_EVENTS);
117 struct etnaviv_event event[ETNA_NR_EVENTS];
116 struct completion event_free; 118 struct completion event_free;
117 spinlock_t event_spinlock; 119 spinlock_t event_spinlock;
118 120