Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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