summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2016-03-09 04:25:20 -0500
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:52:12 -0500
commitd0965c746d1824b34b589952b247fe5f0e23f8ea (patch)
treef851e9ff21083b1ff46149d244137044ed7f2878 /drivers/gpu/nvgpu/gp10b/gr_gp10b.c
parent2c939d35bb07b9ab6643c301efd63e65fc29ed46 (diff)
gpu: nvgpu: suspend context support for gp10b
Add API gr_gp10b_suspend_contexts() to support context suspend on gp10b sequence to suspend: - disable ctxsw - loop through list of channels - if channel is ctx resident, suspend all SMs - if CILP channel, set CILP preempt pending = true - resume all SMs - otherwise, disable channel/TSG - enable ctxsw - if CILP preempt is pending, wait for it to complete Bug 200156699 Change-Id: Id9609077c283f99f420ad21c636b29f74b8eff6b Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1120334 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b/gr_gp10b.c')
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_gp10b.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
index 6ab8e923..e55c5768 100644
--- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
@@ -1749,6 +1749,109 @@ static u32 get_ecc_override_val(struct gk20a *g)
1749 return 0; 1749 return 0;
1750} 1750}
1751 1751
1752static bool gr_gp10b_suspend_context(struct channel_gk20a *ch,
1753 bool *cilp_preempt_pending)
1754{
1755 struct gk20a *g = ch->g;
1756 struct channel_ctx_gk20a *ch_ctx = &ch->ch_ctx;
1757 struct gr_ctx_desc *gr_ctx = ch_ctx->gr_ctx;
1758 bool ctx_resident = false;
1759 int err = 0;
1760
1761 *cilp_preempt_pending = false;
1762
1763 if (gk20a_is_channel_ctx_resident(ch)) {
1764 gk20a_suspend_all_sms(g, 0, false);
1765
1766 if (gr_ctx->preempt_mode == NVGPU_GR_PREEMPTION_MODE_CILP) {
1767 err = gr_gp10b_set_cilp_preempt_pending(g, ch);
1768 if (err)
1769 gk20a_err(dev_from_gk20a(g),
1770 "unable to set CILP preempt pending\n");
1771 else
1772 *cilp_preempt_pending = true;
1773
1774 gk20a_resume_all_sms(g);
1775 }
1776
1777 ctx_resident = true;
1778 } else {
1779 gk20a_disable_channel_tsg(g, ch);
1780 }
1781
1782 return ctx_resident;
1783}
1784
1785static int gr_gp10b_suspend_contexts(struct gk20a *g,
1786 struct dbg_session_gk20a *dbg_s,
1787 int *ctx_resident_ch_fd)
1788{
1789 unsigned long end_jiffies = jiffies +
1790 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
1791 u32 delay = GR_IDLE_CHECK_DEFAULT;
1792 bool cilp_preempt_pending = false;
1793 struct channel_gk20a *cilp_preempt_pending_ch = NULL;
1794 struct channel_gk20a *ch;
1795 struct dbg_session_channel_data *ch_data;
1796 int err = 0;
1797 int local_ctx_resident_ch_fd = -1;
1798 bool ctx_resident;
1799
1800 mutex_lock(&g->dbg_sessions_lock);
1801
1802 err = gr_gk20a_disable_ctxsw(g);
1803 if (err) {
1804 gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw");
1805 mutex_unlock(&g->dbg_sessions_lock);
1806 goto clean_up;
1807 }
1808
1809 mutex_lock(&dbg_s->ch_list_lock);
1810
1811 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
1812 ch = g->fifo.channel + ch_data->chid;
1813
1814 ctx_resident = gr_gp10b_suspend_context(ch,
1815 &cilp_preempt_pending);
1816 if (ctx_resident)
1817 local_ctx_resident_ch_fd = ch_data->channel_fd;
1818 if (cilp_preempt_pending)
1819 cilp_preempt_pending_ch = ch;
1820 }
1821
1822 mutex_unlock(&dbg_s->ch_list_lock);
1823
1824 err = gr_gk20a_enable_ctxsw(g);
1825 if (err) {
1826 mutex_unlock(&g->dbg_sessions_lock);
1827 goto clean_up;
1828 }
1829
1830 mutex_unlock(&g->dbg_sessions_lock);
1831
1832 if (cilp_preempt_pending_ch) {
1833 struct channel_ctx_gk20a *ch_ctx =
1834 &cilp_preempt_pending_ch->ch_ctx;
1835 struct gr_ctx_desc *gr_ctx = ch_ctx->gr_ctx;
1836
1837 do {
1838 if (!gr_ctx->t18x.cilp_preempt_pending)
1839 break;
1840
1841 usleep_range(delay, delay * 2);
1842 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
1843 } while (time_before(jiffies, end_jiffies)
1844 || !tegra_platform_is_silicon());
1845
1846 err = -ETIMEDOUT;
1847 }
1848
1849 *ctx_resident_ch_fd = local_ctx_resident_ch_fd;
1850
1851clean_up:
1852 return err;
1853}
1854
1752void gp10b_init_gr(struct gpu_ops *gops) 1855void gp10b_init_gr(struct gpu_ops *gops)
1753{ 1856{
1754 gm20b_init_gr(gops); 1857 gm20b_init_gr(gops);
@@ -1787,4 +1890,5 @@ void gp10b_init_gr(struct gpu_ops *gops)
1787 gops->gr.handle_fecs_error = gr_gp10b_handle_fecs_error; 1890 gops->gr.handle_fecs_error = gr_gp10b_handle_fecs_error;
1788 gops->gr.create_gr_sysfs = gr_gp10b_create_sysfs; 1891 gops->gr.create_gr_sysfs = gr_gp10b_create_sysfs;
1789 gops->gr.get_lrf_tex_ltc_dram_override = get_ecc_override_val; 1892 gops->gr.get_lrf_tex_ltc_dram_override = get_ecc_override_val;
1893 gops->gr.suspend_contexts = gr_gp10b_suspend_contexts;
1790} 1894}