Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 1 | /* fuc microcode util functions for nvc0 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 | define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)') |
| 27 | define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))') |
| 28 | |
| 29 | ifdef(`include_code', ` |
| 30 | // Error codes |
| 31 | define(`E_BAD_COMMAND', 0x01) |
| 32 | define(`E_CMD_OVERFLOW', 0x02) |
| 33 | |
| 34 | // Util macros to help with debugging ucode hangs etc |
| 35 | define(`T_WAIT', 0) |
| 36 | define(`T_MMCTX', 1) |
| 37 | define(`T_STRWAIT', 2) |
| 38 | define(`T_STRINIT', 3) |
| 39 | define(`T_AUTO', 4) |
| 40 | define(`T_CHAN', 5) |
| 41 | define(`T_LOAD', 6) |
| 42 | define(`T_SAVE', 7) |
| 43 | define(`T_LCHAN', 8) |
| 44 | define(`T_LCTXH', 9) |
| 45 | |
| 46 | define(`trace_set', ` |
| 47 | mov $r8 0x83c |
| 48 | shl b32 $r8 6 |
| 49 | clear b32 $r9 |
| 50 | bset $r9 $1 |
| 51 | iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] |
| 52 | ') |
| 53 | |
| 54 | define(`trace_clr', ` |
| 55 | mov $r8 0x85c |
| 56 | shl b32 $r8 6 |
| 57 | clear b32 $r9 |
| 58 | bset $r9 $1 |
| 59 | iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] |
| 60 | ') |
| 61 | |
| 62 | // queue_put - add request to queue |
| 63 | // |
| 64 | // In : $r13 queue pointer |
| 65 | // $r14 command |
| 66 | // $r15 data |
| 67 | // |
| 68 | queue_put: |
| 69 | // make sure we have space.. |
| 70 | ld b32 $r8 D[$r13 + 0x0] // GET |
| 71 | ld b32 $r9 D[$r13 + 0x4] // PUT |
| 72 | xor $r8 8 |
| 73 | cmpu b32 $r8 $r9 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 74 | bra ne #queue_put_next |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 75 | mov $r15 E_CMD_OVERFLOW |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 76 | call #error |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 77 | ret |
| 78 | |
| 79 | // store cmd/data on queue |
| 80 | queue_put_next: |
| 81 | and $r8 $r9 7 |
| 82 | shl b32 $r8 3 |
| 83 | add b32 $r8 $r13 |
| 84 | add b32 $r8 8 |
| 85 | st b32 D[$r8 + 0x0] $r14 |
| 86 | st b32 D[$r8 + 0x4] $r15 |
| 87 | |
| 88 | // update PUT |
| 89 | add b32 $r9 1 |
| 90 | and $r9 0xf |
| 91 | st b32 D[$r13 + 0x4] $r9 |
| 92 | ret |
| 93 | |
| 94 | // queue_get - fetch request from queue |
| 95 | // |
| 96 | // In : $r13 queue pointer |
| 97 | // |
| 98 | // Out: $p1 clear on success (data available) |
| 99 | // $r14 command |
| 100 | // $r15 data |
| 101 | // |
| 102 | queue_get: |
| 103 | bset $flags $p1 |
| 104 | ld b32 $r8 D[$r13 + 0x0] // GET |
| 105 | ld b32 $r9 D[$r13 + 0x4] // PUT |
| 106 | cmpu b32 $r8 $r9 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 107 | bra e #queue_get_done |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 108 | // fetch first cmd/data pair |
| 109 | and $r9 $r8 7 |
| 110 | shl b32 $r9 3 |
| 111 | add b32 $r9 $r13 |
| 112 | add b32 $r9 8 |
| 113 | ld b32 $r14 D[$r9 + 0x0] |
| 114 | ld b32 $r15 D[$r9 + 0x4] |
| 115 | |
| 116 | // update GET |
| 117 | add b32 $r8 1 |
| 118 | and $r8 0xf |
| 119 | st b32 D[$r13 + 0x0] $r8 |
| 120 | bclr $flags $p1 |
| 121 | queue_get_done: |
| 122 | ret |
| 123 | |
| 124 | // nv_rd32 - read 32-bit value from nv register |
| 125 | // |
| 126 | // In : $r14 register |
| 127 | // Out: $r15 value |
| 128 | // |
| 129 | nv_rd32: |
| 130 | mov $r11 0x728 |
| 131 | shl b32 $r11 6 |
| 132 | mov b32 $r12 $r14 |
| 133 | bset $r12 31 // MMIO_CTRL_PENDING |
| 134 | iowr I[$r11 + 0x000] $r12 // MMIO_CTRL |
| 135 | nv_rd32_wait: |
| 136 | iord $r12 I[$r11 + 0x000] |
| 137 | xbit $r12 $r12 31 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 138 | bra ne #nv_rd32_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 139 | mov $r10 6 // DONE_MMIO_RD |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 140 | call #wait_doneo |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 141 | iord $r15 I[$r11 + 0x100] // MMIO_RDVAL |
| 142 | ret |
| 143 | |
| 144 | // nv_wr32 - write 32-bit value to nv register |
| 145 | // |
| 146 | // In : $r14 register |
| 147 | // $r15 value |
| 148 | // |
| 149 | nv_wr32: |
| 150 | mov $r11 0x728 |
| 151 | shl b32 $r11 6 |
| 152 | iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL |
| 153 | mov b32 $r12 $r14 |
| 154 | bset $r12 31 // MMIO_CTRL_PENDING |
| 155 | bset $r12 30 // MMIO_CTRL_WRITE |
| 156 | iowr I[$r11 + 0x000] $r12 // MMIO_CTRL |
| 157 | nv_wr32_wait: |
| 158 | iord $r12 I[$r11 + 0x000] |
| 159 | xbit $r12 $r12 31 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 160 | bra ne #nv_wr32_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 161 | ret |
| 162 | |
| 163 | // (re)set watchdog timer |
| 164 | // |
| 165 | // In : $r15 timeout |
| 166 | // |
| 167 | watchdog_reset: |
| 168 | mov $r8 0x430 |
| 169 | shl b32 $r8 6 |
| 170 | bset $r15 31 |
| 171 | iowr I[$r8 + 0x000] $r15 |
| 172 | ret |
| 173 | |
| 174 | // clear watchdog timer |
| 175 | watchdog_clear: |
| 176 | mov $r8 0x430 |
| 177 | shl b32 $r8 6 |
| 178 | iowr I[$r8 + 0x000] $r0 |
| 179 | ret |
| 180 | |
| 181 | // wait_done{z,o} - wait on FUC_DONE bit to become clear/set |
| 182 | // |
| 183 | // In : $r10 bit to wait on |
| 184 | // |
| 185 | define(`wait_done', ` |
| 186 | $1: |
| 187 | trace_set(T_WAIT); |
| 188 | mov $r8 0x818 |
| 189 | shl b32 $r8 6 |
| 190 | iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit |
| 191 | wait_done_$1: |
| 192 | mov $r8 0x400 |
| 193 | shl b32 $r8 6 |
| 194 | iord $r8 I[$r8 + 0x000] // DONE |
| 195 | xbit $r8 $r8 $r10 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 196 | bra $2 #wait_done_$1 |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 197 | trace_clr(T_WAIT) |
| 198 | ret |
| 199 | ') |
| 200 | wait_done(wait_donez, ne) |
| 201 | wait_done(wait_doneo, e) |
| 202 | |
| 203 | // mmctx_size - determine size of a mmio list transfer |
| 204 | // |
| 205 | // In : $r14 mmio list head |
| 206 | // $r15 mmio list tail |
| 207 | // Out: $r15 transfer size (in bytes) |
| 208 | // |
| 209 | mmctx_size: |
| 210 | clear b32 $r9 |
| 211 | nv_mmctx_size_loop: |
| 212 | ld b32 $r8 D[$r14] |
| 213 | shr b32 $r8 26 |
| 214 | add b32 $r8 1 |
| 215 | shl b32 $r8 2 |
| 216 | add b32 $r9 $r8 |
| 217 | add b32 $r14 4 |
| 218 | cmpu b32 $r14 $r15 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 219 | bra ne #nv_mmctx_size_loop |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 220 | mov b32 $r15 $r9 |
| 221 | ret |
| 222 | |
| 223 | // mmctx_xfer - execute a list of mmio transfers |
| 224 | // |
| 225 | // In : $r10 flags |
| 226 | // bit 0: direction (0 = save, 1 = load) |
| 227 | // bit 1: set if first transfer |
| 228 | // bit 2: set if last transfer |
| 229 | // $r11 base |
| 230 | // $r12 mmio list head |
| 231 | // $r13 mmio list tail |
| 232 | // $r14 multi_stride |
| 233 | // $r15 multi_mask |
| 234 | // |
| 235 | mmctx_xfer: |
| 236 | trace_set(T_MMCTX) |
| 237 | mov $r8 0x710 |
| 238 | shl b32 $r8 6 |
| 239 | clear b32 $r9 |
| 240 | or $r11 $r11 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 241 | bra e #mmctx_base_disabled |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 242 | iowr I[$r8 + 0x000] $r11 // MMCTX_BASE |
| 243 | bset $r9 0 // BASE_EN |
| 244 | mmctx_base_disabled: |
| 245 | or $r14 $r14 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 246 | bra e #mmctx_multi_disabled |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 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: |
| 251 | add b32 $r8 0x100 |
| 252 | |
| 253 | xbit $r11 $r10 0 |
| 254 | shl b32 $r11 16 // DIR |
| 255 | bset $r11 12 // QLIMIT = 0x10 |
| 256 | xbit $r14 $r10 1 |
| 257 | shl b32 $r14 17 |
| 258 | or $r11 $r14 // START_TRIGGER |
| 259 | iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL |
| 260 | |
| 261 | // loop over the mmio list, and send requests to the hw |
| 262 | mmctx_exec_loop: |
| 263 | // wait for space in mmctx queue |
| 264 | mmctx_wait_free: |
| 265 | iord $r14 I[$r8 + 0x000] // MMCTX_CTRL |
| 266 | and $r14 0x1f |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 267 | bra e #mmctx_wait_free |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 268 | |
| 269 | // queue up an entry |
| 270 | ld b32 $r14 D[$r12] |
| 271 | or $r14 $r9 |
| 272 | iowr I[$r8 + 0x300] $r14 |
| 273 | add b32 $r12 4 |
| 274 | cmpu b32 $r12 $r13 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 275 | bra ne #mmctx_exec_loop |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 276 | |
| 277 | xbit $r11 $r10 2 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 278 | bra ne #mmctx_stop |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 279 | // wait for queue to empty |
| 280 | mmctx_fini_wait: |
| 281 | iord $r11 I[$r8 + 0x000] // MMCTX_CTRL |
| 282 | and $r11 0x1f |
| 283 | cmpu b32 $r11 0x10 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 284 | bra ne #mmctx_fini_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 285 | mov $r10 2 // DONE_MMCTX |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 286 | call #wait_donez |
| 287 | bra #mmctx_done |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 288 | mmctx_stop: |
| 289 | xbit $r11 $r10 0 |
| 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 |
| 294 | mmctx_stop_wait: |
| 295 | // wait for STOP_TRIGGER to clear |
| 296 | iord $r11 I[$r8 + 0x000] // MMCTX_CTRL |
| 297 | xbit $r11 $r11 18 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 298 | bra ne #mmctx_stop_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 299 | mmctx_done: |
| 300 | trace_clr(T_MMCTX) |
| 301 | ret |
| 302 | |
| 303 | // Wait for DONE_STRAND |
| 304 | // |
| 305 | strand_wait: |
| 306 | push $r10 |
| 307 | mov $r10 2 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 308 | call #wait_donez |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 309 | pop $r10 |
| 310 | ret |
| 311 | |
| 312 | // unknown - call before issuing strand commands |
| 313 | // |
| 314 | strand_pre: |
| 315 | mov $r8 0x4afc |
| 316 | sethi $r8 0x20000 |
| 317 | mov $r9 0xc |
| 318 | iowr I[$r8] $r9 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 319 | call #strand_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 320 | ret |
| 321 | |
| 322 | // unknown - call after issuing strand commands |
| 323 | // |
| 324 | strand_post: |
| 325 | mov $r8 0x4afc |
| 326 | sethi $r8 0x20000 |
| 327 | mov $r9 0xd |
| 328 | iowr I[$r8] $r9 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 329 | call #strand_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 330 | ret |
| 331 | |
| 332 | // Selects strand set?! |
| 333 | // |
| 334 | // In: $r14 id |
| 335 | // |
| 336 | strand_set: |
| 337 | mov $r10 0x4ffc |
| 338 | sethi $r10 0x20000 |
| 339 | sub b32 $r11 $r10 0x500 |
| 340 | mov $r12 0xf |
| 341 | iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf |
| 342 | mov $r12 0xb |
| 343 | iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 344 | call #strand_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 345 | iowr I[$r10 + 0x000] $r14 // 0x93c = <id> |
| 346 | mov $r12 0xa |
| 347 | iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 348 | call #strand_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 349 | ret |
| 350 | |
| 351 | // Initialise strand context data |
| 352 | // |
| 353 | // In : $r15 context base |
| 354 | // Out: $r15 context size (in bytes) |
| 355 | // |
| 356 | // Strandset(?) 3 hardcoded currently |
| 357 | // |
| 358 | strand_ctx_init: |
| 359 | trace_set(T_STRINIT) |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 360 | call #strand_pre |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 361 | mov $r14 3 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 362 | call #strand_set |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 363 | mov $r10 0x46fc |
| 364 | sethi $r10 0x20000 |
| 365 | add b32 $r11 $r10 0x400 |
| 366 | iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0 |
| 367 | mov $r12 1 |
| 368 | iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 369 | call #strand_wait |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 370 | sub b32 $r12 $r0 1 |
| 371 | iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff |
| 372 | mov $r12 2 |
| 373 | iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 374 | call #strand_wait |
| 375 | call #strand_post |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 376 | |
| 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. |
| 380 | mov $r8 0x880 |
| 381 | shl b32 $r8 6 |
| 382 | iord $r9 I[$r8 + 0x000] // STRANDS |
| 383 | add b32 $r8 0x2200 |
| 384 | shr b32 $r14 $r15 8 |
| 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 |
| 389 | shr b32 $r10 6 |
| 390 | add b32 $r10 1 |
| 391 | add b32 $r14 $r10 |
| 392 | add b32 $r8 4 |
| 393 | sub b32 $r9 1 |
Ben Skeggs | be7f261 | 2011-10-28 12:06:42 +1000 | [diff] [blame] | 394 | bra ne #ctx_init_strand_loop |
Ben Skeggs | 0411de8 | 2011-05-25 18:32:44 +1000 | [diff] [blame] | 395 | |
| 396 | shl b32 $r14 8 |
| 397 | sub b32 $r15 $r14 $r15 |
| 398 | trace_clr(T_STRINIT) |
| 399 | ret |
| 400 | ') |