1/* fuc microcode util functions for gf100 PGRAPH 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#ifdef INCLUDE_CODE 27// queue_put - add request to queue 28// 29// In : $r13 queue pointer 30// $r14 command 31// $r15 data 32// 33queue_put: 34 // make sure we have space.. 35 ld b32 $r8 D[$r13 + 0x0] // GET 36 ld b32 $r9 D[$r13 + 0x4] // PUT 37 xor $r8 8 38 cmpu b32 $r8 $r9 39 bra ne #queue_put_next 40 mov $r15 E_CMD_OVERFLOW 41 call(error) 42 ret 43 44 // store cmd/data on queue 45 queue_put_next: 46 and $r8 $r9 7 47 shl b32 $r8 3 48 add b32 $r8 $r13 49 add b32 $r8 8 50 st b32 D[$r8 + 0x0] $r14 51 st b32 D[$r8 + 0x4] $r15 52 53 // update PUT 54 add b32 $r9 1 55 and $r9 0xf 56 st b32 D[$r13 + 0x4] $r9 57 ret 58 59// queue_get - fetch request from queue 60// 61// In : $r13 queue pointer 62// 63// Out: $p1 clear on success (data available) 64// $r14 command 65// $r15 data 66// 67queue_get: 68 bset $flags $p1 69 ld b32 $r8 D[$r13 + 0x0] // GET 70 ld b32 $r9 D[$r13 + 0x4] // PUT 71 cmpu b32 $r8 $r9 72 bra e #queue_get_done 73 // fetch first cmd/data pair 74 and $r9 $r8 7 75 shl b32 $r9 3 76 add b32 $r9 $r13 77 add b32 $r9 8 78 ld b32 $r14 D[$r9 + 0x0] 79 ld b32 $r15 D[$r9 + 0x4] 80 81 // update GET 82 add b32 $r8 1 83 and $r8 0xf 84 st b32 D[$r13 + 0x0] $r8 85 bclr $flags $p1 86queue_get_done: 87 ret 88 89// nv_rd32 - read 32-bit value from nv register 90// 91// In : $r14 register 92// Out: $r15 value 93// 94nv_rd32: 95 mov b32 $r12 $r14 96 bset $r12 31 // MMIO_CTRL_PENDING 97 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 31 101 bra ne #nv_rd32_wait 102 mov $r10 6 // DONE_MMIO_RD 103 call(wait_doneo) 104 nv_iord($r15, NV_PGRAPH_FECS_MMIO_RDVAL, 0) 105 ret 106 107// nv_wr32 - write 32-bit value to nv register 108// 109// In : $r14 register 110// $r15 value 111// 112nv_wr32: 113 nv_iowr(NV_PGRAPH_FECS_MMIO_WRVAL, 0, $r15) 114 mov b32 $r12 $r14 115 bset $r12 31 // MMIO_CTRL_PENDING 116 bset $r12 30 // MMIO_CTRL_WRITE 117 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 31 121 bra ne #nv_wr32_wait 122 ret 123 124// wait_donez - wait on FUC_DONE bit to become clear 125// 126// In : $r10 bit to wait on 127// 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 $r10 134 bra ne #wait_donez_ne 135 trace_clr(T_WAIT) 136 ret 137 138// wait_doneo - wait on FUC_DONE bit to become set 139// 140// In : $r10 bit to wait on 141// 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 $r10 148 bra e #wait_doneo_e 149 trace_clr(T_WAIT) 150 ret 151 152// mmctx_size - determine size of a mmio list transfer 153// 154// In : $r14 mmio list head 155// $r15 mmio list tail 156// Out: $r15 transfer size (in bytes) 157// 158mmctx_size: 159 clear b32 $r9 160 nv_mmctx_size_loop: 161 ld b32 $r8 D[$r14] 162 shr b32 $r8 26 163 add b32 $r8 1 164 shl b32 $r8 2 165 add b32 $r9 $r8 166 add b32 $r14 4 167 cmpu b32 $r14 $r15 168 bra ne #nv_mmctx_size_loop 169 mov b32 $r15 $r9 170 ret 171 172// mmctx_xfer - execute a list of mmio transfers 173// 174// In : $r10 flags 175// bit 0: direction (0 = save, 1 = load) 176// bit 1: set if first transfer 177// bit 2: set if last transfer 178// $r11 base 179// $r12 mmio list head 180// $r13 mmio list tail 181// $r14 multi_stride 182// $r15 multi_mask 183// 184mmctx_xfer: 185 trace_set(T_MMCTX) 186 clear b32 $r9 187 or $r11 $r11 188 bra e #mmctx_base_disabled 189 nv_iowr(NV_PGRAPH_FECS_MMCTX_BASE, 0, $r11) 190 bset $r9 0 // BASE_EN 191 mmctx_base_disabled: 192 or $r14 $r14 193 bra e #mmctx_multi_disabled 194 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_EN 197 mmctx_multi_disabled: 198 199 xbit $r11 $r10 0 200 shl b32 $r11 16 // DIR 201 bset $r11 12 // QLIMIT = 0x10 202 xbit $r14 $r10 1 203 shl b32 $r14 17 204 or $r11 $r14 // START_TRIGGER 205 nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11) 206 207 // loop over the mmio list, and send requests to the hw 208 mmctx_exec_loop: 209 // wait for space in mmctx queue 210 mmctx_wait_free: 211 nv_iord($r14, NV_PGRAPH_FECS_MMCTX_CTRL, 0) 212 and $r14 0x1f 213 bra e #mmctx_wait_free 214 215 // queue up an entry 216 ld b32 $r14 D[$r12] 217 or $r14 $r9 218 nv_iowr(NV_PGRAPH_FECS_MMCTX_QUEUE, 0, $r14) 219 add b32 $r12 4 220 cmpu b32 $r12 $r13 221 bra ne #mmctx_exec_loop 222 223 xbit $r11 $r10 2 224 bra ne #mmctx_stop 225 // wait for queue to empty 226 mmctx_fini_wait: 227 nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0) 228 and $r11 0x1f 229 cmpu b32 $r11 0x10 230 bra ne #mmctx_fini_wait 231 mov $r10 5 // DONE_MMCTX 232 call(wait_donez) 233 bra #mmctx_done 234 mmctx_stop: 235 xbit $r11 $r10 0 236 shl b32 $r11 16 // DIR 237 bset $r11 12 // QLIMIT = 0x10 238 bset $r11 18 // STOP_TRIGGER 239 nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11) 240 mmctx_stop_wait: 241 // wait for STOP_TRIGGER to clear 242 nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0) 243 xbit $r11 $r11 18 244 bra ne #mmctx_stop_wait 245 mmctx_done: 246 trace_clr(T_MMCTX) 247 ret 248 249// Wait for DONE_STRAND 250// 251strand_wait: 252 push $r10 253 mov $r10 2 254 call(wait_donez) 255 pop $r10 256 ret 257 258// unknown - call before issuing strand commands 259// 260strand_pre: 261 mov $r9 NV_PGRAPH_FECS_STRAND_CMD_ENABLE 262 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9) 263 call(strand_wait) 264 ret 265 266// unknown - call after issuing strand commands 267// 268strand_post: 269 mov $r9 NV_PGRAPH_FECS_STRAND_CMD_DISABLE 270 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9) 271 call(strand_wait) 272 ret 273 274// Selects strand set?! 275// 276// In: $r14 id 277// 278strand_set: 279 mov $r12 0xf 280 nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r12) 281 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_DEACTIVATE_FILTER 282 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_FILTER 285 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12) 286 call(strand_wait) 287 ret 288 289// Initialise strand context data 290// 291// In : $r15 context base 292// Out: $r15 context size (in bytes) 293// 294// Strandset(?) 3 hardcoded currently 295// 296strand_ctx_init: 297 trace_set(T_STRINIT) 298 call(strand_pre) 299 mov $r14 3 300 call(strand_set) 301 302 clear b32 $r12 303 nv_iowr(NV_PGRAPH_FECS_STRAND_SELECT, 0x3f, $r12) 304 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_SEEK 305 nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12) 306 call(strand_wait) 307 sub b32 $r12 $r0 1 308 nv_iowr(NV_PGRAPH_FECS_STRAND_DATA, 0x3f, $r12) 309 mov $r12 NV_PGRAPH_FECS_STRAND_CMD_GET_INFO 310 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 of 315 // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry 316 // 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 8 320 ctx_init_strand_loop: 321 iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE 322 iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE 323 iord $r10 I[$r8 + 0x200] // STRAND_SIZE 324 shr b32 $r10 6 325 add b32 $r10 1 326 add b32 $r14 $r10 327 add b32 $r8 4 328 sub b32 $r9 1 329 bra ne #ctx_init_strand_loop 330 331 shl b32 $r14 8 332 sub b32 $r15 $r14 $r15 333 trace_clr(T_STRINIT) 334 ret 335#endif 336