gpu: nvgpu: add TSG support to runlists

- when a TSG channel is made runnable, add it to TSG's
  runnable list
- when a TSG channel is removed from runlist, remove it
  from TSG's runnable list

When we rewrite the entire runlist :
- first add all the channels which are not part of any TSG
- then find all active TSGs, add an entry in runlist for the TSG
  (with TSG id and length of TSG)
- then write entries for each channel in that TSG

Bug 1470692

Change-Id: Ic55a4d5959abc72cd20b8224eb4c31d3ff411861
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/416612
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Deepak Nibade
2014-06-16 12:08:18 +05:30
committed by Dan Willemsen
parent bea937a74e
commit b6466fbe07
3 changed files with 76 additions and 5 deletions

View File

@@ -205,6 +205,7 @@ void gk20a_remove_fifo_support(struct fifo_gk20a *f)
}
kfree(runlist->active_channels);
kfree(runlist->active_tsgs);
kfree(f->runlist_info);
kfree(f->pbdma_map);
@@ -316,6 +317,12 @@ static int init_runlist(struct gk20a *g, struct fifo_gk20a *f)
if (!runlist->active_channels)
goto clean_up_runlist_info;
runlist->active_tsgs =
kzalloc(DIV_ROUND_UP(f->num_channels, BITS_PER_BYTE),
GFP_KERNEL);
if (!runlist->active_tsgs)
goto clean_up_runlist_info;
runlist_size = ram_rl_entry_size_v() * f->num_channels;
for (i = 0; i < MAX_RUNLIST_BUFFERS; i++) {
dma_addr_t iova;
@@ -1734,8 +1741,11 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
u32 *runlist_entry = NULL;
phys_addr_t runlist_pa;
u32 old_buf, new_buf;
u32 chid;
u32 chid, tsgid;
struct channel_gk20a *ch;
struct tsg_gk20a *tsg;
u32 count = 0;
int num_ch;
runlist = &f->runlist_info[runlist_id];
/* valid channel, add/remove it from active list.
@@ -1745,10 +1755,28 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
if (test_and_set_bit(hw_chid,
runlist->active_channels) == 1)
return 0;
if (gk20a_is_channel_marked_as_tsg(
&f->channel[hw_chid])) {
num_ch = gk20a_bind_runnable_channel_to_tsg(
&f->channel[hw_chid],
f->channel[hw_chid].tsgid);
if (num_ch > 0)
set_bit(f->channel[hw_chid].tsgid,
runlist->active_tsgs);
}
} else {
if (test_and_clear_bit(hw_chid,
runlist->active_channels) == 0)
return 0;
if (gk20a_is_channel_marked_as_tsg(
&f->channel[hw_chid])) {
num_ch = gk20a_unbind_channel_from_tsg(
&f->channel[hw_chid],
f->channel[hw_chid].tsgid);
if (!num_ch)
clear_bit(f->channel[hw_chid].tsgid,
runlist->active_tsgs);
}
}
}
@@ -1773,14 +1801,56 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
if (hw_chid != ~0 || /* add/remove a valid channel */
add /* resume to add all channels back */) {
runlist_entry = runlist_entry_base;
/* add non-TSG channels first */
for_each_set_bit(chid,
runlist->active_channels, f->num_channels) {
gk20a_dbg_info("add channel %d to runlist", chid);
runlist_entry[0] = chid;
ch = &f->channel[chid];
if (!gk20a_is_channel_marked_as_tsg(ch)) {
gk20a_dbg_info("add channel %d to runlist",
chid);
runlist_entry[0] = ram_rl_entry_chid_f(chid);
runlist_entry[1] = 0;
runlist_entry += 2;
count++;
}
}
/* now add TSG entries and channels bound to TSG */
mutex_lock(&f->tsg_inuse_mutex);
for_each_set_bit(tsgid,
runlist->active_tsgs, f->num_channels) {
tsg = &f->tsg[tsgid];
/* add TSG entry */
gk20a_dbg_info("add TSG %d to runlist", tsg->tsgid);
runlist_entry[0] = ram_rl_entry_id_f(tsg->tsgid) |
ram_rl_entry_type_f(ram_rl_entry_type_tsg_f()) |
ram_rl_entry_timeslice_scale_f(
ram_rl_entry_timeslice_scale_3_f()) |
ram_rl_entry_timeslice_timeout_f(
ram_rl_entry_timeslice_timeout_128_f()) |
ram_rl_entry_tsg_length_f(
tsg->num_runnable_channels);
runlist_entry[1] = 0;
runlist_entry += 2;
count++;
/* add channels bound to this TSG */
mutex_lock(&tsg->ch_list_lock);
list_for_each_entry(ch,
&tsg->ch_runnable_list, ch_entry) {
gk20a_dbg_info("add channel %d to runlist",
ch->hw_chid);
runlist_entry[0] =
ram_rl_entry_chid_f(ch->hw_chid);
runlist_entry[1] = 0;
runlist_entry += 2;
count++;
}
mutex_unlock(&tsg->ch_list_lock);
}
mutex_unlock(&f->tsg_inuse_mutex);
} else /* suspend to remove all channels */
count = 0;

View File

@@ -30,6 +30,7 @@
struct fifo_runlist_info_gk20a {
unsigned long *active_channels;
unsigned long *active_tsgs;
/* Each engine has its own SW and HW runlist buffer.*/
struct runlist_mem_desc mem[MAX_RUNLIST_BUFFERS];
u32 cur_buffer;

View File

@@ -50,7 +50,7 @@ int gk20a_bind_runnable_channel_to_tsg(struct channel_gk20a *ch, int tsgid)
tsg->num_runnable_channels += 1;
mutex_unlock(&tsg->ch_list_lock);
return 0;
return tsg->num_runnable_channels;
}
int gk20a_unbind_channel_from_tsg(struct channel_gk20a *ch, int tsgid)
@@ -68,7 +68,7 @@ int gk20a_unbind_channel_from_tsg(struct channel_gk20a *ch, int tsgid)
tsg->num_runnable_channels -= 1;
mutex_unlock(&tsg->ch_list_lock);
return 0;
return tsg->num_runnable_channels;
}
/*