summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2017-12-23 15:33:49 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-12-29 16:30:59 -0500
commit79ffeb637dbcc5ad719cb5e900be32e06cb37ac5 (patch)
treeaac97edae9badba1e78c9be8901a99cd5d7db2c7
parent32353ab744937add05253cea617f397ea3d13920 (diff)
gpu: nvgpu: Wait for ECC scrubbing on all TPCs
We send a broadcast request to invoke scrubbing on all TPCs, but we check only TPC0 for scrubbing to finish. This likely produces correct results, because each TPC should take exactly the same number of cycles for scrubbing, but it's not certain. Change the polling loop to check all TPCs to make sure there are no timing glitches. Change-Id: Id3add77069743890379099a44aec8994f59d9a5e Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1625349 Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gv11b/gr_gv11b.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
index 56d223dd..e00277f0 100644
--- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
+++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
@@ -3717,25 +3717,35 @@ static int gr_gv11b_ecc_scrub_is_done(struct gk20a *g,
3717 u32 scrub_reg, u32 scrub_mask, u32 scrub_done) 3717 u32 scrub_reg, u32 scrub_mask, u32 scrub_done)
3718{ 3718{
3719 struct nvgpu_timeout timeout; 3719 struct nvgpu_timeout timeout;
3720 int status = 0;
3721 u32 val; 3720 u32 val;
3721 u32 gpc, tpc;
3722 u32 gpc_offset, tpc_offset;
3722 3723
3723 nvgpu_timeout_init(g, &timeout, 3724 nvgpu_timeout_init(g, &timeout,
3724 ECC_SCRUBBING_TIMEOUT_MAX / 3725 ECC_SCRUBBING_TIMEOUT_MAX /
3725 ECC_SCRUBBING_TIMEOUT_DEFAULT, 3726 ECC_SCRUBBING_TIMEOUT_DEFAULT,
3726 NVGPU_TIMER_RETRY_TIMER); 3727 NVGPU_TIMER_RETRY_TIMER);
3727 do {
3728 val = gk20a_readl(g, scrub_reg);
3729 if ((val & scrub_mask) == scrub_done)
3730 goto exit;
3731 nvgpu_udelay(ECC_SCRUBBING_TIMEOUT_DEFAULT);
3732 } while (!nvgpu_timeout_expired(&timeout));
3733 3728
3734 if (nvgpu_timeout_peek_expired(&timeout)) 3729 for (gpc = 0; gpc < g->gr.gpc_count; gpc++) {
3735 status = -ETIMEDOUT; 3730 gpc_offset = gk20a_gr_gpc_offset(g, gpc);
3736exit: 3731
3737 return status; 3732 for (tpc = 0; tpc < g->gr.tpc_count; tpc++) {
3733 tpc_offset = gk20a_gr_tpc_offset(g, tpc);
3738 3734
3735 do {
3736 val = gk20a_readl(g, gpc_offset + tpc_offset + scrub_reg);
3737 if ((val & scrub_mask) == scrub_done)
3738 break;
3739
3740 if (nvgpu_timeout_expired(&timeout))
3741 return -ETIMEDOUT;
3742
3743 nvgpu_udelay(ECC_SCRUBBING_TIMEOUT_DEFAULT);
3744 } while (1);
3745 }
3746 }
3747
3748 return 0;
3739} 3749}
3740 3750
3741static int gr_gv11b_ecc_scrub_sm_lrf(struct gk20a *g) 3751static int gr_gv11b_ecc_scrub_sm_lrf(struct gk20a *g)