diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 87 |
1 files changed, 44 insertions, 43 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 6fe330c0..b714b2e2 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -5525,9 +5525,9 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, | |||
5525 | int ret = 0; | 5525 | int ret = 0; |
5526 | bool do_warp_sync = false, early_exit = false, ignore_debugger = false; | 5526 | bool do_warp_sync = false, early_exit = false, ignore_debugger = false; |
5527 | bool disable_sm_exceptions = true; | 5527 | bool disable_sm_exceptions = true; |
5528 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | 5528 | u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); |
5529 | u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); | 5529 | bool sm_debugger_attached; |
5530 | u32 offset = gpc_stride * gpc + tpc_in_gpc_stride * tpc; | 5530 | u32 global_esr, warp_esr; |
5531 | 5531 | ||
5532 | /* these three interrupts don't require locking down the SM. They can | 5532 | /* these three interrupts don't require locking down the SM. They can |
5533 | * be handled by usermode clients as they aren't fatal. Additionally, | 5533 | * be handled by usermode clients as they aren't fatal. Additionally, |
@@ -5537,27 +5537,26 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, | |||
5537 | u32 global_mask = gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f() | | 5537 | u32 global_mask = gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f() | |
5538 | gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f() | | 5538 | gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f() | |
5539 | gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f(); | 5539 | gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f(); |
5540 | u32 global_esr, warp_esr; | ||
5541 | bool sm_debugger_attached = g->ops.gr.sm_debugger_attached(g); | ||
5542 | 5540 | ||
5543 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); | 5541 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); |
5544 | 5542 | ||
5545 | global_esr = gk20a_readl(g, | 5543 | sm_debugger_attached = g->ops.gr.sm_debugger_attached(g); |
5546 | gr_gpc0_tpc0_sm_hww_global_esr_r() + offset); | 5544 | |
5545 | global_esr = g->ops.gr.get_sm_hww_global_esr(g, gpc, tpc, sm); | ||
5546 | *hww_global_esr = global_esr; | ||
5547 | warp_esr = g->ops.gr.get_sm_hww_warp_esr(g, gpc, tpc, sm); | 5547 | warp_esr = g->ops.gr.get_sm_hww_warp_esr(g, gpc, tpc, sm); |
5548 | 5548 | ||
5549 | if (!sm_debugger_attached) { | 5549 | if (!sm_debugger_attached) { |
5550 | nvgpu_err(g, "sm hww global %08x warp %08x", | 5550 | nvgpu_err(g, "sm hww global 0x%08x warp 0x%08x", |
5551 | global_esr, warp_esr); | 5551 | global_esr, warp_esr); |
5552 | return -EFAULT; | 5552 | return -EFAULT; |
5553 | } | 5553 | } |
5554 | 5554 | ||
5555 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 5555 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5556 | "sm hww global %08x warp %08x", global_esr, warp_esr); | 5556 | "sm hww global 0x%08x warp 0x%08x", global_esr, warp_esr); |
5557 | 5557 | ||
5558 | gr_gk20a_elpg_protected_call(g, | 5558 | gr_gk20a_elpg_protected_call(g, |
5559 | g->ops.gr.record_sm_error_state(g, gpc, tpc)); | 5559 | g->ops.gr.record_sm_error_state(g, gpc, tpc)); |
5560 | *hww_global_esr = global_esr; | ||
5561 | 5560 | ||
5562 | if (g->ops.gr.pre_process_sm_exception) { | 5561 | if (g->ops.gr.pre_process_sm_exception) { |
5563 | ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, sm, | 5562 | ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, sm, |
@@ -5615,7 +5614,8 @@ int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, | |||
5615 | } | 5614 | } |
5616 | 5615 | ||
5617 | if (ignore_debugger) | 5616 | if (ignore_debugger) |
5618 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "ignore_debugger set, skipping event posting"); | 5617 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5618 | "ignore_debugger set, skipping event posting"); | ||
5619 | else | 5619 | else |
5620 | *post_event |= true; | 5620 | *post_event |= true; |
5621 | 5621 | ||
@@ -5655,15 +5655,14 @@ static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
5655 | u32 *hww_global_esr) | 5655 | u32 *hww_global_esr) |
5656 | { | 5656 | { |
5657 | int ret = 0; | 5657 | int ret = 0; |
5658 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | 5658 | u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); |
5659 | u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); | ||
5660 | u32 offset = gpc_stride * gpc + tpc_in_gpc_stride * tpc; | ||
5661 | u32 tpc_exception = gk20a_readl(g, gr_gpc0_tpc0_tpccs_tpc_exception_r() | 5659 | u32 tpc_exception = gk20a_readl(g, gr_gpc0_tpc0_tpccs_tpc_exception_r() |
5662 | + offset); | 5660 | + offset); |
5663 | u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); | 5661 | u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); |
5664 | 5662 | ||
5665 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, ""); | 5663 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, ""); |
5666 | 5664 | ||
5665 | |||
5667 | /* check if an sm exeption is pending */ | 5666 | /* check if an sm exeption is pending */ |
5668 | if (gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(tpc_exception) == | 5667 | if (gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(tpc_exception) == |
5669 | gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v()) { | 5668 | gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v()) { |
@@ -5685,6 +5684,11 @@ static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, | |||
5685 | ret = g->ops.gr.handle_sm_exception(g, | 5684 | ret = g->ops.gr.handle_sm_exception(g, |
5686 | gpc, tpc, sm, post_event, fault_ch, | 5685 | gpc, tpc, sm, post_event, fault_ch, |
5687 | hww_global_esr); | 5686 | hww_global_esr); |
5687 | /* clear the hwws, also causes tpc and gpc | ||
5688 | * exceptions to be cleared | ||
5689 | */ | ||
5690 | gk20a_gr_clear_sm_hww(g, gpc, tpc, *hww_global_esr); | ||
5691 | |||
5688 | } | 5692 | } |
5689 | 5693 | ||
5690 | } | 5694 | } |
@@ -5704,12 +5708,10 @@ static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | |||
5704 | struct channel_gk20a *fault_ch, u32 *hww_global_esr) | 5708 | struct channel_gk20a *fault_ch, u32 *hww_global_esr) |
5705 | { | 5709 | { |
5706 | int ret = 0; | 5710 | int ret = 0; |
5707 | u32 gpc_offset, tpc_offset, gpc, tpc; | 5711 | u32 gpc_offset, gpc, tpc; |
5708 | struct gr_gk20a *gr = &g->gr; | 5712 | struct gr_gk20a *gr = &g->gr; |
5709 | u32 exception1 = gk20a_readl(g, gr_exception1_r()); | 5713 | u32 exception1 = gk20a_readl(g, gr_exception1_r()); |
5710 | u32 gpc_exception, global_esr; | 5714 | u32 gpc_exception; |
5711 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | ||
5712 | u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); | ||
5713 | 5715 | ||
5714 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, ""); | 5716 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, ""); |
5715 | 5717 | ||
@@ -5720,7 +5722,7 @@ static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | |||
5720 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 5722 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5721 | "GPC%d exception pending", gpc); | 5723 | "GPC%d exception pending", gpc); |
5722 | 5724 | ||
5723 | gpc_offset = gpc_stride * gpc; | 5725 | gpc_offset = gk20a_gr_gpc_offset(g, gpc); |
5724 | 5726 | ||
5725 | gpc_exception = gk20a_readl(g, gr_gpc0_gpccs_gpc_exception_r() | 5727 | gpc_exception = gk20a_readl(g, gr_gpc0_gpccs_gpc_exception_r() |
5726 | + gpc_offset); | 5728 | + gpc_offset); |
@@ -5734,18 +5736,9 @@ static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, | |||
5734 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, | 5736 | gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, |
5735 | "GPC%d: TPC%d exception pending", gpc, tpc); | 5737 | "GPC%d: TPC%d exception pending", gpc, tpc); |
5736 | 5738 | ||
5737 | tpc_offset = tpc_in_gpc_stride * tpc; | ||
5738 | |||
5739 | global_esr = gk20a_readl(g, | ||
5740 | gr_gpc0_tpc0_sm_hww_global_esr_r() + | ||
5741 | gpc_offset + tpc_offset); | ||
5742 | |||
5743 | ret = gk20a_gr_handle_tpc_exception(g, gpc, tpc, | 5739 | ret = gk20a_gr_handle_tpc_exception(g, gpc, tpc, |
5744 | post_event, fault_ch, hww_global_esr); | 5740 | post_event, fault_ch, hww_global_esr); |
5745 | 5741 | ||
5746 | /* clear the hwws, also causes tpc and gpc | ||
5747 | * exceptions to be cleared */ | ||
5748 | gk20a_gr_clear_sm_hww(g, gpc, tpc, global_esr); | ||
5749 | } | 5742 | } |
5750 | 5743 | ||
5751 | /* Handle GCC exception */ | 5744 | /* Handle GCC exception */ |
@@ -7946,8 +7939,8 @@ int gk20a_gr_wait_for_sm_lock_down(struct gk20a *g, u32 gpc, u32 tpc, | |||
7946 | 7939 | ||
7947 | /* wait for the sm to lock down */ | 7940 | /* wait for the sm to lock down */ |
7948 | do { | 7941 | do { |
7949 | u32 global_esr = gk20a_readl(g, | 7942 | u32 global_esr = g->ops.gr.get_sm_hww_global_esr(g, |
7950 | gr_gpc0_tpc0_sm_hww_global_esr_r() + offset); | 7943 | gpc, tpc, sm); |
7951 | dbgr_status0 = gk20a_readl(g, | 7944 | dbgr_status0 = gk20a_readl(g, |
7952 | gr_gpc0_tpc0_sm_dbgr_status0_r() + offset); | 7945 | gr_gpc0_tpc0_sm_dbgr_status0_r() + offset); |
7953 | 7946 | ||
@@ -8440,28 +8433,25 @@ int gr_gk20a_resume_from_pause(struct gk20a *g) | |||
8440 | int gr_gk20a_clear_sm_errors(struct gk20a *g) | 8433 | int gr_gk20a_clear_sm_errors(struct gk20a *g) |
8441 | { | 8434 | { |
8442 | int ret = 0; | 8435 | int ret = 0; |
8443 | u32 gpc_offset, tpc_offset, gpc, tpc; | 8436 | u32 gpc, tpc, sm; |
8444 | struct gr_gk20a *gr = &g->gr; | 8437 | struct gr_gk20a *gr = &g->gr; |
8445 | u32 global_esr; | 8438 | u32 global_esr; |
8446 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | 8439 | u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); |
8447 | u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); | ||
8448 | 8440 | ||
8449 | for (gpc = 0; gpc < gr->gpc_count; gpc++) { | 8441 | for (gpc = 0; gpc < gr->gpc_count; gpc++) { |
8450 | 8442 | ||
8451 | gpc_offset = gpc_stride * gpc; | ||
8452 | |||
8453 | /* check if any tpc has an exception */ | 8443 | /* check if any tpc has an exception */ |
8454 | for (tpc = 0; tpc < gr->tpc_count; tpc++) { | 8444 | for (tpc = 0; tpc < gr->tpc_count; tpc++) { |
8455 | 8445 | ||
8456 | tpc_offset = tpc_in_gpc_stride * tpc; | 8446 | for (sm = 0; sm < sm_per_tpc; sm++) { |
8447 | global_esr = g->ops.gr.get_sm_hww_global_esr(g, | ||
8448 | gpc, tpc, sm); | ||
8457 | 8449 | ||
8458 | global_esr = gk20a_readl(g, | 8450 | /* clearing hwws, also causes tpc and gpc |
8459 | gr_gpc0_tpc0_sm_hww_global_esr_r() + | 8451 | * exceptions to be cleared |
8460 | gpc_offset + tpc_offset); | 8452 | */ |
8461 | 8453 | gk20a_gr_clear_sm_hww(g, gpc, tpc, global_esr); | |
8462 | /* clear the hwws, also causes tpc and gpc | 8454 | } |
8463 | * exceptions to be cleared */ | ||
8464 | gk20a_gr_clear_sm_hww(g, gpc, tpc, global_esr); | ||
8465 | } | 8455 | } |
8466 | } | 8456 | } |
8467 | 8457 | ||
@@ -8498,3 +8488,14 @@ u32 gk20a_gr_get_sm_hww_warp_esr(struct gk20a *g, u32 gpc, u32 tpc, u32 sm) | |||
8498 | gr_gpc0_tpc0_sm_hww_warp_esr_r() + offset); | 8488 | gr_gpc0_tpc0_sm_hww_warp_esr_r() + offset); |
8499 | return hww_warp_esr; | 8489 | return hww_warp_esr; |
8500 | } | 8490 | } |
8491 | |||
8492 | u32 gk20a_gr_get_sm_hww_global_esr(struct gk20a *g, u32 gpc, u32 tpc, u32 sm) | ||
8493 | { | ||
8494 | u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); | ||
8495 | |||
8496 | u32 hww_global_esr = gk20a_readl(g, | ||
8497 | gr_gpc0_tpc0_sm_hww_global_esr_r() + offset); | ||
8498 | |||
8499 | return hww_global_esr; | ||
8500 | } | ||
8501 | |||