From 51f3f542fabb31527024eba5b8f52bf87cc30659 Mon Sep 17 00:00:00 2001 From: Seema Khowala Date: Wed, 22 Feb 2017 11:52:46 -0800 Subject: gpu: nvgpu: add is_preempt_pending fifo ops is_preempt_pending fifo ops is added as t19x preempt done sequence is differnt than legacy chips. Change-Id: I6b46be1f5b911ae11bbe806968cb8fabb21848e0 Signed-off-by: Seema Khowala Reviewed-on: http://git-master/r/1309678 Reviewed-by: svccoveritychecker GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 95 +++++++++++++++++++++--------------- drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 21 ++++++-- drivers/gpu/nvgpu/gk20a/gk20a.h | 4 ++ 3 files changed, 77 insertions(+), 43 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a') diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index b52e5310..de2c3f9e 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -2441,66 +2441,82 @@ void gk20a_fifo_issue_preempt(struct gk20a *g, u32 id, bool is_tsg) fifo_preempt_type_channel_f()); } -static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) +int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, + unsigned int id_type, unsigned int timeout_rc_type) { struct nvgpu_timeout timeout; u32 delay = GR_IDLE_CHECK_DEFAULT; - u32 ret = 0; - - gk20a_dbg_fn("%d", id); - - /* issue preempt */ - gk20a_fifo_issue_preempt(g, id, is_tsg); + int ret = -EBUSY; - gk20a_dbg_fn("%d", id); - /* wait for preempt */ - ret = -EBUSY; nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), NVGPU_TIMER_CPU_TIMER); do { if (!(gk20a_readl(g, fifo_preempt_r()) & - fifo_preempt_pending_true_f())) { + fifo_preempt_pending_true_f())) { ret = 0; break; } usleep_range(delay, delay * 2); delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); - } while (!nvgpu_timeout_expired(&timeout)); + } while (!nvgpu_timeout_expired_msg(&timeout, "preempt timeout")); - gk20a_dbg_fn("%d", id); - if (ret) { - if (is_tsg) { - struct tsg_gk20a *tsg = &g->fifo.tsg[id]; - struct channel_gk20a *ch = NULL; + return ret; +} - gk20a_err(dev_from_gk20a(g), - "preempt TSG %d timeout\n", id); +void __locked_fifo_preempt_timeout_rc(struct gk20a *g, u32 id, + unsigned int id_type) +{ + if (id_type == ID_TYPE_TSG) { + struct tsg_gk20a *tsg = &g->fifo.tsg[id]; + struct channel_gk20a *ch = NULL; - down_read(&tsg->ch_list_lock); - list_for_each_entry(ch, &tsg->ch_list, ch_entry) { - if (!gk20a_channel_get(ch)) - continue; - gk20a_set_error_notifier(ch, - NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT); - gk20a_channel_put(ch); - } - up_read(&tsg->ch_list_lock); - gk20a_fifo_recover_tsg(g, id, true); - } else { - struct channel_gk20a *ch = &g->fifo.channel[id]; + gk20a_err(dev_from_gk20a(g), + "preempt TSG %d timeout\n", id); - gk20a_err(dev_from_gk20a(g), - "preempt channel %d timeout\n", id); + down_read(&tsg->ch_list_lock); + list_for_each_entry(ch, &tsg->ch_list, ch_entry) { + if (!gk20a_channel_get(ch)) + continue; + gk20a_set_error_notifier(ch, + NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT); + gk20a_channel_put(ch); + } + up_read(&tsg->ch_list_lock); + gk20a_fifo_recover_tsg(g, id, true); + } else { + struct channel_gk20a *ch = &g->fifo.channel[id]; - if (gk20a_channel_get(ch)) { - gk20a_set_error_notifier(ch, - NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT); - gk20a_fifo_recover_ch(g, id, true); - gk20a_channel_put(ch); - } + gk20a_err(dev_from_gk20a(g), + "preempt channel %d timeout\n", id); + + if (gk20a_channel_get(ch)) { + gk20a_set_error_notifier(ch, + NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT); + gk20a_fifo_recover_ch(g, id, true); + gk20a_channel_put(ch); } } +} + +int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) +{ + int ret; + unsigned int id_type; + + gk20a_dbg_fn("%d", id); + + /* issue preempt */ + gk20a_fifo_issue_preempt(g, id, is_tsg); + + id_type = is_tsg ? ID_TYPE_TSG : ID_TYPE_CHANNEL; + + /* wait for preempt */ + ret = g->ops.fifo.is_preempt_pending(g, id, id_type, + PREEMPT_TIMEOUT_RC); + + if (ret) + __locked_fifo_preempt_timeout_rc(g, id, id_type); return ret; } @@ -3802,4 +3818,5 @@ void gk20a_init_fifo(struct gpu_ops *gops) gops->fifo.dump_eng_status = gk20a_dump_eng_status; gops->fifo.dump_channel_status_ramfc = gk20a_dump_channel_status_ramfc; gops->fifo.intr_0_error_mask = gk20a_fifo_intr_0_error_mask; + gops->fifo.is_preempt_pending = gk20a_fifo_is_preempt_pending; } diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 2de5e2d6..9793f37b 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h @@ -25,11 +25,18 @@ #include "tsg_gk20a.h" #include "debug_gk20a.h" -#define MAX_RUNLIST_BUFFERS 2 +#define MAX_RUNLIST_BUFFERS 2 -#define FIFO_INVAL_ENGINE_ID ((u32)~0) -#define FIFO_INVAL_CHANNEL_ID ((u32)~0) -#define FIFO_INVAL_TSG_ID ((u32)~0) +#define FIFO_INVAL_ENGINE_ID ((u32)~0) +#define FIFO_INVAL_CHANNEL_ID ((u32)~0) +#define FIFO_INVAL_TSG_ID ((u32)~0) + +#define ID_TYPE_CHANNEL 0 +#define ID_TYPE_TSG 1 +#define ID_TYPE_UNKNOWN ((u32)~0) + +#define PREEMPT_TIMEOUT_RC 1 +#define PREEMPT_TIMEOUT_NORC 0 /* * Number of entries in the kickoff latency buffer, used to calculate @@ -336,4 +343,10 @@ struct channel_gk20a *gk20a_refch_from_inst_ptr(struct gk20a *g, u64 inst_ptr); u32 gk20a_fifo_intr_0_error_mask(struct gk20a *g); +int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, unsigned int id_type, + unsigned int timeout_rc_type); +int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg); +void __locked_fifo_preempt_timeout_rc(struct gk20a *g, u32 id, + unsigned int id_type); + #endif /*__GR_GK20A_H__*/ diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index c1e1b564..d5757130 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -450,6 +450,10 @@ struct gpu_ops { struct gk20a_debug_output *o, u32 hw_chid, struct ch_state *ch_state); u32 (*intr_0_error_mask)(struct gk20a *g); + int (*is_preempt_pending)(struct gk20a *g, u32 id, + unsigned int id_type, unsigned int timeout_rc_type); + int (*preempt_ch_tsg)(struct gk20a *g, u32 id, + unsigned int id_type, unsigned int timeout_rc_type); } fifo; struct pmu_v { /*used for change of enum zbc update cmd id from ver 0 to ver1*/ -- cgit v1.2.2