summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index c8cc4373..a41955bd 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -1722,41 +1722,32 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
1722 phys_addr_t runlist_pa; 1722 phys_addr_t runlist_pa;
1723 u32 old_buf, new_buf; 1723 u32 old_buf, new_buf;
1724 u32 chid, tsgid; 1724 u32 chid, tsgid;
1725 struct channel_gk20a *ch; 1725 struct channel_gk20a *ch = NULL;
1726 struct tsg_gk20a *tsg; 1726 struct tsg_gk20a *tsg = NULL;
1727 u32 count = 0; 1727 u32 count = 0;
1728 int num_ch;
1729 runlist = &f->runlist_info[runlist_id]; 1728 runlist = &f->runlist_info[runlist_id];
1730 1729
1731 /* valid channel, add/remove it from active list. 1730 /* valid channel, add/remove it from active list.
1732 Otherwise, keep active list untouched for suspend/resume. */ 1731 Otherwise, keep active list untouched for suspend/resume. */
1733 if (hw_chid != ~0) { 1732 if (hw_chid != ~0) {
1733 ch = &f->channel[hw_chid];
1734 if (gk20a_is_channel_marked_as_tsg(ch))
1735 tsg = &f->tsg[ch->tsgid];
1736
1734 if (add) { 1737 if (add) {
1735 if (test_and_set_bit(hw_chid, 1738 if (test_and_set_bit(hw_chid,
1736 runlist->active_channels) == 1) 1739 runlist->active_channels) == 1)
1737 return 0; 1740 return 0;
1738 if (gk20a_is_channel_marked_as_tsg( 1741 if (tsg && ++tsg->num_active_channels > 0)
1739 &f->channel[hw_chid])) { 1742 set_bit(f->channel[hw_chid].tsgid,
1740 num_ch = gk20a_bind_runnable_channel_to_tsg( 1743 runlist->active_tsgs);
1741 &f->channel[hw_chid],
1742 f->channel[hw_chid].tsgid);
1743 if (num_ch > 0)
1744 set_bit(f->channel[hw_chid].tsgid,
1745 runlist->active_tsgs);
1746 }
1747 } else { 1744 } else {
1748 if (test_and_clear_bit(hw_chid, 1745 if (test_and_clear_bit(hw_chid,
1749 runlist->active_channels) == 0) 1746 runlist->active_channels) == 0)
1750 return 0; 1747 return 0;
1751 if (gk20a_is_channel_marked_as_tsg( 1748 if (tsg && --tsg->num_active_channels == 0)
1752 &f->channel[hw_chid])) { 1749 clear_bit(f->channel[hw_chid].tsgid,
1753 num_ch = gk20a_unbind_channel_from_tsg( 1750 runlist->active_tsgs);
1754 &f->channel[hw_chid],
1755 f->channel[hw_chid].tsgid);
1756 if (!num_ch)
1757 clear_bit(f->channel[hw_chid].tsgid,
1758 runlist->active_tsgs);
1759 }
1760 } 1751 }
1761 } 1752 }
1762 1753
@@ -1811,15 +1802,17 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
1811 ram_rl_entry_timeslice_timeout_f( 1802 ram_rl_entry_timeslice_timeout_f(
1812 ram_rl_entry_timeslice_timeout_128_f()) | 1803 ram_rl_entry_timeslice_timeout_128_f()) |
1813 ram_rl_entry_tsg_length_f( 1804 ram_rl_entry_tsg_length_f(
1814 tsg->num_runnable_channels); 1805 tsg->num_active_channels);
1815 runlist_entry[1] = 0; 1806 runlist_entry[1] = 0;
1816 runlist_entry += 2; 1807 runlist_entry += 2;
1817 count++; 1808 count++;
1818 1809
1819 /* add channels bound to this TSG */ 1810 /* add runnable channels bound to this TSG */
1820 mutex_lock(&tsg->ch_list_lock); 1811 mutex_lock(&tsg->ch_list_lock);
1821 list_for_each_entry(ch, 1812 list_for_each_entry(ch, &tsg->ch_list, ch_entry) {
1822 &tsg->ch_runnable_list, ch_entry) { 1813 if (!test_bit(ch->hw_chid,
1814 runlist->active_channels))
1815 continue;
1823 gk20a_dbg_info("add channel %d to runlist", 1816 gk20a_dbg_info("add channel %d to runlist",
1824 ch->hw_chid); 1817 ch->hw_chid);
1825 runlist_entry[0] = 1818 runlist_entry[0] =