summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2015-10-28 06:43:14 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-11-03 17:20:08 -0500
commit9592a4e6fce8204e9ada54ba00902e792199fec5 (patch)
tree37cc1bffce5ea48555a1ed88865e5f545627b546
parent8d279dbac10b8521aa7eaeb7640c01d21ce044f2 (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>
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c56
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h5
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c35
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.c37
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.h5
-rw-r--r--include/uapi/linux/nvgpu.h6
6 files changed, 115 insertions, 29 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
135static int channel_gk20a_set_schedule_params(struct channel_gk20a *c, 135int 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
163static 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;
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index 29697b9f..e7809daa 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -253,4 +253,9 @@ int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
253 u64 gpfifo_base, u32 gpfifo_entries, u32 flags); 253 u64 gpfifo_base, u32 gpfifo_entries, u32 flags);
254void channel_gk20a_enable(struct channel_gk20a *ch); 254void channel_gk20a_enable(struct channel_gk20a *ch);
255void gk20a_channel_timeout_restart_all_channels(struct gk20a *g); 255void gk20a_channel_timeout_restart_all_channels(struct gk20a *g);
256
257int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g,
258 int timeslice_period,
259 int *__timeslice_timeout, int *__timeslice_scale);
260
256#endif /* CHANNEL_GK20A_H */ 261#endif /* CHANNEL_GK20A_H */
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 39cb1174..5eba9f12 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -2115,6 +2115,32 @@ static int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id)
2115 return ret; 2115 return ret;
2116} 2116}
2117 2117
2118static inline u32 gk20a_get_tsg_runlist_entry_0(struct tsg_gk20a *tsg)
2119{
2120 u32 runlist_entry_0 = 0;
2121
2122 if (tsg->timeslice_timeout)
2123 runlist_entry_0 = ram_rl_entry_id_f(tsg->tsgid) |
2124 ram_rl_entry_type_f(ram_rl_entry_type_tsg_f()) |
2125 ram_rl_entry_timeslice_scale_f(
2126 tsg->timeslice_scale) |
2127 ram_rl_entry_timeslice_timeout_f(
2128 tsg->timeslice_timeout) |
2129 ram_rl_entry_tsg_length_f(
2130 tsg->num_active_channels);
2131 else
2132 runlist_entry_0 = ram_rl_entry_id_f(tsg->tsgid) |
2133 ram_rl_entry_type_f(ram_rl_entry_type_tsg_f()) |
2134 ram_rl_entry_timeslice_scale_f(
2135 ram_rl_entry_timeslice_scale_3_f()) |
2136 ram_rl_entry_timeslice_timeout_f(
2137 ram_rl_entry_timeslice_timeout_128_f()) |
2138 ram_rl_entry_tsg_length_f(
2139 tsg->num_active_channels);
2140
2141 return runlist_entry_0;
2142}
2143
2118static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, 2144static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
2119 u32 hw_chid, bool add, 2145 u32 hw_chid, bool add,
2120 bool wait_for_finish) 2146 bool wait_for_finish)
@@ -2201,14 +2227,7 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
2201 tsg = &f->tsg[tsgid]; 2227 tsg = &f->tsg[tsgid];
2202 /* add TSG entry */ 2228 /* add TSG entry */
2203 gk20a_dbg_info("add TSG %d to runlist", tsg->tsgid); 2229 gk20a_dbg_info("add TSG %d to runlist", tsg->tsgid);
2204 runlist_entry[0] = ram_rl_entry_id_f(tsg->tsgid) | 2230 runlist_entry[0] = gk20a_get_tsg_runlist_entry_0(tsg);
2205 ram_rl_entry_type_f(ram_rl_entry_type_tsg_f()) |
2206 ram_rl_entry_timeslice_scale_f(
2207 ram_rl_entry_timeslice_scale_3_f()) |
2208 ram_rl_entry_timeslice_timeout_f(
2209 ram_rl_entry_timeslice_timeout_128_f()) |
2210 ram_rl_entry_tsg_length_f(
2211 tsg->num_active_channels);
2212 runlist_entry[1] = 0; 2231 runlist_entry[1] = 0;
2213 runlist_entry += 2; 2232 runlist_entry += 2;
2214 count++; 2233 count++;
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
index 37a326d2..5cd43329 100644
--- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -126,6 +126,34 @@ int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid)
126 return 0; 126 return 0;
127} 127}
128 128
129static int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg,
130 u32 priority)
131{
132 int timeslice_period;
133
134 switch (priority) {
135 case NVGPU_PRIORITY_LOW:
136 timeslice_period = g->timeslice_low_priority_us;
137 break;
138 case NVGPU_PRIORITY_MEDIUM:
139 timeslice_period = g->timeslice_medium_priority_us;
140 break;
141 case NVGPU_PRIORITY_HIGH:
142 timeslice_period = g->timeslice_high_priority_us;
143 break;
144 default:
145 pr_err("Unsupported priority");
146 return -EINVAL;
147 }
148
149 gk20a_channel_get_timescale_from_timeslice(g, timeslice_period,
150 &tsg->timeslice_timeout, &tsg->timeslice_scale);
151
152 g->ops.fifo.update_runlist(g, 0, ~0, true, true);
153
154 return 0;
155}
156
129static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg) 157static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg)
130{ 158{
131 mutex_lock(&f->tsg_inuse_mutex); 159 mutex_lock(&f->tsg_inuse_mutex);
@@ -320,6 +348,13 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
320 break; 348 break;
321 } 349 }
322 350
351 case NVGPU_IOCTL_TSG_SET_PRIORITY:
352 {
353 err = gk20a_tsg_set_priority(g, tsg,
354 ((struct nvgpu_set_priority_args *)buf)->priority);
355 break;
356 }
357
323 default: 358 default:
324 gk20a_err(dev_from_gk20a(g), 359 gk20a_err(dev_from_gk20a(g),
325 "unrecognized tsg gpu ioctl cmd: 0x%x", 360 "unrecognized tsg gpu ioctl cmd: 0x%x",
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h
index fde33863..6178daa5 100644
--- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -42,6 +42,9 @@ struct tsg_gk20a {
42 int num_active_channels; 42 int num_active_channels;
43 struct mutex ch_list_lock; 43 struct mutex ch_list_lock;
44 44
45 int timeslice_timeout;
46 int timeslice_scale;
47
45 struct gr_ctx_desc *tsg_gr_ctx; 48 struct gr_ctx_desc *tsg_gr_ctx;
46 49
47 struct vm_gk20a *vm; 50 struct vm_gk20a *vm;
diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h
index f55346db..6024edee 100644
--- a/include/uapi/linux/nvgpu.h
+++ b/include/uapi/linux/nvgpu.h
@@ -377,11 +377,13 @@ struct nvgpu_gpu_vsms_mapping {
377 _IO(NVGPU_TSG_IOCTL_MAGIC, 4) 377 _IO(NVGPU_TSG_IOCTL_MAGIC, 4)
378#define NVGPU_IOCTL_TSG_PREEMPT \ 378#define NVGPU_IOCTL_TSG_PREEMPT \
379 _IO(NVGPU_TSG_IOCTL_MAGIC, 5) 379 _IO(NVGPU_TSG_IOCTL_MAGIC, 5)
380#define NVGPU_IOCTL_TSG_SET_PRIORITY \
381 _IOW(NVGPU_TSG_IOCTL_MAGIC, 6, struct nvgpu_set_priority_args)
380 382
381#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \ 383#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \
382 sizeof(int) 384 sizeof(struct nvgpu_set_priority_args)
383#define NVGPU_TSG_IOCTL_LAST \ 385#define NVGPU_TSG_IOCTL_LAST \
384 _IOC_NR(NVGPU_IOCTL_TSG_PREEMPT) 386 _IOC_NR(NVGPU_IOCTL_TSG_SET_PRIORITY)
385/* 387/*
386 * /dev/nvhost-dbg-gpu device 388 * /dev/nvhost-dbg-gpu device
387 * 389 *