summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c
diff options
context:
space:
mode:
authorRichard Zhao <rizhao@nvidia.com>2016-03-07 17:23:12 -0500
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-04-11 18:38:12 -0400
commit60b715e85600a6be283e54c610c2a3db3b552059 (patch)
treeaaf2332b8a03c5869a1be74843eae5ea5ccb99be /drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c
parent6eeabfbdd08e48f924885952c80ff41aa2b534b7 (diff)
gpu: nvgpu: vgpu: add fecs trace support
Bug 1648908 Change-Id: I7901e7bce5f7aa124a188101dd0736241d87bd53 Signed-off-by: Richard Zhao <rizhao@nvidia.com> Reviewed-on: http://git-master/r/1031861 Reviewed-on: http://git-master/r/1121261 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-by: Aingara Paramakuru <aparamakuru@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c')
-rw-r--r--drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c196
1 files changed, 195 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c b/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c
index cb955811..568f3784 100644
--- a/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c
@@ -12,10 +12,204 @@
12 */ 12 */
13 13
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/tegra-ivc.h>
16#include <linux/tegra_vgpu.h>
17
15#include "gk20a/gk20a.h" 18#include "gk20a/gk20a.h"
19#include "gk20a/ctxsw_trace_gk20a.h"
20#include "vgpu.h"
16#include "fecs_trace_vgpu.h" 21#include "fecs_trace_vgpu.h"
17 22
23struct vgpu_fecs_trace {
24 struct tegra_hv_ivm_cookie *cookie;
25 struct nvgpu_ctxsw_ring_header *header;
26 struct nvgpu_ctxsw_trace_entry *entries;
27 int num_entries;
28 void *buf;
29};
30
31static int vgpu_fecs_trace_init(struct gk20a *g)
32{
33 struct device *dev = g->dev;
34 struct device_node *np = dev->of_node;
35 struct of_phandle_args args;
36 struct device_node *hv_np;
37 struct vgpu_fecs_trace *vcst;
38 u32 mempool;
39 int err;
40
41 gk20a_dbg_fn("");
42
43 vcst = kzalloc(sizeof(*vcst), GFP_KERNEL);
44 if (!vcst)
45 return -ENOMEM;
46
47 err = of_parse_phandle_with_fixed_args(np,
48 "mempool-fecs-trace", 1, 0, &args);
49 if (err) {
50 dev_info(dev_from_gk20a(g), "does not support fecs trace\n");
51 goto fail;
52 }
53
54 hv_np = args.np;
55 mempool = args.args[0];
56 vcst->cookie = tegra_hv_mempool_reserve(hv_np, mempool);
57 if (IS_ERR(vcst->cookie)) {
58 dev_info(dev_from_gk20a(g),
59 "mempool %u reserve failed\n", mempool);
60 err = -EINVAL;
61 goto fail;
62 }
63
64 vcst->buf = ioremap_cache(vcst->cookie->ipa, vcst->cookie->size);
65 vcst->header = vcst->buf;
66 vcst->num_entries = vcst->header->num_ents;
67 if (unlikely(vcst->header->ent_size != sizeof(*vcst->entries))) {
68 dev_err(dev_from_gk20a(g),
69 "entry size mismatch\n");
70 goto fail;
71 }
72 vcst->entries = vcst->buf + sizeof(*vcst->header);
73 g->fecs_trace = (struct gk20a_fecs_trace *)vcst;
74
75 return 0;
76fail:
77 iounmap(vcst->buf);
78 if (vcst->cookie)
79 tegra_hv_mempool_unreserve(vcst->cookie);
80 kfree(vcst);
81 return err;
82}
83
84static int vgpu_fecs_trace_deinit(struct gk20a *g)
85{
86 struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace;
87
88 iounmap(vcst->buf);
89 tegra_hv_mempool_unreserve(vcst->cookie);
90 kfree(vcst);
91 return 0;
92}
93
94static int vgpu_fecs_trace_enable(struct gk20a *g)
95{
96 struct tegra_vgpu_cmd_msg msg = {
97 .cmd = TEGRA_VGPU_CMD_FECS_TRACE_ENABLE,
98 .handle = gk20a_get_platform(g->dev)->virt_handle,
99 };
100 int err;
101
102 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
103 err = err ? err : msg.ret;
104 WARN_ON(err);
105 return err;
106}
107
108static int vgpu_fecs_trace_disable(struct gk20a *g)
109{
110 struct tegra_vgpu_cmd_msg msg = {
111 .cmd = TEGRA_VGPU_CMD_FECS_TRACE_DISABLE,
112 .handle = gk20a_get_platform(g->dev)->virt_handle,
113 };
114 int err;
115
116 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
117 err = err ? err : msg.ret;
118 WARN_ON(err);
119 return err;
120}
121
122static int vgpu_fecs_trace_poll(struct gk20a *g)
123{
124 struct tegra_vgpu_cmd_msg msg = {
125 .cmd = TEGRA_VGPU_CMD_FECS_TRACE_POLL,
126 .handle = gk20a_get_platform(g->dev)->virt_handle,
127 };
128 int err;
129
130 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
131 err = err ? err : msg.ret;
132 WARN_ON(err);
133 return err;
134}
135
136static int vgpu_alloc_user_buffer(struct gk20a *g, void **buf, size_t *size)
137{
138 struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace;
139
140 *buf = vcst->buf;
141 *size = vcst->cookie->size;
142 return 0;
143}
144
145static int vgpu_free_user_buffer(struct gk20a *g)
146{
147 return 0;
148}
149
150static int vgpu_mmap_user_buffer(struct gk20a *g, struct vm_area_struct *vma)
151{
152 struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace;
153 unsigned long size = vcst->cookie->size;
154 unsigned long vsize = vma->vm_end - vma->vm_start;
155
156 size = min(size, vsize);
157 size = round_up(size, PAGE_SIZE);
158
159 return remap_pfn_range(vma, vma->vm_start,
160 vcst->cookie->ipa >> PAGE_SHIFT,
161 size,
162 vma->vm_page_prot);
163}
164
165static int vgpu_fecs_trace_max_entries(struct gk20a *g,
166 struct nvgpu_ctxsw_trace_filter *filter)
167{
168 struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace;
169
170 return vcst->header->num_ents;
171}
172
173#if NVGPU_CTXSW_FILTER_SIZE != TEGRA_VGPU_FECS_TRACE_FILTER_SIZE
174#error "FECS trace filter size mismatch!"
175#endif
176
177static int vgpu_fecs_trace_set_filter(struct gk20a *g,
178 struct nvgpu_ctxsw_trace_filter *filter)
179{
180 struct tegra_vgpu_cmd_msg msg = {
181 .cmd = TEGRA_VGPU_CMD_FECS_TRACE_SET_FILTER,
182 .handle = gk20a_get_platform(g->dev)->virt_handle,
183 };
184 struct tegra_vgpu_fecs_trace_filter *p = &msg.params.fecs_trace_filter;
185 int err;
186
187 memcpy(&p->tag_bits, &filter->tag_bits, sizeof(p->tag_bits));
188 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
189 err = err ? err : msg.ret;
190 WARN_ON(err);
191 return err;
192}
193
18void vgpu_init_fecs_trace_ops(struct gpu_ops *ops) 194void vgpu_init_fecs_trace_ops(struct gpu_ops *ops)
19{ 195{
20 memset(&ops->fecs_trace, 0, sizeof(ops->fecs_trace)); 196 ops->fecs_trace.init = vgpu_fecs_trace_init;
197 ops->fecs_trace.deinit = vgpu_fecs_trace_deinit;
198 ops->fecs_trace.enable = vgpu_fecs_trace_enable;
199 ops->fecs_trace.disable = vgpu_fecs_trace_disable;
200 ops->fecs_trace.reset = NULL;
201 ops->fecs_trace.flush = NULL;
202 ops->fecs_trace.poll = vgpu_fecs_trace_poll;
203 ops->fecs_trace.bind_channel = NULL;
204 ops->fecs_trace.unbind_channel = NULL;
205 ops->fecs_trace.max_entries = vgpu_fecs_trace_max_entries;
206 ops->fecs_trace.alloc_user_buffer = vgpu_alloc_user_buffer;
207 ops->fecs_trace.free_user_buffer = vgpu_free_user_buffer;
208 ops->fecs_trace.mmap_user_buffer = vgpu_mmap_user_buffer;
209 ops->fecs_trace.set_filter = vgpu_fecs_trace_set_filter;
210}
211
212void vgpu_fecs_trace_data_update(struct gk20a *g)
213{
214 gk20a_ctxsw_trace_wake_up(g, 0);
21} 215}