]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/com.fuc
drm/nouveau/gr: namespace + nvidia gpu names (no binary change)
[mirror_ubuntu-focal-kernel.git] / drivers / gpu / drm / nouveau / nvkm / engine / gr / fuc / com.fuc
1 /* fuc microcode util functions for gf100 PGRAPH
2 *
3 * Copyright 2011 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Ben Skeggs
24 */
25
26 #ifdef INCLUDE_CODE
27 // queue_put - add request to queue
28 //
29 // In : $r13 queue pointer
30 // $r14 command
31 // $r15 data
32 //
33 queue_put:
34 // make sure we have space..
35 ld b32 $r8 D[$r13 + 0x0] // GET
36 ld b32 $r9 D[$r13 + 0x4] // PUT
37 xor $r8 8
38 cmpu b32 $r8 $r9
39 bra ne #queue_put_next
40 mov $r15 E_CMD_OVERFLOW
41 call(error)
42 ret
43
44 // store cmd/data on queue
45 queue_put_next:
46 and $r8 $r9 7
47 shl b32 $r8 3
48 add b32 $r8 $r13
49 add b32 $r8 8
50 st b32 D[$r8 + 0x0] $r14
51 st b32 D[$r8 + 0x4] $r15
52
53 // update PUT
54 add b32 $r9 1
55 and $r9 0xf
56 st b32 D[$r13 + 0x4] $r9
57 ret
58
59 // queue_get - fetch request from queue
60 //
61 // In : $r13 queue pointer
62 //
63 // Out: $p1 clear on success (data available)
64 // $r14 command
65 // $r15 data
66 //
67 queue_get:
68 bset $flags $p1
69 ld b32 $r8 D[$r13 + 0x0] // GET
70 ld b32 $r9 D[$r13 + 0x4] // PUT
71 cmpu b32 $r8 $r9
72 bra e #queue_get_done
73 // fetch first cmd/data pair
74 and $r9 $r8 7
75 shl b32 $r9 3
76 add b32 $r9 $r13
77 add b32 $r9 8
78 ld b32 $r14 D[$r9 + 0x0]
79 ld b32 $r15 D[$r9 + 0x4]
80
81 // update GET
82 add b32 $r8 1
83 and $r8 0xf
84 st b32 D[$r13 + 0x0] $r8
85 bclr $flags $p1
86 queue_get_done:
87 ret
88
89 // nv_rd32 - read 32-bit value from nv register
90 //
91 // In : $r14 register
92 // Out: $r15 value
93 //
94 nv_rd32:
95 mov b32 $r12 $r14
96 bset $r12 31 // MMIO_CTRL_PENDING
97 nv_iowr(NV_PGRAPH_FECS_MMIO_CTRL, 0, $r12)
98 nv_rd32_wait:
99 nv_iord($r12, NV_PGRAPH_FECS_MMIO_CTRL, 0)
100 xbit $r12 $r12 31
101 bra ne #nv_rd32_wait
102 mov $r10 6 // DONE_MMIO_RD
103 call(wait_doneo)
104 nv_iord($r15, NV_PGRAPH_FECS_MMIO_RDVAL, 0)
105 ret
106
107 // nv_wr32 - write 32-bit value to nv register
108 //
109 // In : $r14 register
110 // $r15 value
111 //
112 nv_wr32:
113 nv_iowr(NV_PGRAPH_FECS_MMIO_WRVAL, 0, $r15)
114 mov b32 $r12 $r14
115 bset $r12 31 // MMIO_CTRL_PENDING
116 bset $r12 30 // MMIO_CTRL_WRITE
117 nv_iowr(NV_PGRAPH_FECS_MMIO_CTRL, 0, $r12)
118 nv_wr32_wait:
119 nv_iord($r12, NV_PGRAPH_FECS_MMIO_CTRL, 0)
120 xbit $r12 $r12 31
121 bra ne #nv_wr32_wait
122 ret
123
124 // wait_donez - wait on FUC_DONE bit to become clear
125 //
126 // In : $r10 bit to wait on
127 //
128 wait_donez:
129 trace_set(T_WAIT);
130 nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)
131 wait_donez_ne:
132 nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)
133 xbit $r8 $r8 $r10
134 bra ne #wait_donez_ne
135 trace_clr(T_WAIT)
136 ret
137
138 // wait_doneo - wait on FUC_DONE bit to become set
139 //
140 // In : $r10 bit to wait on
141 //
142 wait_doneo:
143 trace_set(T_WAIT);
144 nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)
145 wait_doneo_e:
146 nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)
147 xbit $r8 $r8 $r10
148 bra e #wait_doneo_e
149 trace_clr(T_WAIT)
150 ret
151
152 // mmctx_size - determine size of a mmio list transfer
153 //
154 // In : $r14 mmio list head
155 // $r15 mmio list tail
156 // Out: $r15 transfer size (in bytes)
157 //
158 mmctx_size:
159 clear b32 $r9
160 nv_mmctx_size_loop:
161 ld b32 $r8 D[$r14]
162 shr b32 $r8 26
163 add b32 $r8 1
164 shl b32 $r8 2
165 add b32 $r9 $r8
166 add b32 $r14 4
167 cmpu b32 $r14 $r15
168 bra ne #nv_mmctx_size_loop
169 mov b32 $r15 $r9
170 ret
171
172 // mmctx_xfer - execute a list of mmio transfers
173 //
174 // In : $r10 flags
175 // bit 0: direction (0 = save, 1 = load)
176 // bit 1: set if first transfer
177 // bit 2: set if last transfer
178 // $r11 base
179 // $r12 mmio list head
180 // $r13 mmio list tail
181 // $r14 multi_stride
182 // $r15 multi_mask
183 //
184 mmctx_xfer:
185 trace_set(T_MMCTX)
186 clear b32 $r9
187 or $r11 $r11
188 bra e #mmctx_base_disabled
189 nv_iowr(NV_PGRAPH_FECS_MMCTX_BASE, 0, $r11)
190 bset $r9 0 // BASE_EN
191 mmctx_base_disabled:
192 or $r14 $r14
193 bra e #mmctx_multi_disabled
194 nv_iowr(NV_PGRAPH_FECS_MMCTX_MULTI_STRIDE, 0, $r14)
195 nv_iowr(NV_PGRAPH_FECS_MMCTX_MULTI_MASK, 0, $r15)
196 bset $r9 1 // MULTI_EN
197 mmctx_multi_disabled:
198
199 xbit $r11 $r10 0
200 shl b32 $r11 16 // DIR
201 bset $r11 12 // QLIMIT = 0x10
202 xbit $r14 $r10 1
203 shl b32 $r14 17
204 or $r11 $r14 // START_TRIGGER
205 nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11)
206
207 // loop over the mmio list, and send requests to the hw
208 mmctx_exec_loop:
209 // wait for space in mmctx queue
210 mmctx_wait_free:
211 nv_iord($r14, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
212 and $r14 0x1f
213 bra e #mmctx_wait_free
214
215 // queue up an entry
216 ld b32 $r14 D[$r12]
217 or $r14 $r9
218 nv_iowr(NV_PGRAPH_FECS_MMCTX_QUEUE, 0, $r14)
219 add b32 $r12 4
220 cmpu b32 $r12 $r13
221 bra ne #mmctx_exec_loop
222
223 xbit $r11 $r10 2
224 bra ne #mmctx_stop
225 // wait for queue to empty
226 mmctx_fini_wait:
227 nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
228 and $r11 0x1f
229 cmpu b32 $r11 0x10
230 bra ne #mmctx_fini_wait
231 mov $r10 5 // DONE_MMCTX
232 call(wait_donez)
233 bra #mmctx_done
234 mmctx_stop:
235 xbit $r11 $r10 0
236 shl b32 $r11 16 // DIR
237 bset $r11 12 // QLIMIT = 0x10
238 bset $r11 18 // STOP_TRIGGER
239 nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11)
240 mmctx_stop_wait:
241 // wait for STOP_TRIGGER to clear
242 nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
243 xbit $r11 $r11 18
244 bra ne #mmctx_stop_wait
245 mmctx_done:
246 trace_clr(T_MMCTX)
247 ret
248
249 // Wait for DONE_STRAND
250 //
251 strand_wait:
252 push $r10
253 mov $r10 2
254 call(wait_donez)
255 pop $r10
256 ret
257
258 // unknown - call before issuing strand commands
259 //
260 strand_pre:
261 mov $r9 NV_PGRAPH_FECS_STRAND_CMD_ENABLE
262 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9)
263 call(strand_wait)
264 ret
265
266 // unknown - call after issuing strand commands
267 //
268 strand_post:
269 mov $r9 NV_PGRAPH_FECS_STRAND_CMD_DISABLE
270 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9)
271 call(strand_wait)
272 ret
273
274 // Selects strand set?!
275 //
276 // In: $r14 id
277 //
278 strand_set:
279 mov $r12 0xf
280 nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r12)
281 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_DEACTIVATE_FILTER
282 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
283 nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r14)
284 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_ACTIVATE_FILTER
285 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
286 call(strand_wait)
287 ret
288
289 // Initialise strand context data
290 //
291 // In : $r15 context base
292 // Out: $r15 context size (in bytes)
293 //
294 // Strandset(?) 3 hardcoded currently
295 //
296 strand_ctx_init:
297 trace_set(T_STRINIT)
298 call(strand_pre)
299 mov $r14 3
300 call(strand_set)
301
302 clear b32 $r12
303 nv_iowr(NV_PGRAPH_FECS_STRAND_SELECT, 0x3f, $r12)
304 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_SEEK
305 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
306 call(strand_wait)
307 sub b32 $r12 $r0 1
308 nv_iowr(NV_PGRAPH_FECS_STRAND_DATA, 0x3f, $r12)
309 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_GET_INFO
310 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
311 call(strand_wait)
312 call(strand_post)
313
314 // read the size of each strand, poke the context offset of
315 // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
316 // about it later then.
317 nv_mkio($r8, NV_PGRAPH_FECS_STRAND_SAVE_SWBASE, 0x00)
318 nv_iord($r9, NV_PGRAPH_FECS_STRANDS_CNT, 0x00)
319 shr b32 $r14 $r15 8
320 ctx_init_strand_loop:
321 iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE
322 iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE
323 iord $r10 I[$r8 + 0x200] // STRAND_SIZE
324 shr b32 $r10 6
325 add b32 $r10 1
326 add b32 $r14 $r10
327 add b32 $r8 4
328 sub b32 $r9 1
329 bra ne #ctx_init_strand_loop
330
331 shl b32 $r14 8
332 sub b32 $r15 $r14 $r15
333 trace_clr(T_STRINIT)
334 ret
335 #endif