diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 16 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 10 |
4 files changed, 24 insertions, 9 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index b4c132ce..085caec5 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -2789,16 +2789,10 @@ int gk20a_channel_suspend(struct gk20a *g) | |||
2789 | struct fifo_gk20a *f = &g->fifo; | 2789 | struct fifo_gk20a *f = &g->fifo; |
2790 | u32 chid; | 2790 | u32 chid; |
2791 | bool channels_in_use = false; | 2791 | bool channels_in_use = false; |
2792 | int err; | ||
2793 | u32 active_runlist_ids = 0; | 2792 | u32 active_runlist_ids = 0; |
2794 | 2793 | ||
2795 | gk20a_dbg_fn(""); | 2794 | gk20a_dbg_fn(""); |
2796 | 2795 | ||
2797 | /* wait for engine idle */ | ||
2798 | err = g->ops.fifo.wait_engine_idle(g); | ||
2799 | if (err) | ||
2800 | return err; | ||
2801 | |||
2802 | for (chid = 0; chid < f->num_channels; chid++) { | 2796 | for (chid = 0; chid < f->num_channels; chid++) { |
2803 | struct channel_gk20a *ch = &f->channel[chid]; | 2797 | struct channel_gk20a *ch = &f->channel[chid]; |
2804 | if (gk20a_channel_get(ch)) { | 2798 | if (gk20a_channel_get(ch)) { |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index ff052400..2e38c4b6 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -3016,6 +3016,19 @@ bool gk20a_fifo_mmu_fault_pending(struct gk20a *g) | |||
3016 | return false; | 3016 | return false; |
3017 | } | 3017 | } |
3018 | 3018 | ||
3019 | bool gk20a_fifo_is_engine_busy(struct gk20a *g) | ||
3020 | { | ||
3021 | int i; | ||
3022 | |||
3023 | for (i = 0; i < fifo_engine_status__size_1_v(); i++) { | ||
3024 | u32 status = gk20a_readl(g, fifo_engine_status_r(i)); | ||
3025 | if (fifo_engine_status_engine_v(status) == | ||
3026 | fifo_engine_status_engine_busy_v()) | ||
3027 | return true; | ||
3028 | } | ||
3029 | return false; | ||
3030 | } | ||
3031 | |||
3019 | int gk20a_fifo_wait_engine_idle(struct gk20a *g) | 3032 | int gk20a_fifo_wait_engine_idle(struct gk20a *g) |
3020 | { | 3033 | { |
3021 | unsigned long end_jiffies = jiffies + | 3034 | unsigned long end_jiffies = jiffies + |
@@ -3023,7 +3036,6 @@ int gk20a_fifo_wait_engine_idle(struct gk20a *g) | |||
3023 | unsigned long delay = GR_IDLE_CHECK_DEFAULT; | 3036 | unsigned long delay = GR_IDLE_CHECK_DEFAULT; |
3024 | int ret = -ETIMEDOUT; | 3037 | int ret = -ETIMEDOUT; |
3025 | u32 i; | 3038 | u32 i; |
3026 | struct device *d = dev_from_gk20a(g); | ||
3027 | 3039 | ||
3028 | gk20a_dbg_fn(""); | 3040 | gk20a_dbg_fn(""); |
3029 | 3041 | ||
@@ -3041,7 +3053,7 @@ int gk20a_fifo_wait_engine_idle(struct gk20a *g) | |||
3041 | } while (time_before(jiffies, end_jiffies) || | 3053 | } while (time_before(jiffies, end_jiffies) || |
3042 | !tegra_platform_is_silicon()); | 3054 | !tegra_platform_is_silicon()); |
3043 | if (ret) { | 3055 | if (ret) { |
3044 | gk20a_err(d, "cannot idle engine %u\n", i); | 3056 | gk20a_dbg_info("cannot idle engine %u", i); |
3045 | break; | 3057 | break; |
3046 | } | 3058 | } |
3047 | } | 3059 | } |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 17c6dbf6..71a9d35d 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | |||
@@ -206,6 +206,7 @@ void gk20a_init_fifo(struct gpu_ops *gops); | |||
206 | void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, | 206 | void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, |
207 | unsigned long fault_id); | 207 | unsigned long fault_id); |
208 | int gk20a_fifo_wait_engine_idle(struct gk20a *g); | 208 | int gk20a_fifo_wait_engine_idle(struct gk20a *g); |
209 | bool gk20a_fifo_is_engine_busy(struct gk20a *g); | ||
209 | u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g); | 210 | u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g); |
210 | u32 gk20a_fifo_get_pbdma_signature(struct gk20a *g); | 211 | u32 gk20a_fifo_get_pbdma_signature(struct gk20a *g); |
211 | u32 gk20a_fifo_get_failing_engine_data(struct gk20a *g, | 212 | u32 gk20a_fifo_get_failing_engine_data(struct gk20a *g, |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index f6bb9445..10fa86a1 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -767,6 +767,10 @@ static int gk20a_pm_prepare_poweroff(struct device *dev) | |||
767 | if (!g->power_on) | 767 | if (!g->power_on) |
768 | goto done; | 768 | goto done; |
769 | 769 | ||
770 | if (gk20a_fifo_is_engine_busy(g)) { | ||
771 | mutex_unlock(&g->poweroff_lock); | ||
772 | return -EBUSY; | ||
773 | } | ||
770 | gk20a_scale_suspend(dev); | 774 | gk20a_scale_suspend(dev); |
771 | 775 | ||
772 | /* cancel any pending cde work */ | 776 | /* cancel any pending cde work */ |
@@ -1353,6 +1357,7 @@ static int gk20a_pm_runtime_suspend(struct device *dev) | |||
1353 | fail_railgate: | 1357 | fail_railgate: |
1354 | gk20a_pm_finalize_poweron(dev); | 1358 | gk20a_pm_finalize_poweron(dev); |
1355 | fail: | 1359 | fail: |
1360 | pm_runtime_mark_last_busy(dev); | ||
1356 | return err; | 1361 | return err; |
1357 | } | 1362 | } |
1358 | 1363 | ||
@@ -1751,6 +1756,7 @@ int __gk20a_do_idle(struct device *dev, bool force_reset) | |||
1751 | msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS); | 1756 | msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS); |
1752 | int ref_cnt; | 1757 | int ref_cnt; |
1753 | bool is_railgated; | 1758 | bool is_railgated; |
1759 | int err = 0; | ||
1754 | 1760 | ||
1755 | /* acquire busy lock to block other busy() calls */ | 1761 | /* acquire busy lock to block other busy() calls */ |
1756 | down_write(&g->busy_lock); | 1762 | down_write(&g->busy_lock); |
@@ -1825,7 +1831,9 @@ int __gk20a_do_idle(struct device *dev, bool force_reset) | |||
1825 | */ | 1831 | */ |
1826 | 1832 | ||
1827 | /* Save the GPU state */ | 1833 | /* Save the GPU state */ |
1828 | gk20a_pm_prepare_poweroff(dev); | 1834 | err = gk20a_pm_prepare_poweroff(dev); |
1835 | if (err) | ||
1836 | goto fail_drop_usage_count; | ||
1829 | 1837 | ||
1830 | /* railgate GPU */ | 1838 | /* railgate GPU */ |
1831 | platform->railgate(dev); | 1839 | platform->railgate(dev); |