diff options
| -rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_drv.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_drv.h | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 37 | ||||
| -rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 12 |
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); |
| 550 | out_bind: | 544 | out_bind: |
| 551 | kfree(priv); | 545 | kfree(priv); |
| 552 | out_unref: | 546 | out_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 */ | ||
| 111 | static inline bool fence_after(u32 a, u32 b) | ||
| 112 | { | ||
| 113 | return (s32)(a - b) > 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | static 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 | ||
| 977 | void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu) | 979 | void 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 | ||
| 1038 | static void etnaviv_fence_release(struct dma_fence *fence) | 1037 | static 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 */ | ||
| 1074 | static 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) | |||
| 1078 | static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events, | 1083 | static 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 | ||
| 1119 | static void event_free(struct etnaviv_gpu *gpu, unsigned int event) | 1124 | static 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 | ||
| 89 | struct etnaviv_cmdbuf_suballoc; | 86 | struct etnaviv_cmdbuf_suballoc; |
| 90 | struct etnaviv_cmdbuf; | 87 | struct etnaviv_cmdbuf; |
| 88 | struct regulator; | ||
| 89 | struct 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 | ||
| 164 | static inline bool fence_completed(struct etnaviv_gpu *gpu, u32 fence) | ||
| 165 | { | ||
| 166 | return fence_after_eq(gpu->completed_fence, fence); | ||
| 167 | } | ||
| 168 | |||
| 169 | int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); | 161 | int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); |
| 170 | 162 | ||
| 171 | int etnaviv_gpu_init(struct etnaviv_gpu *gpu); | 163 | int etnaviv_gpu_init(struct etnaviv_gpu *gpu); |
