diff options
author | Richard Zhao <rizhao@nvidia.com> | 2016-03-31 14:16:23 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-05-31 13:47:22 -0400 |
commit | d707c5a444e024e1184213a75f44a73dbb1707d2 (patch) | |
tree | 09711370df9d9078e4f604e60983877bbf30b9de /drivers/gpu/nvgpu/gk20a | |
parent | a71ce831fbbca3ba8602e0b07ecd630c4a39f376 (diff) |
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 <rizhao@nvidia.com>
Reviewed-on: http://git-master/r/1144932
(cherry picked from commit c3787de7d38651d46969348f5acae2ba86b31ec7)
Reviewed-on: http://git-master/r/1126942
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/hal_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 48 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.h | 6 |
6 files changed, 41 insertions, 24 deletions
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) | |||
952 | 952 | ||
953 | unbind: | 953 | unbind: |
954 | if (gk20a_is_channel_marked_as_tsg(ch)) | 954 | if (gk20a_is_channel_marked_as_tsg(ch)) |
955 | gk20a_tsg_unbind_channel(ch); | 955 | g->ops.fifo.tsg_unbind_channel(ch); |
956 | 956 | ||
957 | g->ops.fifo.unbind_channel(ch); | 957 | g->ops.fifo.unbind_channel(ch); |
958 | g->ops.fifo.free_inst(g, ch); | 958 | 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) | |||
2015 | int err; | 2015 | int err; |
2016 | 2016 | ||
2017 | if (gk20a_is_channel_marked_as_tsg(ch)) | 2017 | if (gk20a_is_channel_marked_as_tsg(ch)) |
2018 | err = gk20a_fifo_preempt_tsg(ch->g, ch->tsgid); | 2018 | err = g->ops.fifo.preempt_tsg(ch->g, ch->tsgid); |
2019 | else | 2019 | else |
2020 | err = g->ops.fifo.preempt_channel(ch->g, ch->hw_chid); | 2020 | err = g->ops.fifo.preempt_channel(ch->g, ch->hw_chid); |
2021 | 2021 | ||
@@ -2754,6 +2754,7 @@ void gk20a_init_fifo(struct gpu_ops *gops) | |||
2754 | { | 2754 | { |
2755 | gk20a_init_channel(gops); | 2755 | gk20a_init_channel(gops); |
2756 | gops->fifo.preempt_channel = gk20a_fifo_preempt_channel; | 2756 | gops->fifo.preempt_channel = gk20a_fifo_preempt_channel; |
2757 | gops->fifo.preempt_tsg = gk20a_fifo_preempt_tsg; | ||
2757 | gops->fifo.update_runlist = gk20a_fifo_update_runlist; | 2758 | gops->fifo.update_runlist = gk20a_fifo_update_runlist; |
2758 | gops->fifo.trigger_mmu_fault = gk20a_fifo_trigger_mmu_fault; | 2759 | gops->fifo.trigger_mmu_fault = gk20a_fifo_trigger_mmu_fault; |
2759 | gops->fifo.apply_pb_timeout = gk20a_fifo_apply_pb_timeout; | 2760 | 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 { | |||
324 | u32 gpfifo_entries, u32 flags); | 324 | u32 gpfifo_entries, u32 flags); |
325 | int (*resetup_ramfc)(struct channel_gk20a *c); | 325 | int (*resetup_ramfc)(struct channel_gk20a *c); |
326 | int (*preempt_channel)(struct gk20a *g, u32 hw_chid); | 326 | int (*preempt_channel)(struct gk20a *g, u32 hw_chid); |
327 | int (*preempt_tsg)(struct gk20a *g, u32 tsgid); | ||
327 | int (*update_runlist)(struct gk20a *g, u32 runlist_id, | 328 | int (*update_runlist)(struct gk20a *g, u32 runlist_id, |
328 | u32 hw_chid, bool add, | 329 | u32 hw_chid, bool add, |
329 | bool wait_for_finish); | 330 | bool wait_for_finish); |
@@ -345,6 +346,9 @@ struct gpu_ops { | |||
345 | void (*device_info_data_parse)(struct gk20a *g, | 346 | void (*device_info_data_parse)(struct gk20a *g, |
346 | u32 table_entry, u32 *inst_id, | 347 | u32 table_entry, u32 *inst_id, |
347 | u32 *pri_base, u32 *fault_id); | 348 | u32 *pri_base, u32 *fault_id); |
349 | int (*tsg_bind_channel)(struct tsg_gk20a *tsg, | ||
350 | struct channel_gk20a *ch); | ||
351 | int (*tsg_unbind_channel)(struct channel_gk20a *ch); | ||
348 | } fifo; | 352 | } fifo; |
349 | struct pmu_v { | 353 | struct pmu_v { |
350 | /*used for change of enum zbc update cmd id from ver 0 to ver1*/ | 354 | /*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 @@ | |||
30 | #include "regops_gk20a.h" | 30 | #include "regops_gk20a.h" |
31 | #include "therm_gk20a.h" | 31 | #include "therm_gk20a.h" |
32 | #include "hw_proj_gk20a.h" | 32 | #include "hw_proj_gk20a.h" |
33 | #include "tsg_gk20a.h" | ||
33 | 34 | ||
34 | static struct gpu_ops gk20a_ops = { | 35 | static struct gpu_ops gk20a_ops = { |
35 | .clock_gating = { | 36 | .clock_gating = { |
@@ -142,6 +143,7 @@ int gk20a_init_hal(struct gk20a *g) | |||
142 | gk20a_init_regops(gops); | 143 | gk20a_init_regops(gops); |
143 | gk20a_init_debug_ops(gops); | 144 | gk20a_init_debug_ops(gops); |
144 | gk20a_init_therm_ops(gops); | 145 | gk20a_init_therm_ops(gops); |
146 | gk20a_init_tsg_ops(gops); | ||
145 | gops->name = "gk20a"; | 147 | gops->name = "gk20a"; |
146 | gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; | 148 | gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; |
147 | gops->get_litter_value = gk20a_get_litter_value; | 149 | 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) | |||
37 | 37 | ||
38 | int gk20a_enable_tsg(struct tsg_gk20a *tsg) | 38 | int gk20a_enable_tsg(struct tsg_gk20a *tsg) |
39 | { | 39 | { |
40 | struct gk20a *g = tsg->g; | ||
40 | struct channel_gk20a *ch; | 41 | struct channel_gk20a *ch; |
41 | 42 | ||
42 | mutex_lock(&tsg->ch_list_lock); | 43 | mutex_lock(&tsg->ch_list_lock); |
43 | list_for_each_entry(ch, &tsg->ch_list, ch_entry) { | 44 | list_for_each_entry(ch, &tsg->ch_list, ch_entry) { |
44 | gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid), | 45 | g->ops.fifo.enable_channel(ch); |
45 | gk20a_readl(ch->g, ccsr_channel_r(ch->hw_chid)) | ||
46 | | ccsr_channel_enable_set_true_f()); | ||
47 | } | 46 | } |
48 | mutex_unlock(&tsg->ch_list_lock); | 47 | mutex_unlock(&tsg->ch_list_lock); |
49 | 48 | ||
@@ -52,13 +51,12 @@ int gk20a_enable_tsg(struct tsg_gk20a *tsg) | |||
52 | 51 | ||
53 | int gk20a_disable_tsg(struct tsg_gk20a *tsg) | 52 | int gk20a_disable_tsg(struct tsg_gk20a *tsg) |
54 | { | 53 | { |
54 | struct gk20a *g = tsg->g; | ||
55 | struct channel_gk20a *ch; | 55 | struct channel_gk20a *ch; |
56 | 56 | ||
57 | mutex_lock(&tsg->ch_list_lock); | 57 | mutex_lock(&tsg->ch_list_lock); |
58 | list_for_each_entry(ch, &tsg->ch_list, ch_entry) { | 58 | list_for_each_entry(ch, &tsg->ch_list, ch_entry) { |
59 | gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid), | 59 | g->ops.fifo.disable_channel(ch); |
60 | gk20a_readl(ch->g, ccsr_channel_r(ch->hw_chid)) | ||
61 | | ccsr_channel_enable_clr_true_f()); | ||
62 | } | 60 | } |
63 | mutex_unlock(&tsg->ch_list_lock); | 61 | mutex_unlock(&tsg->ch_list_lock); |
64 | 62 | ||
@@ -80,31 +78,37 @@ static bool gk20a_is_channel_active(struct gk20a *g, struct channel_gk20a *ch) | |||
80 | return false; | 78 | return false; |
81 | } | 79 | } |
82 | 80 | ||
83 | /* | 81 | static int gk20a_tsg_bind_channel_fd(struct tsg_gk20a *tsg, int ch_fd) |
84 | * API to mark channel as part of TSG | ||
85 | * | ||
86 | * Note that channel is not runnable when we bind it to TSG | ||
87 | */ | ||
88 | static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) | ||
89 | { | 82 | { |
90 | struct file *f = fget(ch_fd); | 83 | struct file *f = fget(ch_fd); |
91 | struct channel_gk20a *ch; | 84 | struct channel_gk20a *ch; |
92 | 85 | int err; | |
93 | gk20a_dbg_fn(""); | ||
94 | 86 | ||
95 | ch = gk20a_get_channel_from_file(ch_fd); | 87 | ch = gk20a_get_channel_from_file(ch_fd); |
96 | if (!ch) | 88 | if (!ch) |
97 | return -EINVAL; | 89 | return -EINVAL; |
90 | err = ch->g->ops.fifo.tsg_bind_channel(tsg, ch); | ||
91 | fput(f); | ||
92 | return err; | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * API to mark channel as part of TSG | ||
97 | * | ||
98 | * Note that channel is not runnable when we bind it to TSG | ||
99 | */ | ||
100 | int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, | ||
101 | struct channel_gk20a *ch) | ||
102 | { | ||
103 | gk20a_dbg_fn(""); | ||
98 | 104 | ||
99 | /* check if channel is already bound to some TSG */ | 105 | /* check if channel is already bound to some TSG */ |
100 | if (gk20a_is_channel_marked_as_tsg(ch)) { | 106 | if (gk20a_is_channel_marked_as_tsg(ch)) { |
101 | fput(f); | ||
102 | return -EINVAL; | 107 | return -EINVAL; |
103 | } | 108 | } |
104 | 109 | ||
105 | /* channel cannot be bound to TSG if it is already active */ | 110 | /* channel cannot be bound to TSG if it is already active */ |
106 | if (gk20a_is_channel_active(tsg->g, ch)) { | 111 | if (gk20a_is_channel_active(tsg->g, ch)) { |
107 | fput(f); | ||
108 | return -EINVAL; | 112 | return -EINVAL; |
109 | } | 113 | } |
110 | 114 | ||
@@ -119,8 +123,6 @@ static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) | |||
119 | gk20a_dbg(gpu_dbg_fn, "BIND tsg:%d channel:%d\n", | 123 | gk20a_dbg(gpu_dbg_fn, "BIND tsg:%d channel:%d\n", |
120 | tsg->tsgid, ch->hw_chid); | 124 | tsg->tsgid, ch->hw_chid); |
121 | 125 | ||
122 | fput(f); | ||
123 | |||
124 | gk20a_dbg_fn("done"); | 126 | gk20a_dbg_fn("done"); |
125 | return 0; | 127 | return 0; |
126 | } | 128 | } |
@@ -494,7 +496,7 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, | |||
494 | err = -EINVAL; | 496 | err = -EINVAL; |
495 | break; | 497 | break; |
496 | } | 498 | } |
497 | err = gk20a_tsg_bind_channel(tsg, ch_fd); | 499 | err = gk20a_tsg_bind_channel_fd(tsg, ch_fd); |
498 | break; | 500 | break; |
499 | } | 501 | } |
500 | 502 | ||
@@ -539,7 +541,7 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, | |||
539 | return err; | 541 | return err; |
540 | } | 542 | } |
541 | /* preempt TSG */ | 543 | /* preempt TSG */ |
542 | err = gk20a_fifo_preempt_tsg(g, tsg->tsgid); | 544 | err = g->ops.fifo.preempt_tsg(g, tsg->tsgid); |
543 | gk20a_idle(g->dev); | 545 | gk20a_idle(g->dev); |
544 | break; | 546 | break; |
545 | } | 547 | } |
@@ -600,3 +602,9 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, | |||
600 | 602 | ||
601 | return err; | 603 | return err; |
602 | } | 604 | } |
605 | |||
606 | void gk20a_init_tsg_ops(struct gpu_ops *gops) | ||
607 | { | ||
608 | gops->fifo.tsg_bind_channel = gk20a_tsg_bind_channel; | ||
609 | gops->fifo.tsg_unbind_channel = gk20a_tsg_unbind_channel; | ||
610 | } | ||
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, | |||
28 | unsigned int cmd, unsigned long arg); | 28 | unsigned int cmd, unsigned long arg); |
29 | 29 | ||
30 | int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid); | 30 | int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid); |
31 | 31 | void gk20a_init_tsg_ops(struct gpu_ops *gops); | |
32 | int gk20a_tsg_unbind_channel(struct channel_gk20a *ch); | ||
33 | 32 | ||
34 | struct tsg_gk20a { | 33 | struct tsg_gk20a { |
35 | struct gk20a *g; | 34 | struct gk20a *g; |
@@ -59,6 +58,9 @@ struct tsg_gk20a { | |||
59 | 58 | ||
60 | int gk20a_enable_tsg(struct tsg_gk20a *tsg); | 59 | int gk20a_enable_tsg(struct tsg_gk20a *tsg); |
61 | int gk20a_disable_tsg(struct tsg_gk20a *tsg); | 60 | int gk20a_disable_tsg(struct tsg_gk20a *tsg); |
61 | int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, | ||
62 | struct channel_gk20a *ch); | ||
63 | int gk20a_tsg_unbind_channel(struct channel_gk20a *ch); | ||
62 | 64 | ||
63 | void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg, | 65 | void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg, |
64 | int event_id); | 66 | int event_id); |