1 /* fuc microcode for copy engine on nva3- chipsets
3 * Copyright 2011 Red Hat Inc.
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
26 /* To build for nva3:nvc0
27 * m4 -DNVA3 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nva3_copy.fuc.h
30 * m4 -DNVC0 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_copy.fuc.h
34 .section nva3_pcopy_data,
35 .section nvc0_pcopy_data
46 ctx_query_address_high: .b32 0
47 ctx_query_address_low: .b32 0
48 ctx_query_counter: .b32 0
49 ctx_src_address_high: .b32 0
50 ctx_src_address_low: .b32 0
52 ctx_src_tile_mode: .b32 0
60 ctx_dst_address_high: .b32 0
61 ctx_dst_address_low: .b32 0
63 ctx_dst_tile_mode: .b32 0
72 ctx_swz_const0: .b32 0
73 ctx_swz_const1: .b32 0
81 .b32 ctx_object ~0xffffffff
84 .b32 0x00010000 + cmd_nop ~0xffffffff
85 // mthd 0x0140, PM_TRIGGER
87 .b32 0x00010000 + cmd_pm_trigger ~0xffffffff
89 // mthd 0x0180-0x018c, DMA_
90 .b16 0x060 ctx_dma_count
92 .b32 0x00010000 + cmd_dma ~0xffffffff
93 .b32 0x00010000 + cmd_dma ~0xffffffff
94 .b32 0x00010000 + cmd_dma ~0xffffffff
96 // mthd 0x0200-0x0218, SRC_TILE
98 .b32 ctx_src_tile_mode ~0x00000fff
99 .b32 ctx_src_xsize ~0x0007ffff
100 .b32 ctx_src_ysize ~0x00001fff
101 .b32 ctx_src_zsize ~0x000007ff
102 .b32 ctx_src_zoff ~0x00000fff
103 .b32 ctx_src_xoff ~0x0007ffff
104 .b32 ctx_src_yoff ~0x00001fff
105 // mthd 0x0220-0x0238, DST_TILE
107 .b32 ctx_dst_tile_mode ~0x00000fff
108 .b32 ctx_dst_xsize ~0x0007ffff
109 .b32 ctx_dst_ysize ~0x00001fff
110 .b32 ctx_dst_zsize ~0x000007ff
111 .b32 ctx_dst_zoff ~0x00000fff
112 .b32 ctx_dst_xoff ~0x0007ffff
113 .b32 ctx_dst_yoff ~0x00001fff
114 // mthd 0x0300-0x0304, EXEC, WRCACHE_FLUSH
116 .b32 0x00010000 + cmd_exec ~0xffffffff
117 .b32 0x00010000 + cmd_wrcache_flush ~0xffffffff
118 // mthd 0x030c-0x0340, various stuff
120 .b32 ctx_src_address_high ~0x000000ff
121 .b32 ctx_src_address_low ~0xfffffff0
122 .b32 ctx_dst_address_high ~0x000000ff
123 .b32 ctx_dst_address_low ~0xfffffff0
124 .b32 ctx_src_pitch ~0x0007ffff
125 .b32 ctx_dst_pitch ~0x0007ffff
126 .b32 ctx_xcnt ~0x0000ffff
127 .b32 ctx_ycnt ~0x00001fff
128 .b32 ctx_format ~0x0333ffff
129 .b32 ctx_swz_const0 ~0xffffffff
130 .b32 ctx_swz_const1 ~0xffffffff
131 .b32 ctx_query_address_high ~0x000000ff
132 .b32 ctx_query_address_low ~0xffffffff
133 .b32 ctx_query_counter ~0xffffffff
137 .section nva3_pcopy_code,
138 .section nvc0_pcopy_code
145 // setup i0 handler and route fifo and ctxswitch to it
151 iowr I[$r2 + 0x300] $r2
158 // enable fifo access and context switching
163 // sleep forever, waking for interrupts
171 iord $r1 I[$r0 + 0x200]
173 and $r2 $r1 0x00000008
177 and $r2 $r1 0x00000004
182 and $r1 $r1 0x0000000c
183 iowr I[$r0 + 0x100] $r1
186 // $p1 direction (0 = unload, 1 = load)
192 // target 7 hardcoded to ctx dma object
195 // read SCRATCH3 to decide if we are PCOPY0 or PCOPY1
202 // channel is in vram
208 // read 16-byte PCOPYn info, containing context pointer, from channel
213 // get a chunk of stack space, aligned to 256 byte boundary
223 // set context pointer, from within channel VM
226 ld b32 $r4 D[$r5 + 0]
228 ld b32 $r6 D[$r5 + 4]
233 // 256-byte context, at start of data segment
248 // read current channel
252 // if it's active, unload it and return
260 iowr I[$r2 + 0x200] $r4
265 iord $r3 I[$r2 + 0x100]
267 // is there a channel waiting to be loaded?
269 bra e chsw_finish_load
273 // load dma objects back into TARGET regs
275 mov $r6 ctx_dma_count
277 ld b32 $r7 D[$r5 + $r6 * 4]
278 add b32 $r8 $r6 0x180
282 bra nc chsw_load_ctx_dma
287 iowr I[$r2 + 0x200] $r3
291 // read incoming fifo command
293 iord $r2 I[$r3 + 0x100]
294 iord $r3 I[$r3 + 0x000]
296 // $r2 will be used to store exception data
299 // lookup method in the dispatch table, ILLEGAL_MTHD if not found
300 mov $r5 dispatch_table
304 ld b16 $r6 D[$r5 + 0]
305 ld b16 $r7 D[$r5 + 2]
308 bra c dispatch_illegal_mthd
311 bra c dispatch_valid_mthd
317 // ensure no bits set in reserved fields, INVALID_BITFIELD
322 ld b32 $r5 D[$r4 + 4]
325 bra ne dispatch_invalid_bitfield
327 // depending on dispatch flags: execute method, or save data as state
328 ld b16 $r5 D[$r4 + 0]
329 ld b16 $r6 D[$r4 + 2]
337 bra $p1 dispatch_error
340 dispatch_invalid_bitfield:
342 dispatch_illegal_mthd:
345 // store exception data in SCRATCH0/SCRATCH1, signal hostirq
348 iowr I[$r4 + 0x000] $r2
349 iowr I[$r4 + 0x100] $r3
353 iord $r2 I[$r0 + 0x200]
368 // $r2: hostirq state
370 // $r4: dispatch table entry
374 // $r2: hostirq state
383 // $r2: hostirq state
385 // $r4: dispatch table entry
389 // $r2: hostirq state
399 // SET_DMA_* method handler
403 // $r2: hostirq state
405 // $r4: dispatch table entry
409 // $r2: hostirq state
412 sub b32 $r4 dispatch_dma
415 st b32 D[$r4 + ctx_dma] $r3
422 // Calculates the hw swizzle mask and adjusts the surface's xcnt to match
425 // zero out a chunk of the stack to store the swizzle into
427 st b32 D[$sp + 0x00] $r0
428 st b32 D[$sp + 0x04] $r0
429 st b32 D[$sp + 0x08] $r0
430 st b32 D[$sp + 0x0c] $r0
432 // extract cpp, src_ncomp and dst_ncomp from FORMAT
433 ld b32 $r4 D[$r0 + ctx_format]
441 // convert FORMAT swizzle mask to hw swizzle mask
470 st b8 D[$sp + $r8] $r12
479 // SRC_XCNT = (xcnt * src_cpp), or 0 if no src ref in swz (hw will hang)
481 st b32 D[$r0 + ctx_src_cpp] $r6
482 ld b32 $r8 D[$r0 + ctx_xcnt]
489 st b32 D[$r0 + ctx_dst_cpp] $r7
494 iowr I[$r5 + 0x000] $r6
495 iowr I[$r5 + 0x100] $r7
497 ld b32 $r6 D[$r0 + ctx_dst_cpp]
500 ld b32 $r7 D[$r0 + ctx_src_cpp]
503 iowr I[$r5 + 0x000] $r6
505 ld b32 $r6 D[$sp + 0x00]
506 iowr I[$r5 + 0x000] $r6
507 ld b32 $r6 D[$sp + 0x04]
508 iowr I[$r5 + 0x100] $r6
509 ld b32 $r6 D[$sp + 0x08]
510 iowr I[$r5 + 0x200] $r6
511 ld b32 $r6 D[$sp + 0x0c]
512 iowr I[$r5 + 0x300] $r6
514 ld b32 $r6 D[$r0 + ctx_swz_const0]
515 iowr I[$r5 + 0x000] $r6
516 ld b32 $r6 D[$r0 + ctx_swz_const1]
517 iowr I[$r5 + 0x100] $r6
521 // Setup to handle a tiled surface
523 // Calculates a number of parameters the hardware requires in order
524 // to correctly handle tiling.
526 // Offset calculation is performed as follows (Tp/Th/Td from TILE_MODE):
527 // nTx = round_up(w * cpp, 1 << Tp) >> Tp
528 // nTy = round_up(h, 1 << Th) >> Th
529 // Txo = (x * cpp) & ((1 << Tp) - 1)
530 // Tx = (x * cpp) >> Tp
531 // Tyo = y & ((1 << Th) - 1)
533 // Tzo = z & ((1 << Td) - 1)
536 // off = (Tzo << Tp << Th) + (Tyo << Tp) + Txo
537 // off += ((Tz * nTy * nTx)) + (Ty * nTx) + Tx) << Td << Th << Tp;
540 // $r4: hw command (0x104800)
541 // $r5: ctx offset adjustment for src/dst selection
542 // $p2: set if dst surface
544 cmd_exec_set_surface_tiled:
545 // translate TILE_MODE into Tp, Th, Td shift values
546 ld b32 $r7 D[$r5 + ctx_src_tile_mode]
566 // Op = (x * cpp) & ((1 << Tp) - 1)
567 // Tx = (x * cpp) >> Tp
568 ld b32 $r10 D[$r5 + ctx_src_xoff]
569 ld b32 $r11 D[$r5 + ctx_src_cpp]
577 // Tyo = y & ((1 << Th) - 1)
579 ld b32 $r13 D[$r5 + ctx_src_yoff]
586 // YTILE = ((1 << Th) << 12) | ((1 << Th) - Tyo)
594 iowr I[$r6 + 0x000] $r15
600 // nTx = ((w * cpp) + ((1 << Tp) - 1) >> Tp)
601 ld b32 $r15 D[$r5 + ctx_src_xsize]
602 ld b32 $r11 D[$r5 + ctx_src_cpp]
611 // nTy = (h + ((1 << Th) - 1)) >> Th
612 ld b32 $r15 D[$r5 + ctx_src_ysize]
621 // CFG_YZ_TILE_SIZE = ((1 << Th) >> 2) << Td
628 // Tzo = z & ((1 << Td) - 1)
632 ld b32 $r8 D[$r5 + ctx_src_zoff]
642 // Ot = ((Tz * nTy * nTx) + (Ty * nTx) + Tx) << Ts
652 // PITCH = (nTx - 1) << Ts
655 iowr I[$r6 + 0x200] $r9
657 // SRC_ADDRESS_LOW = (Ot + Op) & 0xffffffff
658 // CFG_ADDRESS_HIGH |= ((Ot + Op) >> 32) << 16
659 ld b32 $r7 D[$r5 + ctx_src_address_low]
660 ld b32 $r8 D[$r5 + ctx_src_address_high]
667 iowr I[$r6 + 0x000] $r7
669 iowr I[$r6 + 0x000] $r8
672 // Setup to handle a linear surface
674 // Nothing to see here.. Sets ADDRESS and PITCH, pretty non-exciting
676 cmd_exec_set_surface_linear:
680 ld b32 $r7 D[$r5 + ctx_src_address_low]
681 iowr I[$r6 + 0x000] $r7
683 ld b32 $r7 D[$r5 + ctx_src_address_high]
685 iowr I[$r6 + 0x000] $r7
687 ld b32 $r7 D[$r5 + ctx_src_pitch]
688 iowr I[$r6 + 0x000] $r7
691 // wait for regs to be available for use
706 // if QUERY_SHORT not set, write out { -, 0, TIME_LO, TIME_HI }
712 ld b32 $r5 D[$r0 + ctx_query_address_low]
714 iowr I[$r4 + 0x000] $r5
715 iowr I[$r4 + 0x100] $r0
717 iowr I[$r4 + 0x200] $r5
719 ld b32 $r5 D[$r0 + ctx_query_address_high]
721 iowr I[$r4 + 0x000] $r5
725 iowr I[$r4 + 0x000] $r5
729 iowr I[$r4 + 0x100] $r5
732 iowr I[$r4 + 0x200] $r5
735 iowr I[$r4 + 0x300] $r5
740 iowr I[$r4 + 0x000] $r5
747 ld b32 $r5 D[$r0 + ctx_query_address_low]
748 iowr I[$r4 + 0x000] $r5
749 iowr I[$r4 + 0x100] $r0
751 iowr I[$r4 + 0x200] $r5
753 ld b32 $r5 D[$r0 + ctx_query_address_high]
755 iowr I[$r4 + 0x000] $r5
758 iowr I[$r4 + 0x000] $r5
761 iowr I[$r4 + 0x100] $r5
762 ld b32 $r5 D[$r0 + ctx_query_counter]
764 iowr I[$r4 + 0x000] $r5
769 iowr I[$r4 + 0x000] $r5
772 // Execute a copy operation
776 // $r2: hostirq state
778 // 000002000 QUERY_SHORT
780 // 000000100 DST_LINEAR
781 // 000000010 SRC_LINEAR
783 // $r4: dispatch table entry
787 // $r2: hostirq state
792 // if format requested, call function to calculate it, otherwise
793 // fill in cpp/xcnt for both surfaces as if (cpp == 1)
795 bra e cmd_exec_no_format
796 call cmd_exec_set_format
798 bra cmd_exec_init_src_surface
803 st b32 D[$r0 + ctx_src_cpp] $r7
804 st b32 D[$r0 + ctx_dst_cpp] $r7
805 ld b32 $r7 D[$r0 + ctx_xcnt]
806 iowr I[$r6 + 0x000] $r7
807 iowr I[$r6 + 0x100] $r7
810 cmd_exec_init_src_surface:
815 call cmd_exec_set_surface_linear
816 bra cmd_exec_init_dst_surface
818 call cmd_exec_set_surface_tiled
821 cmd_exec_init_dst_surface:
823 mov $r5 ctx_dst_address_high - ctx_src_address_high
826 call cmd_exec_set_surface_linear
829 call cmd_exec_set_surface_tiled
835 ld b32 $r6 D[$r0 + ctx_ycnt]
836 iowr I[$r5 + 0x100] $r6
838 // SRC_TARGET = 1, DST_TARGET = 2
843 // if requested, queue up a QUERY write after the copy has completed
855 // $r2: hostirq state
857 // $r4: dispatch table entry
861 // $r2: hostirq state