diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 76 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 4 |
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 | ||
31 | struct fifo_runlist_info_gk20a { | 31 | struct 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 | ||
56 | int gk20a_unbind_channel_from_tsg(struct channel_gk20a *ch, int tsgid) | 56 | 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) | |||
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 | /* |