summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c')
-rw-r--r--drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c b/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c
new file mode 100644
index 00000000..b780457f
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c
@@ -0,0 +1,112 @@
1/*
2 * GP10B priv ring
3 *
4 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26
27#include <nvgpu/log.h>
28#include <nvgpu/timers.h>
29#include <nvgpu/enabled.h>
30
31#include <nvgpu/hw/gp10b/hw_mc_gp10b.h>
32#include <nvgpu/hw/gp10b/hw_pri_ringmaster_gp10b.h>
33#include <nvgpu/hw/gp10b/hw_pri_ringstation_sys_gp10b.h>
34#include <nvgpu/hw/gp10b/hw_pri_ringstation_gpc_gp10b.h>
35
36void gp10b_priv_ring_isr(struct gk20a *g)
37{
38 u32 status0, status1;
39 u32 cmd;
40 s32 retry = 100;
41 u32 gpc;
42 u32 gpc_stride, offset;
43
44 if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
45 nvgpu_info(g, "unhandled priv ring intr");
46 return;
47 }
48
49 status0 = gk20a_readl(g, pri_ringmaster_intr_status0_r());
50 status1 = gk20a_readl(g, pri_ringmaster_intr_status1_r());
51
52 nvgpu_err(g, "ringmaster intr status0: 0x%08x,"
53 "status1: 0x%08x", status0, status1);
54
55 if (pri_ringmaster_intr_status0_ring_start_conn_fault_v(status0) != 0)
56 nvgpu_err(g,
57 "BUG: connectivity problem on the startup sequence");
58
59 if (pri_ringmaster_intr_status0_disconnect_fault_v(status0) != 0)
60 nvgpu_err(g, "ring disconnected");
61
62 if (pri_ringmaster_intr_status0_overflow_fault_v(status0) != 0)
63 nvgpu_err(g, "ring overflowed");
64
65 if (pri_ringmaster_intr_status0_gbl_write_error_sys_v(status0) != 0) {
66 nvgpu_err(g, "SYS write error. ADR %08x WRDAT %08x INFO %08x, CODE %08x",
67 gk20a_readl(g, pri_ringstation_sys_priv_error_adr_r()),
68 gk20a_readl(g, pri_ringstation_sys_priv_error_wrdat_r()),
69 gk20a_readl(g, pri_ringstation_sys_priv_error_info_r()),
70 gk20a_readl(g, pri_ringstation_sys_priv_error_code_r()));
71 }
72
73 if (status1) {
74 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
75 for (gpc = 0; gpc < g->gr.gpc_count; gpc++) {
76 offset = gpc * gpc_stride;
77 if (status1 & BIT(gpc)) {
78 nvgpu_err(g, "GPC%u write error. ADR %08x "
79 "WRDAT %08x INFO %08x, CODE %08x", gpc,
80 gk20a_readl(g,
81 pri_ringstation_gpc_gpc0_priv_error_adr_r() + offset),
82 gk20a_readl(g,
83 pri_ringstation_gpc_gpc0_priv_error_wrdat_r() + offset),
84 gk20a_readl(g,
85 pri_ringstation_gpc_gpc0_priv_error_info_r() + offset),
86 gk20a_readl(g,
87 pri_ringstation_gpc_gpc0_priv_error_code_r() + offset));
88 status1 = status1 & (~(BIT(gpc)));
89 if (!status1)
90 break;
91 }
92 }
93 }
94 /* clear interrupt */
95 cmd = gk20a_readl(g, pri_ringmaster_command_r());
96 cmd = set_field(cmd, pri_ringmaster_command_cmd_m(),
97 pri_ringmaster_command_cmd_ack_interrupt_f());
98 gk20a_writel(g, pri_ringmaster_command_r(), cmd);
99
100 /* poll for clear interrupt done */
101 cmd = pri_ringmaster_command_cmd_v(
102 gk20a_readl(g, pri_ringmaster_command_r()));
103 while (cmd != pri_ringmaster_command_cmd_no_cmd_v() && retry) {
104 nvgpu_udelay(20);
105 cmd = pri_ringmaster_command_cmd_v(
106 gk20a_readl(g, pri_ringmaster_command_r()));
107 retry--;
108 }
109
110 if (retry == 0)
111 nvgpu_err(g, "priv ringmaster intr ack failed");
112}