summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-06-16 02:38:18 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:16 -0400
commitb6466fbe07d28fcc1a2ea93715a1f88b48dd8550 (patch)
tree8eef989215f1becfa5d72642dccaf7727b3a21f1
parentbea937a74ede83ff3973b52d684ffdfabaa33767 (diff)
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>
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c76
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.c4
3 files changed, 76 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index e9febb77..52c0627d 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -205,6 +205,7 @@ void gk20a_remove_fifo_support(struct fifo_gk20a *f)
205 } 205 }
206 206
207 kfree(runlist->active_channels); 207 kfree(runlist->active_channels);
208 kfree(runlist->active_tsgs);
208 209
209 kfree(f->runlist_info); 210 kfree(f->runlist_info);
210 kfree(f->pbdma_map); 211 kfree(f->pbdma_map);
@@ -316,6 +317,12 @@ static int init_runlist(struct gk20a *g, struct fifo_gk20a *f)
316 if (!runlist->active_channels) 317 if (!runlist->active_channels)
317 goto clean_up_runlist_info; 318 goto clean_up_runlist_info;
318 319
320 runlist->active_tsgs =
321 kzalloc(DIV_ROUND_UP(f->num_channels, BITS_PER_BYTE),
322 GFP_KERNEL);
323 if (!runlist->active_tsgs)
324 goto clean_up_runlist_info;
325
319 runlist_size = ram_rl_entry_size_v() * f->num_channels; 326 runlist_size = ram_rl_entry_size_v() * f->num_channels;
320 for (i = 0; i < MAX_RUNLIST_BUFFERS; i++) { 327 for (i = 0; i < MAX_RUNLIST_BUFFERS; i++) {
321 dma_addr_t iova; 328 dma_addr_t iova;
@@ -1734,8 +1741,11 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
1734 u32 *runlist_entry = NULL; 1741 u32 *runlist_entry = NULL;
1735 phys_addr_t runlist_pa; 1742 phys_addr_t runlist_pa;
1736 u32 old_buf, new_buf; 1743 u32 old_buf, new_buf;
1737 u32 chid; 1744 u32 chid, tsgid;
1745 struct channel_gk20a *ch;
1746 struct tsg_gk20a *tsg;
1738 u32 count = 0; 1747 u32 count = 0;
1748 int num_ch;
1739 runlist = &f->runlist_info[runlist_id]; 1749 runlist = &f->runlist_info[runlist_id];
1740 1750
1741 /* valid channel, add/remove it from active list. 1751 /* 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,
1745 if (test_and_set_bit(hw_chid, 1755 if (test_and_set_bit(hw_chid,
1746 runlist->active_channels) == 1) 1756 runlist->active_channels) == 1)
1747 return 0; 1757 return 0;
1758 if (gk20a_is_channel_marked_as_tsg(
1759 &f->channel[hw_chid])) {
1760 num_ch = gk20a_bind_runnable_channel_to_tsg(
1761 &f->channel[hw_chid],
1762 f->channel[hw_chid].tsgid);
1763 if (num_ch > 0)
1764 set_bit(f->channel[hw_chid].tsgid,
1765 runlist->active_tsgs);
1766 }
1748 } else { 1767 } else {
1749 if (test_and_clear_bit(hw_chid, 1768 if (test_and_clear_bit(hw_chid,
1750 runlist->active_channels) == 0) 1769 runlist->active_channels) == 0)
1751 return 0; 1770 return 0;
1771 if (gk20a_is_channel_marked_as_tsg(
1772 &f->channel[hw_chid])) {
1773 num_ch = gk20a_unbind_channel_from_tsg(
1774 &f->channel[hw_chid],
1775 f->channel[hw_chid].tsgid);
1776 if (!num_ch)
1777 clear_bit(f->channel[hw_chid].tsgid,
1778 runlist->active_tsgs);
1779 }
1752 } 1780 }
1753 } 1781 }
1754 1782
@@ -1773,14 +1801,56 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
1773 if (hw_chid != ~0 || /* add/remove a valid channel */ 1801 if (hw_chid != ~0 || /* add/remove a valid channel */
1774 add /* resume to add all channels back */) { 1802 add /* resume to add all channels back */) {
1775 runlist_entry = runlist_entry_base; 1803 runlist_entry = runlist_entry_base;
1804
1805 /* add non-TSG channels first */
1776 for_each_set_bit(chid, 1806 for_each_set_bit(chid,
1777 runlist->active_channels, f->num_channels) { 1807 runlist->active_channels, f->num_channels) {
1778 gk20a_dbg_info("add channel %d to runlist", chid); 1808 ch = &f->channel[chid];
1779 runlist_entry[0] = chid; 1809
1810 if (!gk20a_is_channel_marked_as_tsg(ch)) {
1811 gk20a_dbg_info("add channel %d to runlist",
1812 chid);
1813 runlist_entry[0] = ram_rl_entry_chid_f(chid);
1814 runlist_entry[1] = 0;
1815 runlist_entry += 2;
1816 count++;
1817 }
1818 }
1819
1820 /* now add TSG entries and channels bound to TSG */
1821 mutex_lock(&f->tsg_inuse_mutex);
1822 for_each_set_bit(tsgid,
1823 runlist->active_tsgs, f->num_channels) {
1824 tsg = &f->tsg[tsgid];
1825 /* add TSG entry */
1826 gk20a_dbg_info("add TSG %d to runlist", tsg->tsgid);
1827 runlist_entry[0] = ram_rl_entry_id_f(tsg->tsgid) |
1828 ram_rl_entry_type_f(ram_rl_entry_type_tsg_f()) |
1829 ram_rl_entry_timeslice_scale_f(
1830 ram_rl_entry_timeslice_scale_3_f()) |
1831 ram_rl_entry_timeslice_timeout_f(
1832 ram_rl_entry_timeslice_timeout_128_f()) |
1833 ram_rl_entry_tsg_length_f(
1834 tsg->num_runnable_channels);
1780 runlist_entry[1] = 0; 1835 runlist_entry[1] = 0;
1781 runlist_entry += 2; 1836 runlist_entry += 2;
1782 count++; 1837 count++;
1838
1839 /* add channels bound to this TSG */
1840 mutex_lock(&tsg->ch_list_lock);
1841 list_for_each_entry(ch,
1842 &tsg->ch_runnable_list, ch_entry) {
1843 gk20a_dbg_info("add channel %d to runlist",
1844 ch->hw_chid);
1845 runlist_entry[0] =
1846 ram_rl_entry_chid_f(ch->hw_chid);
1847 runlist_entry[1] = 0;
1848 runlist_entry += 2;
1849 count++;
1850 }
1851 mutex_unlock(&tsg->ch_list_lock);
1783 } 1852 }
1853 mutex_unlock(&f->tsg_inuse_mutex);
1784 } else /* suspend to remove all channels */ 1854 } else /* suspend to remove all channels */
1785 count = 0; 1855 count = 0;
1786 1856
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
index f94fce02..6e6907c1 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
@@ -30,6 +30,7 @@
30 30
31struct fifo_runlist_info_gk20a { 31struct fifo_runlist_info_gk20a {
32 unsigned long *active_channels; 32 unsigned long *active_channels;
33 unsigned long *active_tsgs;
33 /* Each engine has its own SW and HW runlist buffer.*/ 34 /* Each engine has its own SW and HW runlist buffer.*/
34 struct runlist_mem_desc mem[MAX_RUNLIST_BUFFERS]; 35 struct runlist_mem_desc mem[MAX_RUNLIST_BUFFERS];
35 u32 cur_buffer; 36 u32 cur_buffer;
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
index d9e10d30..7c65c695 100644
--- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
@@ -50,7 +50,7 @@ int gk20a_bind_runnable_channel_to_tsg(struct channel_gk20a *ch, int tsgid)
50 tsg->num_runnable_channels += 1; 50 tsg->num_runnable_channels += 1;
51 mutex_unlock(&tsg->ch_list_lock); 51 mutex_unlock(&tsg->ch_list_lock);
52 52
53 return 0; 53 return tsg->num_runnable_channels;
54} 54}
55 55
56int gk20a_unbind_channel_from_tsg(struct channel_gk20a *ch, int tsgid) 56int 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)
68 tsg->num_runnable_channels -= 1; 68 tsg->num_runnable_channels -= 1;
69 mutex_unlock(&tsg->ch_list_lock); 69 mutex_unlock(&tsg->ch_list_lock);
70 70
71 return 0; 71 return tsg->num_runnable_channels;
72} 72}
73 73
74/* 74/*