97f775b0245193317ea8df0f13465b7fbca33bbd
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / gpu / drm / nouveau / core / engine / graph / fuc / gpc.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 /* TODO
27  * - bracket certain functions with scratch writes, useful for debugging
28  * - watchdog timer around ctx operations
29  */
30
31 #ifdef INCLUDE_DATA
32 gpc_mmio_list_head:     .b32 #mmio_list_base
33 gpc_mmio_list_tail:
34 tpc_mmio_list_head:     .b32 #mmio_list_base
35 tpc_mmio_list_tail:
36 unk_mmio_list_head:     .b32 #mmio_list_base
37 unk_mmio_list_tail:     .b32 #mmio_list_base
38
39 gpc_id:                 .b32 0
40
41 tpc_count:              .b32 0
42 tpc_mask:               .b32 0
43
44 #ifdef NVGK
45 unk_count:              .b32 1
46 unk_mask:               .b32 1
47 #endif
48
49 cmd_queue:              queue_init
50
51 mmio_list_base:
52 #endif
53
54 #ifdef INCLUDE_CODE
55 // reports an exception to the host
56 //
57 // In: $r15 error code (see nvc0.fuc)
58 //
59 error:
60         push $r14
61         mov $r14 -0x67ec        // 0x9814
62         sethi $r14 0x400000
63         call #nv_wr32           // HUB_CTXCTL_CC_SCRATCH[5] = error code
64         add b32 $r14 0x41c
65         mov $r15 1
66         call #nv_wr32           // HUB_CTXCTL_INTR_UP_SET
67         pop $r14
68         ret
69
70 // GPC fuc initialisation, executed by triggering ucode start, will
71 // fall through to main loop after completion.
72 //
73 // Input:
74 //   CC_SCRATCH[1]: context base
75 //
76 // Output:
77 //   CC_SCRATCH[0]:
78 //           31:31: set to signal completion
79 //   CC_SCRATCH[1]:
80 //            31:0: GPC context size
81 //
82 init:
83         clear b32 $r0
84         mov $sp $r0
85
86         // enable fifo access
87         mov $r1 0x1200
88         mov $r2 2
89         iowr I[$r1 + 0x000] $r2         // FIFO_ENABLE
90
91         // setup i0 handler, and route all interrupts to it
92         mov $r1 #ih
93         mov $iv0 $r1
94         mov $r1 0x400
95         iowr I[$r1 + 0x300] $r0         // INTR_DISPATCH
96
97         // enable fifo interrupt
98         mov $r2 4
99         iowr I[$r1 + 0x000] $r2         // INTR_EN_SET
100
101         // enable interrupts
102         bset $flags ie0
103
104         // figure out which GPC we are, and how many TPCs we have
105         mov $r1 0x608
106         shl b32 $r1 6
107         iord $r2 I[$r1 + 0x000]         // UNITS
108         mov $r3 1
109         and $r2 0x1f
110         shl b32 $r3 $r2
111         sub b32 $r3 1
112         st b32 D[$r0 + #tpc_count] $r2
113         st b32 D[$r0 + #tpc_mask] $r3
114         add b32 $r1 0x400
115         iord $r2 I[$r1 + 0x000]         // MYINDEX
116         st b32 D[$r0 + #gpc_id] $r2
117
118         // initialise context base, and size tracking
119         mov $r2 0x800
120         shl b32 $r2 6
121         iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
122         clear b32 $r3           // track GPC context size here
123
124         // set mmctx base addresses now so we don't have to do it later,
125         // they don't currently ever change
126         mov $r4 0x700
127         shl b32 $r4 6
128         shr b32 $r5 $r2 8
129         iowr I[$r4 + 0x000] $r5         // MMCTX_SAVE_SWBASE
130         iowr I[$r4 + 0x100] $r5         // MMCTX_LOAD_SWBASE
131
132         // calculate GPC mmio context size
133         ld b32 $r14 D[$r0 + #gpc_mmio_list_head]
134         ld b32 $r15 D[$r0 + #gpc_mmio_list_tail]
135         call #mmctx_size
136         add b32 $r2 $r15
137         add b32 $r3 $r15
138
139         // calculate per-TPC mmio context size
140         ld b32 $r14 D[$r0 + #tpc_mmio_list_head]
141         ld b32 $r15 D[$r0 + #tpc_mmio_list_tail]
142         call #mmctx_size
143         ld b32 $r14 D[$r0 + #tpc_count]
144         mulu $r14 $r15
145         add b32 $r2 $r14
146         add b32 $r3 $r14
147
148 #ifdef NVGK
149         // calculate per-UNK mmio context size
150         ld b32 $r14 D[$r0 + #unk_mmio_list_head]
151         ld b32 $r15 D[$r0 + #unk_mmio_list_tail]
152         call #mmctx_size
153         ld b32 $r14 D[$r0 + #unk_count]
154         mulu $r14 $r15
155         add b32 $r2 $r14
156         add b32 $r3 $r14
157 #endif
158
159         // round up base/size to 256 byte boundary (for strand SWBASE)
160         add b32 $r4 0x1300
161         shr b32 $r3 2
162         iowr I[$r4 + 0x000] $r3         // MMCTX_LOAD_COUNT, wtf for?!?
163         shr b32 $r2 8
164         shr b32 $r3 6
165         add b32 $r2 1
166         add b32 $r3 1
167         shl b32 $r2 8
168         shl b32 $r3 8
169
170         // calculate size of strand context data
171         mov b32 $r15 $r2
172         call #strand_ctx_init
173         add b32 $r3 $r15
174
175         // save context size, and tell HUB we're done
176         mov $r1 0x800
177         shl b32 $r1 6
178         iowr I[$r1 + 0x100] $r3         // CC_SCRATCH[1]  = context size
179         add b32 $r1 0x800
180         clear b32 $r2
181         bset $r2 31
182         iowr I[$r1 + 0x000] $r2         // CC_SCRATCH[0] |= 0x80000000
183
184 // Main program loop, very simple, sleeps until woken up by the interrupt
185 // handler, pulls a command from the queue and executes its handler
186 //
187 main:
188         bset $flags $p0
189         sleep $p0
190         mov $r13 #cmd_queue
191         call #queue_get
192         bra $p1 #main
193
194         // 0x0000-0x0003 are all context transfers
195         cmpu b32 $r14 0x04
196         bra nc #main_not_ctx_xfer
197                 // fetch $flags and mask off $p1/$p2
198                 mov $r1 $flags
199                 mov $r2 0x0006
200                 not b32 $r2
201                 and $r1 $r2
202                 // set $p1/$p2 according to transfer type
203                 shl b32 $r14 1
204                 or $r1 $r14
205                 mov $flags $r1
206                 // transfer context data
207                 call #ctx_xfer
208                 bra #main
209
210         main_not_ctx_xfer:
211         shl b32 $r15 $r14 16
212         or $r15 E_BAD_COMMAND
213         call #error
214         bra #main
215
216 // interrupt handler
217 ih:
218         push $r8
219         mov $r8 $flags
220         push $r8
221         push $r9
222         push $r10
223         push $r11
224         push $r13
225         push $r14
226         push $r15
227
228         // incoming fifo command?
229         iord $r10 I[$r0 + 0x200]        // INTR
230         and $r11 $r10 0x00000004
231         bra e #ih_no_fifo
232                 // queue incoming fifo command for later processing
233                 mov $r11 0x1900
234                 mov $r13 #cmd_queue
235                 iord $r14 I[$r11 + 0x100]       // FIFO_CMD
236                 iord $r15 I[$r11 + 0x000]       // FIFO_DATA
237                 call #queue_put
238                 add b32 $r11 0x400
239                 mov $r14 1
240                 iowr I[$r11 + 0x000] $r14       // FIFO_ACK
241
242         // ack, and wake up main()
243         ih_no_fifo:
244         iowr I[$r0 + 0x100] $r10        // INTR_ACK
245
246         pop $r15
247         pop $r14
248         pop $r13
249         pop $r11
250         pop $r10
251         pop $r9
252         pop $r8
253         mov $flags $r8
254         pop $r8
255         bclr $flags $p0
256         iret
257
258 // Set this GPC's bit in HUB_BAR, used to signal completion of various
259 // activities to the HUB fuc
260 //
261 hub_barrier_done:
262         mov $r15 1
263         ld b32 $r14 D[$r0 + #gpc_id]
264         shl b32 $r15 $r14
265         mov $r14 -0x6be8        // 0x409418 - HUB_BAR_SET
266         sethi $r14 0x400000
267         call #nv_wr32
268         ret
269
270 // Disables various things, waits a bit, and re-enables them..
271 //
272 // Not sure how exactly this helps, perhaps "ENABLE" is not such a
273 // good description for the bits we turn off?  Anyways, without this,
274 // funny things happen.
275 //
276 ctx_redswitch:
277         mov $r14 0x614
278         shl b32 $r14 6
279         mov $r15 0x020
280         iowr I[$r14] $r15       // GPC_RED_SWITCH = POWER
281         mov $r15 8
282         ctx_redswitch_delay:
283                 sub b32 $r15 1
284                 bra ne #ctx_redswitch_delay
285         mov $r15 0xa20
286         iowr I[$r14] $r15       // GPC_RED_SWITCH = UNK11, ENABLE, POWER
287         ret
288
289 // Transfer GPC context data between GPU and storage area
290 //
291 // In: $r15 context base address
292 //     $p1 clear on save, set on load
293 //     $p2 set if opposite direction done/will be done, so:
294 //              on save it means: "a load will follow this save"
295 //              on load it means: "a save preceeded this load"
296 //
297 ctx_xfer:
298         // set context base address
299         mov $r1 0xa04
300         shl b32 $r1 6
301         iowr I[$r1 + 0x000] $r15// MEM_BASE
302         bra not $p1 #ctx_xfer_not_load
303                 call #ctx_redswitch
304         ctx_xfer_not_load:
305
306         // strands
307         mov $r1 0x4afc
308         sethi $r1 0x20000
309         mov $r2 0xc
310         iowr I[$r1] $r2         // STRAND_CMD(0x3f) = 0x0c
311         call #strand_wait
312         mov $r2 0x47fc
313         sethi $r2 0x20000
314         iowr I[$r2] $r0         // STRAND_FIRST_GENE(0x3f) = 0x00
315         xbit $r2 $flags $p1
316         add b32 $r2 3
317         iowr I[$r1] $r2         // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
318
319         // mmio context
320         xbit $r10 $flags $p1    // direction
321         or $r10 2               // first
322         mov $r11 0x0000
323         sethi $r11 0x500000
324         ld b32 $r12 D[$r0 + #gpc_id]
325         shl b32 $r12 15
326         add b32 $r11 $r12       // base = NV_PGRAPH_GPCn
327         ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
328         ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
329         mov $r14 0              // not multi
330         call #mmctx_xfer
331
332         // per-TPC mmio context
333         xbit $r10 $flags $p1    // direction
334         mov $r11 0x4000
335         sethi $r11 0x500000     // base = NV_PGRAPH_GPC0_TPC0
336         ld b32 $r12 D[$r0 + #gpc_id]
337         shl b32 $r12 15
338         add b32 $r11 $r12       // base = NV_PGRAPH_GPCn_TPC0
339         ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
340         ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
341         ld b32 $r15 D[$r0 + #tpc_mask]
342         mov $r14 0x800          // stride = 0x800
343         call #mmctx_xfer
344
345 #ifdef NVGK
346         // per-UNK mmio context
347         xbit $r10 $flags $p1    // direction
348         or $r10 4               // last
349         mov $r11 0x3000
350         sethi $r11 0x500000     // base = NV_PGRAPH_GPC0_UNK0
351         ld b32 $r12 D[$r0 + #gpc_id]
352         shl b32 $r12 15
353         add b32 $r11 $r12       // base = NV_PGRAPH_GPCn_UNK0
354         ld b32 $r12 D[$r0 + #unk_mmio_list_head]
355         ld b32 $r13 D[$r0 + #unk_mmio_list_tail]
356         ld b32 $r15 D[$r0 + #unk_mask]
357         mov $r14 0x200          // stride = 0x200
358         call #mmctx_xfer
359 #endif
360
361         // wait for strands to finish
362         call #strand_wait
363
364         // if load, or a save without a load following, do some
365         // unknown stuff that's done after finishing a block of
366         // strand commands
367         bra $p1 #ctx_xfer_post
368         bra not $p2 #ctx_xfer_done
369         ctx_xfer_post:
370                 mov $r1 0x4afc
371                 sethi $r1 0x20000
372                 mov $r2 0xd
373                 iowr I[$r1] $r2         // STRAND_CMD(0x3f) = 0x0d
374                 call #strand_wait
375
376         // mark completion in HUB's barrier
377         ctx_xfer_done:
378         call #hub_barrier_done
379         ret
380 #endif