summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 9796d7c6..713c7737 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -328,18 +328,9 @@ static int channel_gk20a_setup_userd(struct channel_gk20a *c)
328static void channel_gk20a_bind(struct channel_gk20a *c) 328static void channel_gk20a_bind(struct channel_gk20a *c)
329{ 329{
330 struct gk20a *g = c->g; 330 struct gk20a *g = c->g;
331 struct fifo_gk20a *f = &g->fifo;
332 u32 engine_id;
333 struct fifo_engine_info_gk20a *engine_info = NULL;
334 u32 inst_ptr = gk20a_mm_inst_block_addr(g, &c->inst_block) 331 u32 inst_ptr = gk20a_mm_inst_block_addr(g, &c->inst_block)
335 >> ram_in_base_shift_v(); 332 >> ram_in_base_shift_v();
336 333
337 /* TODO:Need to handle non GR engine channel bind path */
338 engine_id = gk20a_fifo_get_gr_engine_id(g);
339
340 /* Consider 1st available GR engine */
341 engine_info = (f->engine_info + engine_id);
342
343 gk20a_dbg_info("bind channel %d inst ptr 0x%08x", 334 gk20a_dbg_info("bind channel %d inst ptr 0x%08x",
344 c->hw_chid, inst_ptr); 335 c->hw_chid, inst_ptr);
345 336
@@ -348,7 +339,7 @@ static void channel_gk20a_bind(struct channel_gk20a *c)
348 gk20a_writel(g, ccsr_channel_r(c->hw_chid), 339 gk20a_writel(g, ccsr_channel_r(c->hw_chid),
349 (gk20a_readl(g, ccsr_channel_r(c->hw_chid)) & 340 (gk20a_readl(g, ccsr_channel_r(c->hw_chid)) &
350 ~ccsr_channel_runlist_f(~0)) | 341 ~ccsr_channel_runlist_f(~0)) |
351 ccsr_channel_runlist_f(engine_info->runlist_id)); 342 ccsr_channel_runlist_f(c->runlist_id));
352 343
353 gk20a_writel(g, ccsr_channel_inst_r(c->hw_chid), 344 gk20a_writel(g, ccsr_channel_inst_r(c->hw_chid),
354 ccsr_channel_inst_ptr_f(inst_ptr) | 345 ccsr_channel_inst_ptr_f(inst_ptr) |
@@ -401,7 +392,7 @@ void channel_gk20a_free_inst(struct gk20a *g, struct channel_gk20a *ch)
401 392
402static int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add) 393static int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add)
403{ 394{
404 return c->g->ops.fifo.update_runlist(c->g, 0, c->hw_chid, add, true); 395 return c->g->ops.fifo.update_runlist(c->g, c->runlist_id, c->hw_chid, add, true);
405} 396}
406 397
407void channel_gk20a_enable(struct channel_gk20a *ch) 398void channel_gk20a_enable(struct channel_gk20a *ch)
@@ -715,7 +706,7 @@ static int gk20a_channel_set_runlist_interleave(struct channel_gk20a *ch,
715 break; 706 break;
716 } 707 }
717 708
718 return ret ? ret : g->ops.fifo.update_runlist(g, 0, ~0, true, true); 709 return ret ? ret : g->ops.fifo.update_runlist(g, ch->runlist_id, ~0, true, true);
719} 710}
720 711
721static int gk20a_init_error_notifier(struct channel_gk20a *ch, 712static int gk20a_init_error_notifier(struct channel_gk20a *ch,
@@ -1102,7 +1093,7 @@ struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g,
1102 void (*update_fn)(struct channel_gk20a *, void *), 1093 void (*update_fn)(struct channel_gk20a *, void *),
1103 void *update_fn_data) 1094 void *update_fn_data)
1104{ 1095{
1105 struct channel_gk20a *ch = gk20a_open_new_channel(g); 1096 struct channel_gk20a *ch = gk20a_open_new_channel(g, -1);
1106 1097
1107 if (ch) { 1098 if (ch) {
1108 spin_lock(&ch->update_fn_lock); 1099 spin_lock(&ch->update_fn_lock);
@@ -1114,11 +1105,16 @@ struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g,
1114 return ch; 1105 return ch;
1115} 1106}
1116 1107
1117struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g) 1108struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, s32 runlist_id)
1118{ 1109{
1119 struct fifo_gk20a *f = &g->fifo; 1110 struct fifo_gk20a *f = &g->fifo;
1120 struct channel_gk20a *ch; 1111 struct channel_gk20a *ch;
1121 1112
1113 /* compatibility with existing code */
1114 if (!gk20a_fifo_is_valid_runlist_id(g, runlist_id)) {
1115 runlist_id = gk20a_fifo_get_gr_runlist_id(g);
1116 }
1117
1122 gk20a_dbg_fn(""); 1118 gk20a_dbg_fn("");
1123 1119
1124 ch = allocate_channel(f); 1120 ch = allocate_channel(f);
@@ -1133,6 +1129,9 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
1133 BUG_ON(ch->g); 1129 BUG_ON(ch->g);
1134 ch->g = g; 1130 ch->g = g;
1135 1131
1132 /* Runlist for the channel */
1133 ch->runlist_id = runlist_id;
1134
1136 if (g->ops.fifo.alloc_inst(g, ch)) { 1135 if (g->ops.fifo.alloc_inst(g, ch)) {
1137 ch->g = NULL; 1136 ch->g = NULL;
1138 free_channel(f, ch); 1137 free_channel(f, ch);
@@ -1184,7 +1183,8 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
1184 return ch; 1183 return ch;
1185} 1184}
1186 1185
1187static int __gk20a_channel_open(struct gk20a *g, struct file *filp) 1186/* note: runlist_id -1 is synonym for the ENGINE_GR_GK20A runlist id */
1187static int __gk20a_channel_open(struct gk20a *g, struct file *filp, s32 runlist_id)
1188{ 1188{
1189 int err; 1189 int err;
1190 struct channel_gk20a *ch; 1190 struct channel_gk20a *ch;
@@ -1198,7 +1198,7 @@ static int __gk20a_channel_open(struct gk20a *g, struct file *filp)
1198 gk20a_err(dev_from_gk20a(g), "failed to power on, %d", err); 1198 gk20a_err(dev_from_gk20a(g), "failed to power on, %d", err);
1199 return err; 1199 return err;
1200 } 1200 }
1201 ch = gk20a_open_new_channel(g); 1201 ch = gk20a_open_new_channel(g, runlist_id);
1202 gk20a_idle(g->dev); 1202 gk20a_idle(g->dev);
1203 if (!ch) { 1203 if (!ch) {
1204 gk20a_err(dev_from_gk20a(g), 1204 gk20a_err(dev_from_gk20a(g),
@@ -1220,7 +1220,7 @@ int gk20a_channel_open(struct inode *inode, struct file *filp)
1220 int ret; 1220 int ret;
1221 1221
1222 gk20a_dbg_fn("start"); 1222 gk20a_dbg_fn("start");
1223 ret = __gk20a_channel_open(g, filp); 1223 ret = __gk20a_channel_open(g, filp, -1);
1224 1224
1225 gk20a_dbg_fn("end"); 1225 gk20a_dbg_fn("end");
1226 return ret; 1226 return ret;
@@ -1233,6 +1233,7 @@ int gk20a_channel_open_ioctl(struct gk20a *g,
1233 int fd; 1233 int fd;
1234 struct file *file; 1234 struct file *file;
1235 char *name; 1235 char *name;
1236 s32 runlist_id = args->in.runlist_id;
1236 1237
1237 err = get_unused_fd_flags(O_RDWR); 1238 err = get_unused_fd_flags(O_RDWR);
1238 if (err < 0) 1239 if (err < 0)
@@ -1253,12 +1254,12 @@ int gk20a_channel_open_ioctl(struct gk20a *g,
1253 goto clean_up; 1254 goto clean_up;
1254 } 1255 }
1255 1256
1256 err = __gk20a_channel_open(g, file); 1257 err = __gk20a_channel_open(g, file, runlist_id);
1257 if (err) 1258 if (err)
1258 goto clean_up_file; 1259 goto clean_up_file;
1259 1260
1260 fd_install(fd, file); 1261 fd_install(fd, file);
1261 args->channel_fd = fd; 1262 args->out.channel_fd = fd;
1262 return 0; 1263 return 0;
1263 1264
1264clean_up_file: 1265clean_up_file:
@@ -2780,6 +2781,7 @@ int gk20a_channel_suspend(struct gk20a *g)
2780 u32 chid; 2781 u32 chid;
2781 bool channels_in_use = false; 2782 bool channels_in_use = false;
2782 int err; 2783 int err;
2784 u32 active_runlist_ids = 0;
2783 2785
2784 gk20a_dbg_fn(""); 2786 gk20a_dbg_fn("");
2785 2787
@@ -2803,12 +2805,14 @@ int gk20a_channel_suspend(struct gk20a *g)
2803 2805
2804 channels_in_use = true; 2806 channels_in_use = true;
2805 2807
2808 active_runlist_ids |= BIT(ch->runlist_id);
2809
2806 gk20a_channel_put(ch); 2810 gk20a_channel_put(ch);
2807 } 2811 }
2808 } 2812 }
2809 2813
2810 if (channels_in_use) { 2814 if (channels_in_use) {
2811 g->ops.fifo.update_runlist(g, 0, ~0, false, true); 2815 gk20a_fifo_update_runlist_ids(g, active_runlist_ids, ~0, false, true);
2812 2816
2813 for (chid = 0; chid < f->num_channels; chid++) { 2817 for (chid = 0; chid < f->num_channels; chid++) {
2814 if (gk20a_channel_get(&f->channel[chid])) { 2818 if (gk20a_channel_get(&f->channel[chid])) {
@@ -2827,6 +2831,7 @@ int gk20a_channel_resume(struct gk20a *g)
2827 struct fifo_gk20a *f = &g->fifo; 2831 struct fifo_gk20a *f = &g->fifo;
2828 u32 chid; 2832 u32 chid;
2829 bool channels_in_use = false; 2833 bool channels_in_use = false;
2834 u32 active_runlist_ids = 0;
2830 2835
2831 gk20a_dbg_fn(""); 2836 gk20a_dbg_fn("");
2832 2837
@@ -2835,12 +2840,13 @@ int gk20a_channel_resume(struct gk20a *g)
2835 gk20a_dbg_info("resume channel %d", chid); 2840 gk20a_dbg_info("resume channel %d", chid);
2836 g->ops.fifo.bind_channel(&f->channel[chid]); 2841 g->ops.fifo.bind_channel(&f->channel[chid]);
2837 channels_in_use = true; 2842 channels_in_use = true;
2843 active_runlist_ids |= BIT(f->channel[chid].runlist_id);
2838 gk20a_channel_put(&f->channel[chid]); 2844 gk20a_channel_put(&f->channel[chid]);
2839 } 2845 }
2840 } 2846 }
2841 2847
2842 if (channels_in_use) 2848 if (channels_in_use)
2843 g->ops.fifo.update_runlist(g, 0, ~0, true, true); 2849 gk20a_fifo_update_runlist_ids(g, active_runlist_ids, ~0, true, true);
2844 2850
2845 gk20a_dbg_fn("done"); 2851 gk20a_dbg_fn("done");
2846 return 0; 2852 return 0;