diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 52c0627d..daf40d9c 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -1955,6 +1955,41 @@ bool gk20a_fifo_mmu_fault_pending(struct gk20a *g) | |||
1955 | return false; | 1955 | return false; |
1956 | } | 1956 | } |
1957 | 1957 | ||
1958 | int gk20a_fifo_wait_engine_idle(struct gk20a *g) | ||
1959 | { | ||
1960 | unsigned long end_jiffies = jiffies + | ||
1961 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | ||
1962 | unsigned long delay = GR_IDLE_CHECK_DEFAULT; | ||
1963 | int ret = -ETIMEDOUT; | ||
1964 | u32 i; | ||
1965 | struct device *d = dev_from_gk20a(g); | ||
1966 | |||
1967 | gk20a_dbg_fn(""); | ||
1968 | |||
1969 | for (i = 0; i < fifo_engine_status__size_1_v(); i++) { | ||
1970 | do { | ||
1971 | u32 status = gk20a_readl(g, fifo_engine_status_r(i)); | ||
1972 | if (!fifo_engine_status_engine_v(status)) { | ||
1973 | ret = 0; | ||
1974 | break; | ||
1975 | } | ||
1976 | |||
1977 | usleep_range(delay, delay * 2); | ||
1978 | delay = min_t(unsigned long, | ||
1979 | delay << 1, GR_IDLE_CHECK_MAX); | ||
1980 | } while (time_before(jiffies, end_jiffies) || | ||
1981 | !tegra_platform_is_silicon()); | ||
1982 | if (ret) { | ||
1983 | gk20a_err(d, "cannot idle engine %u\n", i); | ||
1984 | break; | ||
1985 | } | ||
1986 | } | ||
1987 | |||
1988 | gk20a_dbg_fn("done"); | ||
1989 | |||
1990 | return ret; | ||
1991 | } | ||
1992 | |||
1958 | void gk20a_init_fifo(struct gpu_ops *gops) | 1993 | void gk20a_init_fifo(struct gpu_ops *gops) |
1959 | { | 1994 | { |
1960 | gk20a_init_channel(gops); | 1995 | gk20a_init_channel(gops); |