summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c89
1 files changed, 51 insertions, 38 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index e65d3f00..1ea7d6b3 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -2467,63 +2467,76 @@ unsigned int gk20a_fifo_handle_pbdma_intr_1(struct gk20a *g,
2467 2467
2468 return rc_type; 2468 return rc_type;
2469} 2469}
2470static u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, 2470
2471 struct fifo_gk20a *f, 2471static void gk20a_fifo_pbdma_fault_rc(struct gk20a *g,
2472 u32 pbdma_id) 2472 struct fifo_gk20a *f, u32 pbdma_id,
2473 u32 error_notifier)
2474{
2475 u32 status;
2476 u32 id;
2477
2478 nvgpu_log(g, gpu_dbg_info, "pbdma id %d error notifier %d",
2479 pbdma_id, error_notifier);
2480 status = gk20a_readl(g, fifo_pbdma_status_r(pbdma_id));
2481 /* Remove channel from runlist */
2482 id = fifo_pbdma_status_id_v(status);
2483 if (fifo_pbdma_status_id_type_v(status)
2484 == fifo_pbdma_status_id_type_chid_v()) {
2485 struct channel_gk20a *ch = &f->channel[id];
2486
2487 if (gk20a_channel_get(ch)) {
2488 gk20a_set_error_notifier(ch, error_notifier);
2489 gk20a_fifo_recover_ch(g, id, true);
2490 gk20a_channel_put(ch);
2491 }
2492 } else if (fifo_pbdma_status_id_type_v(status)
2493 == fifo_pbdma_status_id_type_tsgid_v()) {
2494 struct tsg_gk20a *tsg = &f->tsg[id];
2495 struct channel_gk20a *ch = NULL;
2496
2497 nvgpu_rwsem_down_read(&tsg->ch_list_lock);
2498 list_for_each_entry(ch, &tsg->ch_list, ch_entry) {
2499 if (gk20a_channel_get(ch)) {
2500 gk20a_set_error_notifier(ch,
2501 error_notifier);
2502 gk20a_channel_put(ch);
2503 }
2504 }
2505 nvgpu_rwsem_up_read(&tsg->ch_list_lock);
2506 gk20a_fifo_recover_tsg(g, id, true);
2507 }
2508}
2509
2510u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, struct fifo_gk20a *f,
2511 u32 pbdma_id, unsigned int rc)
2473{ 2512{
2474 u32 pbdma_intr_0 = gk20a_readl(g, pbdma_intr_0_r(pbdma_id)); 2513 u32 pbdma_intr_0 = gk20a_readl(g, pbdma_intr_0_r(pbdma_id));
2475 u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id)); 2514 u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id));
2476 u32 status = gk20a_readl(g, fifo_pbdma_status_r(pbdma_id));
2477 2515
2478 u32 handled = 0; 2516 u32 handled = 0;
2479 u32 error_notifier = NVGPU_CHANNEL_PBDMA_ERROR; 2517 u32 error_notifier = NVGPU_CHANNEL_PBDMA_ERROR;
2480 unsigned int rc_type = RC_TYPE_NO_RC; 2518 unsigned int rc_type = RC_TYPE_NO_RC;
2481 2519
2482 gk20a_dbg_fn("");
2483
2484 gk20a_dbg(gpu_dbg_intr, "pbdma id intr pending %d %08x %08x", pbdma_id,
2485 pbdma_intr_0, pbdma_intr_1);
2486 if (pbdma_intr_0) { 2520 if (pbdma_intr_0) {
2521 nvgpu_log(g, gpu_dbg_info | gpu_dbg_intr,
2522 "pbdma id %d intr_0 0x%08x pending",
2523 pbdma_id, pbdma_intr_0);
2487 rc_type = g->ops.fifo.handle_pbdma_intr_0(g, pbdma_id, 2524 rc_type = g->ops.fifo.handle_pbdma_intr_0(g, pbdma_id,
2488 pbdma_intr_0, &handled, &error_notifier); 2525 pbdma_intr_0, &handled, &error_notifier);
2489 gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0); 2526 gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0);
2490 } 2527 }
2491 2528
2492 if (pbdma_intr_1) { 2529 if (pbdma_intr_1) {
2530 nvgpu_log(g, gpu_dbg_info | gpu_dbg_intr,
2531 "pbdma id %d intr_1 0x%08x pending",
2532 pbdma_id, pbdma_intr_1);
2493 rc_type = g->ops.fifo.handle_pbdma_intr_1(g, pbdma_id, 2533 rc_type = g->ops.fifo.handle_pbdma_intr_1(g, pbdma_id,
2494 pbdma_intr_1, &handled, &error_notifier); 2534 pbdma_intr_1, &handled, &error_notifier);
2495 gk20a_writel(g, pbdma_intr_1_r(pbdma_id), pbdma_intr_1); 2535 gk20a_writel(g, pbdma_intr_1_r(pbdma_id), pbdma_intr_1);
2496 } 2536 }
2497 2537
2498 if (rc_type == RC_TYPE_PBDMA_FAULT) { 2538 if (rc == RC_YES && rc_type == RC_TYPE_PBDMA_FAULT)
2499 /* Remove the channel from runlist */ 2539 gk20a_fifo_pbdma_fault_rc(g, f, pbdma_id, error_notifier);
2500 u32 id = fifo_pbdma_status_id_v(status);
2501 if (fifo_pbdma_status_id_type_v(status)
2502 == fifo_pbdma_status_id_type_chid_v()) {
2503 struct channel_gk20a *ch = &f->channel[id];
2504
2505 if (gk20a_channel_get(ch)) {
2506 gk20a_set_error_notifier(ch, error_notifier);
2507 gk20a_fifo_recover_ch(g, id, true);
2508 gk20a_channel_put(ch);
2509 }
2510 } else if (fifo_pbdma_status_id_type_v(status)
2511 == fifo_pbdma_status_id_type_tsgid_v()) {
2512 struct tsg_gk20a *tsg = &f->tsg[id];
2513 struct channel_gk20a *ch = NULL;
2514
2515 nvgpu_rwsem_down_read(&tsg->ch_list_lock);
2516 list_for_each_entry(ch, &tsg->ch_list, ch_entry) {
2517 if (gk20a_channel_get(ch)) {
2518 gk20a_set_error_notifier(ch,
2519 error_notifier);
2520 gk20a_channel_put(ch);
2521 }
2522 }
2523 nvgpu_rwsem_up_read(&tsg->ch_list_lock);
2524 gk20a_fifo_recover_tsg(g, id, true);
2525 }
2526 }
2527 2540
2528 return handled; 2541 return handled;
2529} 2542}
@@ -2539,7 +2552,7 @@ static u32 fifo_pbdma_isr(struct gk20a *g, u32 fifo_intr)
2539 if (fifo_intr_pbdma_id_status_v(pbdma_pending, i)) { 2552 if (fifo_intr_pbdma_id_status_v(pbdma_pending, i)) {
2540 gk20a_dbg(gpu_dbg_intr, "pbdma id %d intr pending", i); 2553 gk20a_dbg(gpu_dbg_intr, "pbdma id %d intr pending", i);
2541 clear_intr |= 2554 clear_intr |=
2542 gk20a_fifo_handle_pbdma_intr(g, f, i); 2555 gk20a_fifo_handle_pbdma_intr(g, f, i, RC_YES);
2543 } 2556 }
2544 } 2557 }
2545 return fifo_intr_0_pbdma_intr_pending_f(); 2558 return fifo_intr_0_pbdma_intr_pending_f();