summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2015-03-16 13:00:32 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-04-04 22:00:44 -0400
commit78d8f8fe366d521e1acb62a96ca5f0d72e15c8f5 (patch)
treee061e1aa42b10bd0bb3b1293770626106edea765 /drivers/gpu/nvgpu
parent1eded552869f6957bec7695554752e26391daaee (diff)
gpu: nvgpu: Cache channel state before dumping
Split channel debug dump into two phases. In first phase we just copy the data to a temporary buffer, and in second phase we dump the state from the temporary buffer. Change-Id: I2578b9fdaaa76f1230df7badbca9fcb5f3854e56 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/717886 Reviewed-by: Konsta Holtta <kholtta@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/debug_gk20a.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/debug_gk20a.c b/drivers/gpu/nvgpu/gk20a/debug_gk20a.c
index ace05c07..2c37d22d 100644
--- a/drivers/gpu/nvgpu/gk20a/debug_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/debug_gk20a.c
@@ -34,6 +34,11 @@
34unsigned int gk20a_debug_trace_cmdbuf; 34unsigned int gk20a_debug_trace_cmdbuf;
35static struct platform_device *gk20a_device; 35static struct platform_device *gk20a_device;
36 36
37struct ch_state {
38 int pid;
39 u8 inst_block[0];
40};
41
37static const char * const ccsr_chan_status_str[] = { 42static const char * const ccsr_chan_status_str[] = {
38 "idle", 43 "idle",
39 "pending", 44 "pending",
@@ -97,23 +102,25 @@ void gk20a_debug_output(struct gk20a_debug_output *o,
97 102
98static void gk20a_debug_show_channel(struct gk20a *g, 103static void gk20a_debug_show_channel(struct gk20a *g,
99 struct gk20a_debug_output *o, 104 struct gk20a_debug_output *o,
100 struct channel_gk20a *ch) 105 u32 hw_chid,
106 struct ch_state *ch_state)
101{ 107{
102 u32 channel = gk20a_readl(g, ccsr_channel_r(ch->hw_chid)); 108 u32 channel = gk20a_readl(g, ccsr_channel_r(hw_chid));
103 u32 status = ccsr_channel_status_v(channel); 109 u32 status = ccsr_channel_status_v(channel);
104 u32 syncpointa, syncpointb; 110 u32 syncpointa, syncpointb;
105 void *inst_ptr; 111 void *inst_ptr;
106 112
107 inst_ptr = ch->inst_block.cpu_va; 113 if (!ch_state)
108 if (!inst_ptr)
109 return; 114 return;
110 115
116 inst_ptr = &ch_state->inst_block[0];
117
111 syncpointa = gk20a_mem_rd32(inst_ptr, ram_fc_syncpointa_w()); 118 syncpointa = gk20a_mem_rd32(inst_ptr, ram_fc_syncpointa_w());
112 syncpointb = gk20a_mem_rd32(inst_ptr, ram_fc_syncpointb_w()); 119 syncpointb = gk20a_mem_rd32(inst_ptr, ram_fc_syncpointb_w());
113 120
114 gk20a_debug_output(o, "%d-%s, pid %d: ", ch->hw_chid, 121 gk20a_debug_output(o, "%d-%s, pid %d: ", hw_chid,
115 ch->g->dev->name, 122 g->dev->name,
116 ch->pid); 123 ch_state->pid);
117 gk20a_debug_output(o, "%s in use %s %s\n", 124 gk20a_debug_output(o, "%s in use %s %s\n",
118 ccsr_channel_enable_v(channel) ? "" : "not", 125 ccsr_channel_enable_v(channel) ? "" : "not",
119 ccsr_chan_status_str[status], 126 ccsr_chan_status_str[status],
@@ -160,6 +167,8 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o)
160 u32 chid; 167 u32 chid;
161 int i, err; 168 int i, err;
162 169
170 struct ch_state **ch_state;
171
163 err = gk20a_busy(g->dev); 172 err = gk20a_busy(g->dev);
164 if (err) { 173 if (err) {
165 gk20a_debug_output(o, "failed to power on gpu: %d\n", err); 174 gk20a_debug_output(o, "failed to power on gpu: %d\n", err);
@@ -214,12 +223,34 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o)
214 } 223 }
215 gk20a_debug_output(o, "\n"); 224 gk20a_debug_output(o, "\n");
216 225
226 ch_state = kzalloc(sizeof(*ch_state)
227 * f->num_channels, GFP_KERNEL);
228 if (!ch_state) {
229 gk20a_debug_output(o, "cannot alloc memory for channels\n");
230 goto done;
231 }
232
233 for (chid = 0; chid < f->num_channels; chid++) {
234 if (f->channel[chid].in_use)
235 ch_state[chid] = kmalloc(sizeof(struct ch_state) + ram_in_alloc_size_v(), GFP_KERNEL);
236 }
237
238 for (chid = 0; chid < f->num_channels; chid++) {
239 if (ch_state[chid] && f->channel[chid].inst_block.cpu_va) {
240 ch_state[chid]->pid = f->channel[chid].pid;
241 memcpy(&ch_state[chid]->inst_block[0],
242 f->channel[chid].inst_block.cpu_va,
243 ram_in_alloc_size_v());
244 }
245 }
217 for (chid = 0; chid < f->num_channels; chid++) { 246 for (chid = 0; chid < f->num_channels; chid++) {
218 if (f->channel[chid].in_use) { 247 if (ch_state[chid]) {
219 struct channel_gk20a *gpu_ch = &f->channel[chid]; 248 gk20a_debug_show_channel(g, o, chid, ch_state[chid]);
220 gk20a_debug_show_channel(g, o, gpu_ch); 249 kfree(ch_state[chid]);
221 } 250 }
222 } 251 }
252 kfree(ch_state);
253done:
223 gk20a_idle(g->dev); 254 gk20a_idle(g->dev);
224} 255}
225 256