diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-05-12 21:54:05 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-06-30 23:44:32 -0400 |
commit | fec43a722abd3cec0cc730b4257771860706f8b7 (patch) | |
tree | 436ce0745646f254fca9f6fb797655e4f1323fe9 | |
parent | 16b133df331459004cf77b9b82f68ff3a2bef2be (diff) |
drm/nvc0/gr: port mp trap handling from calim's kepler code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index f9b9d82c287f..af40e654ac89 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | |||
@@ -237,6 +237,43 @@ nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv) | |||
237 | nv_wr32(priv, 0x409c20, ustat); | 237 | nv_wr32(priv, 0x409c20, ustat); |
238 | } | 238 | } |
239 | 239 | ||
240 | static const struct nouveau_enum nvc0_mp_warp_error[] = { | ||
241 | { 0x00, "NO_ERROR" }, | ||
242 | { 0x01, "STACK_MISMATCH" }, | ||
243 | { 0x05, "MISALIGNED_PC" }, | ||
244 | { 0x08, "MISALIGNED_GPR" }, | ||
245 | { 0x09, "INVALID_OPCODE" }, | ||
246 | { 0x0d, "GPR_OUT_OF_BOUNDS" }, | ||
247 | { 0x0e, "MEM_OUT_OF_BOUNDS" }, | ||
248 | { 0x0f, "UNALIGNED_MEM_ACCESS" }, | ||
249 | { 0x11, "INVALID_PARAM" }, | ||
250 | {} | ||
251 | }; | ||
252 | |||
253 | static const struct nouveau_bitfield nvc0_mp_global_error[] = { | ||
254 | { 0x00000004, "MULTIPLE_WARP_ERRORS" }, | ||
255 | { 0x00000008, "OUT_OF_STACK_SPACE" }, | ||
256 | {} | ||
257 | }; | ||
258 | |||
259 | static void | ||
260 | nvc0_graph_trap_mp(struct nvc0_graph_priv *priv, int gpc, int tpc) | ||
261 | { | ||
262 | u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x648)); | ||
263 | u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x650)); | ||
264 | |||
265 | nv_error(priv, "GPC%i/TPC%i/MP trap:", gpc, tpc); | ||
266 | nouveau_bitfield_print(nvc0_mp_global_error, gerr); | ||
267 | if (werr) { | ||
268 | pr_cont(" "); | ||
269 | nouveau_enum_print(nvc0_mp_warp_error, werr & 0xffff); | ||
270 | } | ||
271 | pr_cont("\n"); | ||
272 | |||
273 | nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x648), 0x00000000); | ||
274 | nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x650), gerr); | ||
275 | } | ||
276 | |||
240 | static void | 277 | static void |
241 | nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc) | 278 | nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc) |
242 | { | 279 | { |
@@ -251,12 +288,7 @@ nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc) | |||
251 | } | 288 | } |
252 | 289 | ||
253 | if (stat & 0x00000002) { | 290 | if (stat & 0x00000002) { |
254 | u32 trap0 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0644)); | 291 | nvc0_graph_trap_mp(priv, gpc, tpc); |
255 | u32 trap1 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x064c)); | ||
256 | nv_error(priv, "GPC%d/TPC%d/MP: 0x%08x 0x%08x\n", | ||
257 | gpc, tpc, trap0, trap1); | ||
258 | nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0644), 0x001ffffe); | ||
259 | nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x064c), 0x0000000f); | ||
260 | nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000002); | 292 | nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000002); |
261 | stat &= ~0x00000002; | 293 | stat &= ~0x00000002; |
262 | } | 294 | } |