diff options
author | David Nieto <dmartineznie@nvidia.com> | 2017-05-05 17:22:06 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-05-11 09:04:33 -0400 |
commit | 8c246cb18df28bac83297df2c9d0c47725b94273 (patch) | |
tree | f0bc4bdd963b14ccafc9c888dd65d3485bb9bf5b /drivers/gpu/nvgpu/gv11b | |
parent | 44dcc5a53fabc68a32f16a1a3a46a2582b5b192b (diff) |
gpu: nvgpu: gv11b: MMU parity HWW error intr
Adding support for ISR handling of ecc uncorrectable errors
for volta resiliency (Volta-686)
TODO: move interrupt init out of MC
bug 1881052
JIRA: GPUT19X-82
Change-Id: I45db01a6062445dd1f64a8297744cd15105e3344
Signed-off-by: David Nieto <dmartineznie@nvidia.com>
Reviewed-on: http://git-master/r/1476603
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gv11b')
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/fb_gv11b.c | 136 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/fb_gv11b.h | 29 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/mc_gv11b.c | 5 |
3 files changed, 161 insertions, 9 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/fb_gv11b.c b/drivers/gpu/nvgpu/gv11b/fb_gv11b.c index 98aad4e0..c3524953 100644 --- a/drivers/gpu/nvgpu/gv11b/fb_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/fb_gv11b.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <nvgpu/hw/gv11b/hw_mc_gv11b.h> | 27 | #include <nvgpu/hw/gv11b/hw_mc_gv11b.h> |
28 | #include <nvgpu/hw/gv11b/hw_fifo_gv11b.h> | 28 | #include <nvgpu/hw/gv11b/hw_fifo_gv11b.h> |
29 | 29 | ||
30 | #include <nvgpu/log.h> | ||
31 | |||
30 | static void gv11b_init_nvlink_soc_credits(struct gk20a *g) | 32 | static void gv11b_init_nvlink_soc_credits(struct gk20a *g) |
31 | { | 33 | { |
32 | void __iomem *soc1 = ioremap(0x02b10010, 4096); | 34 | void __iomem *soc1 = ioremap(0x02b10010, 4096); |
@@ -34,7 +36,7 @@ static void gv11b_init_nvlink_soc_credits(struct gk20a *g) | |||
34 | void __iomem *soc3 = ioremap(0x02b30010, 4096); | 36 | void __iomem *soc3 = ioremap(0x02b30010, 4096); |
35 | void __iomem *soc4 = ioremap(0x02b40010, 4096); | 37 | void __iomem *soc4 = ioremap(0x02b40010, 4096); |
36 | 38 | ||
37 | gk20a_dbg_info("init nvlink soc credits"); | 39 | nvgpu_info(g, "init nvlink soc credits"); |
38 | 40 | ||
39 | writel_relaxed(0x14050000, soc1); | 41 | writel_relaxed(0x14050000, soc1); |
40 | writel_relaxed(0x08020000, soc1 + 4); | 42 | writel_relaxed(0x08020000, soc1 + 4); |
@@ -51,7 +53,7 @@ static void gv11b_fb_reset(struct gk20a *g) | |||
51 | { | 53 | { |
52 | u32 val; | 54 | u32 val; |
53 | 55 | ||
54 | gk20a_dbg_info("reset gv11b fb"); | 56 | nvgpu_info(g, "reset gv11b fb"); |
55 | 57 | ||
56 | g->ops.mc.reset(g, mc_enable_pfb_enabled_f() | | 58 | g->ops.mc.reset(g, mc_enable_pfb_enabled_f() | |
57 | mc_enable_l2_enabled_f() | | 59 | mc_enable_l2_enabled_f() | |
@@ -69,14 +71,14 @@ static void gv11b_fb_reset(struct gk20a *g) | |||
69 | gv11b_init_nvlink_soc_credits(g); | 71 | gv11b_init_nvlink_soc_credits(g); |
70 | 72 | ||
71 | val = gk20a_readl(g, fifo_fb_iface_r()); | 73 | val = gk20a_readl(g, fifo_fb_iface_r()); |
72 | gk20a_dbg_info("fifo_fb_iface val = 0x%x", val); | 74 | nvgpu_info(g, "fifo_fb_iface val = 0x%x", val); |
73 | if (!(val & fifo_fb_iface_control_enable_f() && | 75 | if (!(val & fifo_fb_iface_control_enable_f() && |
74 | val & fifo_fb_iface_status_enabled_f())) { | 76 | val & fifo_fb_iface_status_enabled_f())) { |
75 | gk20a_dbg_info("fifo_fb_iface set control enable"); | 77 | nvgpu_info(g, "fifo_fb_iface set control enable"); |
76 | gk20a_writel(g, fifo_fb_iface_r(), | 78 | gk20a_writel(g, fifo_fb_iface_r(), |
77 | fifo_fb_iface_control_enable_f()); | 79 | fifo_fb_iface_control_enable_f()); |
78 | val = gk20a_readl(g, fifo_fb_iface_r()); | 80 | val = gk20a_readl(g, fifo_fb_iface_r()); |
79 | gk20a_dbg_info("fifo_fb_iface val = 0x%x", val); | 81 | nvgpu_info(g, "fifo_fb_iface val = 0x%x", val); |
80 | } | 82 | } |
81 | } | 83 | } |
82 | 84 | ||
@@ -129,19 +131,137 @@ static void gv11b_init_kind_attr(void) | |||
129 | } | 131 | } |
130 | } | 132 | } |
131 | 133 | ||
134 | static void gv11b_fb_intr_en_set(struct gk20a *g, | ||
135 | unsigned int index, u32 mask) | ||
136 | { | ||
137 | u32 reg_val; | ||
138 | |||
139 | reg_val = gk20a_readl(g, fb_niso_intr_en_set_r(index)); | ||
140 | reg_val |= mask; | ||
141 | gk20a_writel(g, fb_niso_intr_en_set_r(index), reg_val); | ||
142 | } | ||
143 | |||
144 | static void gv11b_fb_intr_en_clr(struct gk20a *g, | ||
145 | unsigned int index, u32 mask) | ||
146 | { | ||
147 | u32 reg_val; | ||
148 | |||
149 | reg_val = gk20a_readl(g, fb_niso_intr_en_clr_r(index)); | ||
150 | reg_val |= mask; | ||
151 | gk20a_writel(g, fb_niso_intr_en_clr_r(index), reg_val); | ||
152 | } | ||
153 | |||
154 | static u32 gv11b_fb_get_hub_intr_clr_mask(struct gk20a *g, | ||
155 | unsigned int intr_type) | ||
156 | { | ||
157 | u32 mask = 0; | ||
158 | |||
159 | if (intr_type == HUB_INTR_TYPE_ALL) { | ||
160 | mask |= | ||
161 | fb_niso_intr_en_clr_mmu_ecc_uncorrected_error_notify_set_f(); | ||
162 | return mask; | ||
163 | } | ||
164 | |||
165 | if (intr_type & HUB_INTR_TYPE_ECC_UNCORRECTED) { | ||
166 | mask |= | ||
167 | fb_niso_intr_en_clr_mmu_ecc_uncorrected_error_notify_set_f(); | ||
168 | } | ||
169 | |||
170 | return mask; | ||
171 | } | ||
172 | |||
173 | static u32 gv11b_fb_get_hub_intr_en_mask(struct gk20a *g, | ||
174 | unsigned int intr_type) | ||
175 | { | ||
176 | u32 mask = 0; | ||
177 | |||
178 | if (intr_type == HUB_INTR_TYPE_ALL) { | ||
179 | mask |= | ||
180 | fb_niso_intr_en_set_mmu_ecc_uncorrected_error_notify_set_f(); | ||
181 | return mask; | ||
182 | } | ||
183 | |||
184 | if (intr_type & HUB_INTR_TYPE_ECC_UNCORRECTED) { | ||
185 | mask |= | ||
186 | fb_niso_intr_en_set_mmu_ecc_uncorrected_error_notify_set_f(); | ||
187 | } | ||
188 | |||
189 | return mask; | ||
190 | } | ||
191 | |||
192 | void gv11b_fb_enable_hub_intr(struct gk20a *g, | ||
193 | unsigned int index, unsigned int intr_type) | ||
194 | { | ||
195 | u32 mask = 0; | ||
196 | |||
197 | mask = gv11b_fb_get_hub_intr_en_mask(g, intr_type); | ||
198 | |||
199 | if (mask) | ||
200 | gv11b_fb_intr_en_set(g, index, mask); | ||
201 | } | ||
202 | |||
203 | void gv11b_fb_disable_hub_intr(struct gk20a *g, | ||
204 | unsigned int index, unsigned int intr_type) | ||
205 | { | ||
206 | u32 mask = 0; | ||
207 | |||
208 | mask = gv11b_fb_get_hub_intr_clr_mask(g, intr_type); | ||
209 | |||
210 | if (mask) | ||
211 | gv11b_fb_intr_en_clr(g, index, mask); | ||
212 | } | ||
213 | |||
132 | static void gv11b_fb_hub_isr(struct gk20a *g) | 214 | static void gv11b_fb_hub_isr(struct gk20a *g) |
133 | { | 215 | { |
216 | u32 status; | ||
134 | u32 niso_intr = gk20a_readl(g, fb_niso_intr_r()); | 217 | u32 niso_intr = gk20a_readl(g, fb_niso_intr_r()); |
135 | 218 | ||
136 | gk20a_dbg_info("enter hub isr, niso_intr = 0x%x", niso_intr); | 219 | nvgpu_info(g, "enter hub isr, niso_intr = 0x%x", niso_intr); |
137 | 220 | ||
138 | if (niso_intr & | 221 | if (niso_intr & |
139 | (fb_niso_intr_hub_access_counter_notify_pending_f() | | 222 | (fb_niso_intr_hub_access_counter_notify_pending_f() | |
140 | fb_niso_intr_hub_access_counter_error_pending_f())) { | 223 | fb_niso_intr_hub_access_counter_error_pending_f())) { |
141 | 224 | ||
142 | gk20a_dbg_info("hub access counter notify/error"); | 225 | nvgpu_info(g, "hub access counter notify/error"); |
226 | } else if (niso_intr & | ||
227 | fb_niso_intr_mmu_ecc_uncorrected_error_notify_pending_f()) { | ||
228 | |||
229 | nvgpu_info(g, "ecc uncorrected error notify"); | ||
230 | |||
231 | /* disable interrupts during handling */ | ||
232 | gv11b_fb_disable_hub_intr(g, STALL_REG_INDEX, | ||
233 | HUB_INTR_TYPE_ECC_UNCORRECTED); | ||
234 | |||
235 | status = gk20a_readl(g, fb_mmu_l2tlb_ecc_status_r()); | ||
236 | if (status) { | ||
237 | nvgpu_info(g, "hub mmu L2 ecc status: 0x%x", | ||
238 | status); | ||
239 | gk20a_writel(g, fb_mmu_l2tlb_ecc_status_r(), | ||
240 | fb_mmu_l2tlb_ecc_status_reset_clear_f()); | ||
241 | } | ||
242 | |||
243 | status = gk20a_readl(g, fb_mmu_hubtlb_ecc_status_r()); | ||
244 | if (status) { | ||
245 | nvgpu_info(g, "hub mmu hub tlb ecc status: 0x%x", | ||
246 | status); | ||
247 | gk20a_writel(g, fb_mmu_hubtlb_ecc_status_r(), | ||
248 | fb_mmu_hubtlb_ecc_status_reset_clear_f()); | ||
249 | } | ||
250 | |||
251 | status = gk20a_readl(g, fb_mmu_fillunit_ecc_status_r()); | ||
252 | if (status) { | ||
253 | nvgpu_info(g, "hub mmu fill unit ecc status: 0x%x", | ||
254 | status); | ||
255 | gk20a_writel(g, fb_mmu_fillunit_ecc_status_r(), | ||
256 | fb_mmu_fillunit_ecc_status_reset_clear_f()); | ||
257 | } | ||
258 | |||
259 | /* re-enable interrupts after handling */ | ||
260 | gv11b_fb_enable_hub_intr(g, STALL_REG_INDEX, | ||
261 | HUB_INTR_TYPE_ECC_UNCORRECTED); | ||
262 | |||
143 | } else { | 263 | } else { |
144 | gk20a_dbg_info("mmu fault : TODO"); | 264 | nvgpu_info(g, "mmu fault : TODO"); |
145 | } | 265 | } |
146 | } | 266 | } |
147 | 267 | ||
diff --git a/drivers/gpu/nvgpu/gv11b/fb_gv11b.h b/drivers/gpu/nvgpu/gv11b/fb_gv11b.h index ab688aba..eff3c25d 100644 --- a/drivers/gpu/nvgpu/gv11b/fb_gv11b.h +++ b/drivers/gpu/nvgpu/gv11b/fb_gv11b.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * GV11B FB | 2 | * GV11B FB |
3 | * | 3 | * |
4 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
@@ -17,5 +17,32 @@ | |||
17 | #define _NVGPU_GV11B_FB | 17 | #define _NVGPU_GV11B_FB |
18 | struct gpu_ops; | 18 | struct gpu_ops; |
19 | 19 | ||
20 | #define STALL_REG_INDEX 0 | ||
21 | #define NONSTALL_REG_INDEX 1 | ||
22 | |||
23 | #define NONREPLAY_REG_INDEX 0 | ||
24 | #define REPLAY_REG_INDEX 1 | ||
25 | |||
26 | #define FAULT_BUF_DISABLED 0 | ||
27 | #define FAULT_BUF_ENABLED 1 | ||
28 | |||
29 | #define FAULT_BUF_VALID 1 | ||
30 | #define CHECK_NEXT_FAULT_BUF 1 | ||
31 | |||
32 | #define HUB_INTR_TYPE_OTHER 1 /* bit 0 */ | ||
33 | #define HUB_INTR_TYPE_NONREPLAY 2 /* bit 1 */ | ||
34 | #define HUB_INTR_TYPE_REPLAY 4 /* bit 2 */ | ||
35 | #define HUB_INTR_TYPE_ECC_UNCORRECTED 8 /* bit 3 */ | ||
36 | #define HUB_INTR_TYPE_ACCESS_COUNTER 16 /* bit 4 */ | ||
37 | #define HUB_INTR_TYPE_ALL (HUB_INTR_TYPE_OTHER | \ | ||
38 | HUB_INTR_TYPE_NONREPLAY | \ | ||
39 | HUB_INTR_TYPE_REPLAY | \ | ||
40 | HUB_INTR_TYPE_ECC_UNCORRECTED | \ | ||
41 | HUB_INTR_TYPE_ACCESS_COUNTER) | ||
42 | |||
43 | void gv11b_fb_enable_hub_intr(struct gk20a *g, | ||
44 | unsigned int index, unsigned int intr_type); | ||
45 | void gv11b_fb_disable_hub_intr(struct gk20a *g, | ||
46 | unsigned int index, unsigned int intr_type); | ||
20 | void gv11b_init_fb(struct gpu_ops *gops); | 47 | void gv11b_init_fb(struct gpu_ops *gops); |
21 | #endif | 48 | #endif |
diff --git a/drivers/gpu/nvgpu/gv11b/mc_gv11b.c b/drivers/gpu/nvgpu/gv11b/mc_gv11b.c index c901fd76..8b8fcea0 100644 --- a/drivers/gpu/nvgpu/gv11b/mc_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/mc_gv11b.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "gp10b/mc_gp10b.h" | 20 | #include "gp10b/mc_gp10b.h" |
21 | 21 | ||
22 | #include "mc_gv11b.h" | 22 | #include "mc_gv11b.h" |
23 | #include "fb_gv11b.h" | ||
23 | 24 | ||
24 | #include <nvgpu/hw/gv11b/hw_mc_gv11b.h> | 25 | #include <nvgpu/hw/gv11b/hw_mc_gv11b.h> |
25 | 26 | ||
@@ -47,6 +48,10 @@ static void mc_gv11b_intr_enable(struct gk20a *g) | |||
47 | | eng_intr_mask; | 48 | | eng_intr_mask; |
48 | gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_NONSTALLING), | 49 | gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_NONSTALLING), |
49 | g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_NONSTALLING]); | 50 | g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_NONSTALLING]); |
51 | |||
52 | /* TODO: Enable PRI faults for HUB ECC err intr */ | ||
53 | gv11b_fb_enable_hub_intr(g, STALL_REG_INDEX, | ||
54 | HUB_INTR_TYPE_ECC_UNCORRECTED); | ||
50 | } | 55 | } |
51 | 56 | ||
52 | static bool gv11b_mc_is_intr_hub_pending(struct gk20a *g, u32 mc_intr_0) | 57 | static bool gv11b_mc_is_intr_hub_pending(struct gk20a *g, u32 mc_intr_0) |