diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 89 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 5 |
2 files changed, 56 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 | } |
2470 | static u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, | 2470 | |
2471 | struct fifo_gk20a *f, | 2471 | static 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 | |||
2510 | u32 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(); |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 42ad288f..fa1d9f72 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | |||
@@ -58,6 +58,9 @@ enum { | |||
58 | #define PREEMPT_TIMEOUT_RC 1 | 58 | #define PREEMPT_TIMEOUT_RC 1 |
59 | #define PREEMPT_TIMEOUT_NORC 0 | 59 | #define PREEMPT_TIMEOUT_NORC 0 |
60 | 60 | ||
61 | #define RC_YES 1 | ||
62 | #define RC_NO 0 | ||
63 | |||
61 | #define GRFIFO_TIMEOUT_CHECK_PERIOD_US 100000 | 64 | #define GRFIFO_TIMEOUT_CHECK_PERIOD_US 100000 |
62 | 65 | ||
63 | #define RC_TYPE_NORMAL 0 | 66 | #define RC_TYPE_NORMAL 0 |
@@ -407,6 +410,8 @@ unsigned int gk20a_fifo_handle_pbdma_intr_0(struct gk20a *g, u32 pbdma_id, | |||
407 | u32 pbdma_intr_0, u32 *handled, u32 *error_notifier); | 410 | u32 pbdma_intr_0, u32 *handled, u32 *error_notifier); |
408 | unsigned int gk20a_fifo_handle_pbdma_intr_1(struct gk20a *g, u32 pbdma_id, | 411 | unsigned int gk20a_fifo_handle_pbdma_intr_1(struct gk20a *g, u32 pbdma_id, |
409 | u32 pbdma_intr_1, u32 *handled, u32 *error_notifier); | 412 | u32 pbdma_intr_1, u32 *handled, u32 *error_notifier); |
413 | u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, struct fifo_gk20a *f, | ||
414 | u32 pbdma_id, unsigned int rc); | ||
410 | 415 | ||
411 | u32 gk20a_fifo_default_timeslice_us(struct gk20a *g); | 416 | u32 gk20a_fifo_default_timeslice_us(struct gk20a *g); |
412 | 417 | ||