diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 145 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | 2 |
3 files changed, 148 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 3871eb17..55bc6b20 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -155,6 +155,12 @@ struct gpu_ops { | |||
155 | u32 (*get_pmu_cmdline_args_size)(struct pmu_gk20a *pmu); | 155 | u32 (*get_pmu_cmdline_args_size)(struct pmu_gk20a *pmu); |
156 | void (*set_pmu_cmdline_args_cpu_freq)(struct pmu_gk20a *pmu, | 156 | void (*set_pmu_cmdline_args_cpu_freq)(struct pmu_gk20a *pmu, |
157 | u32 freq); | 157 | u32 freq); |
158 | void (*set_pmu_cmdline_args_trace_size)(struct pmu_gk20a *pmu, | ||
159 | u32 size); | ||
160 | void (*set_pmu_cmdline_args_trace_dma_base)( | ||
161 | struct pmu_gk20a *pmu); | ||
162 | void (*set_pmu_cmdline_args_trace_dma_idx)( | ||
163 | struct pmu_gk20a *pmu, u32 idx); | ||
158 | void * (*get_pmu_cmdline_args_ptr)(struct pmu_gk20a *pmu); | 164 | void * (*get_pmu_cmdline_args_ptr)(struct pmu_gk20a *pmu); |
159 | u32 (*get_pmu_allocation_struct_size)(struct pmu_gk20a *pmu); | 165 | u32 (*get_pmu_allocation_struct_size)(struct pmu_gk20a *pmu); |
160 | void (*set_pmu_allocation_ptr)(struct pmu_gk20a *pmu, | 166 | void (*set_pmu_allocation_ptr)(struct pmu_gk20a *pmu, |
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index a5b9f05f..c23d83cf 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | |||
@@ -63,6 +63,46 @@ static void set_pmu_cmdline_args_secure_mode_v1(struct pmu_gk20a *pmu, u32 val) | |||
63 | pmu->args_v1.secure_mode = val; | 63 | pmu->args_v1.secure_mode = val; |
64 | } | 64 | } |
65 | 65 | ||
66 | static void set_pmu_cmdline_args_falctracesize_v1( | ||
67 | struct pmu_gk20a *pmu, u32 size) | ||
68 | { | ||
69 | pmu->args_v1.falc_trace_size = size; | ||
70 | } | ||
71 | |||
72 | void printtrace(struct pmu_gk20a *pmu) | ||
73 | { | ||
74 | u32 i = 0, j = 0; | ||
75 | char *trace = pmu->trace_buf.cpuva; | ||
76 | u32 *trace1 = pmu->trace_buf.cpuva; | ||
77 | struct gk20a *g = gk20a_from_pmu(pmu); | ||
78 | gk20a_err(dev_from_gk20a(g), "Dump pmutrace"); | ||
79 | for (i = 0; i < GK20A_PMU_TRACE_BUFSIZE; i += 0x40) { | ||
80 | for (j = 0; j < 0x40; j++) | ||
81 | if (trace1[(i / 4) + j]) | ||
82 | break; | ||
83 | if (j == 0x40) | ||
84 | return; | ||
85 | gk20a_err(dev_from_gk20a(g), "Index %d: ", | ||
86 | trace1[(i / 4)]); | ||
87 | gk20a_err(dev_from_gk20a(g), | ||
88 | "Params: 0x%x 0x%x 0x%x 0x%x Message: ", | ||
89 | trace1[(i / 4) + 1], trace1[(i / 4) + 2], | ||
90 | trace1[(i / 4) + 3], trace1[(i / 4) + 4]); | ||
91 | gk20a_err(dev_from_gk20a(g), "%s", (trace+i+20)); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static void set_pmu_cmdline_args_falctracedmabase_v1(struct pmu_gk20a *pmu) | ||
96 | { | ||
97 | pmu->args_v1.falc_trace_dma_base = ((u32)pmu->trace_buf.pmu_va)/0x100; | ||
98 | } | ||
99 | |||
100 | static void set_pmu_cmdline_args_falctracedmaidx_v1( | ||
101 | struct pmu_gk20a *pmu, u32 idx) | ||
102 | { | ||
103 | pmu->args_v1.falc_trace_dma_idx = idx; | ||
104 | } | ||
105 | |||
66 | static void set_pmu_cmdline_args_cpufreq_v0(struct pmu_gk20a *pmu, u32 freq) | 106 | static void set_pmu_cmdline_args_cpufreq_v0(struct pmu_gk20a *pmu, u32 freq) |
67 | { | 107 | { |
68 | pmu->args_v0.cpu_freq_hz = freq; | 108 | pmu->args_v0.cpu_freq_hz = freq; |
@@ -509,6 +549,12 @@ int gk20a_init_pmu(struct pmu_gk20a *pmu) | |||
509 | set_pmu_cmdline_args_cpufreq_v1; | 549 | set_pmu_cmdline_args_cpufreq_v1; |
510 | g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode = | 550 | g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode = |
511 | set_pmu_cmdline_args_secure_mode_v1; | 551 | set_pmu_cmdline_args_secure_mode_v1; |
552 | g->ops.pmu_ver.set_pmu_cmdline_args_trace_size = | ||
553 | set_pmu_cmdline_args_falctracesize_v1; | ||
554 | g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base = | ||
555 | set_pmu_cmdline_args_falctracedmabase_v1; | ||
556 | g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx = | ||
557 | set_pmu_cmdline_args_falctracedmaidx_v1; | ||
512 | g->ops.pmu_ver.get_pmu_cmdline_args_ptr = | 558 | g->ops.pmu_ver.get_pmu_cmdline_args_ptr = |
513 | get_pmu_cmdline_args_ptr_v1; | 559 | get_pmu_cmdline_args_ptr_v1; |
514 | g->ops.pmu_ver.get_pmu_allocation_struct_size = | 560 | g->ops.pmu_ver.get_pmu_allocation_struct_size = |
@@ -951,6 +997,11 @@ static int pmu_bootstrap(struct pmu_gk20a *pmu) | |||
951 | pwr_pmu_new_instblk_target_sys_coh_f()); | 997 | pwr_pmu_new_instblk_target_sys_coh_f()); |
952 | 998 | ||
953 | /* TBD: load all other surfaces */ | 999 | /* TBD: load all other surfaces */ |
1000 | g->ops.pmu_ver.set_pmu_cmdline_args_trace_size( | ||
1001 | pmu, GK20A_PMU_TRACE_BUFSIZE); | ||
1002 | g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base(pmu); | ||
1003 | g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx( | ||
1004 | pmu, GK20A_PMU_DMAIDX_VIRT); | ||
954 | 1005 | ||
955 | g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, | 1006 | g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, |
956 | clk_get_rate(platform->clk[1])); | 1007 | clk_get_rate(platform->clk[1])); |
@@ -1623,6 +1674,7 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g) | |||
1623 | int i, err = 0; | 1674 | int i, err = 0; |
1624 | u8 *ptr; | 1675 | u8 *ptr; |
1625 | struct sg_table *sgt_seq_buf; | 1676 | struct sg_table *sgt_seq_buf; |
1677 | struct sg_table *sgt_pmu_buf; | ||
1626 | dma_addr_t iova; | 1678 | dma_addr_t iova; |
1627 | 1679 | ||
1628 | gk20a_dbg_fn(""); | 1680 | gk20a_dbg_fn(""); |
@@ -1680,13 +1732,23 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g) | |||
1680 | 1732 | ||
1681 | pmu->seq_buf.iova = iova; | 1733 | pmu->seq_buf.iova = iova; |
1682 | 1734 | ||
1735 | pmu->trace_buf.cpuva = dma_alloc_coherent(d, GK20A_PMU_TRACE_BUFSIZE, | ||
1736 | &iova, | ||
1737 | GFP_KERNEL); | ||
1738 | if (!pmu->trace_buf.cpuva) { | ||
1739 | gk20a_err(d, "failed to allocate trace memory\n"); | ||
1740 | err = -ENOMEM; | ||
1741 | goto err_free_seq_buf; | ||
1742 | } | ||
1743 | pmu->trace_buf.iova = iova; | ||
1744 | |||
1683 | err = gk20a_get_sgtable(d, &sgt_seq_buf, | 1745 | err = gk20a_get_sgtable(d, &sgt_seq_buf, |
1684 | pmu->seq_buf.cpuva, | 1746 | pmu->seq_buf.cpuva, |
1685 | pmu->seq_buf.iova, | 1747 | pmu->seq_buf.iova, |
1686 | GK20A_PMU_SEQ_BUF_SIZE); | 1748 | GK20A_PMU_SEQ_BUF_SIZE); |
1687 | if (err) { | 1749 | if (err) { |
1688 | gk20a_err(d, "failed to allocate sg table\n"); | 1750 | gk20a_err(d, "failed to allocate seq buf sg table\n"); |
1689 | goto err_free_seq_buf; | 1751 | goto err_free_trace_buf; |
1690 | } | 1752 | } |
1691 | 1753 | ||
1692 | pmu->seq_buf.pmu_va = gk20a_gmmu_map(vm, &sgt_seq_buf, | 1754 | 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) | |||
1694 | 0, /* flags */ | 1756 | 0, /* flags */ |
1695 | gk20a_mem_flag_none); | 1757 | gk20a_mem_flag_none); |
1696 | if (!pmu->seq_buf.pmu_va) { | 1758 | if (!pmu->seq_buf.pmu_va) { |
1697 | gk20a_err(d, "failed to map pmu ucode memory!!"); | 1759 | gk20a_err(d, "failed to gmmu map seq buf memory!!"); |
1760 | err = -ENOMEM; | ||
1698 | goto err_free_seq_buf_sgt; | 1761 | goto err_free_seq_buf_sgt; |
1699 | } | 1762 | } |
1700 | 1763 | ||
1764 | err = gk20a_get_sgtable(d, &sgt_pmu_buf, | ||
1765 | pmu->trace_buf.cpuva, | ||
1766 | pmu->trace_buf.iova, | ||
1767 | GK20A_PMU_TRACE_BUFSIZE); | ||
1768 | if (err) { | ||
1769 | gk20a_err(d, "failed to allocate sg table for Trace\n"); | ||
1770 | goto err_unmap_seq_buf; | ||
1771 | } | ||
1772 | |||
1773 | pmu->trace_buf.pmu_va = gk20a_gmmu_map(vm, &sgt_pmu_buf, | ||
1774 | GK20A_PMU_TRACE_BUFSIZE, | ||
1775 | 0, /* flags */ | ||
1776 | gk20a_mem_flag_none); | ||
1777 | if (!pmu->trace_buf.pmu_va) { | ||
1778 | gk20a_err(d, "failed to gmmu map pmu trace memory!!"); | ||
1779 | err = -ENOMEM; | ||
1780 | goto err_free_trace_buf_sgt; | ||
1781 | } | ||
1782 | |||
1701 | ptr = (u8 *)pmu->seq_buf.cpuva; | 1783 | ptr = (u8 *)pmu->seq_buf.cpuva; |
1702 | if (!ptr) { | 1784 | if (!ptr) { |
1703 | gk20a_err(d, "failed to map cpu ptr for zbc buffer"); | 1785 | gk20a_err(d, "failed to map cpu ptr for zbc buffer"); |
1704 | goto err_unmap_seq_buf; | 1786 | goto err_unmap_trace_buf; |
1705 | } | 1787 | } |
1706 | 1788 | ||
1707 | /* TBD: remove this if ZBC save/restore is handled by PMU | 1789 | /* TBD: remove this if ZBC save/restore is handled by PMU |
@@ -1713,17 +1795,29 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g) | |||
1713 | pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE; | 1795 | pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE; |
1714 | 1796 | ||
1715 | gk20a_free_sgtable(&sgt_seq_buf); | 1797 | gk20a_free_sgtable(&sgt_seq_buf); |
1798 | gk20a_free_sgtable(&sgt_pmu_buf); | ||
1799 | |||
1716 | pmu->sw_ready = true; | 1800 | pmu->sw_ready = true; |
1717 | 1801 | ||
1718 | skip_init: | 1802 | skip_init: |
1719 | gk20a_dbg_fn("done"); | 1803 | gk20a_dbg_fn("done"); |
1720 | return 0; | 1804 | return 0; |
1721 | 1805 | err_unmap_trace_buf: | |
1806 | gk20a_gmmu_unmap(vm, pmu->trace_buf.pmu_va, | ||
1807 | GK20A_PMU_TRACE_BUFSIZE, gk20a_mem_flag_none); | ||
1808 | err_free_trace_buf_sgt: | ||
1809 | gk20a_free_sgtable(&sgt_pmu_buf); | ||
1722 | err_unmap_seq_buf: | 1810 | err_unmap_seq_buf: |
1723 | gk20a_gmmu_unmap(vm, pmu->seq_buf.pmu_va, | 1811 | gk20a_gmmu_unmap(vm, pmu->seq_buf.pmu_va, |
1724 | GK20A_PMU_SEQ_BUF_SIZE, gk20a_mem_flag_none); | 1812 | GK20A_PMU_SEQ_BUF_SIZE, gk20a_mem_flag_none); |
1725 | err_free_seq_buf_sgt: | 1813 | err_free_seq_buf_sgt: |
1726 | gk20a_free_sgtable(&sgt_seq_buf); | 1814 | gk20a_free_sgtable(&sgt_seq_buf); |
1815 | err_free_trace_buf: | ||
1816 | dma_free_coherent(d, GK20A_PMU_TRACE_BUFSIZE, | ||
1817 | pmu->trace_buf.cpuva, pmu->trace_buf.iova); | ||
1818 | pmu->trace_buf.cpuva = NULL; | ||
1819 | pmu->trace_buf.iova = 0; | ||
1820 | |||
1727 | err_free_seq_buf: | 1821 | err_free_seq_buf: |
1728 | dma_free_coherent(d, GK20A_PMU_SEQ_BUF_SIZE, | 1822 | dma_free_coherent(d, GK20A_PMU_SEQ_BUF_SIZE, |
1729 | pmu->seq_buf.cpuva, pmu->seq_buf.iova); | 1823 | pmu->seq_buf.cpuva, pmu->seq_buf.iova); |
@@ -2870,6 +2964,7 @@ void pmu_dump_falcon_stats(struct pmu_gk20a *pmu) | |||
2870 | 2964 | ||
2871 | /* PMU may crash due to FECS crash. Dump FECS status */ | 2965 | /* PMU may crash due to FECS crash. Dump FECS status */ |
2872 | gk20a_fecs_dump_falcon_stats(g); | 2966 | gk20a_fecs_dump_falcon_stats(g); |
2967 | printtrace(pmu); | ||
2873 | } | 2968 | } |
2874 | 2969 | ||
2875 | void gk20a_pmu_isr(struct gk20a *g) | 2970 | void gk20a_pmu_isr(struct gk20a *g) |
@@ -3662,6 +3757,40 @@ static const struct file_operations elpg_transitions_fops = { | |||
3662 | .release = single_release, | 3757 | .release = single_release, |
3663 | }; | 3758 | }; |
3664 | 3759 | ||
3760 | static int falc_trace_show(struct seq_file *s, void *data) | ||
3761 | { | ||
3762 | struct gk20a *g = s->private; | ||
3763 | struct pmu_gk20a *pmu = &g->pmu; | ||
3764 | u32 i = 0, j = 0; | ||
3765 | char *trace = pmu->trace_buf.cpuva; | ||
3766 | u32 *trace1 = pmu->trace_buf.cpuva; | ||
3767 | for (i = 0; i < GK20A_PMU_TRACE_BUFSIZE; i += 0x40) { | ||
3768 | for (j = 0; j < 0x40; j++) | ||
3769 | if (trace1[(i / 4) + j]) | ||
3770 | break; | ||
3771 | if (j == 0x40) | ||
3772 | return 0; | ||
3773 | seq_printf(s, "Index %x: ", trace1[(i / 4)]); | ||
3774 | seq_printf(s, "Params: 0x%x 0x%x 0x%x 0x%x Message: ", | ||
3775 | trace1[(i / 4) + 1], trace1[(i / 4) + 2], | ||
3776 | trace1[(i / 4) + 3], trace1[(i / 4) + 4]); | ||
3777 | seq_printf(s, "%s", (trace+i+20)); | ||
3778 | } | ||
3779 | return 0; | ||
3780 | } | ||
3781 | |||
3782 | static int falc_trace_open(struct inode *inode, struct file *file) | ||
3783 | { | ||
3784 | return single_open(file, falc_trace_show, inode->i_private); | ||
3785 | } | ||
3786 | |||
3787 | static const struct file_operations falc_trace_fops = { | ||
3788 | .open = falc_trace_open, | ||
3789 | .read = seq_read, | ||
3790 | .llseek = seq_lseek, | ||
3791 | .release = single_release, | ||
3792 | }; | ||
3793 | |||
3665 | static int perfmon_events_enable_show(struct seq_file *s, void *data) | 3794 | static int perfmon_events_enable_show(struct seq_file *s, void *data) |
3666 | { | 3795 | { |
3667 | struct gk20a *g = s->private; | 3796 | struct gk20a *g = s->private; |
@@ -3760,6 +3889,12 @@ int gk20a_pmu_debugfs_init(struct platform_device *dev) | |||
3760 | goto err_out; | 3889 | goto err_out; |
3761 | 3890 | ||
3762 | d = debugfs_create_file( | 3891 | d = debugfs_create_file( |
3892 | "falc_trace", S_IRUGO, platform->debugfs, g, | ||
3893 | &falc_trace_fops); | ||
3894 | if (!d) | ||
3895 | goto err_out; | ||
3896 | |||
3897 | d = debugfs_create_file( | ||
3763 | "perfmon_events_enable", S_IRUGO, platform->debugfs, g, | 3898 | "perfmon_events_enable", S_IRUGO, platform->debugfs, g, |
3764 | &perfmon_events_enable_fops); | 3899 | &perfmon_events_enable_fops); |
3765 | if (!d) | 3900 | if (!d) |
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h index fec0a572..828058b7 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | |||
@@ -339,6 +339,7 @@ struct pmu_cmdline_args_v1 { | |||
339 | struct pmu_mem_v1 gc6_ctx; /* dmem offset of gc6 context */ | 339 | struct pmu_mem_v1 gc6_ctx; /* dmem offset of gc6 context */ |
340 | }; | 340 | }; |
341 | 341 | ||
342 | #define GK20A_PMU_TRACE_BUFSIZE 0x4000 /* 4K */ | ||
342 | #define GK20A_PMU_DMEM_BLKSIZE2 8 | 343 | #define GK20A_PMU_DMEM_BLKSIZE2 8 |
343 | 344 | ||
344 | #define GK20A_PMU_UCODE_NB_MAX_OVERLAY 32 | 345 | #define GK20A_PMU_UCODE_NB_MAX_OVERLAY 32 |
@@ -1008,6 +1009,7 @@ struct pmu_gk20a { | |||
1008 | struct pmu_mem_desc pg_buf; | 1009 | struct pmu_mem_desc pg_buf; |
1009 | /* TBD: remove this if ZBC seq is fixed */ | 1010 | /* TBD: remove this if ZBC seq is fixed */ |
1010 | struct pmu_mem_desc seq_buf; | 1011 | struct pmu_mem_desc seq_buf; |
1012 | struct pmu_mem_desc trace_buf; | ||
1011 | bool buf_loaded; | 1013 | bool buf_loaded; |
1012 | 1014 | ||
1013 | struct pmu_sha1_gid gid_info; | 1015 | struct pmu_sha1_gid gid_info; |