From e93a4ca50b6b24d3db1f8fdc0e5030fecb5ea8d2 Mon Sep 17 00:00:00 2001 From: Nitin Kumbhar Date: Tue, 4 Sep 2018 16:19:47 +0530 Subject: gpu: nvgpu: move fecs trace debugfs to linux Add fecs trace debugfs initialization as an os op. The debugfs nodes are set up for gpu versions which call gk20a_fecs_trace_init(). JIRA NVGPU-602 Change-Id: I606ec31acbf04f633500be4c342db32f3f537794 Signed-off-by: Nitin Kumbhar Reviewed-on: https://git-master.nvidia.com/r/1812449 Reviewed-by: Deepak Nibade GVS: Gerrit_Virtual_Submit Reviewed-by: svc-misra-checker Reviewed-by: Alex Waterman Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/Makefile | 7 + drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c | 188 ++------------------------ drivers/gpu/nvgpu/include/nvgpu/fecs_trace.h | 60 ++++++++ drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c | 154 +++++++++++++++++++++ drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h | 30 ++++ drivers/gpu/nvgpu/os/linux/module.c | 8 ++ drivers/gpu/nvgpu/os/linux/os_linux.h | 4 + drivers/gpu/nvgpu/os/linux/os_ops.c | 4 + drivers/gpu/nvgpu/os/linux/os_ops_gp106.c | 5 + drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c | 5 + drivers/gpu/nvgpu/os/linux/os_ops_gv100.c | 5 + drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c | 30 ++++ drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h | 24 ++++ 13 files changed, 349 insertions(+), 175 deletions(-) create mode 100644 drivers/gpu/nvgpu/include/nvgpu/fecs_trace.h create mode 100644 drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c create mode 100644 drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h create mode 100644 drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c create mode 100644 drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index a3372cef..3b6a022a 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -53,6 +53,7 @@ nvgpu-y += \ os/linux/os_ops_gp10b.o \ os/linux/os_ops_gp106.o \ os/linux/os_ops_gv100.o \ + os/linux/os_ops_gv11b.o \ os/linux/kmem.o \ os/linux/timers.o \ os/linux/ioctl.o \ @@ -115,6 +116,12 @@ endif nvgpu-$(CONFIG_GK20A_CTXSW_TRACE) += \ os/linux/ctxsw_trace.o +ifeq ($(CONFIG_GK20A_CTXSW_TRACE),y) +nvgpu-$(CONFIG_DEBUG_FS) += \ + os/linux/debug_fecs_trace.o +endif + + nvgpu-$(CONFIG_TEGRA_GK20A) += \ os/linux/module.o \ os/linux/module_usermode.o \ diff --git a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c index 3134df4d..b30d1743 100644 --- a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c @@ -20,10 +20,6 @@ * DEALINGS IN THE SOFTWARE. */ -#ifdef CONFIG_DEBUG_FS -#include -#endif - #include #include #include @@ -43,32 +39,13 @@ #include "fecs_trace_gk20a.h" #include "gk20a.h" #include "gr_gk20a.h" -#include "os/linux/os_linux.h" #include +#include #include #include -/* - * If HW circular buffer is getting too many "buffer full" conditions, - * increasing this constant should help (it drives Linux' internal buffer size). - */ -#define GK20A_FECS_TRACE_NUM_RECORDS (1 << 10) -#define GK20A_FECS_TRACE_HASH_BITS 8 /* 2^8 */ -#define GK20A_FECS_TRACE_FRAME_PERIOD_US (1000000ULL/60ULL) -#define GK20A_FECS_TRACE_PTIMER_SHIFT 5 - -struct gk20a_fecs_trace_record { - u32 magic_lo; - u32 magic_hi; - u32 context_id; - u32 context_ptr; - u32 new_context_id; - u32 new_context_ptr; - u64 ts[]; -}; - struct gk20a_fecs_trace_hash_ent { u32 context_ptr; pid_t pid; @@ -85,29 +62,33 @@ struct gk20a_fecs_trace { }; #ifdef CONFIG_GK20A_CTXSW_TRACE -static inline u32 gk20a_fecs_trace_record_ts_tag_v(u64 ts) +u32 gk20a_fecs_trace_record_ts_tag_invalid_ts_v(void) +{ + return ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_v(); +} + +u32 gk20a_fecs_trace_record_ts_tag_v(u64 ts) { return ctxsw_prog_record_timestamp_timestamp_hi_tag_v((u32) (ts >> 32)); } -static inline u64 gk20a_fecs_trace_record_ts_timestamp_v(u64 ts) +u64 gk20a_fecs_trace_record_ts_timestamp_v(u64 ts) { return ts & ~(((u64)ctxsw_prog_record_timestamp_timestamp_hi_tag_m()) << 32); } - static u32 gk20a_fecs_trace_fecs_context_ptr(struct gk20a *g, struct channel_gk20a *ch) { return (u32) (nvgpu_inst_block_addr(g, &ch->inst_block) >> 12LL); } -static inline int gk20a_fecs_trace_num_ts(void) +int gk20a_fecs_trace_num_ts(void) { return (ctxsw_prog_record_timestamp_record_size_in_bytes_v() - sizeof(struct gk20a_fecs_trace_record)) / sizeof(u64); } -static struct gk20a_fecs_trace_record *gk20a_fecs_trace_get_record( +struct gk20a_fecs_trace_record *gk20a_fecs_trace_get_record( struct gk20a *g, int idx) { struct nvgpu_mem *mem = &g->gr.global_ctx_buffer[FECS_TRACE_BUFFER].mem; @@ -117,7 +98,7 @@ static struct gk20a_fecs_trace_record *gk20a_fecs_trace_get_record( + (idx * ctxsw_prog_record_timestamp_record_size_in_bytes_v())); } -static bool gk20a_fecs_trace_is_valid_record(struct gk20a_fecs_trace_record *r) +bool gk20a_fecs_trace_is_valid_record(struct gk20a_fecs_trace_record *r) { /* * testing magic_hi should suffice. magic_lo is sometimes used @@ -127,13 +108,13 @@ static bool gk20a_fecs_trace_is_valid_record(struct gk20a_fecs_trace_record *r) == ctxsw_prog_record_timestamp_magic_value_hi_v_value_v()); } -static int gk20a_fecs_trace_get_read_index(struct gk20a *g) +int gk20a_fecs_trace_get_read_index(struct gk20a *g) { return gr_gk20a_elpg_protected_call(g, gk20a_readl(g, gr_fecs_mailbox1_r())); } -static int gk20a_fecs_trace_get_write_index(struct gk20a *g) +int gk20a_fecs_trace_get_write_index(struct gk20a *g) { return gr_gk20a_elpg_protected_call(g, gk20a_readl(g, gr_fecs_mailbox0_r())); @@ -424,147 +405,6 @@ size_t gk20a_fecs_trace_buffer_size(struct gk20a *g) * ctxsw_prog_record_timestamp_record_size_in_bytes_v(); } -#ifdef CONFIG_DEBUG_FS -/* - * The sequence iterator functions. We simply use the count of the - * next line as our internal position. - */ -static void *gk20a_fecs_trace_debugfs_ring_seq_start( - struct seq_file *s, loff_t *pos) -{ - if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) - return NULL; - - return pos; -} - -static void *gk20a_fecs_trace_debugfs_ring_seq_next( - struct seq_file *s, void *v, loff_t *pos) -{ - ++(*pos); - if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) - return NULL; - return pos; -} - -static void gk20a_fecs_trace_debugfs_ring_seq_stop( - struct seq_file *s, void *v) -{ -} - -static int gk20a_fecs_trace_debugfs_ring_seq_show( - struct seq_file *s, void *v) -{ - loff_t *pos = (loff_t *) v; - struct gk20a *g = *(struct gk20a **)s->private; - struct gk20a_fecs_trace_record *r = - gk20a_fecs_trace_get_record(g, *pos); - int i; - const u32 invalid_tag = - ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_v(); - u32 tag; - u64 timestamp; - - seq_printf(s, "record #%lld (%p)\n", *pos, r); - seq_printf(s, "\tmagic_lo=%08x\n", r->magic_lo); - seq_printf(s, "\tmagic_hi=%08x\n", r->magic_hi); - if (gk20a_fecs_trace_is_valid_record(r)) { - seq_printf(s, "\tcontext_ptr=%08x\n", r->context_ptr); - seq_printf(s, "\tcontext_id=%08x\n", r->context_id); - seq_printf(s, "\tnew_context_ptr=%08x\n", r->new_context_ptr); - seq_printf(s, "\tnew_context_id=%08x\n", r->new_context_id); - for (i = 0; i < gk20a_fecs_trace_num_ts(); i++) { - tag = gk20a_fecs_trace_record_ts_tag_v(r->ts[i]); - if (tag == invalid_tag) - continue; - timestamp = gk20a_fecs_trace_record_ts_timestamp_v(r->ts[i]); - timestamp <<= GK20A_FECS_TRACE_PTIMER_SHIFT; - seq_printf(s, "\ttag=%02x timestamp=%012llx\n", tag, timestamp); - } - } - return 0; -} - -/* - * Tie them all together into a set of seq_operations. - */ -static const struct seq_operations gk20a_fecs_trace_debugfs_ring_seq_ops = { - .start = gk20a_fecs_trace_debugfs_ring_seq_start, - .next = gk20a_fecs_trace_debugfs_ring_seq_next, - .stop = gk20a_fecs_trace_debugfs_ring_seq_stop, - .show = gk20a_fecs_trace_debugfs_ring_seq_show -}; - -/* - * Time to set up the file operations for our /proc file. In this case, - * all we need is an open function which sets up the sequence ops. - */ - -static int gk20a_ctxsw_debugfs_ring_open(struct inode *inode, - struct file *file) -{ - struct gk20a **p; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - p = __seq_open_private(file, &gk20a_fecs_trace_debugfs_ring_seq_ops, - sizeof(struct gk20a *)); - if (!p) - return -ENOMEM; - - *p = (struct gk20a *)inode->i_private; - return 0; -}; - -/* - * The file operations structure contains our open function along with - * set of the canned seq_ ops. - */ -static const struct file_operations gk20a_fecs_trace_debugfs_ring_fops = { - .owner = THIS_MODULE, - .open = gk20a_ctxsw_debugfs_ring_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release_private -}; - -static int gk20a_fecs_trace_debugfs_read(void *arg, u64 *val) -{ - *val = gk20a_fecs_trace_get_read_index((struct gk20a *)arg); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_read_fops, - gk20a_fecs_trace_debugfs_read, NULL, "%llu\n"); - -static int gk20a_fecs_trace_debugfs_write(void *arg, u64 *val) -{ - *val = gk20a_fecs_trace_get_write_index((struct gk20a *)arg); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_write_fops, - gk20a_fecs_trace_debugfs_write, NULL, "%llu\n"); - -static void gk20a_fecs_trace_debugfs_init(struct gk20a *g) -{ - struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); - - debugfs_create_file("ctxsw_trace_read", 0600, l->debugfs, g, - &gk20a_fecs_trace_debugfs_read_fops); - debugfs_create_file("ctxsw_trace_write", 0600, l->debugfs, g, - &gk20a_fecs_trace_debugfs_write_fops); - debugfs_create_file("ctxsw_trace_ring", 0600, l->debugfs, g, - &gk20a_fecs_trace_debugfs_ring_fops); -} - -#else - -static void gk20a_fecs_trace_debugfs_init(struct gk20a *g) -{ -} - -#endif /* CONFIG_DEBUG_FS */ - int gk20a_fecs_trace_init(struct gk20a *g) { struct gk20a_fecs_trace *trace; @@ -589,8 +429,6 @@ int gk20a_fecs_trace_init(struct gk20a *g) __nvgpu_set_enabled(g, NVGPU_SUPPORT_FECS_CTXSW_TRACE, true); - gk20a_fecs_trace_debugfs_init(g); - trace->init = true; return 0; diff --git a/drivers/gpu/nvgpu/include/nvgpu/fecs_trace.h b/drivers/gpu/nvgpu/include/nvgpu/fecs_trace.h new file mode 100644 index 00000000..5dc35302 --- /dev/null +++ b/drivers/gpu/nvgpu/include/nvgpu/fecs_trace.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_FECS_TRACE_H +#define NVGPU_FECS_TRACE_H + +struct gk20a; + +/* + * If HW circular buffer is getting too many "buffer full" conditions, + * increasing this constant should help (it drives Linux' internal buffer size). + */ +#define GK20A_FECS_TRACE_NUM_RECORDS (1 << 10) +#define GK20A_FECS_TRACE_HASH_BITS 8 /* 2^8 */ +#define GK20A_FECS_TRACE_FRAME_PERIOD_US (1000000ULL/60ULL) +#define GK20A_FECS_TRACE_PTIMER_SHIFT 5 + +struct gk20a_fecs_trace_record { + u32 magic_lo; + u32 magic_hi; + u32 context_id; + u32 context_ptr; + u32 new_context_id; + u32 new_context_ptr; + u64 ts[]; +}; + +#ifdef CONFIG_GK20A_CTXSW_TRACE +u32 gk20a_fecs_trace_record_ts_tag_invalid_ts_v(void); +u32 gk20a_fecs_trace_record_ts_tag_v(u64 ts); +u64 gk20a_fecs_trace_record_ts_timestamp_v(u64 ts); +int gk20a_fecs_trace_num_ts(void); +struct gk20a_fecs_trace_record *gk20a_fecs_trace_get_record(struct gk20a *g, + int idx); +bool gk20a_fecs_trace_is_valid_record(struct gk20a_fecs_trace_record *r); +int gk20a_fecs_trace_get_read_index(struct gk20a *g); +int gk20a_fecs_trace_get_write_index(struct gk20a *g); + +#endif /* CONFIG_GK20A_CTXSW_TRACE */ + +#endif diff --git a/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c b/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c new file mode 100644 index 00000000..9e72d2ce --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include + +#include "os_linux.h" + +/* + * The sequence iterator functions. We simply use the count of the + * next line as our internal position. + */ +static void *gk20a_fecs_trace_debugfs_ring_seq_start( + struct seq_file *s, loff_t *pos) +{ + if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) + return NULL; + + return pos; +} + +static void *gk20a_fecs_trace_debugfs_ring_seq_next( + struct seq_file *s, void *v, loff_t *pos) +{ + ++(*pos); + if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) + return NULL; + return pos; +} + +static void gk20a_fecs_trace_debugfs_ring_seq_stop( + struct seq_file *s, void *v) +{ +} + +static int gk20a_fecs_trace_debugfs_ring_seq_show( + struct seq_file *s, void *v) +{ + loff_t *pos = (loff_t *) v; + struct gk20a *g = *(struct gk20a **)s->private; + struct gk20a_fecs_trace_record *r = + gk20a_fecs_trace_get_record(g, *pos); + int i; + const u32 invalid_tag = gk20a_fecs_trace_record_ts_tag_invalid_ts_v(); + u32 tag; + u64 timestamp; + + seq_printf(s, "record #%lld (%p)\n", *pos, r); + seq_printf(s, "\tmagic_lo=%08x\n", r->magic_lo); + seq_printf(s, "\tmagic_hi=%08x\n", r->magic_hi); + if (gk20a_fecs_trace_is_valid_record(r)) { + seq_printf(s, "\tcontext_ptr=%08x\n", r->context_ptr); + seq_printf(s, "\tcontext_id=%08x\n", r->context_id); + seq_printf(s, "\tnew_context_ptr=%08x\n", r->new_context_ptr); + seq_printf(s, "\tnew_context_id=%08x\n", r->new_context_id); + for (i = 0; i < gk20a_fecs_trace_num_ts(); i++) { + tag = gk20a_fecs_trace_record_ts_tag_v(r->ts[i]); + if (tag == invalid_tag) + continue; + timestamp = gk20a_fecs_trace_record_ts_timestamp_v(r->ts[i]); + timestamp <<= GK20A_FECS_TRACE_PTIMER_SHIFT; + seq_printf(s, "\ttag=%02x timestamp=%012llx\n", tag, timestamp); + } + } + return 0; +} + +/* + * Tie them all together into a set of seq_operations. + */ +static const struct seq_operations gk20a_fecs_trace_debugfs_ring_seq_ops = { + .start = gk20a_fecs_trace_debugfs_ring_seq_start, + .next = gk20a_fecs_trace_debugfs_ring_seq_next, + .stop = gk20a_fecs_trace_debugfs_ring_seq_stop, + .show = gk20a_fecs_trace_debugfs_ring_seq_show +}; + +/* + * Time to set up the file operations for our /proc file. In this case, + * all we need is an open function which sets up the sequence ops. + */ + +static int gk20a_ctxsw_debugfs_ring_open(struct inode *inode, + struct file *file) +{ + struct gk20a **p; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + p = __seq_open_private(file, &gk20a_fecs_trace_debugfs_ring_seq_ops, + sizeof(struct gk20a *)); + if (!p) + return -ENOMEM; + + *p = (struct gk20a *)inode->i_private; + return 0; +}; + +/* + * The file operations structure contains our open function along with + * set of the canned seq_ ops. + */ +static const struct file_operations gk20a_fecs_trace_debugfs_ring_fops = { + .owner = THIS_MODULE, + .open = gk20a_ctxsw_debugfs_ring_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private +}; + +static int gk20a_fecs_trace_debugfs_read(void *arg, u64 *val) +{ + *val = gk20a_fecs_trace_get_read_index((struct gk20a *)arg); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_read_fops, + gk20a_fecs_trace_debugfs_read, NULL, "%llu\n"); + +static int gk20a_fecs_trace_debugfs_write(void *arg, u64 *val) +{ + *val = gk20a_fecs_trace_get_write_index((struct gk20a *)arg); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_write_fops, + gk20a_fecs_trace_debugfs_write, NULL, "%llu\n"); + +int nvgpu_fecs_trace_init_debugfs(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + debugfs_create_file("ctxsw_trace_read", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_read_fops); + debugfs_create_file("ctxsw_trace_write", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_write_fops); + debugfs_create_file("ctxsw_trace_ring", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_ring_fops); + + return 0; +} diff --git a/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h b/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h new file mode 100644 index 00000000..a545f2db --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LINUX_DEBUG_FECS_TRACE_H +#define LINUX_DEBUG_FECS_TRACE_H + +struct gk20a; + +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_GK20A_CTXSW_TRACE) +int nvgpu_fecs_trace_init_debugfs(struct gk20a *g); +#else +int nvgpu_fecs_trace_init_debugfs(struct gk20a *g) +{ + return 0; +} +#endif +#endif diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 85439b88..ff4d9a4c 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -216,6 +216,14 @@ int nvgpu_finalize_poweron_linux(struct nvgpu_os_linux *l) } } + if (l->ops.fecs_trace.init_debugfs) { + err = l->ops.fecs_trace.init_debugfs(g); + if (err) { + nvgpu_err(g, "failed to init linux fecs trace debugfs"); + return err; + } + } + err = nvgpu_pmgr_init_debugfs_linux(l); if (err) { nvgpu_err(g, "failed to init linux pmgr debugfs"); diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h index ff871fe5..a9a9ebb6 100644 --- a/drivers/gpu/nvgpu/os/linux/os_linux.h +++ b/drivers/gpu/nvgpu/os/linux/os_linux.h @@ -46,6 +46,10 @@ struct nvgpu_os_linux_ops { struct { int (*init_debugfs)(struct gk20a *g); } therm; + + struct { + int (*init_debugfs)(struct gk20a *g); + } fecs_trace; }; struct nvgpu_os_linux { diff --git a/drivers/gpu/nvgpu/os/linux/os_ops.c b/drivers/gpu/nvgpu/os/linux/os_ops.c index 5c2eb25c..f1ab4b15 100644 --- a/drivers/gpu/nvgpu/os/linux/os_ops.c +++ b/drivers/gpu/nvgpu/os/linux/os_ops.c @@ -19,6 +19,7 @@ #include "os_ops_gm20b.h" #include "os_ops_gp10b.h" #include "os_ops_gp106.h" +#include "os_ops_gv11b.h" #include "os_ops_gv100.h" #if defined(CONFIG_TEGRA_GPU_NEXT) @@ -44,6 +45,9 @@ int nvgpu_init_os_linux_ops(struct nvgpu_os_linux *l) case NVGPU_GPUID_GV100: nvgpu_gv100_init_os_ops(l); break; + case NVGPU_GPUID_GV11B: + nvgpu_gv11b_init_os_ops(l); + break; #if defined(CONFIG_TEGRA_GPU_NEXT) case NVGPU_GPUID_NEXT: NVGPU_NEXT_INIT_OS_OPS(l); diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c b/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c index 662f4551..14f1b004 100644 --- a/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c @@ -18,6 +18,7 @@ #include "debug_clk_gp106.h" #include "debug_therm_gp106.h" +#include "debug_fecs_trace.h" static struct nvgpu_os_linux_ops gp106_os_linux_ops = { .clk = { @@ -26,10 +27,14 @@ static struct nvgpu_os_linux_ops gp106_os_linux_ops = { .therm = { .init_debugfs = gp106_therm_init_debugfs, }, + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, }; void nvgpu_gp106_init_os_ops(struct nvgpu_os_linux *l) { l->ops.clk = gp106_os_linux_ops.clk; l->ops.therm = gp106_os_linux_ops.therm; + l->ops.fecs_trace = gp106_os_linux_ops.fecs_trace; } diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c b/drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c index 984dcdc0..e2891f73 100644 --- a/drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c @@ -17,6 +17,7 @@ #include "os_linux.h" #include "cde_gp10b.h" +#include "debug_fecs_trace.h" static struct nvgpu_os_linux_ops gp10b_os_linux_ops = { #ifdef CONFIG_NVGPU_SUPPORT_CDE @@ -26,6 +27,9 @@ static struct nvgpu_os_linux_ops gp10b_os_linux_ops = { .populate_scatter_buffer = gp10b_populate_scatter_buffer, }, #endif + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, }; void nvgpu_gp10b_init_os_ops(struct nvgpu_os_linux *l) @@ -33,4 +37,5 @@ void nvgpu_gp10b_init_os_ops(struct nvgpu_os_linux *l) #ifdef CONFIG_NVGPU_SUPPORT_CDE l->ops.cde = gp10b_os_linux_ops.cde; #endif + l->ops.fecs_trace = gp10b_os_linux_ops.fecs_trace; } diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c b/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c index 7a5174a4..f5c5a604 100644 --- a/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c @@ -18,6 +18,7 @@ #include "debug_clk_gp106.h" #include "debug_therm_gp106.h" +#include "debug_fecs_trace.h" static struct nvgpu_os_linux_ops gv100_os_linux_ops = { .clk = { @@ -26,10 +27,14 @@ static struct nvgpu_os_linux_ops gv100_os_linux_ops = { .therm = { .init_debugfs = gp106_therm_init_debugfs, }, + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, }; void nvgpu_gv100_init_os_ops(struct nvgpu_os_linux *l) { l->ops.clk = gv100_os_linux_ops.clk; l->ops.therm = gv100_os_linux_ops.therm; + l->ops.fecs_trace = gv100_os_linux_ops.fecs_trace; } diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c b/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c new file mode 100644 index 00000000..a82ad0ab --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "os_linux.h" + +#include "debug_fecs_trace.h" + +static struct nvgpu_os_linux_ops gv11b_os_linux_ops = { + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, +}; + +void nvgpu_gv11b_init_os_ops(struct nvgpu_os_linux *l) +{ + l->ops.fecs_trace = gv11b_os_linux_ops.fecs_trace; +} diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h b/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h new file mode 100644 index 00000000..eef6c4ac --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LINUX_OS_OPS_GV11B_H +#define LINUX_OS_OPS_GV11B_H + +struct nvgpu_os_linux; + +void nvgpu_gv11b_init_os_ops(struct nvgpu_os_linux *l); + +#endif -- cgit v1.2.2