Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
[pandora-kernel.git] / drivers / gpu / drm / nouveau / nvc0_graph.fuc
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
74         bra ne queue_put_next
75                 mov $r15 E_CMD_OVERFLOW
76                 call error
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
107         bra e queue_get_done
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
138                 bra ne nv_rd32_wait
139         mov $r10 6                      // DONE_MMIO_RD
140         call wait_doneo
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
160                 bra ne nv_wr32_wait
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
196                 bra $2 wait_done_$1
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
219                 bra ne nv_mmctx_size_loop
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
241         bra e mmctx_base_disabled
242                 iowr I[$r8 + 0x000] $r11        // MMCTX_BASE
243                 bset $r9 0                      // BASE_EN
244         mmctx_base_disabled:
245         or $r14 $r14
246         bra e mmctx_multi_disabled
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
267                         bra e mmctx_wait_free
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
275                 bra ne mmctx_exec_loop
276
277         xbit $r11 $r10 2
278         bra ne mmctx_stop
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
284                         bra ne mmctx_fini_wait
285                 mov $r10 2                              // DONE_MMCTX
286                 call wait_donez
287                 bra mmctx_done
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
298                         bra ne mmctx_stop_wait
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
308         call wait_donez
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
319         call strand_wait
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
329         call strand_wait
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
344         call strand_wait
345         iowr I[$r10 + 0x000] $r14               // 0x93c = <id>
346         mov $r12 0xa
347         iowr I[$r11 + 0x000] $r12               // 0x928 = 0xa
348         call strand_wait
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)
360         call strand_pre
361         mov $r14 3
362         call strand_set
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
369         call strand_wait
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
374         call strand_wait
375         call strand_post
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
394                 bra ne ctx_init_strand_loop
395
396         shl b32 $r14 8
397         sub b32 $r15 $r14 $r15
398         trace_clr(T_STRINIT)
399         ret
400 ')