diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 23 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 35 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 1 |
4 files changed, 42 insertions, 19 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 33681c2a..b4d9c785 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -1948,29 +1948,14 @@ int gk20a_channel_suspend(struct gk20a *g) | |||
1948 | struct fifo_gk20a *f = &g->fifo; | 1948 | struct fifo_gk20a *f = &g->fifo; |
1949 | u32 chid; | 1949 | u32 chid; |
1950 | bool channels_in_use = false; | 1950 | bool channels_in_use = false; |
1951 | struct device *d = dev_from_gk20a(g); | ||
1952 | int err; | 1951 | int err; |
1953 | 1952 | ||
1954 | gk20a_dbg_fn(""); | 1953 | gk20a_dbg_fn(""); |
1955 | 1954 | ||
1956 | /* idle the engine by submitting WFI on non-KEPLER_C channel */ | 1955 | /* wait for engine idle */ |
1957 | for (chid = 0; chid < f->num_channels; chid++) { | 1956 | err = gk20a_fifo_wait_engine_idle(g); |
1958 | struct channel_gk20a *c = &f->channel[chid]; | 1957 | if (err) |
1959 | if (c->in_use && c->obj_class != KEPLER_C && !c->has_timedout) { | 1958 | return err; |
1960 | err = gk20a_channel_submit_wfi(c); | ||
1961 | if (err) { | ||
1962 | gk20a_err(d, "cannot idle channel %d\n", | ||
1963 | chid); | ||
1964 | return err; | ||
1965 | } | ||
1966 | |||
1967 | if (c->sync) | ||
1968 | c->sync->wait_cpu(c->sync, | ||
1969 | &c->last_submit.post_fence, | ||
1970 | 500000); | ||
1971 | break; | ||
1972 | } | ||
1973 | } | ||
1974 | 1959 | ||
1975 | for (chid = 0; chid < f->num_channels; chid++) { | 1960 | for (chid = 0; chid < f->num_channels; chid++) { |
1976 | if (f->channel[chid].in_use) { | 1961 | if (f->channel[chid].in_use) { |
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index 8cb1d0a5..fb15b3da 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | |||
@@ -633,6 +633,8 @@ static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, | |||
633 | break; | 633 | break; |
634 | } | 634 | } |
635 | 635 | ||
636 | gk20a_dbg(gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d done", | ||
637 | dev_name(dbg_s->dev), powermode); | ||
636 | return err; | 638 | return err; |
637 | } | 639 | } |
638 | 640 | ||
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); |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 6e6907c1..e738b152 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | |||
@@ -169,4 +169,5 @@ void gk20a_init_fifo(struct gpu_ops *gops); | |||
169 | 169 | ||
170 | void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, | 170 | void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, |
171 | unsigned long fault_id); | 171 | unsigned long fault_id); |
172 | int gk20a_fifo_wait_engine_idle(struct gk20a *g); | ||
172 | #endif /*__GR_GK20A_H__*/ | 173 | #endif /*__GR_GK20A_H__*/ |