diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2015-10-28 06:43:14 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-11-03 17:20:08 -0500 |
commit | 9592a4e6fce8204e9ada54ba00902e792199fec5 (patch) | |
tree | 37cc1bffce5ea48555a1ed88865e5f545627b546 /drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |
parent | 8d279dbac10b8521aa7eaeb7640c01d21ce044f2 (diff) |
gpu: nvgpu: IOCTL to set TSG timeslice
Add new IOCTL NVGPU_IOCTL_TSG_SET_PRIORITY to allow
setting timeslice for entire TSG
Return error from channel specific IOCTL_CHANNEL_SET_PRIORITY
if the channel is part of TSG
Separate out API gk20a_channel_get_timescale_from_timeslice()
to get timeslice_timeout and scale from timeslice period
Use this API to get timeslice_timeout and scale for TSG and
store it in tsg_gk20a structure
Then trigger runlist update so that new timeslice values
will be re-written to runlist for TSG
Bug 200146615
Change-Id: I555467d034f81b372b31372f0835d72b1c159508
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/824206
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 5b5da633..688992c6 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -132,24 +132,14 @@ static int channel_gk20a_commit_userd(struct channel_gk20a *c) | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | static int channel_gk20a_set_schedule_params(struct channel_gk20a *c, | 135 | int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g, |
136 | u32 timeslice_timeout) | 136 | int timeslice_period, |
137 | int *__timeslice_timeout, int *__timeslice_scale) | ||
137 | { | 138 | { |
138 | void *inst_ptr; | 139 | struct gk20a_platform *platform = platform_get_drvdata(g->dev); |
139 | struct gk20a_platform *platform = platform_get_drvdata(c->g->dev); | 140 | int value = scale_ptimer(timeslice_period, |
140 | int shift = 3; | ||
141 | int value = scale_ptimer(timeslice_timeout, | ||
142 | platform->ptimerscaling10x); | 141 | platform->ptimerscaling10x); |
143 | 142 | int shift = 3; | |
144 | inst_ptr = c->inst_block.cpu_va; | ||
145 | if (!inst_ptr) | ||
146 | return -ENOMEM; | ||
147 | |||
148 | /* disable channel */ | ||
149 | c->g->ops.fifo.disable_channel(c); | ||
150 | |||
151 | /* preempt the channel */ | ||
152 | WARN_ON(c->g->ops.fifo.preempt_channel(c->g, c->hw_chid)); | ||
153 | 143 | ||
154 | /* value field is 8 bits long */ | 144 | /* value field is 8 bits long */ |
155 | while (value >= 1 << 8) { | 145 | while (value >= 1 << 8) { |
@@ -164,6 +154,31 @@ static int channel_gk20a_set_schedule_params(struct channel_gk20a *c, | |||
164 | shift = 10; | 154 | shift = 10; |
165 | } | 155 | } |
166 | 156 | ||
157 | *__timeslice_timeout = value; | ||
158 | *__timeslice_scale = shift; | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int channel_gk20a_set_schedule_params(struct channel_gk20a *c, | ||
164 | u32 timeslice_period) | ||
165 | { | ||
166 | void *inst_ptr; | ||
167 | int shift = 0, value = 0; | ||
168 | |||
169 | inst_ptr = c->inst_block.cpu_va; | ||
170 | if (!inst_ptr) | ||
171 | return -ENOMEM; | ||
172 | |||
173 | gk20a_channel_get_timescale_from_timeslice(c->g, timeslice_period, | ||
174 | &value, &shift); | ||
175 | |||
176 | /* disable channel */ | ||
177 | c->g->ops.fifo.disable_channel(c); | ||
178 | |||
179 | /* preempt the channel */ | ||
180 | WARN_ON(c->g->ops.fifo.preempt_channel(c->g, c->hw_chid)); | ||
181 | |||
167 | /* set new timeslice */ | 182 | /* set new timeslice */ |
168 | gk20a_mem_wr32(inst_ptr, ram_fc_runlist_timeslice_w(), | 183 | gk20a_mem_wr32(inst_ptr, ram_fc_runlist_timeslice_w(), |
169 | value | (shift << 12) | | 184 | value | (shift << 12) | |
@@ -2350,6 +2365,13 @@ static int gk20a_channel_set_priority(struct channel_gk20a *ch, | |||
2350 | u32 priority) | 2365 | u32 priority) |
2351 | { | 2366 | { |
2352 | u32 timeslice_timeout; | 2367 | u32 timeslice_timeout; |
2368 | |||
2369 | if (gk20a_is_channel_marked_as_tsg(ch)) { | ||
2370 | gk20a_err(dev_from_gk20a(ch->g), | ||
2371 | "invalid operation for TSG!\n"); | ||
2372 | return -EINVAL; | ||
2373 | } | ||
2374 | |||
2353 | /* set priority of graphics channel */ | 2375 | /* set priority of graphics channel */ |
2354 | switch (priority) { | 2376 | switch (priority) { |
2355 | case NVGPU_PRIORITY_LOW: | 2377 | case NVGPU_PRIORITY_LOW: |
@@ -2714,7 +2736,7 @@ long gk20a_channel_ioctl(struct file *filp, | |||
2714 | __func__, cmd); | 2736 | __func__, cmd); |
2715 | break; | 2737 | break; |
2716 | } | 2738 | } |
2717 | gk20a_channel_set_priority(ch, | 2739 | err = gk20a_channel_set_priority(ch, |
2718 | ((struct nvgpu_set_priority_args *)buf)->priority); | 2740 | ((struct nvgpu_set_priority_args *)buf)->priority); |
2719 | gk20a_idle(dev); | 2741 | gk20a_idle(dev); |
2720 | break; | 2742 | break; |