336 lines · plain
1/* fuc microcode util functions for gf100 PGRAPH2 *3 * Copyright 2011 Red Hat Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR19 * 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 OR21 * OTHER DEALINGS IN THE SOFTWARE.22 *23 * Authors: Ben Skeggs24 */25 26#ifdef INCLUDE_CODE27// queue_put - add request to queue28//29// In : $r13 queue pointer30// $r14 command31// $r15 data32//33queue_put:34 // make sure we have space..35 ld b32 $r8 D[$r13 + 0x0] // GET36 ld b32 $r9 D[$r13 + 0x4] // PUT37 xor $r8 838 cmpu b32 $r8 $r939 bra ne #queue_put_next40 mov $r15 E_CMD_OVERFLOW41 call(error)42 ret43 44 // store cmd/data on queue45 queue_put_next:46 and $r8 $r9 747 shl b32 $r8 348 add b32 $r8 $r1349 add b32 $r8 850 st b32 D[$r8 + 0x0] $r1451 st b32 D[$r8 + 0x4] $r1552 53 // update PUT54 add b32 $r9 155 and $r9 0xf56 st b32 D[$r13 + 0x4] $r957 ret58 59// queue_get - fetch request from queue60//61// In : $r13 queue pointer62//63// Out: $p1 clear on success (data available)64// $r14 command65// $r15 data66//67queue_get:68 bset $flags $p169 ld b32 $r8 D[$r13 + 0x0] // GET70 ld b32 $r9 D[$r13 + 0x4] // PUT71 cmpu b32 $r8 $r972 bra e #queue_get_done73 // fetch first cmd/data pair74 and $r9 $r8 775 shl b32 $r9 376 add b32 $r9 $r1377 add b32 $r9 878 ld b32 $r14 D[$r9 + 0x0]79 ld b32 $r15 D[$r9 + 0x4]80 81 // update GET82 add b32 $r8 183 and $r8 0xf84 st b32 D[$r13 + 0x0] $r885 bclr $flags $p186queue_get_done:87 ret88 89// nv_rd32 - read 32-bit value from nv register90//91// In : $r14 register92// Out: $r15 value93//94nv_rd32:95 mov b32 $r12 $r1496 bset $r12 31 // MMIO_CTRL_PENDING97 nv_iowr(NV_PGRAPH_FECS_MMIO_CTRL, 0, $r12)98 nv_rd32_wait:99 nv_iord($r12, NV_PGRAPH_FECS_MMIO_CTRL, 0)100 xbit $r12 $r12 31101 bra ne #nv_rd32_wait102 mov $r10 6 // DONE_MMIO_RD103 call(wait_doneo)104 nv_iord($r15, NV_PGRAPH_FECS_MMIO_RDVAL, 0)105 ret106 107// nv_wr32 - write 32-bit value to nv register108//109// In : $r14 register110// $r15 value111//112nv_wr32:113 nv_iowr(NV_PGRAPH_FECS_MMIO_WRVAL, 0, $r15)114 mov b32 $r12 $r14115 bset $r12 31 // MMIO_CTRL_PENDING116 bset $r12 30 // MMIO_CTRL_WRITE117 nv_iowr(NV_PGRAPH_FECS_MMIO_CTRL, 0, $r12)118 nv_wr32_wait:119 nv_iord($r12, NV_PGRAPH_FECS_MMIO_CTRL, 0)120 xbit $r12 $r12 31121 bra ne #nv_wr32_wait122 ret123 124// wait_donez - wait on FUC_DONE bit to become clear125//126// In : $r10 bit to wait on127//128wait_donez:129 trace_set(T_WAIT);130 nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)131 wait_donez_ne:132 nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)133 xbit $r8 $r8 $r10134 bra ne #wait_donez_ne135 trace_clr(T_WAIT)136 ret137 138// wait_doneo - wait on FUC_DONE bit to become set139//140// In : $r10 bit to wait on141//142wait_doneo:143 trace_set(T_WAIT);144 nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)145 wait_doneo_e:146 nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)147 xbit $r8 $r8 $r10148 bra e #wait_doneo_e149 trace_clr(T_WAIT)150 ret151 152// mmctx_size - determine size of a mmio list transfer153//154// In : $r14 mmio list head155// $r15 mmio list tail156// Out: $r15 transfer size (in bytes)157//158mmctx_size:159 clear b32 $r9160 nv_mmctx_size_loop:161 ld b32 $r8 D[$r14]162 shr b32 $r8 26163 add b32 $r8 1164 shl b32 $r8 2165 add b32 $r9 $r8166 add b32 $r14 4167 cmpu b32 $r14 $r15168 bra ne #nv_mmctx_size_loop169 mov b32 $r15 $r9170 ret171 172// mmctx_xfer - execute a list of mmio transfers173//174// In : $r10 flags175// bit 0: direction (0 = save, 1 = load)176// bit 1: set if first transfer177// bit 2: set if last transfer178// $r11 base179// $r12 mmio list head180// $r13 mmio list tail181// $r14 multi_stride182// $r15 multi_mask183//184mmctx_xfer:185 trace_set(T_MMCTX)186 clear b32 $r9187 or $r11 $r11188 bra e #mmctx_base_disabled189 nv_iowr(NV_PGRAPH_FECS_MMCTX_BASE, 0, $r11)190 bset $r9 0 // BASE_EN191 mmctx_base_disabled:192 or $r14 $r14193 bra e #mmctx_multi_disabled194 nv_iowr(NV_PGRAPH_FECS_MMCTX_MULTI_STRIDE, 0, $r14)195 nv_iowr(NV_PGRAPH_FECS_MMCTX_MULTI_MASK, 0, $r15)196 bset $r9 1 // MULTI_EN197 mmctx_multi_disabled:198 199 xbit $r11 $r10 0200 shl b32 $r11 16 // DIR201 bset $r11 12 // QLIMIT = 0x10202 xbit $r14 $r10 1203 shl b32 $r14 17204 or $r11 $r14 // START_TRIGGER205 nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11)206 207 // loop over the mmio list, and send requests to the hw208 mmctx_exec_loop:209 // wait for space in mmctx queue210 mmctx_wait_free:211 nv_iord($r14, NV_PGRAPH_FECS_MMCTX_CTRL, 0)212 and $r14 0x1f213 bra e #mmctx_wait_free214 215 // queue up an entry216 ld b32 $r14 D[$r12]217 or $r14 $r9218 nv_iowr(NV_PGRAPH_FECS_MMCTX_QUEUE, 0, $r14)219 add b32 $r12 4220 cmpu b32 $r12 $r13221 bra ne #mmctx_exec_loop222 223 xbit $r11 $r10 2224 bra ne #mmctx_stop225 // wait for queue to empty226 mmctx_fini_wait:227 nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0)228 and $r11 0x1f229 cmpu b32 $r11 0x10230 bra ne #mmctx_fini_wait231 mov $r10 5 // DONE_MMCTX232 call(wait_donez)233 bra #mmctx_done234 mmctx_stop:235 xbit $r11 $r10 0236 shl b32 $r11 16 // DIR237 bset $r11 12 // QLIMIT = 0x10238 bset $r11 18 // STOP_TRIGGER239 nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11)240 mmctx_stop_wait:241 // wait for STOP_TRIGGER to clear242 nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0)243 xbit $r11 $r11 18244 bra ne #mmctx_stop_wait245 mmctx_done:246 trace_clr(T_MMCTX)247 ret248 249// Wait for DONE_STRAND250//251strand_wait:252 push $r10253 mov $r10 2254 call(wait_donez)255 pop $r10256 ret257 258// unknown - call before issuing strand commands259//260strand_pre:261 mov $r9 NV_PGRAPH_FECS_STRAND_CMD_ENABLE262 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9)263 call(strand_wait)264 ret265 266// unknown - call after issuing strand commands267//268strand_post:269 mov $r9 NV_PGRAPH_FECS_STRAND_CMD_DISABLE270 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9)271 call(strand_wait)272 ret273 274// Selects strand set?!275//276// In: $r14 id277//278strand_set:279 mov $r12 0xf280 nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r12)281 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_DEACTIVATE_FILTER282 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)283 nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r14)284 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_ACTIVATE_FILTER285 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)286 call(strand_wait)287 ret288 289// Initialise strand context data290//291// In : $r15 context base292// Out: $r15 context size (in bytes)293//294// Strandset(?) 3 hardcoded currently295//296strand_ctx_init:297 trace_set(T_STRINIT)298 call(strand_pre)299 mov $r14 3300 call(strand_set)301 302 clear b32 $r12303 nv_iowr(NV_PGRAPH_FECS_STRAND_SELECT, 0x3f, $r12)304 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_SEEK305 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)306 call(strand_wait)307 sub b32 $r12 $r0 1308 nv_iowr(NV_PGRAPH_FECS_STRAND_DATA, 0x3f, $r12)309 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_GET_INFO310 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)311 call(strand_wait)312 call(strand_post)313 314 // read the size of each strand, poke the context offset of315 // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry316 // about it later then.317 nv_mkio($r8, NV_PGRAPH_FECS_STRAND_SAVE_SWBASE, 0x00)318 nv_iord($r9, NV_PGRAPH_FECS_STRANDS_CNT, 0x00)319 shr b32 $r14 $r15 8320 ctx_init_strand_loop:321 iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE322 iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE323 iord $r10 I[$r8 + 0x200] // STRAND_SIZE324 shr b32 $r10 6325 add b32 $r10 1326 add b32 $r14 $r10327 add b32 $r8 4328 sub b32 $r9 1329 bra ne #ctx_init_strand_loop330 331 shl b32 $r14 8332 sub b32 $r15 $r14 $r15333 trace_clr(T_STRINIT)334 ret335#endif336