1 /* fuc microcode for copy engine on gt215- 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.
27 .section #gt215_ce_data
29 .section #gf100_ce_data
40 ctx_query_address_high: .b32 0
41 ctx_query_address_low: .b32 0
42 ctx_query_counter: .b32 0
43 ctx_src_address_high: .b32 0
44 ctx_src_address_low: .b32 0
46 ctx_src_tile_mode: .b32 0
54 ctx_dst_address_high: .b32 0
55 ctx_dst_address_low: .b32 0
57 ctx_dst_tile_mode: .b32 0
66 ctx_swz_const0: .b32 0
67 ctx_swz_const1: .b32 0
75 .b32 #ctx_object ~0xffffffff
78 .b32 0x00010000 + #cmd_nop ~0xffffffff
79 // mthd 0x0140, PM_TRIGGER
81 .b32 0x00010000 + #cmd_pm_trigger ~0xffffffff
83 // mthd 0x0180-0x018c, DMA_
84 .b16 0x060 #ctx_dma_count
86 .b32 0x00010000 + #cmd_dma ~0xffffffff
87 .b32 0x00010000 + #cmd_dma ~0xffffffff
88 .b32 0x00010000 + #cmd_dma ~0xffffffff
90 // mthd 0x0200-0x0218, SRC_TILE
92 .b32 #ctx_src_tile_mode ~0x00000fff
93 .b32 #ctx_src_xsize ~0x0007ffff
94 .b32 #ctx_src_ysize ~0x00001fff
95 .b32 #ctx_src_zsize ~0x000007ff
96 .b32 #ctx_src_zoff ~0x00000fff
97 .b32 #ctx_src_xoff ~0x0007ffff
98 .b32 #ctx_src_yoff ~0x00001fff
99 // mthd 0x0220-0x0238, DST_TILE
101 .b32 #ctx_dst_tile_mode ~0x00000fff
102 .b32 #ctx_dst_xsize ~0x0007ffff
103 .b32 #ctx_dst_ysize ~0x00001fff
104 .b32 #ctx_dst_zsize ~0x000007ff
105 .b32 #ctx_dst_zoff ~0x00000fff
106 .b32 #ctx_dst_xoff ~0x0007ffff
107 .b32 #ctx_dst_yoff ~0x00001fff
108 // mthd 0x0300-0x0304, EXEC, WRCACHE_FLUSH
110 .b32 0x00010000 + #cmd_exec ~0xffffffff
111 .b32 0x00010000 + #cmd_wrcache_flush ~0xffffffff
112 // mthd 0x030c-0x0340, various stuff
114 .b32 #ctx_src_address_high ~0x000000ff
115 .b32 #ctx_src_address_low ~0xffffffff
116 .b32 #ctx_dst_address_high ~0x000000ff
117 .b32 #ctx_dst_address_low ~0xffffffff
118 .b32 #ctx_src_pitch ~0x0007ffff
119 .b32 #ctx_dst_pitch ~0x0007ffff
120 .b32 #ctx_xcnt ~0x0000ffff
121 .b32 #ctx_ycnt ~0x00001fff
122 .b32 #ctx_format ~0x0333ffff
123 .b32 #ctx_swz_const0 ~0xffffffff
124 .b32 #ctx_swz_const1 ~0xffffffff
125 .b32 #ctx_query_address_high ~0x000000ff
126 .b32 #ctx_query_address_low ~0xffffffff
127 .b32 #ctx_query_counter ~0xffffffff
131 .section #gt215_ce_code
133 .section #gf100_ce_code
140 // setup i0 handler and route fifo and ctxswitch to it
146 iowr I[$r1 + 0x300] $r2
153 // enable fifo access and context switching
158 // sleep forever, waking for interrupts
166 iord $r1 I[$r0 + 0x200]
168 and $r2 $r1 0x00000008
172 and $r2 $r1 0x00000004
177 and $r1 $r1 0x0000000c
178 iowr I[$r0 + 0x100] $r1
181 // $p1 direction (0 = unload, 1 = load)
187 // target 7 hardcoded to ctx dma object
190 // read SCRATCH3 to decide if we are PCOPY0 or PCOPY1
197 // channel is in vram
203 // read 16-byte PCOPYn info, containing context pointer, from channel
208 // get a chunk of stack space, aligned to 256 byte boundary
218 // set context pointer, from within channel VM
221 ld b32 $r4 D[$r5 + 0]
223 ld b32 $r6 D[$r5 + 4]
228 // 256-byte context, at start of data segment
243 // read current channel
247 // if it's active, unload it and return
249 bra e #chsw_no_unload
255 iowr I[$r2 + 0x200] $r4
260 iord $r3 I[$r2 + 0x100]
262 // is there a channel waiting to be loaded?
264 bra e #chsw_finish_load
268 // load dma objects back into TARGET regs
270 mov $r6 #ctx_dma_count
272 ld b32 $r7 D[$r5 + $r6 * 4]
273 add b32 $r8 $r6 0x180
277 bra nc #chsw_load_ctx_dma
281 iowr I[$r2 + 0x200] $r3
285 // read incoming fifo command
287 iord $r2 I[$r3 + 0x100]
288 iord $r3 I[$r3 + 0x000]
290 // $r2 will be used to store exception data
293 // lookup method in the dispatch table, ILLEGAL_MTHD if not found
294 mov $r5 #dispatch_table
298 ld b16 $r6 D[$r5 + 0]
299 ld b16 $r7 D[$r5 + 2]
302 bra c #dispatch_illegal_mthd
305 bra c #dispatch_valid_mthd
311 // ensure no bits set in reserved fields, INVALID_BITFIELD
316 ld b32 $r5 D[$r4 + 4]
319 bra ne #dispatch_invalid_bitfield
321 // depending on dispatch flags: execute method, or save data as state
322 ld b16 $r5 D[$r4 + 0]
323 ld b16 $r6 D[$r4 + 2]
331 bra $p1 #dispatch_error
334 dispatch_invalid_bitfield:
336 dispatch_illegal_mthd:
339 // store exception data in SCRATCH0/SCRATCH1, signal hostirq
342 iowr I[$r4 + 0x000] $r2
343 iowr I[$r4 + 0x100] $r3
347 iord $r2 I[$r0 + 0x200]
362 // $r2: hostirq state
364 // $r4: dispatch table entry
368 // $r2: hostirq state
377 // $r2: hostirq state
379 // $r4: dispatch table entry
383 // $r2: hostirq state
393 // SET_DMA_* method handler
397 // $r2: hostirq state
399 // $r4: dispatch table entry
403 // $r2: hostirq state
406 sub b32 $r4 #dispatch_dma
409 st b32 D[$r4 + #ctx_dma] $r3
416 // Calculates the hw swizzle mask and adjusts the surface's xcnt to match
419 // zero out a chunk of the stack to store the swizzle into
421 st b32 D[$sp + 0x00] $r0
422 st b32 D[$sp + 0x04] $r0
423 st b32 D[$sp + 0x08] $r0
424 st b32 D[$sp + 0x0c] $r0
426 // extract cpp, src_ncomp and dst_ncomp from FORMAT
427 ld b32 $r4 D[$r0 + #ctx_format]
435 // convert FORMAT swizzle mask to hw swizzle mask
464 st b8 D[$sp + $r8] $r12
473 // SRC_XCNT = (xcnt * src_cpp), or 0 if no src ref in swz (hw will hang)
475 st b32 D[$r0 + #ctx_src_cpp] $r6
476 ld b32 $r8 D[$r0 + #ctx_xcnt]
483 st b32 D[$r0 + #ctx_dst_cpp] $r7
488 iowr I[$r5 + 0x000] $r6
489 iowr I[$r5 + 0x100] $r7
491 ld b32 $r6 D[$r0 + #ctx_dst_cpp]
494 ld b32 $r7 D[$r0 + #ctx_src_cpp]
497 iowr I[$r5 + 0x000] $r6
499 ld b32 $r6 D[$sp + 0x00]
500 iowr I[$r5 + 0x000] $r6
501 ld b32 $r6 D[$sp + 0x04]
502 iowr I[$r5 + 0x100] $r6
503 ld b32 $r6 D[$sp + 0x08]
504 iowr I[$r5 + 0x200] $r6
505 ld b32 $r6 D[$sp + 0x0c]
506 iowr I[$r5 + 0x300] $r6
508 ld b32 $r6 D[$r0 + #ctx_swz_const0]
509 iowr I[$r5 + 0x000] $r6
510 ld b32 $r6 D[$r0 + #ctx_swz_const1]
511 iowr I[$r5 + 0x100] $r6
515 // Setup to handle a tiled surface
517 // Calculates a number of parameters the hardware requires in order
518 // to correctly handle tiling.
520 // Offset calculation is performed as follows (Tp/Th/Td from TILE_MODE):
521 // nTx = round_up(w * cpp, 1 << Tp) >> Tp
522 // nTy = round_up(h, 1 << Th) >> Th
523 // Txo = (x * cpp) & ((1 << Tp) - 1)
524 // Tx = (x * cpp) >> Tp
525 // Tyo = y & ((1 << Th) - 1)
527 // Tzo = z & ((1 << Td) - 1)
530 // off = (Tzo << Tp << Th) + (Tyo << Tp) + Txo
531 // off += ((Tz * nTy * nTx)) + (Ty * nTx) + Tx) << Td << Th << Tp;
534 // $r4: hw command (0x104800)
535 // $r5: ctx offset adjustment for src/dst selection
536 // $p2: set if dst surface
538 cmd_exec_set_surface_tiled:
539 // translate TILE_MODE into Tp, Th, Td shift values
540 ld b32 $r7 D[$r5 + #ctx_src_tile_mode]
560 // Op = (x * cpp) & ((1 << Tp) - 1)
561 // Tx = (x * cpp) >> Tp
562 ld b32 $r10 D[$r5 + #ctx_src_xoff]
563 ld b32 $r11 D[$r5 + #ctx_src_cpp]
571 // Tyo = y & ((1 << Th) - 1)
573 ld b32 $r13 D[$r5 + #ctx_src_yoff]
580 // YTILE = ((1 << Th) << 12) | ((1 << Th) - Tyo)
588 iowr I[$r6 + 0x000] $r15
594 // nTx = ((w * cpp) + ((1 << Tp) - 1) >> Tp)
595 ld b32 $r15 D[$r5 + #ctx_src_xsize]
596 ld b32 $r11 D[$r5 + #ctx_src_cpp]
605 // nTy = (h + ((1 << Th) - 1)) >> Th
606 ld b32 $r15 D[$r5 + #ctx_src_ysize]
615 // CFG_YZ_TILE_SIZE = ((1 << Th) >> 2) << Td
622 // Tzo = z & ((1 << Td) - 1)
626 ld b32 $r8 D[$r5 + #ctx_src_zoff]
636 // Ot = ((Tz * nTy * nTx) + (Ty * nTx) + Tx) << Ts
646 // PITCH = (nTx - 1) << Ts
649 iowr I[$r6 + 0x200] $r9
651 // SRC_ADDRESS_LOW = (Ot + Op) & 0xffffffff
652 // CFG_ADDRESS_HIGH |= ((Ot + Op) >> 32) << 16
653 ld b32 $r7 D[$r5 + #ctx_src_address_low]
654 ld b32 $r8 D[$r5 + #ctx_src_address_high]
661 iowr I[$r6 + 0x000] $r7
663 iowr I[$r6 + 0x000] $r8
666 // Setup to handle a linear surface
668 // Nothing to see here.. Sets ADDRESS and PITCH, pretty non-exciting
670 cmd_exec_set_surface_linear:
674 ld b32 $r7 D[$r5 + #ctx_src_address_low]
675 iowr I[$r6 + 0x000] $r7
677 ld b32 $r7 D[$r5 + #ctx_src_address_high]
679 iowr I[$r6 + 0x000] $r7
681 ld b32 $r7 D[$r5 + #ctx_src_pitch]
682 iowr I[$r6 + 0x000] $r7
685 // wait for regs to be available for use
700 // if QUERY_SHORT not set, write out { -, 0, TIME_LO, TIME_HI }
702 bra ne #query_counter
706 ld b32 $r5 D[$r0 + #ctx_query_address_low]
708 iowr I[$r4 + 0x000] $r5
709 iowr I[$r4 + 0x100] $r0
711 iowr I[$r4 + 0x200] $r5
713 ld b32 $r5 D[$r0 + #ctx_query_address_high]
715 iowr I[$r4 + 0x000] $r5
719 iowr I[$r4 + 0x000] $r5
723 iowr I[$r4 + 0x100] $r5
726 iowr I[$r4 + 0x200] $r5
729 iowr I[$r4 + 0x300] $r5
734 iowr I[$r4 + 0x000] $r5
741 ld b32 $r5 D[$r0 + #ctx_query_address_low]
742 iowr I[$r4 + 0x000] $r5
743 iowr I[$r4 + 0x100] $r0
745 iowr I[$r4 + 0x200] $r5
747 ld b32 $r5 D[$r0 + #ctx_query_address_high]
749 iowr I[$r4 + 0x000] $r5
752 iowr I[$r4 + 0x000] $r5
755 iowr I[$r4 + 0x100] $r5
756 ld b32 $r5 D[$r0 + #ctx_query_counter]
758 iowr I[$r4 + 0x000] $r5
763 iowr I[$r4 + 0x000] $r5
766 // Execute a copy operation
770 // $r2: hostirq state
772 // 000002000 QUERY_SHORT
774 // 000000100 DST_LINEAR
775 // 000000010 SRC_LINEAR
777 // $r4: dispatch table entry
781 // $r2: hostirq state
786 // if format requested, call function to calculate it, otherwise
787 // fill in cpp/xcnt for both surfaces as if (cpp == 1)
789 bra e #cmd_exec_no_format
790 call #cmd_exec_set_format
792 bra #cmd_exec_init_src_surface
797 st b32 D[$r0 + #ctx_src_cpp] $r7
798 st b32 D[$r0 + #ctx_dst_cpp] $r7
799 ld b32 $r7 D[$r0 + #ctx_xcnt]
800 iowr I[$r6 + 0x000] $r7
801 iowr I[$r6 + 0x100] $r7
804 cmd_exec_init_src_surface:
809 call #cmd_exec_set_surface_linear
810 bra #cmd_exec_init_dst_surface
812 call #cmd_exec_set_surface_tiled
815 cmd_exec_init_dst_surface:
817 mov $r5 #ctx_dst_address_high - #ctx_src_address_high
820 call #cmd_exec_set_surface_linear
823 call #cmd_exec_set_surface_tiled
829 ld b32 $r6 D[$r0 + #ctx_ycnt]
830 iowr I[$r5 + 0x100] $r6
832 // SRC_TARGET = 1, DST_TARGET = 2
837 // if requested, queue up a QUERY write after the copy has completed
849 // $r2: hostirq state
851 // $r4: dispatch table entry
855 // $r2: hostirq state