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 <nkumbhar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1812449
Reviewed-by: Deepak Nibade <dnibade@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: svc-misra-checker <svc-misra-checker@nvidia.com>
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Nitin Kumbhar
2018-09-04 16:19:47 +05:30
committed by mobile promotions
parent b2ba12ed55
commit e93a4ca50b
13 changed files with 349 additions and 175 deletions

View File

@@ -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 \

View File

@@ -20,10 +20,6 @@
* DEALINGS IN THE SOFTWARE.
*/
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#endif
#include <nvgpu/kmem.h>
#include <nvgpu/dma.h>
#include <nvgpu/enabled.h>
@@ -43,32 +39,13 @@
#include "fecs_trace_gk20a.h"
#include "gk20a.h"
#include "gr_gk20a.h"
#include "os/linux/os_linux.h"
#include <nvgpu/log.h>
#include <nvgpu/fecs_trace.h>
#include <nvgpu/hw/gk20a/hw_ctxsw_prog_gk20a.h>
#include <nvgpu/hw/gk20a/hw_gr_gk20a.h>
/*
* 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;

View File

@@ -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

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include <linux/debugfs.h>
#include <nvgpu/fecs_trace.h>
#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;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@@ -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");

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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