diff options
author | Christian Gmeiner <christian.gmeiner@gmail.com> | 2017-09-24 09:15:19 -0400 |
---|---|---|
committer | Lucas Stach <l.stach@pengutronix.de> | 2017-10-10 05:45:39 -0400 |
commit | 355502e03ad26e3c872a0f5c408a4accca57ba7e (patch) | |
tree | c1327e81702aa186a5ea6be0a9279f0667315cc4 | |
parent | 6eb3ecc33a6aaedda5ceb0824cafe34c47af2f55 (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.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 6 |
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, | |||
1148 | static unsigned int event_alloc(struct etnaviv_gpu *gpu) | 1145 | static 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 | ||
90 | struct etnaviv_event { | 90 | struct etnaviv_event { |
91 | bool used; | ||
92 | struct dma_fence *fence; | 91 | struct dma_fence *fence; |
93 | }; | 92 | }; |
94 | 93 | ||
95 | struct etnaviv_cmdbuf_suballoc; | 94 | struct etnaviv_cmdbuf_suballoc; |
96 | struct etnaviv_cmdbuf; | 95 | struct etnaviv_cmdbuf; |
97 | 96 | ||
97 | #define ETNA_NR_EVENTS 30 | ||
98 | |||
98 | struct etnaviv_gpu { | 99 | struct 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 | ||