1 /* fuc microcode util functions for nvc0 PGRAPH
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 define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)')
27 define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
29 ifdef(`include_code', `
31 define(`E_BAD_COMMAND', 0x01)
32 define(`E_CMD_OVERFLOW', 0x02)
34 // Util macros to help with debugging ucode hangs etc
37 define(`T_STRWAIT', 2)
38 define(`T_STRINIT', 3)
51 iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
59 iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
62 // queue_put - add request to queue
64 // In : $r13 queue pointer
69 // make sure we have space..
70 ld b32 $r8 D[$r13 + 0x0] // GET
71 ld b32 $r9 D[$r13 + 0x4] // PUT
74 bra ne #queue_put_next
75 mov $r15 E_CMD_OVERFLOW
79 // store cmd/data on queue
85 st b32 D[$r8 + 0x0] $r14
86 st b32 D[$r8 + 0x4] $r15
91 st b32 D[$r13 + 0x4] $r9
94 // queue_get - fetch request from queue
96 // In : $r13 queue pointer
98 // Out: $p1 clear on success (data available)
104 ld b32 $r8 D[$r13 + 0x0] // GET
105 ld b32 $r9 D[$r13 + 0x4] // PUT
107 bra e #queue_get_done
108 // fetch first cmd/data pair
113 ld b32 $r14 D[$r9 + 0x0]
114 ld b32 $r15 D[$r9 + 0x4]
119 st b32 D[$r13 + 0x0] $r8
124 // nv_rd32 - read 32-bit value from nv register
126 // In : $r14 register
133 bset $r12 31 // MMIO_CTRL_PENDING
134 iowr I[$r11 + 0x000] $r12 // MMIO_CTRL
136 iord $r12 I[$r11 + 0x000]
139 mov $r10 6 // DONE_MMIO_RD
141 iord $r15 I[$r11 + 0x100] // MMIO_RDVAL
144 // nv_wr32 - write 32-bit value to nv register
146 // In : $r14 register
152 iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL
154 bset $r12 31 // MMIO_CTRL_PENDING
155 bset $r12 30 // MMIO_CTRL_WRITE
156 iowr I[$r11 + 0x000] $r12 // MMIO_CTRL
158 iord $r12 I[$r11 + 0x000]
163 // (re)set watchdog timer
171 iowr I[$r8 + 0x000] $r15
174 // clear watchdog timer
178 iowr I[$r8 + 0x000] $r0
181 // wait_done{z,o} - wait on FUC_DONE bit to become clear/set
183 // In : $r10 bit to wait on
185 define(`wait_done', `
190 iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit
194 iord $r8 I[$r8 + 0x000] // DONE
200 wait_done(wait_donez, ne)
201 wait_done(wait_doneo, e)
203 // mmctx_size - determine size of a mmio list transfer
205 // In : $r14 mmio list head
206 // $r15 mmio list tail
207 // Out: $r15 transfer size (in bytes)
219 bra ne #nv_mmctx_size_loop
223 // mmctx_xfer - execute a list of mmio transfers
226 // bit 0: direction (0 = save, 1 = load)
227 // bit 1: set if first transfer
228 // bit 2: set if last transfer
230 // $r12 mmio list head
231 // $r13 mmio list tail
241 bra e #mmctx_base_disabled
242 iowr I[$r8 + 0x000] $r11 // MMCTX_BASE
243 bset $r9 0 // BASE_EN
246 bra e #mmctx_multi_disabled
247 iowr I[$r8 + 0x200] $r14 // MMCTX_MULTI_STRIDE
248 iowr I[$r8 + 0x300] $r15 // MMCTX_MULTI_MASK
249 bset $r9 1 // MULTI_EN
250 mmctx_multi_disabled:
254 shl b32 $r11 16 // DIR
255 bset $r11 12 // QLIMIT = 0x10
258 or $r11 $r14 // START_TRIGGER
259 iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL
261 // loop over the mmio list, and send requests to the hw
263 // wait for space in mmctx queue
265 iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
267 bra e #mmctx_wait_free
272 iowr I[$r8 + 0x300] $r14
275 bra ne #mmctx_exec_loop
279 // wait for queue to empty
281 iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
284 bra ne #mmctx_fini_wait
285 mov $r10 2 // DONE_MMCTX
290 shl b32 $r11 16 // DIR
291 bset $r11 12 // QLIMIT = 0x10
292 bset $r11 18 // STOP_TRIGGER
293 iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL
295 // wait for STOP_TRIGGER to clear
296 iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
298 bra ne #mmctx_stop_wait
303 // Wait for DONE_STRAND
312 // unknown - call before issuing strand commands
322 // unknown - call after issuing strand commands
332 // Selects strand set?!
339 sub b32 $r11 $r10 0x500
341 iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf
343 iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb
345 iowr I[$r10 + 0x000] $r14 // 0x93c = <id>
347 iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa
351 // Initialise strand context data
353 // In : $r15 context base
354 // Out: $r15 context size (in bytes)
356 // Strandset(?) 3 hardcoded currently
365 add b32 $r11 $r10 0x400
366 iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0
368 iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE
371 iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff
373 iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT
377 // read the size of each strand, poke the context offset of
378 // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
379 // about it later then.
382 iord $r9 I[$r8 + 0x000] // STRANDS
385 ctx_init_strand_loop:
386 iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE
387 iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE
388 iord $r10 I[$r8 + 0x200] // STRAND_SIZE
394 bra ne #ctx_init_strand_loop
397 sub b32 $r15 $r14 $r15