gpu:nvgpu: Enable Falcon trace prints

Dump Falcon trace on PMU Crash and add debugfs node falc_trace.
This needs Debug trace to be enabled in GPmu binary.

Change-Id: I093ef196202958e46d8d9636a848bd6733b5e4cc
Signed-off-by: Vijayakumar <vsubbu@nvidia.com>
Reviewed-on: http://git-master/r/432732
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
This commit is contained in:
Vijayakumar
2014-06-30 17:52:38 +05:30
committed by Dan Willemsen
parent c230159665
commit 2d666411ab
3 changed files with 148 additions and 5 deletions

View File

@@ -155,6 +155,12 @@ struct gpu_ops {
u32 (*get_pmu_cmdline_args_size)(struct pmu_gk20a *pmu); u32 (*get_pmu_cmdline_args_size)(struct pmu_gk20a *pmu);
void (*set_pmu_cmdline_args_cpu_freq)(struct pmu_gk20a *pmu, void (*set_pmu_cmdline_args_cpu_freq)(struct pmu_gk20a *pmu,
u32 freq); u32 freq);
void (*set_pmu_cmdline_args_trace_size)(struct pmu_gk20a *pmu,
u32 size);
void (*set_pmu_cmdline_args_trace_dma_base)(
struct pmu_gk20a *pmu);
void (*set_pmu_cmdline_args_trace_dma_idx)(
struct pmu_gk20a *pmu, u32 idx);
void * (*get_pmu_cmdline_args_ptr)(struct pmu_gk20a *pmu); void * (*get_pmu_cmdline_args_ptr)(struct pmu_gk20a *pmu);
u32 (*get_pmu_allocation_struct_size)(struct pmu_gk20a *pmu); u32 (*get_pmu_allocation_struct_size)(struct pmu_gk20a *pmu);
void (*set_pmu_allocation_ptr)(struct pmu_gk20a *pmu, void (*set_pmu_allocation_ptr)(struct pmu_gk20a *pmu,

View File

@@ -63,6 +63,46 @@ static void set_pmu_cmdline_args_secure_mode_v1(struct pmu_gk20a *pmu, u32 val)
pmu->args_v1.secure_mode = val; pmu->args_v1.secure_mode = val;
} }
static void set_pmu_cmdline_args_falctracesize_v1(
struct pmu_gk20a *pmu, u32 size)
{
pmu->args_v1.falc_trace_size = size;
}
void printtrace(struct pmu_gk20a *pmu)
{
u32 i = 0, j = 0;
char *trace = pmu->trace_buf.cpuva;
u32 *trace1 = pmu->trace_buf.cpuva;
struct gk20a *g = gk20a_from_pmu(pmu);
gk20a_err(dev_from_gk20a(g), "Dump pmutrace");
for (i = 0; i < GK20A_PMU_TRACE_BUFSIZE; i += 0x40) {
for (j = 0; j < 0x40; j++)
if (trace1[(i / 4) + j])
break;
if (j == 0x40)
return;
gk20a_err(dev_from_gk20a(g), "Index %d: ",
trace1[(i / 4)]);
gk20a_err(dev_from_gk20a(g),
"Params: 0x%x 0x%x 0x%x 0x%x Message: ",
trace1[(i / 4) + 1], trace1[(i / 4) + 2],
trace1[(i / 4) + 3], trace1[(i / 4) + 4]);
gk20a_err(dev_from_gk20a(g), "%s", (trace+i+20));
}
}
static void set_pmu_cmdline_args_falctracedmabase_v1(struct pmu_gk20a *pmu)
{
pmu->args_v1.falc_trace_dma_base = ((u32)pmu->trace_buf.pmu_va)/0x100;
}
static void set_pmu_cmdline_args_falctracedmaidx_v1(
struct pmu_gk20a *pmu, u32 idx)
{
pmu->args_v1.falc_trace_dma_idx = idx;
}
static void set_pmu_cmdline_args_cpufreq_v0(struct pmu_gk20a *pmu, u32 freq) static void set_pmu_cmdline_args_cpufreq_v0(struct pmu_gk20a *pmu, u32 freq)
{ {
pmu->args_v0.cpu_freq_hz = freq; pmu->args_v0.cpu_freq_hz = freq;
@@ -509,6 +549,12 @@ int gk20a_init_pmu(struct pmu_gk20a *pmu)
set_pmu_cmdline_args_cpufreq_v1; set_pmu_cmdline_args_cpufreq_v1;
g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode = g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode =
set_pmu_cmdline_args_secure_mode_v1; set_pmu_cmdline_args_secure_mode_v1;
g->ops.pmu_ver.set_pmu_cmdline_args_trace_size =
set_pmu_cmdline_args_falctracesize_v1;
g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base =
set_pmu_cmdline_args_falctracedmabase_v1;
g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx =
set_pmu_cmdline_args_falctracedmaidx_v1;
g->ops.pmu_ver.get_pmu_cmdline_args_ptr = g->ops.pmu_ver.get_pmu_cmdline_args_ptr =
get_pmu_cmdline_args_ptr_v1; get_pmu_cmdline_args_ptr_v1;
g->ops.pmu_ver.get_pmu_allocation_struct_size = g->ops.pmu_ver.get_pmu_allocation_struct_size =
@@ -951,6 +997,11 @@ static int pmu_bootstrap(struct pmu_gk20a *pmu)
pwr_pmu_new_instblk_target_sys_coh_f()); pwr_pmu_new_instblk_target_sys_coh_f());
/* TBD: load all other surfaces */ /* TBD: load all other surfaces */
g->ops.pmu_ver.set_pmu_cmdline_args_trace_size(
pmu, GK20A_PMU_TRACE_BUFSIZE);
g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base(pmu);
g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx(
pmu, GK20A_PMU_DMAIDX_VIRT);
g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu,
clk_get_rate(platform->clk[1])); clk_get_rate(platform->clk[1]));
@@ -1623,6 +1674,7 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g)
int i, err = 0; int i, err = 0;
u8 *ptr; u8 *ptr;
struct sg_table *sgt_seq_buf; struct sg_table *sgt_seq_buf;
struct sg_table *sgt_pmu_buf;
dma_addr_t iova; dma_addr_t iova;
gk20a_dbg_fn(""); gk20a_dbg_fn("");
@@ -1680,13 +1732,23 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g)
pmu->seq_buf.iova = iova; pmu->seq_buf.iova = iova;
pmu->trace_buf.cpuva = dma_alloc_coherent(d, GK20A_PMU_TRACE_BUFSIZE,
&iova,
GFP_KERNEL);
if (!pmu->trace_buf.cpuva) {
gk20a_err(d, "failed to allocate trace memory\n");
err = -ENOMEM;
goto err_free_seq_buf;
}
pmu->trace_buf.iova = iova;
err = gk20a_get_sgtable(d, &sgt_seq_buf, err = gk20a_get_sgtable(d, &sgt_seq_buf,
pmu->seq_buf.cpuva, pmu->seq_buf.cpuva,
pmu->seq_buf.iova, pmu->seq_buf.iova,
GK20A_PMU_SEQ_BUF_SIZE); GK20A_PMU_SEQ_BUF_SIZE);
if (err) { if (err) {
gk20a_err(d, "failed to allocate sg table\n"); gk20a_err(d, "failed to allocate seq buf sg table\n");
goto err_free_seq_buf; goto err_free_trace_buf;
} }
pmu->seq_buf.pmu_va = gk20a_gmmu_map(vm, &sgt_seq_buf, pmu->seq_buf.pmu_va = gk20a_gmmu_map(vm, &sgt_seq_buf,
@@ -1694,14 +1756,34 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g)
0, /* flags */ 0, /* flags */
gk20a_mem_flag_none); gk20a_mem_flag_none);
if (!pmu->seq_buf.pmu_va) { if (!pmu->seq_buf.pmu_va) {
gk20a_err(d, "failed to map pmu ucode memory!!"); gk20a_err(d, "failed to gmmu map seq buf memory!!");
err = -ENOMEM;
goto err_free_seq_buf_sgt; goto err_free_seq_buf_sgt;
} }
err = gk20a_get_sgtable(d, &sgt_pmu_buf,
pmu->trace_buf.cpuva,
pmu->trace_buf.iova,
GK20A_PMU_TRACE_BUFSIZE);
if (err) {
gk20a_err(d, "failed to allocate sg table for Trace\n");
goto err_unmap_seq_buf;
}
pmu->trace_buf.pmu_va = gk20a_gmmu_map(vm, &sgt_pmu_buf,
GK20A_PMU_TRACE_BUFSIZE,
0, /* flags */
gk20a_mem_flag_none);
if (!pmu->trace_buf.pmu_va) {
gk20a_err(d, "failed to gmmu map pmu trace memory!!");
err = -ENOMEM;
goto err_free_trace_buf_sgt;
}
ptr = (u8 *)pmu->seq_buf.cpuva; ptr = (u8 *)pmu->seq_buf.cpuva;
if (!ptr) { if (!ptr) {
gk20a_err(d, "failed to map cpu ptr for zbc buffer"); gk20a_err(d, "failed to map cpu ptr for zbc buffer");
goto err_unmap_seq_buf; goto err_unmap_trace_buf;
} }
/* TBD: remove this if ZBC save/restore is handled by PMU /* TBD: remove this if ZBC save/restore is handled by PMU
@@ -1713,17 +1795,29 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g)
pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE; pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE;
gk20a_free_sgtable(&sgt_seq_buf); gk20a_free_sgtable(&sgt_seq_buf);
gk20a_free_sgtable(&sgt_pmu_buf);
pmu->sw_ready = true; pmu->sw_ready = true;
skip_init: skip_init:
gk20a_dbg_fn("done"); gk20a_dbg_fn("done");
return 0; return 0;
err_unmap_trace_buf:
gk20a_gmmu_unmap(vm, pmu->trace_buf.pmu_va,
GK20A_PMU_TRACE_BUFSIZE, gk20a_mem_flag_none);
err_free_trace_buf_sgt:
gk20a_free_sgtable(&sgt_pmu_buf);
err_unmap_seq_buf: err_unmap_seq_buf:
gk20a_gmmu_unmap(vm, pmu->seq_buf.pmu_va, gk20a_gmmu_unmap(vm, pmu->seq_buf.pmu_va,
GK20A_PMU_SEQ_BUF_SIZE, gk20a_mem_flag_none); GK20A_PMU_SEQ_BUF_SIZE, gk20a_mem_flag_none);
err_free_seq_buf_sgt: err_free_seq_buf_sgt:
gk20a_free_sgtable(&sgt_seq_buf); gk20a_free_sgtable(&sgt_seq_buf);
err_free_trace_buf:
dma_free_coherent(d, GK20A_PMU_TRACE_BUFSIZE,
pmu->trace_buf.cpuva, pmu->trace_buf.iova);
pmu->trace_buf.cpuva = NULL;
pmu->trace_buf.iova = 0;
err_free_seq_buf: err_free_seq_buf:
dma_free_coherent(d, GK20A_PMU_SEQ_BUF_SIZE, dma_free_coherent(d, GK20A_PMU_SEQ_BUF_SIZE,
pmu->seq_buf.cpuva, pmu->seq_buf.iova); pmu->seq_buf.cpuva, pmu->seq_buf.iova);
@@ -2870,6 +2964,7 @@ void pmu_dump_falcon_stats(struct pmu_gk20a *pmu)
/* PMU may crash due to FECS crash. Dump FECS status */ /* PMU may crash due to FECS crash. Dump FECS status */
gk20a_fecs_dump_falcon_stats(g); gk20a_fecs_dump_falcon_stats(g);
printtrace(pmu);
} }
void gk20a_pmu_isr(struct gk20a *g) void gk20a_pmu_isr(struct gk20a *g)
@@ -3662,6 +3757,40 @@ static const struct file_operations elpg_transitions_fops = {
.release = single_release, .release = single_release,
}; };
static int falc_trace_show(struct seq_file *s, void *data)
{
struct gk20a *g = s->private;
struct pmu_gk20a *pmu = &g->pmu;
u32 i = 0, j = 0;
char *trace = pmu->trace_buf.cpuva;
u32 *trace1 = pmu->trace_buf.cpuva;
for (i = 0; i < GK20A_PMU_TRACE_BUFSIZE; i += 0x40) {
for (j = 0; j < 0x40; j++)
if (trace1[(i / 4) + j])
break;
if (j == 0x40)
return 0;
seq_printf(s, "Index %x: ", trace1[(i / 4)]);
seq_printf(s, "Params: 0x%x 0x%x 0x%x 0x%x Message: ",
trace1[(i / 4) + 1], trace1[(i / 4) + 2],
trace1[(i / 4) + 3], trace1[(i / 4) + 4]);
seq_printf(s, "%s", (trace+i+20));
}
return 0;
}
static int falc_trace_open(struct inode *inode, struct file *file)
{
return single_open(file, falc_trace_show, inode->i_private);
}
static const struct file_operations falc_trace_fops = {
.open = falc_trace_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int perfmon_events_enable_show(struct seq_file *s, void *data) static int perfmon_events_enable_show(struct seq_file *s, void *data)
{ {
struct gk20a *g = s->private; struct gk20a *g = s->private;
@@ -3759,6 +3888,12 @@ int gk20a_pmu_debugfs_init(struct platform_device *dev)
if (!d) if (!d)
goto err_out; goto err_out;
d = debugfs_create_file(
"falc_trace", S_IRUGO, platform->debugfs, g,
&falc_trace_fops);
if (!d)
goto err_out;
d = debugfs_create_file( d = debugfs_create_file(
"perfmon_events_enable", S_IRUGO, platform->debugfs, g, "perfmon_events_enable", S_IRUGO, platform->debugfs, g,
&perfmon_events_enable_fops); &perfmon_events_enable_fops);

View File

@@ -339,6 +339,7 @@ struct pmu_cmdline_args_v1 {
struct pmu_mem_v1 gc6_ctx; /* dmem offset of gc6 context */ struct pmu_mem_v1 gc6_ctx; /* dmem offset of gc6 context */
}; };
#define GK20A_PMU_TRACE_BUFSIZE 0x4000 /* 4K */
#define GK20A_PMU_DMEM_BLKSIZE2 8 #define GK20A_PMU_DMEM_BLKSIZE2 8
#define GK20A_PMU_UCODE_NB_MAX_OVERLAY 32 #define GK20A_PMU_UCODE_NB_MAX_OVERLAY 32
@@ -1008,6 +1009,7 @@ struct pmu_gk20a {
struct pmu_mem_desc pg_buf; struct pmu_mem_desc pg_buf;
/* TBD: remove this if ZBC seq is fixed */ /* TBD: remove this if ZBC seq is fixed */
struct pmu_mem_desc seq_buf; struct pmu_mem_desc seq_buf;
struct pmu_mem_desc trace_buf;
bool buf_loaded; bool buf_loaded;
struct pmu_sha1_gid gid_info; struct pmu_sha1_gid gid_info;