summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/common/linux/nvhost.c19
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c18
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c19
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h10
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/nvhost.h2
5 files changed, 62 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/nvhost.c b/drivers/gpu/nvgpu/common/linux/nvhost.c
index a76953e3..fa169cf0 100644
--- a/drivers/gpu/nvgpu/common/linux/nvhost.c
+++ b/drivers/gpu/nvgpu/common/linux/nvhost.c
@@ -166,6 +166,25 @@ u32 nvgpu_nvhost_syncpt_read_maxval(
166 return nvhost_syncpt_read_maxval(nvhost_dev->host1x_pdev, id); 166 return nvhost_syncpt_read_maxval(nvhost_dev->host1x_pdev, id);
167} 167}
168 168
169void nvgpu_nvhost_syncpt_set_safe_state(
170 struct nvgpu_nvhost_dev *nvhost_dev, u32 id)
171{
172 u32 val;
173
174 /*
175 * Add large number of increments to current value
176 * so that all waiters on this syncpoint are released
177 *
178 * We don't expect any case where more than 0x10000 increments
179 * are pending
180 */
181 val = nvhost_syncpt_read_minval(nvhost_dev->host1x_pdev, id);
182 val += 0x10000;
183
184 nvhost_syncpt_set_minval(nvhost_dev->host1x_pdev, id, val);
185 nvhost_syncpt_set_maxval(nvhost_dev->host1x_pdev, id, val);
186}
187
169int nvgpu_nvhost_create_symlink(struct gk20a *g) 188int nvgpu_nvhost_create_symlink(struct gk20a *g)
170{ 189{
171 struct device *dev = dev_from_gk20a(g); 190 struct device *dev = dev_from_gk20a(g);
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 78953558..65b17304 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -196,6 +196,8 @@ void gk20a_channel_abort_clean_up(struct channel_gk20a *ch)
196 nvgpu_mutex_acquire(&ch->sync_lock); 196 nvgpu_mutex_acquire(&ch->sync_lock);
197 if (ch->sync) 197 if (ch->sync)
198 ch->sync->set_min_eq_max(ch->sync); 198 ch->sync->set_min_eq_max(ch->sync);
199 if (ch->user_sync)
200 ch->user_sync->set_safe_state(ch->user_sync);
199 nvgpu_mutex_release(&ch->sync_lock); 201 nvgpu_mutex_release(&ch->sync_lock);
200 202
201 /* release all job semaphores (applies only to jobs that use 203 /* release all job semaphores (applies only to jobs that use
@@ -435,11 +437,18 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force)
435 /* sync must be destroyed before releasing channel vm */ 437 /* sync must be destroyed before releasing channel vm */
436 nvgpu_mutex_acquire(&ch->sync_lock); 438 nvgpu_mutex_acquire(&ch->sync_lock);
437 if (ch->sync) { 439 if (ch->sync) {
438 gk20a_channel_sync_destroy(ch->sync); 440 gk20a_channel_sync_destroy(ch->sync, false);
439 ch->sync = NULL; 441 ch->sync = NULL;
440 } 442 }
441 if (ch->user_sync) { 443 if (ch->user_sync) {
442 gk20a_channel_sync_destroy(ch->user_sync); 444 /*
445 * Set user managed syncpoint to safe state
446 * But it's already done if channel has timedout
447 */
448 if (ch->has_timedout)
449 gk20a_channel_sync_destroy(ch->user_sync, false);
450 else
451 gk20a_channel_sync_destroy(ch->user_sync, true);
443 ch->user_sync = NULL; 452 ch->user_sync = NULL;
444 } 453 }
445 nvgpu_mutex_release(&ch->sync_lock); 454 nvgpu_mutex_release(&ch->sync_lock);
@@ -1211,7 +1220,7 @@ clean_up_prealloc:
1211 channel_gk20a_free_prealloc_resources(c); 1220 channel_gk20a_free_prealloc_resources(c);
1212clean_up_sync: 1221clean_up_sync:
1213 if (c->sync) { 1222 if (c->sync) {
1214 gk20a_channel_sync_destroy(c->sync); 1223 gk20a_channel_sync_destroy(c->sync, false);
1215 c->sync = NULL; 1224 c->sync = NULL;
1216 } 1225 }
1217clean_up_unmap: 1226clean_up_unmap:
@@ -1905,7 +1914,8 @@ void gk20a_channel_clean_up_jobs(struct channel_gk20a *c,
1905 if (nvgpu_atomic_dec_and_test( 1914 if (nvgpu_atomic_dec_and_test(
1906 &c->sync->refcount) && 1915 &c->sync->refcount) &&
1907 g->aggressive_sync_destroy) { 1916 g->aggressive_sync_destroy) {
1908 gk20a_channel_sync_destroy(c->sync); 1917 gk20a_channel_sync_destroy(c->sync,
1918 false);
1909 c->sync = NULL; 1919 c->sync = NULL;
1910 } 1920 }
1911 nvgpu_mutex_release(&c->sync_lock); 1921 nvgpu_mutex_release(&c->sync_lock);
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
index 3c12147f..236ddaaf 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
@@ -280,6 +280,13 @@ static void gk20a_channel_syncpt_set_min_eq_max(struct gk20a_channel_sync *s)
280 nvgpu_nvhost_syncpt_set_min_eq_max_ext(sp->nvhost_dev, sp->id); 280 nvgpu_nvhost_syncpt_set_min_eq_max_ext(sp->nvhost_dev, sp->id);
281} 281}
282 282
283static void gk20a_channel_syncpt_set_safe_state(struct gk20a_channel_sync *s)
284{
285 struct gk20a_channel_syncpt *sp =
286 container_of(s, struct gk20a_channel_syncpt, ops);
287 nvgpu_nvhost_syncpt_set_safe_state(sp->nvhost_dev, sp->id);
288}
289
283static void gk20a_channel_syncpt_signal_timeline( 290static void gk20a_channel_syncpt_signal_timeline(
284 struct gk20a_channel_sync *s) 291 struct gk20a_channel_sync *s)
285{ 292{
@@ -357,6 +364,7 @@ gk20a_channel_syncpt_create(struct channel_gk20a *c, bool user_managed)
357 sp->ops.incr_wfi = gk20a_channel_syncpt_incr_wfi; 364 sp->ops.incr_wfi = gk20a_channel_syncpt_incr_wfi;
358 sp->ops.incr_user = gk20a_channel_syncpt_incr_user; 365 sp->ops.incr_user = gk20a_channel_syncpt_incr_user;
359 sp->ops.set_min_eq_max = gk20a_channel_syncpt_set_min_eq_max; 366 sp->ops.set_min_eq_max = gk20a_channel_syncpt_set_min_eq_max;
367 sp->ops.set_safe_state = gk20a_channel_syncpt_set_safe_state;
360 sp->ops.signal_timeline = gk20a_channel_syncpt_signal_timeline; 368 sp->ops.signal_timeline = gk20a_channel_syncpt_signal_timeline;
361 sp->ops.syncpt_id = gk20a_channel_syncpt_id; 369 sp->ops.syncpt_id = gk20a_channel_syncpt_id;
362 sp->ops.syncpt_address = gk20a_channel_syncpt_address; 370 sp->ops.syncpt_address = gk20a_channel_syncpt_address;
@@ -634,6 +642,11 @@ static void gk20a_channel_semaphore_set_min_eq_max(struct gk20a_channel_sync *s)
634 /* Nothing to do. */ 642 /* Nothing to do. */
635} 643}
636 644
645static void gk20a_channel_semaphore_set_safe_state(struct gk20a_channel_sync *s)
646{
647 /* Nothing to do. */
648}
649
637static void gk20a_channel_semaphore_signal_timeline( 650static void gk20a_channel_semaphore_signal_timeline(
638 struct gk20a_channel_sync *s) 651 struct gk20a_channel_sync *s)
639{ 652{
@@ -703,6 +716,7 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed)
703 sema->ops.incr_wfi = gk20a_channel_semaphore_incr_wfi; 716 sema->ops.incr_wfi = gk20a_channel_semaphore_incr_wfi;
704 sema->ops.incr_user = gk20a_channel_semaphore_incr_user; 717 sema->ops.incr_user = gk20a_channel_semaphore_incr_user;
705 sema->ops.set_min_eq_max = gk20a_channel_semaphore_set_min_eq_max; 718 sema->ops.set_min_eq_max = gk20a_channel_semaphore_set_min_eq_max;
719 sema->ops.set_safe_state = gk20a_channel_semaphore_set_safe_state;
706 sema->ops.signal_timeline = gk20a_channel_semaphore_signal_timeline; 720 sema->ops.signal_timeline = gk20a_channel_semaphore_signal_timeline;
707 sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id; 721 sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id;
708 sema->ops.syncpt_address = gk20a_channel_semaphore_syncpt_address; 722 sema->ops.syncpt_address = gk20a_channel_semaphore_syncpt_address;
@@ -711,8 +725,11 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed)
711 return &sema->ops; 725 return &sema->ops;
712} 726}
713 727
714void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync) 728void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync,
729 bool set_safe_state)
715{ 730{
731 if (set_safe_state)
732 sync->set_safe_state(sync);
716 sync->destroy(sync); 733 sync->destroy(sync);
717} 734}
718 735
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h
index 3f44b27a..da8cb251 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h
@@ -86,6 +86,13 @@ struct gk20a_channel_sync {
86 /* Reset the channel syncpoint/semaphore. */ 86 /* Reset the channel syncpoint/semaphore. */
87 void (*set_min_eq_max)(struct gk20a_channel_sync *s); 87 void (*set_min_eq_max)(struct gk20a_channel_sync *s);
88 88
89 /*
90 * Set the channel syncpoint/semaphore to safe state
91 * This should be used to reset User managed syncpoint since we don't
92 * track threshold values for those syncpoints
93 */
94 void (*set_safe_state)(struct gk20a_channel_sync *s);
95
89 /* Signals the sync timeline (if owned by the gk20a_channel_sync layer). 96 /* Signals the sync timeline (if owned by the gk20a_channel_sync layer).
90 * This should be called when we notice that a gk20a_fence is 97 * This should be called when we notice that a gk20a_fence is
91 * expired. */ 98 * expired. */
@@ -101,7 +108,8 @@ struct gk20a_channel_sync {
101 void (*destroy)(struct gk20a_channel_sync *s); 108 void (*destroy)(struct gk20a_channel_sync *s);
102}; 109};
103 110
104void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync); 111void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync,
112 bool set_safe_state);
105struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c, 113struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c,
106 bool user_managed); 114 bool user_managed);
107bool gk20a_channel_sync_needs_sync_framework(struct gk20a *g); 115bool gk20a_channel_sync_needs_sync_framework(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvhost.h b/drivers/gpu/nvgpu/include/nvgpu/nvhost.h
index d5b5831a..13de012a 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/nvhost.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/nvhost.h
@@ -52,6 +52,8 @@ int nvgpu_nvhost_syncpt_read_ext_check(struct nvgpu_nvhost_dev *nvhost_dev,
52 u32 id, u32 *val); 52 u32 id, u32 *val);
53u32 nvgpu_nvhost_syncpt_read_maxval(struct nvgpu_nvhost_dev *nvhost_dev, 53u32 nvgpu_nvhost_syncpt_read_maxval(struct nvgpu_nvhost_dev *nvhost_dev,
54 u32 id); 54 u32 id);
55void nvgpu_nvhost_syncpt_set_safe_state(
56 struct nvgpu_nvhost_dev *nvhost_dev, u32 id);
55 57
56int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev, 58int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev,
57 u32 id, u32 thresh, void (*callback)(void *, int), void *private_data); 59 u32 id, u32 thresh, void (*callback)(void *, int), void *private_data);