diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b/ltc_gp10b.c')
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/ltc_gp10b.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c index d0be86a4..e68e762d 100644 --- a/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c | |||
@@ -133,21 +133,48 @@ static void gp10b_ltc_isr(struct gk20a *g) | |||
133 | if ((mc_intr & 1 << ltc) == 0) | 133 | if ((mc_intr & 1 << ltc) == 0) |
134 | continue; | 134 | continue; |
135 | for (slice = 0; slice < g->gr.slices_per_ltc; slice++) { | 135 | for (slice = 0; slice < g->gr.slices_per_ltc; slice++) { |
136 | ltc_intr = gk20a_readl(g, ltc_ltc0_lts0_intr_r() + | 136 | u32 offset = proj_ltc_stride_v() * ltc + |
137 | proj_ltc_stride_v() * ltc + | 137 | proj_lts_stride_v() * slice; |
138 | proj_lts_stride_v() * slice); | 138 | ltc_intr = gk20a_readl(g, ltc_ltc0_lts0_intr_r() + offset); |
139 | 139 | ||
140 | /* Detect and handle ECC errors */ | 140 | /* Detect and handle ECC errors */ |
141 | if (ltc_intr & | 141 | if (ltc_intr & |
142 | ltc_ltcs_ltss_intr_ecc_sec_error_pending_f()) { | 142 | ltc_ltcs_ltss_intr_ecc_sec_error_pending_f()) { |
143 | u32 ecc_stats_reg_val; | ||
144 | |||
143 | gk20a_err(dev_from_gk20a(g), | 145 | gk20a_err(dev_from_gk20a(g), |
144 | "Single bit error detected in GPU L2!"); | 146 | "Single bit error detected in GPU L2!"); |
147 | |||
148 | ecc_stats_reg_val = | ||
149 | gk20a_readl(g, | ||
150 | ltc_ltc0_lts0_dstg_ecc_report_r() + offset); | ||
151 | g->gr.t18x.ecc_stats.l2_sec_count.counters[ltc] += | ||
152 | ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(ecc_stats_reg_val); | ||
153 | ecc_stats_reg_val &= | ||
154 | ~(ltc_ltc0_lts0_dstg_ecc_report_sec_count_m()); | ||
155 | gk20a_writel(g, | ||
156 | ltc_ltc0_lts0_dstg_ecc_report_r() + offset, | ||
157 | ecc_stats_reg_val); | ||
158 | |||
145 | g->ops.mm.l2_flush(g, true); | 159 | g->ops.mm.l2_flush(g, true); |
146 | } | 160 | } |
147 | if (ltc_intr & | 161 | if (ltc_intr & |
148 | ltc_ltcs_ltss_intr_ecc_ded_error_pending_f()) { | 162 | ltc_ltcs_ltss_intr_ecc_ded_error_pending_f()) { |
163 | u32 ecc_stats_reg_val; | ||
164 | |||
149 | gk20a_err(dev_from_gk20a(g), | 165 | gk20a_err(dev_from_gk20a(g), |
150 | "Double bit error detected in GPU L2!"); | 166 | "Double bit error detected in GPU L2!"); |
167 | |||
168 | ecc_stats_reg_val = | ||
169 | gk20a_readl(g, | ||
170 | ltc_ltc0_lts0_dstg_ecc_report_r() + offset); | ||
171 | g->gr.t18x.ecc_stats.l2_ded_count.counters[ltc] += | ||
172 | ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(ecc_stats_reg_val); | ||
173 | ecc_stats_reg_val &= | ||
174 | ~(ltc_ltc0_lts0_dstg_ecc_report_ded_count_m()); | ||
175 | gk20a_writel(g, | ||
176 | ltc_ltc0_lts0_dstg_ecc_report_r() + offset, | ||
177 | ecc_stats_reg_val); | ||
151 | } | 178 | } |
152 | 179 | ||
153 | gk20a_err(dev_from_gk20a(g), "ltc%d, slice %d: %08x", | 180 | gk20a_err(dev_from_gk20a(g), "ltc%d, slice %d: %08x", |