diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b')
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/gr_gp10b.c | 104 |
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 | ||
1752 | static 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 | |||
1785 | static 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 | |||
1851 | clean_up: | ||
1852 | return err; | ||
1853 | } | ||
1854 | |||
1752 | void gp10b_init_gr(struct gpu_ops *gops) | 1855 | void 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 | } |