diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 766ea749..ab06b4f9 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -165,6 +165,61 @@ u32 gk20a_fifo_get_all_ce_engine_reset_mask(struct gk20a *g) | |||
165 | return reset_mask; | 165 | return reset_mask; |
166 | } | 166 | } |
167 | 167 | ||
168 | u32 gk20a_fifo_get_gr_runlist_id(struct gk20a *g) | ||
169 | { | ||
170 | u32 gr_engine_cnt = 0; | ||
171 | u32 gr_engine_id = FIFO_INVAL_ENGINE_ID; | ||
172 | struct fifo_engine_info_gk20a *engine_info; | ||
173 | u32 gr_runlist_id = ~0; | ||
174 | |||
175 | /* Consider 1st available GR engine */ | ||
176 | gr_engine_cnt = gk20a_fifo_get_engine_ids(g, &gr_engine_id, | ||
177 | 1, ENGINE_GR_GK20A); | ||
178 | |||
179 | if (!gr_engine_cnt) { | ||
180 | gk20a_err(dev_from_gk20a(g), | ||
181 | "No GR engine available on this device!"); | ||
182 | goto end; | ||
183 | } | ||
184 | |||
185 | engine_info = gk20a_fifo_get_engine_info(g, gr_engine_id); | ||
186 | |||
187 | if (engine_info) { | ||
188 | gr_runlist_id = engine_info->runlist_id; | ||
189 | } else { | ||
190 | gk20a_err(g->dev, | ||
191 | "gr_engine_id is not in active list/invalid %d", gr_engine_id); | ||
192 | } | ||
193 | |||
194 | end: | ||
195 | return gr_runlist_id; | ||
196 | } | ||
197 | |||
198 | bool gk20a_fifo_is_valid_runlist_id(struct gk20a *g, u32 runlist_id) | ||
199 | { | ||
200 | struct fifo_gk20a *f = NULL; | ||
201 | u32 engine_id_idx; | ||
202 | u32 active_engine_id; | ||
203 | struct fifo_engine_info_gk20a *engine_info; | ||
204 | |||
205 | if (!g) | ||
206 | return false; | ||
207 | |||
208 | f = &g->fifo; | ||
209 | |||
210 | for (engine_id_idx = 0; engine_id_idx < f->num_engines; ++engine_id_idx) { | ||
211 | active_engine_id = f->active_engines_list[engine_id_idx]; | ||
212 | engine_info = gk20a_fifo_get_engine_info(g, active_engine_id); | ||
213 | if (engine_info && (engine_info->runlist_id == runlist_id)) { | ||
214 | return true; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | gk20a_err(g->dev, "runlist_id is not in active list/invalid %d", runlist_id); | ||
219 | |||
220 | return false; | ||
221 | } | ||
222 | |||
168 | /* | 223 | /* |
169 | * Link engine IDs to MMU IDs and vice versa. | 224 | * Link engine IDs to MMU IDs and vice versa. |
170 | */ | 225 | */ |
@@ -2736,6 +2791,30 @@ clean_up: | |||
2736 | return ret; | 2791 | return ret; |
2737 | } | 2792 | } |
2738 | 2793 | ||
2794 | int gk20a_fifo_update_runlist_ids(struct gk20a *g, u32 runlist_ids, u32 hw_chid, | ||
2795 | bool add, bool wait_for_finish) | ||
2796 | { | ||
2797 | u32 ret = -EINVAL; | ||
2798 | u32 runlist_id = 0; | ||
2799 | u32 errcode; | ||
2800 | |||
2801 | if (!g) | ||
2802 | goto end; | ||
2803 | |||
2804 | ret = 0; | ||
2805 | for_each_set_bit(runlist_id, (unsigned long *)&runlist_ids, 32) { | ||
2806 | /* Capture the last failure error code */ | ||
2807 | errcode = g->ops.fifo.update_runlist(g, runlist_id, hw_chid, add, wait_for_finish); | ||
2808 | if (errcode) { | ||
2809 | gk20a_err(dev_from_gk20a(g), | ||
2810 | "failed to update_runlist %d %d", runlist_id, errcode); | ||
2811 | ret = errcode; | ||
2812 | } | ||
2813 | } | ||
2814 | end: | ||
2815 | return ret; | ||
2816 | } | ||
2817 | |||
2739 | /* add/remove a channel from runlist | 2818 | /* add/remove a channel from runlist |
2740 | special cases below: runlist->active_channels will NOT be changed. | 2819 | special cases below: runlist->active_channels will NOT be changed. |
2741 | (hw_chid == ~0 && !add) means remove all active channels from runlist. | 2820 | (hw_chid == ~0 && !add) means remove all active channels from runlist. |