Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hch/vfs...
[pandora-kernel.git] / drivers / gpu / drm / nouveau / nvc0_grgpc.fuc
1 /* fuc microcode for nvc0 PGRAPH/GPC
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 /* To build:
27  *    m4 nvc0_grgpc.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_grgpc.fuc.h
28  */
29
30 /* TODO
31  * - bracket certain functions with scratch writes, useful for debugging
32  * - watchdog timer around ctx operations
33  */
34
35 .section nvc0_grgpc_data
36 include(`nvc0_graph.fuc')
37 gpc_id:                 .b32 0
38 gpc_mmio_list_head:     .b32 0
39 gpc_mmio_list_tail:     .b32 0
40
41 tpc_count:              .b32 0
42 tpc_mask:               .b32 0
43 tpc_mmio_list_head:     .b32 0
44 tpc_mmio_list_tail:     .b32 0
45
46 cmd_queue:              queue_init
47
48 // chipset descriptions
49 chipsets:
50 .b8  0xc0 0 0 0
51 .b16 nvc0_gpc_mmio_head
52 .b16 nvc0_gpc_mmio_tail
53 .b16 nvc0_tpc_mmio_head
54 .b16 nvc0_tpc_mmio_tail
55 .b8  0xc1 0 0 0
56 .b16 nvc0_gpc_mmio_head
57 .b16 nvc1_gpc_mmio_tail
58 .b16 nvc0_tpc_mmio_head
59 .b16 nvc1_tpc_mmio_tail
60 .b8  0xc3 0 0 0
61 .b16 nvc0_gpc_mmio_head
62 .b16 nvc0_gpc_mmio_tail
63 .b16 nvc0_tpc_mmio_head
64 .b16 nvc3_tpc_mmio_tail
65 .b8  0xc4 0 0 0
66 .b16 nvc0_gpc_mmio_head
67 .b16 nvc0_gpc_mmio_tail
68 .b16 nvc0_tpc_mmio_head
69 .b16 nvc3_tpc_mmio_tail
70 .b8  0xc8 0 0 0
71 .b16 nvc0_gpc_mmio_head
72 .b16 nvc0_gpc_mmio_tail
73 .b16 nvc0_tpc_mmio_head
74 .b16 nvc0_tpc_mmio_tail
75 .b8  0xce 0 0 0
76 .b16 nvc0_gpc_mmio_head
77 .b16 nvc0_gpc_mmio_tail
78 .b16 nvc0_tpc_mmio_head
79 .b16 nvc3_tpc_mmio_tail
80 .b8  0xcf 0 0 0
81 .b16 nvc0_gpc_mmio_head
82 .b16 nvc0_gpc_mmio_tail
83 .b16 nvc0_tpc_mmio_head
84 .b16 nvcf_tpc_mmio_tail
85 .b8  0 0 0 0
86
87 // GPC mmio lists
88 nvc0_gpc_mmio_head:
89 mmctx_data(0x000380, 1)
90 mmctx_data(0x000400, 6)
91 mmctx_data(0x000450, 9)
92 mmctx_data(0x000600, 1)
93 mmctx_data(0x000684, 1)
94 mmctx_data(0x000700, 5)
95 mmctx_data(0x000800, 1)
96 mmctx_data(0x000808, 3)
97 mmctx_data(0x000828, 1)
98 mmctx_data(0x000830, 1)
99 mmctx_data(0x0008d8, 1)
100 mmctx_data(0x0008e0, 1)
101 mmctx_data(0x0008e8, 6)
102 mmctx_data(0x00091c, 1)
103 mmctx_data(0x000924, 3)
104 mmctx_data(0x000b00, 1)
105 mmctx_data(0x000b08, 6)
106 mmctx_data(0x000bb8, 1)
107 mmctx_data(0x000c08, 1)
108 mmctx_data(0x000c10, 8)
109 mmctx_data(0x000c80, 1)
110 mmctx_data(0x000c8c, 1)
111 mmctx_data(0x001000, 3)
112 mmctx_data(0x001014, 1)
113 nvc0_gpc_mmio_tail:
114 mmctx_data(0x000c6c, 1);
115 nvc1_gpc_mmio_tail:
116
117 // TPC mmio lists
118 nvc0_tpc_mmio_head:
119 mmctx_data(0x000018, 1)
120 mmctx_data(0x00003c, 1)
121 mmctx_data(0x000048, 1)
122 mmctx_data(0x000064, 1)
123 mmctx_data(0x000088, 1)
124 mmctx_data(0x000200, 6)
125 mmctx_data(0x00021c, 2)
126 mmctx_data(0x000300, 6)
127 mmctx_data(0x0003d0, 1)
128 mmctx_data(0x0003e0, 2)
129 mmctx_data(0x000400, 3)
130 mmctx_data(0x000420, 1)
131 mmctx_data(0x0004b0, 1)
132 mmctx_data(0x0004e8, 1)
133 mmctx_data(0x0004f4, 1)
134 mmctx_data(0x000520, 2)
135 mmctx_data(0x000604, 4)
136 mmctx_data(0x000644, 20)
137 mmctx_data(0x000698, 1)
138 mmctx_data(0x000750, 2)
139 nvc0_tpc_mmio_tail:
140 mmctx_data(0x000758, 1)
141 mmctx_data(0x0002c4, 1)
142 mmctx_data(0x0006e0, 1)
143 nvcf_tpc_mmio_tail:
144 mmctx_data(0x0004bc, 1)
145 nvc3_tpc_mmio_tail:
146 mmctx_data(0x000544, 1)
147 nvc1_tpc_mmio_tail:
148
149
150 .section nvc0_grgpc_code
151 bra init
152 define(`include_code')
153 include(`nvc0_graph.fuc')
154
155 // reports an exception to the host
156 //
157 // In: $r15 error code (see nvc0_graph.fuc)
158 //
159 error:
160         push $r14
161         mov $r14 -0x67ec        // 0x9814
162         sethi $r14 0x400000
163         call nv_wr32            // HUB_CTXCTL_CC_SCRATCH[5] = error code
164         add b32 $r14 0x41c
165         mov $r15 1
166         call nv_wr32            // HUB_CTXCTL_INTR_UP_SET
167         pop $r14
168         ret
169
170 // GPC fuc initialisation, executed by triggering ucode start, will
171 // fall through to main loop after completion.
172 //
173 // Input:
174 //   CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
175 //   CC_SCRATCH[1]: context base
176 //
177 // Output:
178 //   CC_SCRATCH[0]:
179 //           31:31: set to signal completion
180 //   CC_SCRATCH[1]:
181 //            31:0: GPC context size
182 //
183 init:
184         clear b32 $r0
185         mov $sp $r0
186
187         // enable fifo access
188         mov $r1 0x1200
189         mov $r2 2
190         iowr I[$r1 + 0x000] $r2         // FIFO_ENABLE
191
192         // setup i0 handler, and route all interrupts to it
193         mov $r1 ih
194         mov $iv0 $r1
195         mov $r1 0x400
196         iowr I[$r1 + 0x300] $r0         // INTR_DISPATCH
197
198         // enable fifo interrupt
199         mov $r2 4
200         iowr I[$r1 + 0x000] $r2         // INTR_EN_SET
201
202         // enable interrupts
203         bset $flags ie0
204
205         // figure out which GPC we are, and how many TPCs we have
206         mov $r1 0x608
207         shl b32 $r1 6
208         iord $r2 I[$r1 + 0x000]         // UNITS
209         mov $r3 1
210         and $r2 0x1f
211         shl b32 $r3 $r2
212         sub b32 $r3 1
213         st b32 D[$r0 + tpc_count] $r2
214         st b32 D[$r0 + tpc_mask] $r3
215         add b32 $r1 0x400
216         iord $r2 I[$r1 + 0x000]         // MYINDEX
217         st b32 D[$r0 + gpc_id] $r2
218
219         // find context data for this chipset
220         mov $r2 0x800
221         shl b32 $r2 6
222         iord $r2 I[$r2 + 0x000]         // CC_SCRATCH[0]
223         mov $r1 chipsets - 12
224         init_find_chipset:
225                 add b32 $r1 12
226                 ld b32 $r3 D[$r1 + 0x00]
227                 cmpu b32 $r3 $r2
228                 bra e init_context
229                 cmpu b32 $r3 0
230                 bra ne init_find_chipset
231                 // unknown chipset
232                 ret
233
234         // initialise context base, and size tracking
235         init_context:
236         mov $r2 0x800
237         shl b32 $r2 6
238         iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
239         clear b32 $r3           // track GPC context size here
240
241         // set mmctx base addresses now so we don't have to do it later,
242         // they don't currently ever change
243         mov $r4 0x700
244         shl b32 $r4 6
245         shr b32 $r5 $r2 8
246         iowr I[$r4 + 0x000] $r5         // MMCTX_SAVE_SWBASE
247         iowr I[$r4 + 0x100] $r5         // MMCTX_LOAD_SWBASE
248
249         // calculate GPC mmio context size, store the chipset-specific
250         // mmio list pointers somewhere we can get at them later without
251         // re-parsing the chipset list
252         clear b32 $r14
253         clear b32 $r15
254         ld b16 $r14 D[$r1 + 4]
255         ld b16 $r15 D[$r1 + 6]
256         st b16 D[$r0 + gpc_mmio_list_head] $r14
257         st b16 D[$r0 + gpc_mmio_list_tail] $r15
258         call mmctx_size
259         add b32 $r2 $r15
260         add b32 $r3 $r15
261
262         // calculate per-TPC mmio context size, store the list pointers
263         ld b16 $r14 D[$r1 + 8]
264         ld b16 $r15 D[$r1 + 10]
265         st b16 D[$r0 + tpc_mmio_list_head] $r14
266         st b16 D[$r0 + tpc_mmio_list_tail] $r15
267         call mmctx_size
268         ld b32 $r14 D[$r0 + tpc_count]
269         mulu $r14 $r15
270         add b32 $r2 $r14
271         add b32 $r3 $r14
272
273         // round up base/size to 256 byte boundary (for strand SWBASE)
274         add b32 $r4 0x1300
275         shr b32 $r3 2
276         iowr I[$r4 + 0x000] $r3         // MMCTX_LOAD_COUNT, wtf for?!?
277         shr b32 $r2 8
278         shr b32 $r3 6
279         add b32 $r2 1
280         add b32 $r3 1
281         shl b32 $r2 8
282         shl b32 $r3 8
283
284         // calculate size of strand context data
285         mov b32 $r15 $r2
286         call strand_ctx_init
287         add b32 $r3 $r15
288
289         // save context size, and tell HUB we're done
290         mov $r1 0x800
291         shl b32 $r1 6
292         iowr I[$r1 + 0x100] $r3         // CC_SCRATCH[1]  = context size
293         add b32 $r1 0x800
294         clear b32 $r2
295         bset $r2 31
296         iowr I[$r1 + 0x000] $r2         // CC_SCRATCH[0] |= 0x80000000
297
298 // Main program loop, very simple, sleeps until woken up by the interrupt
299 // handler, pulls a command from the queue and executes its handler
300 //
301 main:
302         bset $flags $p0
303         sleep $p0
304         mov $r13 cmd_queue
305         call queue_get
306         bra $p1 main
307
308         // 0x0000-0x0003 are all context transfers
309         cmpu b32 $r14 0x04
310         bra nc main_not_ctx_xfer
311                 // fetch $flags and mask off $p1/$p2
312                 mov $r1 $flags
313                 mov $r2 0x0006
314                 not b32 $r2
315                 and $r1 $r2
316                 // set $p1/$p2 according to transfer type
317                 shl b32 $r14 1
318                 or $r1 $r14
319                 mov $flags $r1
320                 // transfer context data
321                 call ctx_xfer
322                 bra main
323
324         main_not_ctx_xfer:
325         shl b32 $r15 $r14 16
326         or $r15 E_BAD_COMMAND
327         call error
328         bra main
329
330 // interrupt handler
331 ih:
332         push $r8
333         mov $r8 $flags
334         push $r8
335         push $r9
336         push $r10
337         push $r11
338         push $r13
339         push $r14
340         push $r15
341
342         // incoming fifo command?
343         iord $r10 I[$r0 + 0x200]        // INTR
344         and $r11 $r10 0x00000004
345         bra e ih_no_fifo
346                 // queue incoming fifo command for later processing
347                 mov $r11 0x1900
348                 mov $r13 cmd_queue
349                 iord $r14 I[$r11 + 0x100]       // FIFO_CMD
350                 iord $r15 I[$r11 + 0x000]       // FIFO_DATA
351                 call queue_put
352                 add b32 $r11 0x400
353                 mov $r14 1
354                 iowr I[$r11 + 0x000] $r14       // FIFO_ACK
355
356         // ack, and wake up main()
357         ih_no_fifo:
358         iowr I[$r0 + 0x100] $r10        // INTR_ACK
359
360         pop $r15
361         pop $r14
362         pop $r13
363         pop $r11
364         pop $r10
365         pop $r9
366         pop $r8
367         mov $flags $r8
368         pop $r8
369         bclr $flags $p0
370         iret
371
372 // Set this GPC's bit in HUB_BAR, used to signal completion of various
373 // activities to the HUB fuc
374 //
375 hub_barrier_done:
376         mov $r15 1
377         ld b32 $r14 D[$r0 + gpc_id]
378         shl b32 $r15 $r14
379         mov $r14 -0x6be8        // 0x409418 - HUB_BAR_SET
380         sethi $r14 0x400000
381         call nv_wr32
382         ret
383
384 // Disables various things, waits a bit, and re-enables them..
385 //
386 // Not sure how exactly this helps, perhaps "ENABLE" is not such a
387 // good description for the bits we turn off?  Anyways, without this,
388 // funny things happen.
389 //
390 ctx_redswitch:
391         mov $r14 0x614
392         shl b32 $r14 6
393         mov $r15 0x020
394         iowr I[$r14] $r15       // GPC_RED_SWITCH = POWER
395         mov $r15 8
396         ctx_redswitch_delay:
397                 sub b32 $r15 1
398                 bra ne ctx_redswitch_delay
399         mov $r15 0xa20
400         iowr I[$r14] $r15       // GPC_RED_SWITCH = UNK11, ENABLE, POWER
401         ret
402
403 // Transfer GPC context data between GPU and storage area
404 //
405 // In: $r15 context base address
406 //     $p1 clear on save, set on load
407 //     $p2 set if opposite direction done/will be done, so:
408 //              on save it means: "a load will follow this save"
409 //              on load it means: "a save preceeded this load"
410 //
411 ctx_xfer:
412         // set context base address
413         mov $r1 0xa04
414         shl b32 $r1 6
415         iowr I[$r1 + 0x000] $r15// MEM_BASE
416         bra not $p1 ctx_xfer_not_load
417                 call ctx_redswitch
418         ctx_xfer_not_load:
419
420         // strands
421         mov $r1 0x4afc
422         sethi $r1 0x20000
423         mov $r2 0xc
424         iowr I[$r1] $r2         // STRAND_CMD(0x3f) = 0x0c
425         call strand_wait
426         mov $r2 0x47fc
427         sethi $r2 0x20000
428         iowr I[$r2] $r0         // STRAND_FIRST_GENE(0x3f) = 0x00
429         xbit $r2 $flags $p1
430         add b32 $r2 3
431         iowr I[$r1] $r2         // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
432
433         // mmio context
434         xbit $r10 $flags $p1    // direction
435         or $r10 2               // first
436         mov $r11 0x0000
437         sethi $r11 0x500000
438         ld b32 $r12 D[$r0 + gpc_id]
439         shl b32 $r12 15
440         add b32 $r11 $r12       // base = NV_PGRAPH_GPCn
441         ld b32 $r12 D[$r0 + gpc_mmio_list_head]
442         ld b32 $r13 D[$r0 + gpc_mmio_list_tail]
443         mov $r14 0              // not multi
444         call mmctx_xfer
445
446         // per-TPC mmio context
447         xbit $r10 $flags $p1    // direction
448         or $r10 4               // last
449         mov $r11 0x4000
450         sethi $r11 0x500000     // base = NV_PGRAPH_GPC0_TPC0
451         ld b32 $r12 D[$r0 + gpc_id]
452         shl b32 $r12 15
453         add b32 $r11 $r12       // base = NV_PGRAPH_GPCn_TPC0
454         ld b32 $r12 D[$r0 + tpc_mmio_list_head]
455         ld b32 $r13 D[$r0 + tpc_mmio_list_tail]
456         ld b32 $r15 D[$r0 + tpc_mask]
457         mov $r14 0x800          // stride = 0x800
458         call mmctx_xfer
459
460         // wait for strands to finish
461         call strand_wait
462
463         // if load, or a save without a load following, do some
464         // unknown stuff that's done after finishing a block of
465         // strand commands
466         bra $p1 ctx_xfer_post
467         bra not $p2 ctx_xfer_done
468         ctx_xfer_post:
469                 mov $r1 0x4afc
470                 sethi $r1 0x20000
471                 mov $r2 0xd
472                 iowr I[$r1] $r2         // STRAND_CMD(0x3f) = 0x0d
473                 call strand_wait
474
475         // mark completion in HUB's barrier
476         ctx_xfer_done:
477         call hub_barrier_done
478         ret
479
480 .align 256