diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c index 851ae18b..b94c0c93 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | |||
@@ -172,6 +172,7 @@ static void gk20a_channel_syncpt_update(void *priv, int nr_completed) | |||
172 | 172 | ||
173 | static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s, | 173 | static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s, |
174 | bool gfx_class, bool wfi_cmd, | 174 | bool gfx_class, bool wfi_cmd, |
175 | bool register_irq, | ||
175 | struct priv_cmd_entry **entry, | 176 | struct priv_cmd_entry **entry, |
176 | struct gk20a_channel_fence *fence) | 177 | struct gk20a_channel_fence *fence) |
177 | { | 178 | { |
@@ -184,18 +185,12 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s, | |||
184 | container_of(s, struct gk20a_channel_syncpt, ops); | 185 | container_of(s, struct gk20a_channel_syncpt, ops); |
185 | struct channel_gk20a *c = sp->c; | 186 | struct channel_gk20a *c = sp->c; |
186 | 187 | ||
187 | /* nvhost action_gpfifo_submit_complete releases this ref. */ | ||
188 | err = gk20a_channel_busy(c->g->dev); | ||
189 | if (err) | ||
190 | return err; | ||
191 | |||
192 | incr_cmd_size = 4; | 188 | incr_cmd_size = 4; |
193 | if (wfi_cmd) | 189 | if (wfi_cmd) |
194 | incr_cmd_size += 2; | 190 | incr_cmd_size += 2; |
195 | 191 | ||
196 | gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd); | 192 | gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd); |
197 | if (incr_cmd == NULL) { | 193 | if (incr_cmd == NULL) { |
198 | gk20a_channel_idle(c->g->dev); | ||
199 | gk20a_err(dev_from_gk20a(c->g), | 194 | gk20a_err(dev_from_gk20a(c->g), |
200 | "not enough priv cmd buffer space"); | 195 | "not enough priv cmd buffer space"); |
201 | return -EAGAIN; | 196 | return -EAGAIN; |
@@ -230,15 +225,22 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s, | |||
230 | 225 | ||
231 | thresh = nvhost_syncpt_incr_max_ext(sp->host1x_pdev, sp->id, 1); | 226 | thresh = nvhost_syncpt_incr_max_ext(sp->host1x_pdev, sp->id, 1); |
232 | 227 | ||
233 | err = nvhost_intr_register_notifier(sp->host1x_pdev, sp->id, thresh, | 228 | if (register_irq) { |
234 | gk20a_channel_syncpt_update, c); | 229 | /* nvhost action_gpfifo_submit_complete releases this ref. */ |
230 | err = gk20a_channel_busy(c->g->dev); | ||
231 | |||
232 | if (!err) { | ||
233 | err = nvhost_intr_register_notifier(sp->host1x_pdev, | ||
234 | sp->id, thresh, | ||
235 | gk20a_channel_syncpt_update, c); | ||
236 | if (err) | ||
237 | gk20a_channel_idle(c->g->dev); | ||
238 | } | ||
235 | 239 | ||
236 | /* Adding interrupt action should never fail. A proper error handling | 240 | /* Adding interrupt action should never fail. A proper error |
237 | * here would require us to decrement the syncpt max back to its | 241 | * handling here would require us to decrement the syncpt max |
238 | * original value. */ | 242 | * back to its original value. */ |
239 | if (WARN(err, "failed to set submit complete interrupt")) { | 243 | WARN(err, "failed to set submit complete interrupt"); |
240 | gk20a_channel_idle(c->g->dev); | ||
241 | err = 0; /* Ignore this error. */ | ||
242 | } | 244 | } |
243 | 245 | ||
244 | fence->thresh = thresh; | 246 | fence->thresh = thresh; |
@@ -255,6 +257,7 @@ int gk20a_channel_syncpt_incr_wfi(struct gk20a_channel_sync *s, | |||
255 | return __gk20a_channel_syncpt_incr(s, | 257 | return __gk20a_channel_syncpt_incr(s, |
256 | false /* use host class */, | 258 | false /* use host class */, |
257 | true /* wfi */, | 259 | true /* wfi */, |
260 | false /* no irq handler */, | ||
258 | entry, fence); | 261 | entry, fence); |
259 | } | 262 | } |
260 | 263 | ||
@@ -269,6 +272,7 @@ int gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s, | |||
269 | return __gk20a_channel_syncpt_incr(s, | 272 | return __gk20a_channel_syncpt_incr(s, |
270 | sp->c->obj_class == KEPLER_C /* may use gfx class */, | 273 | sp->c->obj_class == KEPLER_C /* may use gfx class */, |
271 | false /* no wfi */, | 274 | false /* no wfi */, |
275 | true /* register irq */, | ||
272 | entry, fence); | 276 | entry, fence); |
273 | } | 277 | } |
274 | 278 | ||
@@ -284,6 +288,7 @@ int gk20a_channel_syncpt_incr_user_syncpt(struct gk20a_channel_sync *s, | |||
284 | int err = __gk20a_channel_syncpt_incr(s, | 288 | int err = __gk20a_channel_syncpt_incr(s, |
285 | sp->c->obj_class == KEPLER_C /* use gfx class? */, | 289 | sp->c->obj_class == KEPLER_C /* use gfx class? */, |
286 | sp->c->obj_class != KEPLER_C /* wfi if host class */, | 290 | sp->c->obj_class != KEPLER_C /* wfi if host class */, |
291 | true /* register irq */, | ||
287 | entry, fence); | 292 | entry, fence); |
288 | if (err) | 293 | if (err) |
289 | return err; | 294 | return err; |