summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
authorAingara Paramakuru <aparamakuru@nvidia.com>2014-05-05 21:14:22 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:01 -0400
commit1fd722f592c2e0523c5e399a2406a4e387057188 (patch)
tree3425fb1a08ec2ccc6397e39c73a5579117e00a05 /drivers/gpu/nvgpu/gk20a
parent69e0cd3dfd8f39bc8d3529325001dcacd774f669 (diff)
gpu: nvgpu: support gk20a virtualization
The nvgpu driver now supports using the Tegra graphics virtualization interfaces to support gk20a in a virtualized environment. Bug 1509608 Change-Id: I6ede15ee7bf0b0ad8a13e8eb5f557c3516ead676 Signed-off-by: Aingara Paramakuru <aparamakuru@nvidia.com> Reviewed-on: http://git-master/r/440122 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r--drivers/gpu/nvgpu/gk20a/Makefile1
-rw-r--r--drivers/gpu/nvgpu/gk20a/as_gk20a.c5
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c89
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h11
-rw-r--r--drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c10
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c9
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c46
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h49
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c7
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c115
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h35
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a.h9
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_vgpu_tegra.c64
13 files changed, 349 insertions, 101 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/Makefile b/drivers/gpu/nvgpu/gk20a/Makefile
index aa9237b4..fbc9cbec 100644
--- a/drivers/gpu/nvgpu/gk20a/Makefile
+++ b/drivers/gpu/nvgpu/gk20a/Makefile
@@ -39,5 +39,6 @@ nvgpu-y := \
39 tsg_gk20a.o 39 tsg_gk20a.o
40nvgpu-$(CONFIG_TEGRA_GK20A) += platform_gk20a_tegra.o 40nvgpu-$(CONFIG_TEGRA_GK20A) += platform_gk20a_tegra.o
41nvgpu-$(CONFIG_SYNC) += sync_gk20a.o 41nvgpu-$(CONFIG_SYNC) += sync_gk20a.o
42nvgpu-$(CONFIG_TEGRA_GR_VIRTUALIZATION) += platform_vgpu_tegra.o
42 43
43obj-$(CONFIG_GK20A) := nvgpu.o 44obj-$(CONFIG_GK20A) := nvgpu.o
diff --git a/drivers/gpu/nvgpu/gk20a/as_gk20a.c b/drivers/gpu/nvgpu/gk20a/as_gk20a.c
index 4849dbd5..1a1ca8ff 100644
--- a/drivers/gpu/nvgpu/gk20a/as_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/as_gk20a.c
@@ -40,6 +40,7 @@ static void release_as_share_id(struct gk20a_as *as, int id)
40static int gk20a_as_alloc_share(struct gk20a_as *as, 40static int gk20a_as_alloc_share(struct gk20a_as *as,
41 struct gk20a_as_share **out) 41 struct gk20a_as_share **out)
42{ 42{
43 struct gk20a *g = gk20a_from_as(as);
43 struct gk20a_as_share *as_share; 44 struct gk20a_as_share *as_share;
44 int err = 0; 45 int err = 0;
45 46
@@ -55,7 +56,7 @@ static int gk20a_as_alloc_share(struct gk20a_as *as,
55 as_share->ref_cnt.counter = 1; 56 as_share->ref_cnt.counter = 1;
56 57
57 /* this will set as_share->vm. */ 58 /* this will set as_share->vm. */
58 err = gk20a_vm_alloc_share(as_share); 59 err = g->ops.mm.vm_alloc_share(as_share);
59 if (err) 60 if (err)
60 goto failed; 61 goto failed;
61 62
@@ -106,7 +107,7 @@ static int gk20a_as_ioctl_bind_channel(
106 atomic_inc(&as_share->ref_cnt); 107 atomic_inc(&as_share->ref_cnt);
107 108
108 /* this will set channel_gk20a->vm */ 109 /* this will set channel_gk20a->vm */
109 err = gk20a_vm_bind_channel(as_share, ch); 110 err = ch->g->ops.mm.vm_bind_channel(as_share, ch);
110 if (err) { 111 if (err) {
111 atomic_dec(&as_share->ref_cnt); 112 atomic_dec(&as_share->ref_cnt);
112 return err; 113 return err;
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 45757884..669ec294 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -56,16 +56,9 @@ static void channel_gk20a_free_priv_cmdbuf(struct channel_gk20a *c);
56 56
57static int channel_gk20a_commit_userd(struct channel_gk20a *c); 57static int channel_gk20a_commit_userd(struct channel_gk20a *c);
58static int channel_gk20a_setup_userd(struct channel_gk20a *c); 58static int channel_gk20a_setup_userd(struct channel_gk20a *c);
59static int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
60 u64 gpfifo_base, u32 gpfifo_entries);
61 59
62static void channel_gk20a_bind(struct channel_gk20a *ch_gk20a); 60static void channel_gk20a_bind(struct channel_gk20a *ch_gk20a);
63 61
64static int channel_gk20a_alloc_inst(struct gk20a *g,
65 struct channel_gk20a *ch);
66static void channel_gk20a_free_inst(struct gk20a *g,
67 struct channel_gk20a *ch);
68
69static int channel_gk20a_update_runlist(struct channel_gk20a *c, 62static int channel_gk20a_update_runlist(struct channel_gk20a *c,
70 bool add); 63 bool add);
71static void gk20a_free_error_notifiers(struct channel_gk20a *ch); 64static void gk20a_free_error_notifiers(struct channel_gk20a *ch);
@@ -173,12 +166,10 @@ static int channel_gk20a_set_schedule_params(struct channel_gk20a *c,
173 return -ENOMEM; 166 return -ENOMEM;
174 167
175 /* disable channel */ 168 /* disable channel */
176 gk20a_writel(c->g, ccsr_channel_r(c->hw_chid), 169 c->g->ops.fifo.disable_channel(c);
177 gk20a_readl(c->g, ccsr_channel_r(c->hw_chid)) |
178 ccsr_channel_enable_clr_true_f());
179 170
180 /* preempt the channel */ 171 /* preempt the channel */
181 WARN_ON(gk20a_fifo_preempt_channel(c->g, c->hw_chid)); 172 WARN_ON(c->g->ops.fifo.preempt_channel(c->g, c->hw_chid));
182 173
183 /* value field is 8 bits long */ 174 /* value field is 8 bits long */
184 while (value >= 1 << 8) { 175 while (value >= 1 << 8) {
@@ -206,8 +197,8 @@ static int channel_gk20a_set_schedule_params(struct channel_gk20a *c,
206 return 0; 197 return 0;
207} 198}
208 199
209static int channel_gk20a_setup_ramfc(struct channel_gk20a *c, 200int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
210 u64 gpfifo_base, u32 gpfifo_entries) 201 u64 gpfifo_base, u32 gpfifo_entries)
211{ 202{
212 void *inst_ptr; 203 void *inst_ptr;
213 204
@@ -269,7 +260,7 @@ static int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
269 260
270 gk20a_mem_wr32(inst_ptr, ram_fc_chid_w(), ram_fc_chid_id_f(c->hw_chid)); 261 gk20a_mem_wr32(inst_ptr, ram_fc_chid_w(), ram_fc_chid_id_f(c->hw_chid));
271 262
272 return 0; 263 return channel_gk20a_commit_userd(c);
273} 264}
274 265
275static int channel_gk20a_setup_userd(struct channel_gk20a *c) 266static int channel_gk20a_setup_userd(struct channel_gk20a *c)
@@ -347,8 +338,7 @@ void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a)
347 } 338 }
348} 339}
349 340
350static int channel_gk20a_alloc_inst(struct gk20a *g, 341int channel_gk20a_alloc_inst(struct gk20a *g, struct channel_gk20a *ch)
351 struct channel_gk20a *ch)
352{ 342{
353 struct device *d = dev_from_gk20a(g); 343 struct device *d = dev_from_gk20a(g);
354 int err = 0; 344 int err = 0;
@@ -384,12 +374,11 @@ static int channel_gk20a_alloc_inst(struct gk20a *g,
384 374
385clean_up: 375clean_up:
386 gk20a_err(d, "fail"); 376 gk20a_err(d, "fail");
387 channel_gk20a_free_inst(g, ch); 377 g->ops.fifo.free_inst(g, ch);
388 return err; 378 return err;
389} 379}
390 380
391static void channel_gk20a_free_inst(struct gk20a *g, 381void channel_gk20a_free_inst(struct gk20a *g, struct channel_gk20a *ch)
392 struct channel_gk20a *ch)
393{ 382{
394 struct device *d = dev_from_gk20a(g); 383 struct device *d = dev_from_gk20a(g);
395 384
@@ -403,7 +392,16 @@ static void channel_gk20a_free_inst(struct gk20a *g,
403 392
404static int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add) 393static int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add)
405{ 394{
406 return gk20a_fifo_update_runlist(c->g, 0, c->hw_chid, add, true); 395 return c->g->ops.fifo.update_runlist(c->g, 0, c->hw_chid, add, true);
396}
397
398void channel_gk20a_disable(struct channel_gk20a *ch)
399{
400 /* disable channel */
401 gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid),
402 gk20a_readl(ch->g,
403 ccsr_channel_r(ch->hw_chid)) |
404 ccsr_channel_enable_clr_true_f());
407} 405}
408 406
409void gk20a_channel_abort(struct channel_gk20a *ch) 407void gk20a_channel_abort(struct channel_gk20a *ch)
@@ -426,11 +424,7 @@ void gk20a_channel_abort(struct channel_gk20a *ch)
426 } 424 }
427 mutex_unlock(&ch->jobs_lock); 425 mutex_unlock(&ch->jobs_lock);
428 426
429 /* disable channel */ 427 ch->g->ops.fifo.disable_channel(ch);
430 gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid),
431 gk20a_readl(ch->g,
432 ccsr_channel_r(ch->hw_chid)) |
433 ccsr_channel_enable_clr_true_f());
434 428
435 if (released_job_semaphore) { 429 if (released_job_semaphore) {
436 wake_up_interruptible_all(&ch->semaphore_wq); 430 wake_up_interruptible_all(&ch->semaphore_wq);
@@ -479,7 +473,7 @@ void gk20a_disable_channel(struct channel_gk20a *ch,
479 gk20a_wait_channel_idle(ch); 473 gk20a_wait_channel_idle(ch);
480 474
481 /* preempt the channel */ 475 /* preempt the channel */
482 gk20a_fifo_preempt_channel(ch->g, ch->hw_chid); 476 ch->g->ops.fifo.preempt_channel(ch->g, ch->hw_chid);
483 477
484 /* remove channel from runlist */ 478 /* remove channel from runlist */
485 channel_gk20a_update_runlist(ch, false); 479 channel_gk20a_update_runlist(ch, false);
@@ -643,7 +637,7 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
643 gk20a_free_error_notifiers(ch); 637 gk20a_free_error_notifiers(ch);
644 638
645 /* release channel ctx */ 639 /* release channel ctx */
646 gk20a_free_channel_ctx(ch); 640 g->ops.gr.free_channel_ctx(ch);
647 641
648 gk20a_gr_flush_channel_tlb(gr); 642 gk20a_gr_flush_channel_tlb(gr);
649 643
@@ -683,8 +677,8 @@ unbind:
683 if (gk20a_is_channel_marked_as_tsg(ch)) 677 if (gk20a_is_channel_marked_as_tsg(ch))
684 gk20a_tsg_unbind_channel(ch); 678 gk20a_tsg_unbind_channel(ch);
685 679
686 channel_gk20a_unbind(ch); 680 g->ops.fifo.unbind_channel(ch);
687 channel_gk20a_free_inst(g, ch); 681 g->ops.fifo.free_inst(g, ch);
688 682
689 ch->vpr = false; 683 ch->vpr = false;
690 ch->vm = NULL; 684 ch->vm = NULL;
@@ -747,7 +741,7 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
747 741
748 ch->g = g; 742 ch->g = g;
749 743
750 if (channel_gk20a_alloc_inst(g, ch)) { 744 if (g->ops.fifo.alloc_inst(g, ch)) {
751 ch->in_use = false; 745 ch->in_use = false;
752 gk20a_err(dev_from_gk20a(g), 746 gk20a_err(dev_from_gk20a(g),
753 "failed to open gk20a channel, out of inst mem"); 747 "failed to open gk20a channel, out of inst mem");
@@ -1097,7 +1091,6 @@ static void recycle_priv_cmdbuf(struct channel_gk20a *c)
1097 gk20a_dbg_fn("done"); 1091 gk20a_dbg_fn("done");
1098} 1092}
1099 1093
1100
1101int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c, 1094int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c,
1102 struct nvhost_alloc_gpfifo_args *args) 1095 struct nvhost_alloc_gpfifo_args *args)
1103{ 1096{
@@ -1181,10 +1174,11 @@ int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c,
1181 gk20a_dbg_info("channel %d : gpfifo_base 0x%016llx, size %d", 1174 gk20a_dbg_info("channel %d : gpfifo_base 0x%016llx, size %d",
1182 c->hw_chid, c->gpfifo.gpu_va, c->gpfifo.entry_num); 1175 c->hw_chid, c->gpfifo.gpu_va, c->gpfifo.entry_num);
1183 1176
1184 channel_gk20a_setup_ramfc(c, c->gpfifo.gpu_va, c->gpfifo.entry_num);
1185
1186 channel_gk20a_setup_userd(c); 1177 channel_gk20a_setup_userd(c);
1187 channel_gk20a_commit_userd(c); 1178
1179 err = g->ops.fifo.setup_ramfc(c, c->gpfifo.gpu_va, c->gpfifo.entry_num);
1180 if (err)
1181 goto clean_up_unmap;
1188 1182
1189 /* TBD: setup engine contexts */ 1183 /* TBD: setup engine contexts */
1190 1184
@@ -1550,7 +1544,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
1550 /* We don't know what context is currently running... */ 1544 /* We don't know what context is currently running... */
1551 /* Note also: there can be more than one context associated with the */ 1545 /* Note also: there can be more than one context associated with the */
1552 /* address space (vm). */ 1546 /* address space (vm). */
1553 gk20a_mm_tlb_invalidate(c->vm); 1547 g->ops.mm.tlb_invalidate(c->vm);
1554 1548
1555 /* Make sure we have enough space for gpfifo entries. If not, 1549 /* Make sure we have enough space for gpfifo entries. If not,
1556 * wait for signals from completed submits */ 1550 * wait for signals from completed submits */
@@ -1929,7 +1923,7 @@ static int gk20a_channel_zcull_bind(struct channel_gk20a *ch,
1929 1923
1930 gk20a_dbg_fn(""); 1924 gk20a_dbg_fn("");
1931 1925
1932 return gr_gk20a_bind_ctxsw_zcull(g, gr, ch, 1926 return g->ops.gr.bind_ctxsw_zcull(g, gr, ch,
1933 args->gpu_va, args->mode); 1927 args->gpu_va, args->mode);
1934} 1928}
1935 1929
@@ -1945,7 +1939,7 @@ int gk20a_channel_suspend(struct gk20a *g)
1945 gk20a_dbg_fn(""); 1939 gk20a_dbg_fn("");
1946 1940
1947 /* wait for engine idle */ 1941 /* wait for engine idle */
1948 err = gk20a_fifo_wait_engine_idle(g); 1942 err = g->ops.fifo.wait_engine_idle(g);
1949 if (err) 1943 if (err)
1950 return err; 1944 return err;
1951 1945
@@ -1954,22 +1948,20 @@ int gk20a_channel_suspend(struct gk20a *g)
1954 1948
1955 gk20a_dbg_info("suspend channel %d", chid); 1949 gk20a_dbg_info("suspend channel %d", chid);
1956 /* disable channel */ 1950 /* disable channel */
1957 gk20a_writel(g, ccsr_channel_r(chid), 1951 g->ops.fifo.disable_channel(&f->channel[chid]);
1958 gk20a_readl(g, ccsr_channel_r(chid)) |
1959 ccsr_channel_enable_clr_true_f());
1960 /* preempt the channel */ 1952 /* preempt the channel */
1961 gk20a_fifo_preempt_channel(g, chid); 1953 g->ops.fifo.preempt_channel(g, chid);
1962 1954
1963 channels_in_use = true; 1955 channels_in_use = true;
1964 } 1956 }
1965 } 1957 }
1966 1958
1967 if (channels_in_use) { 1959 if (channels_in_use) {
1968 gk20a_fifo_update_runlist(g, 0, ~0, false, true); 1960 g->ops.fifo.update_runlist(g, 0, ~0, false, true);
1969 1961
1970 for (chid = 0; chid < f->num_channels; chid++) { 1962 for (chid = 0; chid < f->num_channels; chid++) {
1971 if (f->channel[chid].in_use) 1963 if (f->channel[chid].in_use)
1972 channel_gk20a_unbind(&f->channel[chid]); 1964 g->ops.fifo.unbind_channel(&f->channel[chid]);
1973 } 1965 }
1974 } 1966 }
1975 1967
@@ -1996,7 +1988,7 @@ int gk20a_channel_resume(struct gk20a *g)
1996 } 1988 }
1997 1989
1998 if (channels_in_use) 1990 if (channels_in_use)
1999 gk20a_fifo_update_runlist(g, 0, ~0, true, true); 1991 g->ops.fifo.update_runlist(g, 0, ~0, true, true);
2000 1992
2001 gk20a_dbg_fn("done"); 1993 gk20a_dbg_fn("done");
2002 return 0; 1994 return 0;
@@ -2074,6 +2066,11 @@ clean_up:
2074void gk20a_init_channel(struct gpu_ops *gops) 2066void gk20a_init_channel(struct gpu_ops *gops)
2075{ 2067{
2076 gops->fifo.bind_channel = channel_gk20a_bind; 2068 gops->fifo.bind_channel = channel_gk20a_bind;
2069 gops->fifo.unbind_channel = channel_gk20a_unbind;
2070 gops->fifo.disable_channel = channel_gk20a_disable;
2071 gops->fifo.alloc_inst = channel_gk20a_alloc_inst;
2072 gops->fifo.free_inst = channel_gk20a_free_inst;
2073 gops->fifo.setup_ramfc = channel_gk20a_setup_ramfc;
2077} 2074}
2078 2075
2079long gk20a_channel_ioctl(struct file *filp, 2076long gk20a_channel_ioctl(struct file *filp,
@@ -2144,7 +2141,7 @@ long gk20a_channel_ioctl(struct file *filp,
2144 __func__, cmd); 2141 __func__, cmd);
2145 return err; 2142 return err;
2146 } 2143 }
2147 err = gk20a_alloc_obj_ctx(ch, 2144 err = ch->g->ops.gr.alloc_obj_ctx(ch,
2148 (struct nvhost_alloc_obj_ctx_args *)buf); 2145 (struct nvhost_alloc_obj_ctx_args *)buf);
2149 gk20a_idle(dev); 2146 gk20a_idle(dev);
2150 break; 2147 break;
@@ -2156,7 +2153,7 @@ long gk20a_channel_ioctl(struct file *filp,
2156 __func__, cmd); 2153 __func__, cmd);
2157 return err; 2154 return err;
2158 } 2155 }
2159 err = gk20a_free_obj_ctx(ch, 2156 err = ch->g->ops.gr.free_obj_ctx(ch,
2160 (struct nvhost_free_obj_ctx_args *)buf); 2157 (struct nvhost_free_obj_ctx_args *)buf);
2161 gk20a_idle(dev); 2158 gk20a_idle(dev);
2162 break; 2159 break;
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index 2ea3eccb..37ca8244 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -144,6 +144,10 @@ struct channel_gk20a {
144 void *error_notifier_va; 144 void *error_notifier_va;
145 145
146 struct gk20a_channel_sync *sync; 146 struct gk20a_channel_sync *sync;
147
148#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
149 u64 virt_ctx;
150#endif
147}; 151};
148 152
149static inline bool gk20a_channel_as_bound(struct channel_gk20a *ch) 153static inline bool gk20a_channel_as_bound(struct channel_gk20a *ch)
@@ -193,4 +197,11 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
193int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c, 197int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c,
194 struct nvhost_alloc_gpfifo_args *args); 198 struct nvhost_alloc_gpfifo_args *args);
195 199
200void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a);
201void channel_gk20a_disable(struct channel_gk20a *ch);
202int channel_gk20a_alloc_inst(struct gk20a *g, struct channel_gk20a *ch);
203void channel_gk20a_free_inst(struct gk20a *g, struct channel_gk20a *ch);
204int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
205 u64 gpfifo_base, u32 gpfifo_entries);
206
196#endif /*__CHANNEL_GK20A_H__*/ 207#endif /*__CHANNEL_GK20A_H__*/
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
index e5628c3f..7338f842 100644
--- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
@@ -158,6 +158,9 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg
158 struct zbc_entry *zbc_val; 158 struct zbc_entry *zbc_val;
159 struct zbc_query_params *zbc_tbl; 159 struct zbc_query_params *zbc_tbl;
160 int i, err = 0; 160 int i, err = 0;
161#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
162 struct gk20a_platform *platform = platform_get_drvdata(dev);
163#endif
161 164
162 gk20a_dbg_fn(""); 165 gk20a_dbg_fn("");
163 166
@@ -197,7 +200,7 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg
197 if (zcull_info == NULL) 200 if (zcull_info == NULL)
198 return -ENOMEM; 201 return -ENOMEM;
199 202
200 err = gr_gk20a_get_zcull_info(g, &g->gr, zcull_info); 203 err = g->ops.gr.get_zcull_info(g, &g->gr, zcull_info);
201 if (err) { 204 if (err) {
202 kfree(zcull_info); 205 kfree(zcull_info);
203 break; 206 break;
@@ -219,6 +222,11 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg
219 case NVHOST_GPU_IOCTL_ZBC_SET_TABLE: 222 case NVHOST_GPU_IOCTL_ZBC_SET_TABLE:
220 set_table_args = (struct nvhost_gpu_zbc_set_table_args *)buf; 223 set_table_args = (struct nvhost_gpu_zbc_set_table_args *)buf;
221 224
225#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
226 if (platform->virtual_dev)
227 return -ENOMEM;
228#endif
229
222 zbc_val = kzalloc(sizeof(struct zbc_entry), GFP_KERNEL); 230 zbc_val = kzalloc(sizeof(struct zbc_entry), GFP_KERNEL);
223 if (zbc_val == NULL) 231 if (zbc_val == NULL)
224 return -ENOMEM; 232 return -ENOMEM;
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 4363129d..e6b3fd5f 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -1173,7 +1173,7 @@ void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose)
1173 1173
1174 gk20a_channel_abort(ch); 1174 gk20a_channel_abort(ch);
1175 for (i = 0; i < g->fifo.max_runlists; i++) 1175 for (i = 0; i < g->fifo.max_runlists; i++)
1176 gk20a_fifo_update_runlist(g, i, 1176 g->ops.fifo.update_runlist(g, i,
1177 hw_chid, false, false); 1177 hw_chid, false, false);
1178 1178
1179 if (gk20a_fifo_set_ctx_mmu_error(g, ch)) 1179 if (gk20a_fifo_set_ctx_mmu_error(g, ch))
@@ -1620,7 +1620,7 @@ int gk20a_fifo_disable_engine_activity(struct gk20a *g,
1620 pbdma_chid = fifo_pbdma_status_next_id_v(pbdma_stat); 1620 pbdma_chid = fifo_pbdma_status_next_id_v(pbdma_stat);
1621 1621
1622 if (pbdma_chid != ~0) { 1622 if (pbdma_chid != ~0) {
1623 err = gk20a_fifo_preempt_channel(g, pbdma_chid); 1623 err = g->ops.fifo.preempt_channel(g, pbdma_chid);
1624 if (err) 1624 if (err)
1625 goto clean_up; 1625 goto clean_up;
1626 } 1626 }
@@ -1636,7 +1636,7 @@ int gk20a_fifo_disable_engine_activity(struct gk20a *g,
1636 engine_chid = fifo_engine_status_next_id_v(eng_stat); 1636 engine_chid = fifo_engine_status_next_id_v(eng_stat);
1637 1637
1638 if (engine_chid != ~0 && engine_chid != pbdma_chid) { 1638 if (engine_chid != ~0 && engine_chid != pbdma_chid) {
1639 err = gk20a_fifo_preempt_channel(g, engine_chid); 1639 err = g->ops.fifo.preempt_channel(g, engine_chid);
1640 if (err) 1640 if (err)
1641 goto clean_up; 1641 goto clean_up;
1642 } 1642 }
@@ -1960,6 +1960,9 @@ static void gk20a_fifo_apply_pb_timeout(struct gk20a *g)
1960void gk20a_init_fifo(struct gpu_ops *gops) 1960void gk20a_init_fifo(struct gpu_ops *gops)
1961{ 1961{
1962 gk20a_init_channel(gops); 1962 gk20a_init_channel(gops);
1963 gops->fifo.preempt_channel = gk20a_fifo_preempt_channel;
1964 gops->fifo.update_runlist = gk20a_fifo_update_runlist;
1963 gops->fifo.trigger_mmu_fault = gk20a_fifo_trigger_mmu_fault; 1965 gops->fifo.trigger_mmu_fault = gk20a_fifo_trigger_mmu_fault;
1964 gops->fifo.apply_pb_timeout = gk20a_fifo_apply_pb_timeout; 1966 gops->fifo.apply_pb_timeout = gk20a_fifo_apply_pb_timeout;
1967 gops->fifo.wait_engine_idle = gk20a_fifo_wait_engine_idle;
1965} 1968}
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 0816878a..3499cc89 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -40,6 +40,7 @@
40#include <linux/tegra-powergate.h> 40#include <linux/tegra-powergate.h>
41#include <linux/tegra_pm_domains.h> 41#include <linux/tegra_pm_domains.h>
42#include <linux/clk/tegra.h> 42#include <linux/clk/tegra.h>
43#include <linux/kthread.h>
43 44
44#include <linux/sched.h> 45#include <linux/sched.h>
45#include <linux/input-cfboost.h> 46#include <linux/input-cfboost.h>
@@ -57,6 +58,9 @@
57#include "dbg_gpu_gk20a.h" 58#include "dbg_gpu_gk20a.h"
58#include "hal.h" 59#include "hal.h"
59#include "nvhost_acm.h" 60#include "nvhost_acm.h"
61#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
62#include "vgpu/vgpu.h"
63#endif
60 64
61#define CREATE_TRACE_POINTS 65#define CREATE_TRACE_POINTS
62#include <trace/events/gk20a.h> 66#include <trace/events/gk20a.h>
@@ -737,6 +741,17 @@ static int gk20a_init_client(struct platform_device *dev)
737 741
738 gk20a_dbg_fn(""); 742 gk20a_dbg_fn("");
739 743
744#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
745 {
746 struct gk20a_platform *platform = gk20a_get_platform(dev);
747
748 if (platform->virtual_dev) {
749 err = vgpu_pm_finalize_poweron(&dev->dev);
750 if (err)
751 return err;
752 }
753 }
754#endif
740#ifndef CONFIG_PM_RUNTIME 755#ifndef CONFIG_PM_RUNTIME
741 gk20a_pm_finalize_poweron(&dev->dev); 756 gk20a_pm_finalize_poweron(&dev->dev);
742#endif 757#endif
@@ -753,6 +768,16 @@ static int gk20a_init_client(struct platform_device *dev)
753static void gk20a_deinit_client(struct platform_device *dev) 768static void gk20a_deinit_client(struct platform_device *dev)
754{ 769{
755 gk20a_dbg_fn(""); 770 gk20a_dbg_fn("");
771#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
772 {
773 struct gk20a_platform *platform = gk20a_get_platform(dev);
774
775 if (platform->virtual_dev) {
776 vgpu_pm_prepare_poweroff(&dev->dev);
777 return;
778 }
779 }
780#endif
756#ifndef CONFIG_PM_RUNTIME 781#ifndef CONFIG_PM_RUNTIME
757 gk20a_pm_prepare_poweroff(&dev->dev); 782 gk20a_pm_prepare_poweroff(&dev->dev);
758#endif 783#endif
@@ -1006,6 +1031,10 @@ static struct of_device_id tegra_gk20a_of_match[] = {
1006 .data = &gk20a_tegra_platform }, 1031 .data = &gk20a_tegra_platform },
1007 { .compatible = "nvidia,tegra210-gm20b", 1032 { .compatible = "nvidia,tegra210-gm20b",
1008 .data = &gm20b_tegra_platform }, 1033 .data = &gm20b_tegra_platform },
1034#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
1035 { .compatible = "nvidia,tegra124-gk20a-vgpu",
1036 .data = &vgpu_tegra_platform },
1037#endif
1009#else 1038#else
1010 { .compatible = "nvidia,tegra124-gk20a", 1039 { .compatible = "nvidia,tegra124-gk20a",
1011 .data = &gk20a_generic_platform }, 1040 .data = &gk20a_generic_platform },
@@ -1057,7 +1086,7 @@ static int gk20a_create_device(
1057 return 0; 1086 return 0;
1058} 1087}
1059 1088
1060static void gk20a_user_deinit(struct platform_device *dev) 1089void gk20a_user_deinit(struct platform_device *dev)
1061{ 1090{
1062 struct gk20a *g = get_gk20a(dev); 1091 struct gk20a *g = get_gk20a(dev);
1063 1092
@@ -1098,7 +1127,7 @@ static void gk20a_user_deinit(struct platform_device *dev)
1098 class_destroy(g->class); 1127 class_destroy(g->class);
1099} 1128}
1100 1129
1101static int gk20a_user_init(struct platform_device *dev) 1130int gk20a_user_init(struct platform_device *dev)
1102{ 1131{
1103 int err; 1132 int err;
1104 dev_t devno; 1133 dev_t devno;
@@ -1403,6 +1432,11 @@ static int gk20a_probe(struct platform_device *dev)
1403 1432
1404 platform_set_drvdata(dev, platform); 1433 platform_set_drvdata(dev, platform);
1405 1434
1435#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
1436 if (platform->virtual_dev)
1437 return vgpu_probe(dev);
1438#endif
1439
1406 gk20a = kzalloc(sizeof(struct gk20a), GFP_KERNEL); 1440 gk20a = kzalloc(sizeof(struct gk20a), GFP_KERNEL);
1407 if (!gk20a) { 1441 if (!gk20a) {
1408 dev_err(&dev->dev, "couldn't allocate gk20a support"); 1442 dev_err(&dev->dev, "couldn't allocate gk20a support");
@@ -1546,8 +1580,16 @@ static int gk20a_probe(struct platform_device *dev)
1546static int __exit gk20a_remove(struct platform_device *dev) 1580static int __exit gk20a_remove(struct platform_device *dev)
1547{ 1581{
1548 struct gk20a *g = get_gk20a(dev); 1582 struct gk20a *g = get_gk20a(dev);
1583#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
1584 struct gk20a_platform *platform = gk20a_get_platform(dev);
1585#endif
1549 gk20a_dbg_fn(""); 1586 gk20a_dbg_fn("");
1550 1587
1588#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
1589 if (platform->virtual_dev)
1590 return vgpu_remove(dev);
1591#endif
1592
1551#ifdef CONFIG_INPUT_CFBOOST 1593#ifdef CONFIG_INPUT_CFBOOST
1552 if (g->boost_added) 1594 if (g->boost_added)
1553 cfb_remove_device(&dev->dev); 1595 cfb_remove_device(&dev->dev);
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index a1080f0b..b813541a 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -131,6 +131,16 @@ struct gpu_ops {
131 u32 reg_offset); 131 u32 reg_offset);
132 int (*load_ctxsw_ucode)(struct gk20a *g); 132 int (*load_ctxsw_ucode)(struct gk20a *g);
133 u32 (*get_gpc_tpc_mask)(struct gk20a *g, u32 gpc_index); 133 u32 (*get_gpc_tpc_mask)(struct gk20a *g, u32 gpc_index);
134 void (*free_channel_ctx)(struct channel_gk20a *c);
135 int (*alloc_obj_ctx)(struct channel_gk20a *c,
136 struct nvhost_alloc_obj_ctx_args *args);
137 int (*free_obj_ctx)(struct channel_gk20a *c,
138 struct nvhost_free_obj_ctx_args *args);
139 int (*bind_ctxsw_zcull)(struct gk20a *g, struct gr_gk20a *gr,
140 struct channel_gk20a *c, u64 zcull_va,
141 u32 mode);
142 int (*get_zcull_info)(struct gk20a *g, struct gr_gk20a *gr,
143 struct gr_zcull_info *zcull_params);
134 } gr; 144 } gr;
135 const char *name; 145 const char *name;
136 struct { 146 struct {
@@ -148,9 +158,20 @@ struct gpu_ops {
148 } clock_gating; 158 } clock_gating;
149 struct { 159 struct {
150 void (*bind_channel)(struct channel_gk20a *ch_gk20a); 160 void (*bind_channel)(struct channel_gk20a *ch_gk20a);
161 void (*unbind_channel)(struct channel_gk20a *ch_gk20a);
162 void (*disable_channel)(struct channel_gk20a *ch);
163 int (*alloc_inst)(struct gk20a *g, struct channel_gk20a *ch);
164 void (*free_inst)(struct gk20a *g, struct channel_gk20a *ch);
165 int (*setup_ramfc)(struct channel_gk20a *c, u64 gpfifo_base,
166 u32 gpfifo_entries);
167 int (*preempt_channel)(struct gk20a *g, u32 hw_chid);
168 int (*update_runlist)(struct gk20a *g, u32 runlist_id,
169 u32 hw_chid, bool add,
170 bool wait_for_finish);
151 void (*trigger_mmu_fault)(struct gk20a *g, 171 void (*trigger_mmu_fault)(struct gk20a *g,
152 unsigned long engine_ids); 172 unsigned long engine_ids);
153 void (*apply_pb_timeout)(struct gk20a *g); 173 void (*apply_pb_timeout)(struct gk20a *g);
174 int (*wait_engine_idle)(struct gk20a *g);
154 } fifo; 175 } fifo;
155 struct pmu_v { 176 struct pmu_v {
156 /*used for change of enum zbc update cmd id from ver 0 to ver1*/ 177 /*used for change of enum zbc update cmd id from ver 0 to ver1*/
@@ -241,6 +262,31 @@ struct gpu_ops {
241 void (*clear_sparse)(struct vm_gk20a *vm, u64 vaddr, 262 void (*clear_sparse)(struct vm_gk20a *vm, u64 vaddr,
242 u64 size, u32 pgsz_idx); 263 u64 size, u32 pgsz_idx);
243 bool (*is_debug_mode_enabled)(struct gk20a *g); 264 bool (*is_debug_mode_enabled)(struct gk20a *g);
265 u64 (*gmmu_map)(struct vm_gk20a *vm,
266 u64 map_offset,
267 struct sg_table *sgt,
268 u64 buffer_offset,
269 u64 size,
270 int pgsz_idx,
271 u8 kind_v,
272 u32 ctag_offset,
273 u32 flags,
274 int rw_flag,
275 bool clear_ctags);
276 void (*gmmu_unmap)(struct vm_gk20a *vm,
277 u64 vaddr,
278 u64 size,
279 int pgsz_idx,
280 bool va_allocated,
281 int rw_flag);
282 void (*vm_remove)(struct vm_gk20a *vm);
283 int (*vm_alloc_share)(struct gk20a_as_share *as_share);
284 int (*vm_bind_channel)(struct gk20a_as_share *as_share,
285 struct channel_gk20a *ch);
286 int (*fb_flush)(struct gk20a *g);
287 void (*l2_invalidate)(struct gk20a *g);
288 void (*l2_flush)(struct gk20a *g, bool invalidate);
289 void (*tlb_invalidate)(struct vm_gk20a *vm);
244 } mm; 290 } mm;
245 struct { 291 struct {
246 int (*prepare_ucode)(struct gk20a *g); 292 int (*prepare_ucode)(struct gk20a *g);
@@ -648,4 +694,7 @@ gk20a_request_firmware(struct gk20a *g, const char *fw_name);
648 694
649int gk20a_init_gpu_characteristics(struct gk20a *g); 695int gk20a_init_gpu_characteristics(struct gk20a *g);
650 696
697int gk20a_user_init(struct platform_device *dev);
698void gk20a_user_deinit(struct platform_device *dev);
699
651#endif /* _NVHOST_GK20A_H_ */ 700#endif /* _NVHOST_GK20A_H_ */
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index ef7776df..892a138e 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -825,7 +825,7 @@ static int gr_gk20a_ctx_zcull_setup(struct gk20a *g, struct channel_gk20a *c,
825 } 825 }
826 } 826 }
827 827
828 gk20a_mm_fb_flush(g); 828 g->ops.mm.fb_flush(g);
829 829
830 gk20a_mem_wr32(ctx_ptr + ctxsw_prog_main_image_zcull_o(), 0, 830 gk20a_mem_wr32(ctx_ptr + ctxsw_prog_main_image_zcull_o(), 0,
831 ch_ctx->zcull_ctx.ctx_sw_mode); 831 ch_ctx->zcull_ctx.ctx_sw_mode);
@@ -7077,4 +7077,9 @@ void gk20a_init_gr_ops(struct gpu_ops *gops)
7077 gops->gr.falcon_load_ucode = gr_gk20a_load_ctxsw_ucode_segments; 7077 gops->gr.falcon_load_ucode = gr_gk20a_load_ctxsw_ucode_segments;
7078 gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode; 7078 gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode;
7079 gops->gr.get_gpc_tpc_mask = gr_gk20a_get_gpc_tpc_mask; 7079 gops->gr.get_gpc_tpc_mask = gr_gk20a_get_gpc_tpc_mask;
7080 gops->gr.free_channel_ctx = gk20a_free_channel_ctx;
7081 gops->gr.alloc_obj_ctx = gk20a_alloc_obj_ctx;
7082 gops->gr.free_obj_ctx = gk20a_free_obj_ctx;
7083 gops->gr.bind_ctxsw_zcull = gr_gk20a_bind_ctxsw_zcull;
7084 gops->gr.get_zcull_info = gr_gk20a_get_zcull_info;
7080} 7085}
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 654938b2..3feb675b 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -88,7 +88,6 @@ static inline u32 lo32(u64 f)
88 return (u32)(f & 0xffffffff); 88 return (u32)(f & 0xffffffff);
89} 89}
90 90
91static void gk20a_vm_unmap_locked(struct mapped_buffer_node *mapped_buffer);
92static struct mapped_buffer_node *find_mapped_buffer_locked( 91static struct mapped_buffer_node *find_mapped_buffer_locked(
93 struct rb_root *root, u64 addr); 92 struct rb_root *root, u64 addr);
94static struct mapped_buffer_node *find_mapped_buffer_reverse_locked( 93static struct mapped_buffer_node *find_mapped_buffer_reverse_locked(
@@ -100,7 +99,6 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm,
100 u64 first_vaddr, u64 last_vaddr, 99 u64 first_vaddr, u64 last_vaddr,
101 u8 kind_v, u32 ctag_offset, bool cacheable, 100 u8 kind_v, u32 ctag_offset, bool cacheable,
102 int rw_flag); 101 int rw_flag);
103static void gk20a_vm_remove_support(struct vm_gk20a *vm);
104static int gk20a_init_system_vm(struct mm_gk20a *mm); 102static int gk20a_init_system_vm(struct mm_gk20a *mm);
105static int gk20a_init_bar1_vm(struct mm_gk20a *mm); 103static int gk20a_init_bar1_vm(struct mm_gk20a *mm);
106 104
@@ -335,6 +333,8 @@ int gk20a_init_mm_setup_sw(struct gk20a *g)
335 gk20a_init_bar1_vm(mm); 333 gk20a_init_bar1_vm(mm);
336 gk20a_init_system_vm(mm); 334 gk20a_init_system_vm(mm);
337 335
336 /* set vm_alloc_share op here as gk20a_as_alloc_share needs it */
337 g->ops.mm.vm_alloc_share = gk20a_vm_alloc_share;
338 mm->remove_support = gk20a_remove_mm_support; 338 mm->remove_support = gk20a_remove_mm_support;
339 mm->sw_ready = true; 339 mm->sw_ready = true;
340 340
@@ -833,9 +833,9 @@ static void gk20a_vm_unmap_user(struct vm_gk20a *vm, u64 offset)
833 mutex_unlock(&vm->update_gmmu_lock); 833 mutex_unlock(&vm->update_gmmu_lock);
834} 834}
835 835
836static u64 gk20a_vm_alloc_va(struct vm_gk20a *vm, 836u64 gk20a_vm_alloc_va(struct vm_gk20a *vm,
837 u64 size, 837 u64 size,
838 enum gmmu_pgsz_gk20a gmmu_pgsz_idx) 838 enum gmmu_pgsz_gk20a gmmu_pgsz_idx)
839 839
840{ 840{
841 struct gk20a_allocator *vma = &vm->vma[gmmu_pgsz_idx]; 841 struct gk20a_allocator *vma = &vm->vma[gmmu_pgsz_idx];
@@ -881,9 +881,9 @@ static u64 gk20a_vm_alloc_va(struct vm_gk20a *vm,
881 return offset; 881 return offset;
882} 882}
883 883
884static int gk20a_vm_free_va(struct vm_gk20a *vm, 884int gk20a_vm_free_va(struct vm_gk20a *vm,
885 u64 offset, u64 size, 885 u64 offset, u64 size,
886 enum gmmu_pgsz_gk20a pgsz_idx) 886 enum gmmu_pgsz_gk20a pgsz_idx)
887{ 887{
888 struct gk20a_allocator *vma = &vm->vma[pgsz_idx]; 888 struct gk20a_allocator *vma = &vm->vma[pgsz_idx];
889 u32 page_size = gmmu_page_sizes[pgsz_idx]; 889 u32 page_size = gmmu_page_sizes[pgsz_idx];
@@ -1100,21 +1100,32 @@ static int validate_fixed_buffer(struct vm_gk20a *vm,
1100 return 0; 1100 return 0;
1101} 1101}
1102 1102
1103static u64 __locked_gmmu_map(struct vm_gk20a *vm, 1103u64 gk20a_locked_gmmu_map(struct vm_gk20a *vm,
1104 u64 map_offset, 1104 u64 map_offset,
1105 struct sg_table *sgt, 1105 struct sg_table *sgt,
1106 u64 buffer_offset, 1106 u64 buffer_offset,
1107 u64 size, 1107 u64 size,
1108 int pgsz_idx, 1108 int pgsz_idx,
1109 u8 kind_v, 1109 u8 kind_v,
1110 u32 ctag_offset, 1110 u32 ctag_offset,
1111 u32 flags, 1111 u32 flags,
1112 int rw_flag) 1112 int rw_flag,
1113 bool clear_ctags)
1113{ 1114{
1114 int err = 0, i = 0; 1115 int err = 0, i = 0;
1115 bool allocated = false; 1116 bool allocated = false;
1116 u32 pde_lo, pde_hi; 1117 u32 pde_lo, pde_hi;
1117 struct device *d = dev_from_vm(vm); 1118 struct device *d = dev_from_vm(vm);
1119 struct gk20a *g = gk20a_from_vm(vm);
1120
1121 if (clear_ctags && ctag_offset) {
1122 u32 ctag_lines = ALIGN(size, COMP_TAG_LINE_SIZE) >>
1123 COMP_TAG_LINE_SIZE_SHIFT;
1124
1125 /* init/clear the ctag buffer */
1126 g->ops.ltc.cbc_ctrl(g, gk20a_cbc_op_clear,
1127 ctag_offset, ctag_offset + ctag_lines - 1);
1128 }
1118 1129
1119 /* Allocate (or validate when map_offset != 0) the virtual address. */ 1130 /* Allocate (or validate when map_offset != 0) the virtual address. */
1120 if (!map_offset) { 1131 if (!map_offset) {
@@ -1167,12 +1178,12 @@ fail_alloc:
1167 return 0; 1178 return 0;
1168} 1179}
1169 1180
1170static void __locked_gmmu_unmap(struct vm_gk20a *vm, 1181void gk20a_locked_gmmu_unmap(struct vm_gk20a *vm,
1171 u64 vaddr, 1182 u64 vaddr,
1172 u64 size, 1183 u64 size,
1173 int pgsz_idx, 1184 int pgsz_idx,
1174 bool va_allocated, 1185 bool va_allocated,
1175 int rw_flag) 1186 int rw_flag)
1176{ 1187{
1177 int err = 0; 1188 int err = 0;
1178 struct gk20a *g = gk20a_from_vm(vm); 1189 struct gk20a *g = gk20a_from_vm(vm);
@@ -1298,6 +1309,7 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
1298 struct buffer_attrs bfr = {0}; 1309 struct buffer_attrs bfr = {0};
1299 struct gk20a_comptags comptags; 1310 struct gk20a_comptags comptags;
1300 u64 buf_addr; 1311 u64 buf_addr;
1312 bool clear_ctags = false;
1301 1313
1302 mutex_lock(&vm->update_gmmu_lock); 1314 mutex_lock(&vm->update_gmmu_lock);
1303 1315
@@ -1402,11 +1414,7 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
1402 bfr.kind_v = bfr.uc_kind_v; 1414 bfr.kind_v = bfr.uc_kind_v;
1403 } else { 1415 } else {
1404 gk20a_get_comptags(d, dmabuf, &comptags); 1416 gk20a_get_comptags(d, dmabuf, &comptags);
1405 1417 clear_ctags = true;
1406 /* init/clear the ctag buffer */
1407 g->ops.ltc.cbc_ctrl(g, gk20a_cbc_op_clear,
1408 comptags.offset,
1409 comptags.offset + comptags.lines - 1);
1410 } 1418 }
1411 } 1419 }
1412 1420
@@ -1414,15 +1422,15 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
1414 bfr.ctag_offset = comptags.offset; 1422 bfr.ctag_offset = comptags.offset;
1415 1423
1416 /* update gmmu ptes */ 1424 /* update gmmu ptes */
1417 map_offset = __locked_gmmu_map(vm, map_offset, 1425 map_offset = g->ops.mm.gmmu_map(vm, map_offset,
1418 bfr.sgt, 1426 bfr.sgt,
1419 buffer_offset, /* sg offset */ 1427 buffer_offset, /* sg offset */
1420 mapping_size, 1428 mapping_size,
1421 bfr.pgsz_idx, 1429 bfr.pgsz_idx,
1422 bfr.kind_v, 1430 bfr.kind_v,
1423 bfr.ctag_offset, 1431 bfr.ctag_offset,
1424 flags, rw_flag); 1432 flags, rw_flag,
1425 1433 clear_ctags);
1426 if (!map_offset) 1434 if (!map_offset)
1427 goto clean_up; 1435 goto clean_up;
1428 1436
@@ -1531,17 +1539,18 @@ u64 gk20a_gmmu_map(struct vm_gk20a *vm,
1531 u32 flags, 1539 u32 flags,
1532 int rw_flag) 1540 int rw_flag)
1533{ 1541{
1542 struct gk20a *g = gk20a_from_vm(vm);
1534 u64 vaddr; 1543 u64 vaddr;
1535 1544
1536 mutex_lock(&vm->update_gmmu_lock); 1545 mutex_lock(&vm->update_gmmu_lock);
1537 vaddr = __locked_gmmu_map(vm, 0, /* already mapped? - No */ 1546 vaddr = g->ops.mm.gmmu_map(vm, 0, /* already mapped? - No */
1538 *sgt, /* sg table */ 1547 *sgt, /* sg table */
1539 0, /* sg offset */ 1548 0, /* sg offset */
1540 size, 1549 size,
1541 0, /* page size index = 0 i.e. SZ_4K */ 1550 0, /* page size index = 0 i.e. SZ_4K */
1542 0, /* kind */ 1551 0, /* kind */
1543 0, /* ctag_offset */ 1552 0, /* ctag_offset */
1544 flags, rw_flag); 1553 flags, rw_flag, false);
1545 mutex_unlock(&vm->update_gmmu_lock); 1554 mutex_unlock(&vm->update_gmmu_lock);
1546 if (!vaddr) { 1555 if (!vaddr) {
1547 gk20a_err(dev_from_vm(vm), "failed to allocate va space"); 1556 gk20a_err(dev_from_vm(vm), "failed to allocate va space");
@@ -1549,7 +1558,7 @@ u64 gk20a_gmmu_map(struct vm_gk20a *vm,
1549 } 1558 }
1550 1559
1551 /* Invalidate kernel mappings immediately */ 1560 /* Invalidate kernel mappings immediately */
1552 gk20a_mm_tlb_invalidate(vm); 1561 g->ops.mm.tlb_invalidate(vm);
1553 1562
1554 return vaddr; 1563 return vaddr;
1555} 1564}
@@ -1573,8 +1582,10 @@ void gk20a_gmmu_unmap(struct vm_gk20a *vm,
1573 u64 size, 1582 u64 size,
1574 int rw_flag) 1583 int rw_flag)
1575{ 1584{
1585 struct gk20a *g = gk20a_from_vm(vm);
1586
1576 mutex_lock(&vm->update_gmmu_lock); 1587 mutex_lock(&vm->update_gmmu_lock);
1577 __locked_gmmu_unmap(vm, 1588 g->ops.mm.gmmu_unmap(vm,
1578 vaddr, 1589 vaddr,
1579 size, 1590 size,
1580 0, /* page size 4K */ 1591 0, /* page size 4K */
@@ -1970,10 +1981,10 @@ static int gk20a_vm_put_empty(struct vm_gk20a *vm, u64 vaddr,
1970 } 1981 }
1971 1982
1972 for (i = 0; i < num_pages; i++) { 1983 for (i = 0; i < num_pages; i++) {
1973 u64 page_vaddr = __locked_gmmu_map(vm, vaddr, 1984 u64 page_vaddr = g->ops.mm.gmmu_map(vm, vaddr,
1974 vm->zero_page_sgt, 0, pgsz, pgsz_idx, 0, 0, 1985 vm->zero_page_sgt, 0, pgsz, pgsz_idx, 0, 0,
1975 NVHOST_AS_ALLOC_SPACE_FLAGS_FIXED_OFFSET, 1986 NVHOST_AS_ALLOC_SPACE_FLAGS_FIXED_OFFSET,
1976 gk20a_mem_flag_none); 1987 gk20a_mem_flag_none, false);
1977 1988
1978 if (!page_vaddr) { 1989 if (!page_vaddr) {
1979 gk20a_err(dev_from_vm(vm), "failed to remap clean buffers!"); 1990 gk20a_err(dev_from_vm(vm), "failed to remap clean buffers!");
@@ -1990,7 +2001,7 @@ err_unmap:
1990 /* something went wrong. unmap pages */ 2001 /* something went wrong. unmap pages */
1991 while (i--) { 2002 while (i--) {
1992 vaddr -= pgsz; 2003 vaddr -= pgsz;
1993 __locked_gmmu_unmap(vm, vaddr, pgsz, pgsz_idx, 0, 2004 g->ops.mm.gmmu_unmap(vm, vaddr, pgsz, pgsz_idx, 0,
1994 gk20a_mem_flag_none); 2005 gk20a_mem_flag_none);
1995 } 2006 }
1996 2007
@@ -2005,12 +2016,14 @@ static int gk20a_vm_put_sparse(struct vm_gk20a *vm, u64 vaddr,
2005 2016
2006void gk20a_vm_clear_sparse(struct vm_gk20a *vm, u64 vaddr, 2017void gk20a_vm_clear_sparse(struct vm_gk20a *vm, u64 vaddr,
2007 u64 size, u32 pgsz_idx) { 2018 u64 size, u32 pgsz_idx) {
2008 __locked_gmmu_unmap(vm, vaddr, size, pgsz_idx, 2019 struct gk20a *g = vm->mm->g;
2009 false, gk20a_mem_flag_none); 2020
2021 g->ops.mm.gmmu_unmap(vm, vaddr, size, pgsz_idx,
2022 false, gk20a_mem_flag_none);
2010} 2023}
2011 2024
2012/* NOTE! mapped_buffers lock must be held */ 2025/* NOTE! mapped_buffers lock must be held */
2013static void gk20a_vm_unmap_locked(struct mapped_buffer_node *mapped_buffer) 2026void gk20a_vm_unmap_locked(struct mapped_buffer_node *mapped_buffer)
2014{ 2027{
2015 struct vm_gk20a *vm = mapped_buffer->vm; 2028 struct vm_gk20a *vm = mapped_buffer->vm;
2016 struct gk20a *g = vm->mm->g; 2029 struct gk20a *g = vm->mm->g;
@@ -2026,7 +2039,7 @@ static void gk20a_vm_unmap_locked(struct mapped_buffer_node *mapped_buffer)
2026 if (g->ops.mm.put_empty) { 2039 if (g->ops.mm.put_empty) {
2027 g->ops.mm.put_empty(vm, vaddr, num_pages, pgsz_idx); 2040 g->ops.mm.put_empty(vm, vaddr, num_pages, pgsz_idx);
2028 } else { 2041 } else {
2029 __locked_gmmu_unmap(vm, 2042 g->ops.mm.gmmu_unmap(vm,
2030 mapped_buffer->addr, 2043 mapped_buffer->addr,
2031 mapped_buffer->size, 2044 mapped_buffer->size,
2032 mapped_buffer->pgsz_idx, 2045 mapped_buffer->pgsz_idx,
@@ -2036,7 +2049,7 @@ static void gk20a_vm_unmap_locked(struct mapped_buffer_node *mapped_buffer)
2036 num_pages, pgsz_idx, false); 2049 num_pages, pgsz_idx, false);
2037 } 2050 }
2038 } else 2051 } else
2039 __locked_gmmu_unmap(vm, 2052 g->ops.mm.gmmu_unmap(vm,
2040 mapped_buffer->addr, 2053 mapped_buffer->addr,
2041 mapped_buffer->size, 2054 mapped_buffer->size,
2042 mapped_buffer->pgsz_idx, 2055 mapped_buffer->pgsz_idx,
@@ -2085,7 +2098,7 @@ void gk20a_vm_unmap(struct vm_gk20a *vm, u64 offset)
2085 mutex_unlock(&vm->update_gmmu_lock); 2098 mutex_unlock(&vm->update_gmmu_lock);
2086} 2099}
2087 2100
2088static void gk20a_vm_remove_support(struct vm_gk20a *vm) 2101void gk20a_vm_remove_support(struct vm_gk20a *vm)
2089{ 2102{
2090 struct gk20a *g = vm->mm->g; 2103 struct gk20a *g = vm->mm->g;
2091 struct mapped_buffer_node *mapped_buffer; 2104 struct mapped_buffer_node *mapped_buffer;
@@ -2156,7 +2169,8 @@ static void gk20a_vm_remove_support(struct vm_gk20a *vm)
2156static void gk20a_vm_remove_support_kref(struct kref *ref) 2169static void gk20a_vm_remove_support_kref(struct kref *ref)
2157{ 2170{
2158 struct vm_gk20a *vm = container_of(ref, struct vm_gk20a, ref); 2171 struct vm_gk20a *vm = container_of(ref, struct vm_gk20a, ref);
2159 gk20a_vm_remove_support(vm); 2172 struct gk20a *g = gk20a_from_vm(vm);
2173 g->ops.mm.vm_remove(vm);
2160} 2174}
2161 2175
2162void gk20a_vm_get(struct vm_gk20a *vm) 2176void gk20a_vm_get(struct vm_gk20a *vm)
@@ -3124,5 +3138,14 @@ void gk20a_init_mm(struct gpu_ops *gops)
3124 gops->mm.put_empty = gk20a_vm_put_empty; 3138 gops->mm.put_empty = gk20a_vm_put_empty;
3125 gops->mm.clear_sparse = gk20a_vm_clear_sparse; 3139 gops->mm.clear_sparse = gk20a_vm_clear_sparse;
3126 gops->mm.is_debug_mode_enabled = gk20a_mm_mmu_debug_mode_enabled; 3140 gops->mm.is_debug_mode_enabled = gk20a_mm_mmu_debug_mode_enabled;
3141 gops->mm.gmmu_map = gk20a_locked_gmmu_map;
3142 gops->mm.gmmu_unmap = gk20a_locked_gmmu_unmap;
3143 gops->mm.vm_remove = gk20a_vm_remove_support;
3144 gops->mm.vm_alloc_share = gk20a_vm_alloc_share;
3145 gops->mm.vm_bind_channel = gk20a_vm_bind_channel;
3146 gops->mm.fb_flush = gk20a_mm_fb_flush;
3147 gops->mm.l2_invalidate = gk20a_mm_l2_invalidate;
3148 gops->mm.l2_flush = gk20a_mm_l2_flush;
3149 gops->mm.tlb_invalidate = gk20a_mm_tlb_invalidate;
3127} 3150}
3128 3151
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index b8726c62..f06c465a 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -318,6 +318,10 @@ struct vm_gk20a {
318 dma_addr_t zero_page_iova; 318 dma_addr_t zero_page_iova;
319 void *zero_page_cpuva; 319 void *zero_page_cpuva;
320 struct sg_table *zero_page_sgt; 320 struct sg_table *zero_page_sgt;
321
322#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
323 u64 handle;
324#endif
321}; 325};
322 326
323struct gk20a; 327struct gk20a;
@@ -438,11 +442,30 @@ u64 gk20a_gmmu_map(struct vm_gk20a *vm,
438 u32 flags, 442 u32 flags,
439 int rw_flag); 443 int rw_flag);
440 444
445u64 gk20a_locked_gmmu_map(struct vm_gk20a *vm,
446 u64 map_offset,
447 struct sg_table *sgt,
448 u64 buffer_offset,
449 u64 size,
450 int pgsz_idx,
451 u8 kind_v,
452 u32 ctag_offset,
453 u32 flags,
454 int rw_flag,
455 bool clear_ctags);
456
441void gk20a_gmmu_unmap(struct vm_gk20a *vm, 457void gk20a_gmmu_unmap(struct vm_gk20a *vm,
442 u64 vaddr, 458 u64 vaddr,
443 u64 size, 459 u64 size,
444 int rw_flag); 460 int rw_flag);
445 461
462void gk20a_locked_gmmu_unmap(struct vm_gk20a *vm,
463 u64 vaddr,
464 u64 size,
465 int pgsz_idx,
466 bool va_allocated,
467 int rw_flag);
468
446struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf); 469struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf);
447void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf, 470void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf,
448 struct sg_table *sgt); 471 struct sg_table *sgt);
@@ -461,6 +484,8 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
461/* unmap handle from kernel */ 484/* unmap handle from kernel */
462void gk20a_vm_unmap(struct vm_gk20a *vm, u64 offset); 485void gk20a_vm_unmap(struct vm_gk20a *vm, u64 offset);
463 486
487void gk20a_vm_unmap_locked(struct mapped_buffer_node *mapped_buffer);
488
464/* get reference to all currently mapped buffers */ 489/* get reference to all currently mapped buffers */
465int gk20a_vm_get_buffers(struct vm_gk20a *vm, 490int gk20a_vm_get_buffers(struct vm_gk20a *vm,
466 struct mapped_buffer_node ***mapped_buffers, 491 struct mapped_buffer_node ***mapped_buffers,
@@ -482,6 +507,16 @@ int gk20a_vm_find_buffer(struct vm_gk20a *vm, u64 gpu_va,
482void gk20a_vm_get(struct vm_gk20a *vm); 507void gk20a_vm_get(struct vm_gk20a *vm);
483void gk20a_vm_put(struct vm_gk20a *vm); 508void gk20a_vm_put(struct vm_gk20a *vm);
484 509
510void gk20a_vm_remove_support(struct vm_gk20a *vm);
511
512u64 gk20a_vm_alloc_va(struct vm_gk20a *vm,
513 u64 size,
514 enum gmmu_pgsz_gk20a gmmu_pgsz_idx);
515
516int gk20a_vm_free_va(struct vm_gk20a *vm,
517 u64 offset, u64 size,
518 enum gmmu_pgsz_gk20a pgsz_idx);
519
485/* vm-as interface */ 520/* vm-as interface */
486struct nvhost_as_alloc_space_args; 521struct nvhost_as_alloc_space_args;
487struct nvhost_as_free_space_args; 522struct nvhost_as_free_space_args;
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
index 6dd0c0db..e6ed9898 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
@@ -151,6 +151,12 @@ struct gk20a_platform {
151 * of the CPU. 151 * of the CPU.
152 */ 152 */
153 void (*dump_platform_dependencies)(struct platform_device *dev); 153 void (*dump_platform_dependencies)(struct platform_device *dev);
154
155#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
156 bool virtual_dev;
157 u64 virt_handle;
158 struct task_struct *intr_handler;
159#endif
154}; 160};
155 161
156static inline struct gk20a_platform *gk20a_get_platform( 162static inline struct gk20a_platform *gk20a_get_platform(
@@ -163,6 +169,9 @@ extern struct gk20a_platform gk20a_generic_platform;
163#ifdef CONFIG_TEGRA_GK20A 169#ifdef CONFIG_TEGRA_GK20A
164extern struct gk20a_platform gk20a_tegra_platform; 170extern struct gk20a_platform gk20a_tegra_platform;
165extern struct gk20a_platform gm20b_tegra_platform; 171extern struct gk20a_platform gm20b_tegra_platform;
172#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
173extern struct gk20a_platform vgpu_tegra_platform;
174#endif
166#endif 175#endif
167 176
168static inline bool gk20a_platform_has_syncpoints(struct platform_device *dev) 177static inline bool gk20a_platform_has_syncpoints(struct platform_device *dev)
diff --git a/drivers/gpu/nvgpu/gk20a/platform_vgpu_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_vgpu_tegra.c
new file mode 100644
index 00000000..ea4fde79
--- /dev/null
+++ b/drivers/gpu/nvgpu/gk20a/platform_vgpu_tegra.c
@@ -0,0 +1,64 @@
1/*
2 * Tegra Virtualized GPU Platform Interface
3 *
4 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15
16#include <linux/of_platform.h>
17
18#include "gk20a.h"
19#include "hal_gk20a.h"
20#include "platform_gk20a.h"
21
22static int gk20a_tegra_probe(struct platform_device *dev)
23{
24 struct gk20a_platform *platform = gk20a_get_platform(dev);
25 struct device_node *np = dev->dev.of_node;
26 const __be32 *host1x_ptr;
27 struct platform_device *host1x_pdev = NULL;
28
29 host1x_ptr = of_get_property(np, "nvidia,host1x", NULL);
30 if (host1x_ptr) {
31 struct device_node *host1x_node =
32 of_find_node_by_phandle(be32_to_cpup(host1x_ptr));
33
34 host1x_pdev = of_find_device_by_node(host1x_node);
35 if (!host1x_pdev) {
36 dev_warn(&dev->dev, "host1x device not available");
37 return -EPROBE_DEFER;
38 }
39
40 } else {
41 host1x_pdev = to_platform_device(dev->dev.parent);
42 dev_warn(&dev->dev, "host1x reference not found. assuming host1x to be parent");
43 }
44
45 platform->g->host1x_dev = host1x_pdev;
46
47 return 0;
48}
49
50struct gk20a_platform vgpu_tegra_platform = {
51 .has_syncpoints = true,
52
53 /* power management configuration */
54 .can_railgate = false,
55 .enable_slcg = false,
56 .enable_blcg = false,
57 .enable_elcg = false,
58 .enable_elpg = false,
59 .enable_aelpg = false,
60
61 .probe = gk20a_tegra_probe,
62
63 .virtual_dev = true,
64};