From d707c5a444e024e1184213a75f44a73dbb1707d2 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Thu, 31 Mar 2016 11:16:23 -0700 Subject: gpu: nvgpu: add tsg support for vgpu - make tsg_gk20a.c call HAL for enable/disable channels - add preempt_tsg HAL callbacks - add tsg bind/unbind channel HAL callbacks - add according tsg callbacks for vgpu Bug 1702773 JIRA VFND-1003 Change-Id: I2cba74b3ebd3920ef09219a168e6433d9574dbe8 Signed-off-by: Richard Zhao Reviewed-on: http://git-master/r/1144932 (cherry picked from commit c3787de7d38651d46969348f5acae2ba86b31ec7) Reviewed-on: http://git-master/r/1126942 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 2 +- drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 3 ++- drivers/gpu/nvgpu/gk20a/gk20a.h | 4 +++ drivers/gpu/nvgpu/gk20a/hal_gk20a.c | 2 ++ drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 48 +++++++++++++++++++-------------- drivers/gpu/nvgpu/gk20a/tsg_gk20a.h | 6 +++-- 6 files changed, 41 insertions(+), 24 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index a73a314c..02de1391 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -952,7 +952,7 @@ static void gk20a_free_channel(struct channel_gk20a *ch) unbind: if (gk20a_is_channel_marked_as_tsg(ch)) - gk20a_tsg_unbind_channel(ch); + g->ops.fifo.tsg_unbind_channel(ch); g->ops.fifo.unbind_channel(ch); g->ops.fifo.free_inst(g, ch); diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 92536b36..134a2480 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -2015,7 +2015,7 @@ int gk20a_fifo_preempt(struct gk20a *g, struct channel_gk20a *ch) int err; if (gk20a_is_channel_marked_as_tsg(ch)) - err = gk20a_fifo_preempt_tsg(ch->g, ch->tsgid); + err = g->ops.fifo.preempt_tsg(ch->g, ch->tsgid); else err = g->ops.fifo.preempt_channel(ch->g, ch->hw_chid); @@ -2754,6 +2754,7 @@ void gk20a_init_fifo(struct gpu_ops *gops) { gk20a_init_channel(gops); gops->fifo.preempt_channel = gk20a_fifo_preempt_channel; + gops->fifo.preempt_tsg = gk20a_fifo_preempt_tsg; gops->fifo.update_runlist = gk20a_fifo_update_runlist; gops->fifo.trigger_mmu_fault = gk20a_fifo_trigger_mmu_fault; gops->fifo.apply_pb_timeout = gk20a_fifo_apply_pb_timeout; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 0e13fba3..6f47f228 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -324,6 +324,7 @@ struct gpu_ops { u32 gpfifo_entries, u32 flags); int (*resetup_ramfc)(struct channel_gk20a *c); int (*preempt_channel)(struct gk20a *g, u32 hw_chid); + int (*preempt_tsg)(struct gk20a *g, u32 tsgid); int (*update_runlist)(struct gk20a *g, u32 runlist_id, u32 hw_chid, bool add, bool wait_for_finish); @@ -345,6 +346,9 @@ struct gpu_ops { void (*device_info_data_parse)(struct gk20a *g, u32 table_entry, u32 *inst_id, u32 *pri_base, u32 *fault_id); + int (*tsg_bind_channel)(struct tsg_gk20a *tsg, + struct channel_gk20a *ch); + int (*tsg_unbind_channel)(struct channel_gk20a *ch); } fifo; struct pmu_v { /*used for change of enum zbc update cmd id from ver 0 to ver1*/ diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c index fb3b3e55..5112af55 100644 --- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c @@ -30,6 +30,7 @@ #include "regops_gk20a.h" #include "therm_gk20a.h" #include "hw_proj_gk20a.h" +#include "tsg_gk20a.h" static struct gpu_ops gk20a_ops = { .clock_gating = { @@ -142,6 +143,7 @@ int gk20a_init_hal(struct gk20a *g) gk20a_init_regops(gops); gk20a_init_debug_ops(gops); gk20a_init_therm_ops(gops); + gk20a_init_tsg_ops(gops); gops->name = "gk20a"; gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; gops->get_litter_value = gk20a_get_litter_value; diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index 5b77bf80..1e479395 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c @@ -37,13 +37,12 @@ bool gk20a_is_channel_marked_as_tsg(struct channel_gk20a *ch) int gk20a_enable_tsg(struct tsg_gk20a *tsg) { + struct gk20a *g = tsg->g; struct channel_gk20a *ch; mutex_lock(&tsg->ch_list_lock); list_for_each_entry(ch, &tsg->ch_list, ch_entry) { - gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid), - gk20a_readl(ch->g, ccsr_channel_r(ch->hw_chid)) - | ccsr_channel_enable_set_true_f()); + g->ops.fifo.enable_channel(ch); } mutex_unlock(&tsg->ch_list_lock); @@ -52,13 +51,12 @@ int gk20a_enable_tsg(struct tsg_gk20a *tsg) int gk20a_disable_tsg(struct tsg_gk20a *tsg) { + struct gk20a *g = tsg->g; struct channel_gk20a *ch; mutex_lock(&tsg->ch_list_lock); list_for_each_entry(ch, &tsg->ch_list, ch_entry) { - gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid), - gk20a_readl(ch->g, ccsr_channel_r(ch->hw_chid)) - | ccsr_channel_enable_clr_true_f()); + g->ops.fifo.disable_channel(ch); } mutex_unlock(&tsg->ch_list_lock); @@ -80,31 +78,37 @@ static bool gk20a_is_channel_active(struct gk20a *g, struct channel_gk20a *ch) return false; } -/* - * API to mark channel as part of TSG - * - * Note that channel is not runnable when we bind it to TSG - */ -static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) +static int gk20a_tsg_bind_channel_fd(struct tsg_gk20a *tsg, int ch_fd) { struct file *f = fget(ch_fd); struct channel_gk20a *ch; - - gk20a_dbg_fn(""); + int err; ch = gk20a_get_channel_from_file(ch_fd); if (!ch) return -EINVAL; + err = ch->g->ops.fifo.tsg_bind_channel(tsg, ch); + fput(f); + return err; +} + +/* + * API to mark channel as part of TSG + * + * Note that channel is not runnable when we bind it to TSG + */ +int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, + struct channel_gk20a *ch) +{ + gk20a_dbg_fn(""); /* check if channel is already bound to some TSG */ if (gk20a_is_channel_marked_as_tsg(ch)) { - fput(f); return -EINVAL; } /* channel cannot be bound to TSG if it is already active */ if (gk20a_is_channel_active(tsg->g, ch)) { - fput(f); return -EINVAL; } @@ -119,8 +123,6 @@ static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) gk20a_dbg(gpu_dbg_fn, "BIND tsg:%d channel:%d\n", tsg->tsgid, ch->hw_chid); - fput(f); - gk20a_dbg_fn("done"); return 0; } @@ -494,7 +496,7 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, err = -EINVAL; break; } - err = gk20a_tsg_bind_channel(tsg, ch_fd); + err = gk20a_tsg_bind_channel_fd(tsg, ch_fd); break; } @@ -539,7 +541,7 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, return err; } /* preempt TSG */ - err = gk20a_fifo_preempt_tsg(g, tsg->tsgid); + err = g->ops.fifo.preempt_tsg(g, tsg->tsgid); gk20a_idle(g->dev); break; } @@ -600,3 +602,9 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, return err; } + +void gk20a_init_tsg_ops(struct gpu_ops *gops) +{ + gops->fifo.tsg_bind_channel = gk20a_tsg_bind_channel; + gops->fifo.tsg_unbind_channel = gk20a_tsg_unbind_channel; +} diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h index 9a8bfada..14ead5c0 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h @@ -28,8 +28,7 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid); - -int gk20a_tsg_unbind_channel(struct channel_gk20a *ch); +void gk20a_init_tsg_ops(struct gpu_ops *gops); struct tsg_gk20a { struct gk20a *g; @@ -59,6 +58,9 @@ struct tsg_gk20a { int gk20a_enable_tsg(struct tsg_gk20a *tsg); int gk20a_disable_tsg(struct tsg_gk20a *tsg); +int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, + struct channel_gk20a *ch); +int gk20a_tsg_unbind_channel(struct channel_gk20a *ch); void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg, int event_id); -- cgit v1.2.2