summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c23
-rw-r--r--drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c35
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.h1
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
1958int 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
1958void gk20a_init_fifo(struct gpu_ops *gops) 1993void 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
170void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, 170void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g,
171 unsigned long fault_id); 171 unsigned long fault_id);
172int gk20a_fifo_wait_engine_idle(struct gk20a *g);
172#endif /*__GR_GK20A_H__*/ 173#endif /*__GR_GK20A_H__*/