summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
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/channel_gk20a.c
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/channel_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c89
1 files changed, 43 insertions, 46 deletions
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;