diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2017-12-23 15:33:49 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-12-29 16:30:59 -0500 |
commit | 79ffeb637dbcc5ad719cb5e900be32e06cb37ac5 (patch) | |
tree | aac97edae9badba1e78c9be8901a99cd5d7db2c7 /drivers/gpu/nvgpu | |
parent | 32353ab744937add05253cea617f397ea3d13920 (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>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/gr_gv11b.c | 32 |
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); |
3736 | exit: | 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 | ||
3741 | static int gr_gv11b_ecc_scrub_sm_lrf(struct gk20a *g) | 3751 | static int gr_gv11b_ecc_scrub_sm_lrf(struct gk20a *g) |