diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2015-01-28 08:07:00 -0500 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-04-04 21:07:03 -0400 |
commit | bc1b5fdd56fff2a64a78b4a190897e34f9f08845 (patch) | |
tree | f37841e278840df2c71126a4e0eddd68d69c3aa0 /drivers/gpu/nvgpu/gk20a/debug_gk20a.c | |
parent | aa96b6bd1efa1e26a757080137486884972d248c (diff) |
gpu: nvgpu: APIs to dump GR status
Add below APIs to dump various GR status registers
1. debugfs : /d/gpu.0/gr_status
Read this debugfs at runtime to get status registers
2. API gk20a_gr_debug_dump()
Add this API in code to dump registers at any point
Bug 200062436
Change-Id: Ic1115b5a2fc16362954b5ed8a9e70afb872a8d91
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/486465
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/debug_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/debug_gk20a.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/debug_gk20a.c b/drivers/gpu/nvgpu/gk20a/debug_gk20a.c index 1351304d..9dfab370 100644 --- a/drivers/gpu/nvgpu/gk20a/debug_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/debug_gk20a.c | |||
@@ -83,7 +83,7 @@ static inline void gk20a_debug_write_to_seqfile(void *ctx, const char *str, | |||
83 | seq_write((struct seq_file *)ctx, str, len); | 83 | seq_write((struct seq_file *)ctx, str, len); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void gk20a_debug_output(struct gk20a_debug_output *o, | 86 | void gk20a_debug_output(struct gk20a_debug_output *o, |
87 | const char *fmt, ...) | 87 | const char *fmt, ...) |
88 | { | 88 | { |
89 | va_list args; | 89 | va_list args; |
@@ -223,6 +223,50 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o) | |||
223 | gk20a_idle(g->dev); | 223 | gk20a_idle(g->dev); |
224 | } | 224 | } |
225 | 225 | ||
226 | static int gk20a_gr_dump_regs(struct platform_device *pdev, | ||
227 | struct gk20a_debug_output *o) | ||
228 | { | ||
229 | struct gk20a_platform *platform = gk20a_get_platform(pdev); | ||
230 | struct gk20a *g = platform->g; | ||
231 | int err; | ||
232 | |||
233 | err = gk20a_busy(g->dev); | ||
234 | if (err) { | ||
235 | gk20a_err(&pdev->dev, "failed to power on gpu: %d\n", err); | ||
236 | return -EINVAL; | ||
237 | } | ||
238 | |||
239 | gr_gk20a_elpg_protected_call(g, g->ops.gr.dump_gr_regs(g, o)); | ||
240 | |||
241 | gk20a_idle(g->dev); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | int gk20a_gr_debug_dump(struct platform_device *pdev) | ||
247 | { | ||
248 | struct gk20a_debug_output o = { | ||
249 | .fn = gk20a_debug_write_printk | ||
250 | }; | ||
251 | |||
252 | gk20a_gr_dump_regs(pdev, &o); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static int gk20a_gr_debug_show(struct seq_file *s, void *unused) | ||
258 | { | ||
259 | struct platform_device *pdev = s->private; | ||
260 | struct gk20a_debug_output o = { | ||
261 | .fn = gk20a_debug_write_to_seqfile, | ||
262 | .ctx = s, | ||
263 | }; | ||
264 | |||
265 | gk20a_gr_dump_regs(pdev, &o); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
226 | void gk20a_debug_dump(struct platform_device *pdev) | 270 | void gk20a_debug_dump(struct platform_device *pdev) |
227 | { | 271 | { |
228 | struct gk20a_platform *platform = gk20a_get_platform(pdev); | 272 | struct gk20a_platform *platform = gk20a_get_platform(pdev); |
@@ -277,11 +321,23 @@ static int gk20a_debug_show(struct seq_file *s, void *unused) | |||
277 | return 0; | 321 | return 0; |
278 | } | 322 | } |
279 | 323 | ||
324 | static int gk20a_gr_debug_open(struct inode *inode, struct file *file) | ||
325 | { | ||
326 | return single_open(file, gk20a_gr_debug_show, inode->i_private); | ||
327 | } | ||
328 | |||
280 | static int gk20a_debug_open(struct inode *inode, struct file *file) | 329 | static int gk20a_debug_open(struct inode *inode, struct file *file) |
281 | { | 330 | { |
282 | return single_open(file, gk20a_debug_show, inode->i_private); | 331 | return single_open(file, gk20a_debug_show, inode->i_private); |
283 | } | 332 | } |
284 | 333 | ||
334 | static const struct file_operations gk20a_gr_debug_fops = { | ||
335 | .open = gk20a_gr_debug_open, | ||
336 | .read = seq_read, | ||
337 | .llseek = seq_lseek, | ||
338 | .release = single_release, | ||
339 | }; | ||
340 | |||
285 | static const struct file_operations gk20a_debug_fops = { | 341 | static const struct file_operations gk20a_debug_fops = { |
286 | .open = gk20a_debug_open, | 342 | .open = gk20a_debug_open, |
287 | .read = seq_read, | 343 | .read = seq_read, |
@@ -306,6 +362,8 @@ void gk20a_debug_init(struct platform_device *pdev) | |||
306 | 362 | ||
307 | debugfs_create_file("status", S_IRUGO, platform->debugfs, | 363 | debugfs_create_file("status", S_IRUGO, platform->debugfs, |
308 | pdev, &gk20a_debug_fops); | 364 | pdev, &gk20a_debug_fops); |
365 | debugfs_create_file("gr_status", S_IRUGO, platform->debugfs, | ||
366 | pdev, &gk20a_gr_debug_fops); | ||
309 | debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR, platform->debugfs, | 367 | debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR, platform->debugfs, |
310 | &gk20a_debug_trace_cmdbuf); | 368 | &gk20a_debug_trace_cmdbuf); |
311 | 369 | ||