diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 56 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 35 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 37 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.h | 5 |
5 files changed, 111 insertions, 27 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; |
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); |
254 | void channel_gk20a_enable(struct channel_gk20a *ch); | 254 | void channel_gk20a_enable(struct channel_gk20a *ch); |
255 | void gk20a_channel_timeout_restart_all_channels(struct gk20a *g); | 255 | void gk20a_channel_timeout_restart_all_channels(struct gk20a *g); |
256 | |||
257 | int 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 | ||
2118 | static 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 | |||
2118 | static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, | 2144 | static 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 | ||
129 | static 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 | |||
129 | static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg) | 157 | static 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; |