Commit | Line | Data |
---|---|---|
0411de85 BS |
1 | /* fuc microcode util functions for nvc0 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 | define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)') | |
27 | define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))') | |
28 | ||
29 | ifdef(`include_code', ` | |
30 | // Error codes | |
31 | define(`E_BAD_COMMAND', 0x01) | |
32 | define(`E_CMD_OVERFLOW', 0x02) | |
33 | ||
34 | // Util macros to help with debugging ucode hangs etc | |
35 | define(`T_WAIT', 0) | |
36 | define(`T_MMCTX', 1) | |
37 | define(`T_STRWAIT', 2) | |
38 | define(`T_STRINIT', 3) | |
39 | define(`T_AUTO', 4) | |
40 | define(`T_CHAN', 5) | |
41 | define(`T_LOAD', 6) | |
42 | define(`T_SAVE', 7) | |
43 | define(`T_LCHAN', 8) | |
44 | define(`T_LCTXH', 9) | |
45 | ||
46 | define(`trace_set', ` | |
47 | mov $r8 0x83c | |
48 | shl b32 $r8 6 | |
49 | clear b32 $r9 | |
50 | bset $r9 $1 | |
51 | iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] | |
52 | ') | |
53 | ||
54 | define(`trace_clr', ` | |
55 | mov $r8 0x85c | |
56 | shl b32 $r8 6 | |
57 | clear b32 $r9 | |
58 | bset $r9 $1 | |
59 | iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] | |
60 | ') | |
61 | ||
62 | // queue_put - add request to queue | |
63 | // | |
64 | // In : $r13 queue pointer | |
65 | // $r14 command | |
66 | // $r15 data | |
67 | // | |
68 | queue_put: | |
69 | // make sure we have space.. | |
70 | ld b32 $r8 D[$r13 + 0x0] // GET | |
71 | ld b32 $r9 D[$r13 + 0x4] // PUT | |
72 | xor $r8 8 | |
73 | cmpu b32 $r8 $r9 | |
be7f2615 | 74 | bra ne #queue_put_next |
0411de85 | 75 | mov $r15 E_CMD_OVERFLOW |
be7f2615 | 76 | call #error |
0411de85 BS |
77 | ret |
78 | ||
79 | // store cmd/data on queue | |
80 | queue_put_next: | |
81 | and $r8 $r9 7 | |
82 | shl b32 $r8 3 | |
83 | add b32 $r8 $r13 | |
84 | add b32 $r8 8 | |
85 | st b32 D[$r8 + 0x0] $r14 | |
86 | st b32 D[$r8 + 0x4] $r15 | |
87 | ||
88 | // update PUT | |
89 | add b32 $r9 1 | |
90 | and $r9 0xf | |
91 | st b32 D[$r13 + 0x4] $r9 | |
92 | ret | |
93 | ||
94 | // queue_get - fetch request from queue | |
95 | // | |
96 | // In : $r13 queue pointer | |
97 | // | |
98 | // Out: $p1 clear on success (data available) | |
99 | // $r14 command | |
100 | // $r15 data | |
101 | // | |
102 | queue_get: | |
103 | bset $flags $p1 | |
104 | ld b32 $r8 D[$r13 + 0x0] // GET | |
105 | ld b32 $r9 D[$r13 + 0x4] // PUT | |
106 | cmpu b32 $r8 $r9 | |
be7f2615 | 107 | bra e #queue_get_done |
0411de85 BS |
108 | // fetch first cmd/data pair |
109 | and $r9 $r8 7 | |
110 | shl b32 $r9 3 | |
111 | add b32 $r9 $r13 | |
112 | add b32 $r9 8 | |
113 | ld b32 $r14 D[$r9 + 0x0] | |
114 | ld b32 $r15 D[$r9 + 0x4] | |
115 | ||
116 | // update GET | |
117 | add b32 $r8 1 | |
118 | and $r8 0xf | |
119 | st b32 D[$r13 + 0x0] $r8 | |
120 | bclr $flags $p1 | |
121 | queue_get_done: | |
122 | ret | |
123 | ||
124 | // nv_rd32 - read 32-bit value from nv register | |
125 | // | |
126 | // In : $r14 register | |
127 | // Out: $r15 value | |
128 | // | |
129 | nv_rd32: | |
130 | mov $r11 0x728 | |
131 | shl b32 $r11 6 | |
132 | mov b32 $r12 $r14 | |
133 | bset $r12 31 // MMIO_CTRL_PENDING | |
134 | iowr I[$r11 + 0x000] $r12 // MMIO_CTRL | |
135 | nv_rd32_wait: | |
136 | iord $r12 I[$r11 + 0x000] | |
137 | xbit $r12 $r12 31 | |
be7f2615 | 138 | bra ne #nv_rd32_wait |
0411de85 | 139 | mov $r10 6 // DONE_MMIO_RD |
be7f2615 | 140 | call #wait_doneo |
0411de85 BS |
141 | iord $r15 I[$r11 + 0x100] // MMIO_RDVAL |
142 | ret | |
143 | ||
144 | // nv_wr32 - write 32-bit value to nv register | |
145 | // | |
146 | // In : $r14 register | |
147 | // $r15 value | |
148 | // | |
149 | nv_wr32: | |
150 | mov $r11 0x728 | |
151 | shl b32 $r11 6 | |
152 | iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL | |
153 | mov b32 $r12 $r14 | |
154 | bset $r12 31 // MMIO_CTRL_PENDING | |
155 | bset $r12 30 // MMIO_CTRL_WRITE | |
156 | iowr I[$r11 + 0x000] $r12 // MMIO_CTRL | |
157 | nv_wr32_wait: | |
158 | iord $r12 I[$r11 + 0x000] | |
159 | xbit $r12 $r12 31 | |
be7f2615 | 160 | bra ne #nv_wr32_wait |
0411de85 BS |
161 | ret |
162 | ||
163 | // (re)set watchdog timer | |
164 | // | |
165 | // In : $r15 timeout | |
166 | // | |
167 | watchdog_reset: | |
168 | mov $r8 0x430 | |
169 | shl b32 $r8 6 | |
170 | bset $r15 31 | |
171 | iowr I[$r8 + 0x000] $r15 | |
172 | ret | |
173 | ||
174 | // clear watchdog timer | |
175 | watchdog_clear: | |
176 | mov $r8 0x430 | |
177 | shl b32 $r8 6 | |
178 | iowr I[$r8 + 0x000] $r0 | |
179 | ret | |
180 | ||
181 | // wait_done{z,o} - wait on FUC_DONE bit to become clear/set | |
182 | // | |
183 | // In : $r10 bit to wait on | |
184 | // | |
185 | define(`wait_done', ` | |
186 | $1: | |
187 | trace_set(T_WAIT); | |
188 | mov $r8 0x818 | |
189 | shl b32 $r8 6 | |
190 | iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit | |
191 | wait_done_$1: | |
192 | mov $r8 0x400 | |
193 | shl b32 $r8 6 | |
194 | iord $r8 I[$r8 + 0x000] // DONE | |
195 | xbit $r8 $r8 $r10 | |
be7f2615 | 196 | bra $2 #wait_done_$1 |
0411de85 BS |
197 | trace_clr(T_WAIT) |
198 | ret | |
199 | ') | |
200 | wait_done(wait_donez, ne) | |
201 | wait_done(wait_doneo, e) | |
202 | ||
203 | // mmctx_size - determine size of a mmio list transfer | |
204 | // | |
205 | // In : $r14 mmio list head | |
206 | // $r15 mmio list tail | |
207 | // Out: $r15 transfer size (in bytes) | |
208 | // | |
209 | mmctx_size: | |
210 | clear b32 $r9 | |
211 | nv_mmctx_size_loop: | |
212 | ld b32 $r8 D[$r14] | |
213 | shr b32 $r8 26 | |
214 | add b32 $r8 1 | |
215 | shl b32 $r8 2 | |
216 | add b32 $r9 $r8 | |
217 | add b32 $r14 4 | |
218 | cmpu b32 $r14 $r15 | |
be7f2615 | 219 | bra ne #nv_mmctx_size_loop |
0411de85 BS |
220 | mov b32 $r15 $r9 |
221 | ret | |
222 | ||
223 | // mmctx_xfer - execute a list of mmio transfers | |
224 | // | |
225 | // In : $r10 flags | |
226 | // bit 0: direction (0 = save, 1 = load) | |
227 | // bit 1: set if first transfer | |
228 | // bit 2: set if last transfer | |
229 | // $r11 base | |
230 | // $r12 mmio list head | |
231 | // $r13 mmio list tail | |
232 | // $r14 multi_stride | |
233 | // $r15 multi_mask | |
234 | // | |
235 | mmctx_xfer: | |
236 | trace_set(T_MMCTX) | |
237 | mov $r8 0x710 | |
238 | shl b32 $r8 6 | |
239 | clear b32 $r9 | |
240 | or $r11 $r11 | |
be7f2615 | 241 | bra e #mmctx_base_disabled |
0411de85 BS |
242 | iowr I[$r8 + 0x000] $r11 // MMCTX_BASE |
243 | bset $r9 0 // BASE_EN | |
244 | mmctx_base_disabled: | |
245 | or $r14 $r14 | |
be7f2615 | 246 | bra e #mmctx_multi_disabled |
0411de85 BS |
247 | iowr I[$r8 + 0x200] $r14 // MMCTX_MULTI_STRIDE |
248 | iowr I[$r8 + 0x300] $r15 // MMCTX_MULTI_MASK | |
249 | bset $r9 1 // MULTI_EN | |
250 | mmctx_multi_disabled: | |
251 | add b32 $r8 0x100 | |
252 | ||
253 | xbit $r11 $r10 0 | |
254 | shl b32 $r11 16 // DIR | |
255 | bset $r11 12 // QLIMIT = 0x10 | |
256 | xbit $r14 $r10 1 | |
257 | shl b32 $r14 17 | |
258 | or $r11 $r14 // START_TRIGGER | |
259 | iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL | |
260 | ||
261 | // loop over the mmio list, and send requests to the hw | |
262 | mmctx_exec_loop: | |
263 | // wait for space in mmctx queue | |
264 | mmctx_wait_free: | |
265 | iord $r14 I[$r8 + 0x000] // MMCTX_CTRL | |
266 | and $r14 0x1f | |
be7f2615 | 267 | bra e #mmctx_wait_free |
0411de85 BS |
268 | |
269 | // queue up an entry | |
270 | ld b32 $r14 D[$r12] | |
271 | or $r14 $r9 | |
272 | iowr I[$r8 + 0x300] $r14 | |
273 | add b32 $r12 4 | |
274 | cmpu b32 $r12 $r13 | |
be7f2615 | 275 | bra ne #mmctx_exec_loop |
0411de85 BS |
276 | |
277 | xbit $r11 $r10 2 | |
be7f2615 | 278 | bra ne #mmctx_stop |
0411de85 BS |
279 | // wait for queue to empty |
280 | mmctx_fini_wait: | |
281 | iord $r11 I[$r8 + 0x000] // MMCTX_CTRL | |
282 | and $r11 0x1f | |
283 | cmpu b32 $r11 0x10 | |
be7f2615 | 284 | bra ne #mmctx_fini_wait |
0411de85 | 285 | mov $r10 2 // DONE_MMCTX |
be7f2615 BS |
286 | call #wait_donez |
287 | bra #mmctx_done | |
0411de85 BS |
288 | mmctx_stop: |
289 | xbit $r11 $r10 0 | |
290 | shl b32 $r11 16 // DIR | |
291 | bset $r11 12 // QLIMIT = 0x10 | |
292 | bset $r11 18 // STOP_TRIGGER | |
293 | iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL | |
294 | mmctx_stop_wait: | |
295 | // wait for STOP_TRIGGER to clear | |
296 | iord $r11 I[$r8 + 0x000] // MMCTX_CTRL | |
297 | xbit $r11 $r11 18 | |
be7f2615 | 298 | bra ne #mmctx_stop_wait |
0411de85 BS |
299 | mmctx_done: |
300 | trace_clr(T_MMCTX) | |
301 | ret | |
302 | ||
303 | // Wait for DONE_STRAND | |
304 | // | |
305 | strand_wait: | |
306 | push $r10 | |
307 | mov $r10 2 | |
be7f2615 | 308 | call #wait_donez |
0411de85 BS |
309 | pop $r10 |
310 | ret | |
311 | ||
312 | // unknown - call before issuing strand commands | |
313 | // | |
314 | strand_pre: | |
315 | mov $r8 0x4afc | |
316 | sethi $r8 0x20000 | |
317 | mov $r9 0xc | |
318 | iowr I[$r8] $r9 | |
be7f2615 | 319 | call #strand_wait |
0411de85 BS |
320 | ret |
321 | ||
322 | // unknown - call after issuing strand commands | |
323 | // | |
324 | strand_post: | |
325 | mov $r8 0x4afc | |
326 | sethi $r8 0x20000 | |
327 | mov $r9 0xd | |
328 | iowr I[$r8] $r9 | |
be7f2615 | 329 | call #strand_wait |
0411de85 BS |
330 | ret |
331 | ||
332 | // Selects strand set?! | |
333 | // | |
334 | // In: $r14 id | |
335 | // | |
336 | strand_set: | |
337 | mov $r10 0x4ffc | |
338 | sethi $r10 0x20000 | |
339 | sub b32 $r11 $r10 0x500 | |
340 | mov $r12 0xf | |
341 | iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf | |
342 | mov $r12 0xb | |
343 | iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb | |
be7f2615 | 344 | call #strand_wait |
0411de85 BS |
345 | iowr I[$r10 + 0x000] $r14 // 0x93c = <id> |
346 | mov $r12 0xa | |
347 | iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa | |
be7f2615 | 348 | call #strand_wait |
0411de85 BS |
349 | ret |
350 | ||
351 | // Initialise strand context data | |
352 | // | |
353 | // In : $r15 context base | |
354 | // Out: $r15 context size (in bytes) | |
355 | // | |
356 | // Strandset(?) 3 hardcoded currently | |
357 | // | |
358 | strand_ctx_init: | |
359 | trace_set(T_STRINIT) | |
be7f2615 | 360 | call #strand_pre |
0411de85 | 361 | mov $r14 3 |
be7f2615 | 362 | call #strand_set |
0411de85 BS |
363 | mov $r10 0x46fc |
364 | sethi $r10 0x20000 | |
365 | add b32 $r11 $r10 0x400 | |
366 | iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0 | |
367 | mov $r12 1 | |
368 | iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE | |
be7f2615 | 369 | call #strand_wait |
0411de85 BS |
370 | sub b32 $r12 $r0 1 |
371 | iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff | |
372 | mov $r12 2 | |
373 | iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT | |
be7f2615 BS |
374 | call #strand_wait |
375 | call #strand_post | |
0411de85 BS |
376 | |
377 | // read the size of each strand, poke the context offset of | |
378 | // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry | |
379 | // about it later then. | |
380 | mov $r8 0x880 | |
381 | shl b32 $r8 6 | |
382 | iord $r9 I[$r8 + 0x000] // STRANDS | |
383 | add b32 $r8 0x2200 | |
384 | shr b32 $r14 $r15 8 | |
385 | ctx_init_strand_loop: | |
386 | iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE | |
387 | iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE | |
388 | iord $r10 I[$r8 + 0x200] // STRAND_SIZE | |
389 | shr b32 $r10 6 | |
390 | add b32 $r10 1 | |
391 | add b32 $r14 $r10 | |
392 | add b32 $r8 4 | |
393 | sub b32 $r9 1 | |
be7f2615 | 394 | bra ne #ctx_init_strand_loop |
0411de85 BS |
395 | |
396 | shl b32 $r14 8 | |
397 | sub b32 $r15 $r14 $r15 | |
398 | trace_clr(T_STRINIT) | |
399 | ret | |
400 | ') |