Commit 1978a2f2 authored by Ben Skeggs's avatar Ben Skeggs

drm/nve0/gr: initial fuc implementation, based on fermi's code

Currently identical except the available chipset register lists.  This will
*not* currently work and is disabled by default because of this.

May get merged again later, remains to be seen what further changes will be
required.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 2c1a425e
This diff is collapsed.
uint32_t nve0_grgpc_data[] = {
/* 0x0000: gpc_id */
0x00000000,
/* 0x0004: gpc_mmio_list_head */
0x00000000,
/* 0x0008: gpc_mmio_list_tail */
0x00000000,
/* 0x000c: tpc_count */
0x00000000,
/* 0x0010: tpc_mask */
0x00000000,
/* 0x0014: tpc_mmio_list_head */
0x00000000,
/* 0x0018: tpc_mmio_list_tail */
0x00000000,
/* 0x001c: cmd_queue */
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
/* 0x0064: chipsets */
0x000000e4,
0x01040080,
0x014c0104,
0x000000e7,
0x01040080,
0x014c0104,
0x00000000,
/* 0x0080: nve4_gpc_mmio_head */
0x00000380,
0x04000400,
0x0800040c,
0x20000450,
0x00000600,
0x00000684,
0x10000700,
0x00000800,
0x08000808,
0x00000828,
0x00000830,
0x000008d8,
0x000008e0,
0x140008e8,
0x0000091c,
0x08000924,
0x00000b00,
0x14000b08,
0x00000bb8,
0x00000c08,
0x1c000c10,
0x00000c40,
0x00000c6c,
0x00000c80,
0x00000c8c,
0x08001000,
0x00001014,
0x00003024,
0x040030c0,
0x000030e4,
0x14003100,
0x000031d0,
0x040031e0,
/* 0x0104: nve4_gpc_mmio_tail */
/* 0x0104: nve4_tpc_mmio_head */
0x00000048,
0x00000064,
0x00000088,
0x14000200,
0x0400021c,
0x00000230,
0x000002c4,
0x08000400,
0x08000420,
0x000004e8,
0x000004f4,
0x0c000604,
0x54000644,
0x040006ac,
0x000006c8,
0x1c000730,
0x00000758,
0x00000778,
};
uint32_t nve0_grgpc_code[] = {
0x03060ef5,
/* 0x0004: queue_put */
0x9800d898,
0x86f001d9,
0x0489b808,
0xf00c1bf4,
0x21f502f7,
0x00f802ec,
/* 0x001c: queue_put_next */
0xb60798c4,
0x8dbb0384,
0x0880b600,
0x80008e80,
0x90b6018f,
0x0f94f001,
0xf801d980,
/* 0x0039: queue_get */
0x0131f400,
0x9800d898,
0x89b801d9,
0x210bf404,
0xb60789c4,
0x9dbb0394,
0x0890b600,
0x98009e98,
0x80b6019f,
0x0f84f001,
0xf400d880,
/* 0x0066: queue_get_done */
0x00f80132,
/* 0x0068: nv_rd32 */
0x0728b7f1,
0xb906b4b6,
0xc9f002ec,
0x00bcd01f,
/* 0x0078: nv_rd32_wait */
0xc800bccf,
0x1bf41fcc,
0x06a7f0fa,
0x010321f5,
0xf840bfcf,
/* 0x008d: nv_wr32 */
0x28b7f100,
0x06b4b607,
0xb980bfd0,
0xc9f002ec,
0x1ec9f01f,
/* 0x00a3: nv_wr32_wait */
0xcf00bcd0,
0xccc800bc,
0xfa1bf41f,
/* 0x00ae: watchdog_reset */
0x87f100f8,
0x84b60430,
0x1ff9f006,
0xf8008fd0,
/* 0x00bd: watchdog_clear */
0x3087f100,
0x0684b604,
0xf80080d0,
/* 0x00c9: wait_donez */
0x3c87f100,
0x0684b608,
0x99f094bd,
0x0089d000,
0x081887f1,
0xd00684b6,
/* 0x00e2: wait_done_wait_donez */
0x87f1008a,
0x84b60400,
0x0088cf06,
0xf4888aff,
0x87f1f31b,
0x84b6085c,
0xf094bd06,
0x89d00099,
/* 0x0103: wait_doneo */
0xf100f800,
0xb6083c87,
0x94bd0684,
0xd00099f0,
0x87f10089,
0x84b60818,
0x008ad006,
/* 0x011c: wait_done_wait_doneo */
0x040087f1,
0xcf0684b6,
0x8aff0088,
0xf30bf488,
0x085c87f1,
0xbd0684b6,
0x0099f094,
0xf80089d0,
/* 0x013d: mmctx_size */
/* 0x013f: nv_mmctx_size_loop */
0x9894bd00,
0x85b600e8,
0x0180b61a,
0xbb0284b6,
0xe0b60098,
0x04efb804,
0xb9eb1bf4,
0x00f8029f,
/* 0x015c: mmctx_xfer */
0x083c87f1,
0xbd0684b6,
0x0199f094,
0xf10089d0,
0xb6071087,
0x94bd0684,
0xf405bbfd,
0x8bd0090b,
0x0099f000,
/* 0x0180: mmctx_base_disabled */
0xf405eefd,
0x8ed00c0b,
0xc08fd080,
/* 0x018f: mmctx_multi_disabled */
0xb70199f0,
0xc8010080,
0xb4b600ab,
0x0cb9f010,
0xb601aec8,
0xbefd11e4,
0x008bd005,
/* 0x01a8: mmctx_exec_loop */
/* 0x01a8: mmctx_wait_free */
0xf0008ecf,
0x0bf41fe4,
0x00ce98fa,
0xd005e9fd,
0xc0b6c08e,
0x04cdb804,
0xc8e81bf4,
0x1bf402ab,
/* 0x01c9: mmctx_fini_wait */
0x008bcf18,
0xb01fb4f0,
0x1bf410b4,
0x02a7f0f7,
0xf4c921f4,
/* 0x01de: mmctx_stop */
0xabc81b0e,
0x10b4b600,
0xf00cb9f0,
0x8bd012b9,
/* 0x01ed: mmctx_stop_wait */
0x008bcf00,
0xf412bbc8,
/* 0x01f6: mmctx_done */
0x87f1fa1b,
0x84b6085c,
0xf094bd06,
0x89d00199,
/* 0x0207: strand_wait */
0xf900f800,
0x02a7f0a0,
0xfcc921f4,
/* 0x0213: strand_pre */
0xf100f8a0,
0xf04afc87,
0x97f00283,
0x0089d00c,
0x020721f5,
/* 0x0226: strand_post */
0x87f100f8,
0x83f04afc,
0x0d97f002,
0xf50089d0,
0xf8020721,
/* 0x0239: strand_set */
0xfca7f100,
0x02a3f04f,
0x0500aba2,
0xd00fc7f0,
0xc7f000ac,
0x00bcd00b,
0x020721f5,
0xf000aed0,
0xbcd00ac7,
0x0721f500,
/* 0x0263: strand_ctx_init */
0xf100f802,
0xb6083c87,
0x94bd0684,
0xd00399f0,
0x21f50089,
0xe7f00213,
0x3921f503,
0xfca7f102,
0x02a3f046,
0x0400aba0,
0xf040a0d0,
0xbcd001c7,
0x0721f500,
0x010c9202,
0xf000acd0,
0xbcd002c7,
0x0721f500,
0x2621f502,
0x8087f102,
0x0684b608,
0xb70089cf,
0x95220080,
/* 0x02ba: ctx_init_strand_loop */
0x8ed008fe,
0x408ed000,
0xb6808acf,
0xa0b606a5,
0x00eabb01,
0xb60480b6,
0x1bf40192,
0x08e4b6e8,
0xf1f2efbc,
0xb6085c87,
0x94bd0684,
0xd00399f0,
0x00f80089,
/* 0x02ec: error */
0xe7f1e0f9,
0xe3f09814,
0x8d21f440,
0x041ce0b7,
0xf401f7f0,
0xe0fc8d21,
/* 0x0306: init */
0x04bd00f8,
0xf10004fe,
0xf0120017,
0x12d00227,
0x3e17f100,
0x0010fe04,
0x040017f1,
0xf0c010d0,
0x12d00427,
0x1031f400,
0x060817f1,
0xcf0614b6,
0x37f00012,
0x1f24f001,
0xb60432bb,
0x02800132,
0x04038003,
0x040010b7,
0x800012cf,
0x27f10002,
0x24b60800,
0x0022cf06,
/* 0x035f: init_find_chipset */
0xb65817f0,
0x13980c10,
0x0432b800,
0xb00b0bf4,
0x1bf40034,
/* 0x0373: init_context */
0xf100f8f1,
0xb6080027,
0x22cf0624,
0xf134bd40,
0xb6070047,
0x25950644,
0x0045d008,
0xbd4045d0,
0x58f4bde4,
0x1f58021e,
0x020e4003,
0xf5040f40,
0xbb013d21,
0x3fbb002f,
0x041e5800,
0x40051f58,
0x0f400a0e,
0x3d21f50c,
0x030e9801,
0xbb00effd,
0x3ebb002e,
0x0040b700,
0x0235b613,
0xb60043d0,
0x35b60825,
0x0120b606,
0xb60130b6,
0x34b60824,
0x022fb908,
0x026321f5,
0xf1003fbb,
0xb6080017,
0x13d00614,
0x0010b740,
0xf024bd08,
0x12d01f29,
/* 0x0401: main */
0x0031f400,
0xf00028f4,
0x21f41cd7,
0xf401f439,
0xf404e4b0,
0x81fe1e18,
0x0627f001,
0x12fd20bd,
0x01e4b604,
0xfe051efd,
0x21f50018,
0x0ef404c3,
/* 0x0431: main_not_ctx_xfer */
0x10ef94d3,
0xf501f5f0,
0xf402ec21,
/* 0x043e: ih */
0x80f9c60e,
0xf90188fe,
0xf990f980,
0xf9b0f9a0,
0xf9e0f9d0,
0x800acff0,
0xf404abc4,
0xb7f11d0b,
0xd7f01900,
0x40becf1c,
0xf400bfcf,
0xb0b70421,
0xe7f00400,
0x00bed001,
/* 0x0474: ih_no_fifo */
0xfc400ad0,
0xfce0fcf0,
0xfcb0fcd0,
0xfc90fca0,
0x0088fe80,
0x32f480fc,
/* 0x048f: hub_barrier_done */
0xf001f800,
0x0e9801f7,
0x04febb00,
0x9418e7f1,
0xf440e3f0,
0x00f88d21,
/* 0x04a4: ctx_redswitch */
0x0614e7f1,
0xf006e4b6,
0xefd020f7,
0x08f7f000,
/* 0x04b4: ctx_redswitch_delay */
0xf401f2b6,
0xf7f1fd1b,
0xefd00a20,
/* 0x04c3: ctx_xfer */
0xf100f800,
0xb60a0417,
0x1fd00614,
0x0711f400,
0x04a421f5,
/* 0x04d4: ctx_xfer_not_load */
0x4afc17f1,
0xf00213f0,
0x12d00c27,
0x0721f500,
0xfc27f102,
0x0223f047,
0xf00020d0,
0x20b6012c,
0x0012d003,
0xf001acf0,
0xb7f002a5,
0x50b3f000,
0xb6000c98,
0xbcbb0fc4,
0x010c9800,
0xf0020d98,
0x21f500e7,
0xacf0015c,
0x04a5f001,
0x4000b7f1,
0x9850b3f0,
0xc4b6000c,
0x00bcbb0f,
0x98050c98,
0x0f98060d,
0x00e7f104,
0x5c21f508,
0x0721f501,
0x0601f402,
/* 0x054b: ctx_xfer_post */
0xf11412f4,
0xf04afc17,
0x27f00213,
0x0012d00d,
0x020721f5,
/* 0x055c: ctx_xfer_done */
0x048f21f5,
0x000000f8,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};
This diff is collapsed.
This diff is collapsed.
/* fuc microcode util functions for nve0 PGRAPH
*
* Copyright 2011 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)')
define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
ifdef(`include_code', `
// Error codes
define(`E_BAD_COMMAND', 0x01)
define(`E_CMD_OVERFLOW', 0x02)
// Util macros to help with debugging ucode hangs etc
define(`T_WAIT', 0)
define(`T_MMCTX', 1)
define(`T_STRWAIT', 2)
define(`T_STRINIT', 3)
define(`T_AUTO', 4)
define(`T_CHAN', 5)
define(`T_LOAD', 6)
define(`T_SAVE', 7)
define(`T_LCHAN', 8)
define(`T_LCTXH', 9)
define(`trace_set', `
mov $r8 0x83c
shl b32 $r8 6
clear b32 $r9
bset $r9 $1
iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
')
define(`trace_clr', `
mov $r8 0x85c
shl b32 $r8 6
clear b32 $r9
bset $r9 $1
iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
')
// queue_put - add request to queue
//
// In : $r13 queue pointer
// $r14 command
// $r15 data
//
queue_put:
// make sure we have space..
ld b32 $r8 D[$r13 + 0x0] // GET
ld b32 $r9 D[$r13 + 0x4] // PUT
xor $r8 8
cmpu b32 $r8 $r9
bra ne #queue_put_next
mov $r15 E_CMD_OVERFLOW
call #error
ret
// store cmd/data on queue
queue_put_next:
and $r8 $r9 7
shl b32 $r8 3
add b32 $r8 $r13
add b32 $r8 8
st b32 D[$r8 + 0x0] $r14
st b32 D[$r8 + 0x4] $r15
// update PUT
add b32 $r9 1
and $r9 0xf
st b32 D[$r13 + 0x4] $r9
ret
// queue_get - fetch request from queue
//
// In : $r13 queue pointer
//
// Out: $p1 clear on success (data available)
// $r14 command
// $r15 data
//
queue_get:
bset $flags $p1
ld b32 $r8 D[$r13 + 0x0] // GET
ld b32 $r9 D[$r13 + 0x4] // PUT
cmpu b32 $r8 $r9
bra e #queue_get_done
// fetch first cmd/data pair
and $r9 $r8 7
shl b32 $r9 3
add b32 $r9 $r13
add b32 $r9 8
ld b32 $r14 D[$r9 + 0x0]
ld b32 $r15 D[$r9 + 0x4]
// update GET
add b32 $r8 1
and $r8 0xf
st b32 D[$r13 + 0x0] $r8
bclr $flags $p1
queue_get_done:
ret
// nv_rd32 - read 32-bit value from nv register
//
// In : $r14 register
// Out: $r15 value
//
nv_rd32:
mov $r11 0x728
shl b32 $r11 6
mov b32 $r12 $r14
bset $r12 31 // MMIO_CTRL_PENDING
iowr I[$r11 + 0x000] $r12 // MMIO_CTRL
nv_rd32_wait:
iord $r12 I[$r11 + 0x000]
xbit $r12 $r12 31
bra ne #nv_rd32_wait
mov $r10 6 // DONE_MMIO_RD
call #wait_doneo
iord $r15 I[$r11 + 0x100] // MMIO_RDVAL
ret
// nv_wr32 - write 32-bit value to nv register
//
// In : $r14 register
// $r15 value
//
nv_wr32:
mov $r11 0x728
shl b32 $r11 6
iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL
mov b32 $r12 $r14
bset $r12 31 // MMIO_CTRL_PENDING
bset $r12 30 // MMIO_CTRL_WRITE
iowr I[$r11 + 0x000] $r12 // MMIO_CTRL
nv_wr32_wait:
iord $r12 I[$r11 + 0x000]
xbit $r12 $r12 31
bra ne #nv_wr32_wait
ret
// (re)set watchdog timer
//
// In : $r15 timeout
//
watchdog_reset:
mov $r8 0x430
shl b32 $r8 6
bset $r15 31
iowr I[$r8 + 0x000] $r15
ret
// clear watchdog timer
watchdog_clear:
mov $r8 0x430
shl b32 $r8 6
iowr I[$r8 + 0x000] $r0
ret
// wait_done{z,o} - wait on FUC_DONE bit to become clear/set
//
// In : $r10 bit to wait on
//
define(`wait_done', `
$1:
trace_set(T_WAIT);
mov $r8 0x818
shl b32 $r8 6
iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit
wait_done_$1:
mov $r8 0x400
shl b32 $r8 6
iord $r8 I[$r8 + 0x000] // DONE
xbit $r8 $r8 $r10
bra $2 #wait_done_$1
trace_clr(T_WAIT)
ret
')
wait_done(wait_donez, ne)
wait_done(wait_doneo, e)
// mmctx_size - determine size of a mmio list transfer
//
// In : $r14 mmio list head
// $r15 mmio list tail
// Out: $r15 transfer size (in bytes)
//
mmctx_size:
clear b32 $r9
nv_mmctx_size_loop:
ld b32 $r8 D[$r14]
shr b32 $r8 26
add b32 $r8 1
shl b32 $r8 2
add b32 $r9 $r8
add b32 $r14 4
cmpu b32 $r14 $r15
bra ne #nv_mmctx_size_loop
mov b32 $r15 $r9
ret
// mmctx_xfer - execute a list of mmio transfers
//
// In : $r10 flags
// bit 0: direction (0 = save, 1 = load)
// bit 1: set if first transfer
// bit 2: set if last transfer
// $r11 base
// $r12 mmio list head
// $r13 mmio list tail
// $r14 multi_stride
// $r15 multi_mask
//
mmctx_xfer:
trace_set(T_MMCTX)
mov $r8 0x710
shl b32 $r8 6
clear b32 $r9
or $r11 $r11
bra e #mmctx_base_disabled
iowr I[$r8 + 0x000] $r11 // MMCTX_BASE
bset $r9 0 // BASE_EN
mmctx_base_disabled:
or $r14 $r14
bra e #mmctx_multi_disabled
iowr I[$r8 + 0x200] $r14 // MMCTX_MULTI_STRIDE
iowr I[$r8 + 0x300] $r15 // MMCTX_MULTI_MASK
bset $r9 1 // MULTI_EN
mmctx_multi_disabled:
add b32 $r8 0x100
xbit $r11 $r10 0
shl b32 $r11 16 // DIR
bset $r11 12 // QLIMIT = 0x10
xbit $r14 $r10 1
shl b32 $r14 17
or $r11 $r14 // START_TRIGGER
iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL
// loop over the mmio list, and send requests to the hw
mmctx_exec_loop:
// wait for space in mmctx queue
mmctx_wait_free:
iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
and $r14 0x1f
bra e #mmctx_wait_free
// queue up an entry
ld b32 $r14 D[$r12]
or $r14 $r9
iowr I[$r8 + 0x300] $r14
add b32 $r12 4
cmpu b32 $r12 $r13
bra ne #mmctx_exec_loop
xbit $r11 $r10 2
bra ne #mmctx_stop
// wait for queue to empty
mmctx_fini_wait:
iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
and $r11 0x1f
cmpu b32 $r11 0x10
bra ne #mmctx_fini_wait
mov $r10 2 // DONE_MMCTX
call #wait_donez
bra #mmctx_done
mmctx_stop:
xbit $r11 $r10 0
shl b32 $r11 16 // DIR
bset $r11 12 // QLIMIT = 0x10
bset $r11 18 // STOP_TRIGGER
iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL
mmctx_stop_wait:
// wait for STOP_TRIGGER to clear
iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
xbit $r11 $r11 18
bra ne #mmctx_stop_wait
mmctx_done:
trace_clr(T_MMCTX)
ret
// Wait for DONE_STRAND
//
strand_wait:
push $r10
mov $r10 2
call #wait_donez
pop $r10
ret
// unknown - call before issuing strand commands
//
strand_pre:
mov $r8 0x4afc
sethi $r8 0x20000
mov $r9 0xc
iowr I[$r8] $r9
call #strand_wait
ret
// unknown - call after issuing strand commands
//
strand_post:
mov $r8 0x4afc
sethi $r8 0x20000
mov $r9 0xd
iowr I[$r8] $r9
call #strand_wait
ret
// Selects strand set?!
//
// In: $r14 id
//
strand_set:
mov $r10 0x4ffc
sethi $r10 0x20000
sub b32 $r11 $r10 0x500
mov $r12 0xf
iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf
mov $r12 0xb
iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb
call #strand_wait
iowr I[$r10 + 0x000] $r14 // 0x93c = <id>
mov $r12 0xa
iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa
call #strand_wait
ret
// Initialise strand context data
//
// In : $r15 context base
// Out: $r15 context size (in bytes)
//
// Strandset(?) 3 hardcoded currently
//
strand_ctx_init:
trace_set(T_STRINIT)
call #strand_pre
mov $r14 3
call #strand_set
mov $r10 0x46fc
sethi $r10 0x20000
add b32 $r11 $r10 0x400
iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0
mov $r12 1
iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE
call #strand_wait
sub b32 $r12 $r0 1
iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff
mov $r12 2
iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT
call #strand_wait
call #strand_post
// read the size of each strand, poke the context offset of
// each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
// about it later then.
mov $r8 0x880
shl b32 $r8 6
iord $r9 I[$r8 + 0x000] // STRANDS
add b32 $r8 0x2200
shr b32 $r14 $r15 8
ctx_init_strand_loop:
iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE
iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE
iord $r10 I[$r8 + 0x200] // STRAND_SIZE
shr b32 $r10 6
add b32 $r10 1
add b32 $r14 $r10
add b32 $r8 4
sub b32 $r9 1
bra ne #ctx_init_strand_loop
shl b32 $r14 8
sub b32 $r15 $r14 $r15
trace_clr(T_STRINIT)
ret
')
......@@ -23,6 +23,8 @@
*/
#include "nvc0.h"
#include "fuc/hubnve0.fuc.h"
#include "fuc/gpcnve0.fuc.h"
/*******************************************************************************
* Graphics object classes
......@@ -197,6 +199,7 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_device *device = nv_device(parent);
struct nvc0_graph_priv *priv;
int ret, i;
......@@ -210,13 +213,15 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_engine(priv)->cclass = &nve0_graph_cclass;
nv_engine(priv)->sclass = nve0_graph_sclass;
nv_info(priv, "using external firmware\n");
if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
return -EINVAL;
priv->firmware = true;
if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", true)) {
nv_info(priv, "using external firmware\n");
if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
return -EINVAL;
priv->firmware = true;
}
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4);
if (ret)
......@@ -386,81 +391,131 @@ static int
nve0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
{
u32 r000260;
int i;
/* load fuc microcode */
r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c, &priv->fuc409d);
nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
nv_wr32(priv, 0x000260, r000260);
if (priv->firmware) {
/* load fuc microcode */
r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c, &priv->fuc409d);
nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
nv_wr32(priv, 0x000260, r000260);
/* start both of them running */
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x41a10c, 0x00000000);
nv_wr32(priv, 0x40910c, 0x00000000);
nv_wr32(priv, 0x41a100, 0x00000002);
nv_wr32(priv, 0x409100, 0x00000002);
if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001))
nv_error(priv, "0x409800 wait failed\n");
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x409500, 0x7fffffff);
nv_wr32(priv, 0x409504, 0x00000021);
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x409500, 0x00000000);
nv_wr32(priv, 0x409504, 0x00000010);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x10 timeout\n");
return -EBUSY;
}
priv->size = nv_rd32(priv, 0x409800);
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x409500, 0x00000000);
nv_wr32(priv, 0x409504, 0x00000016);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x16 timeout\n");
return -EBUSY;
}
/* start both of them running */
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x41a10c, 0x00000000);
nv_wr32(priv, 0x40910c, 0x00000000);
nv_wr32(priv, 0x41a100, 0x00000002);
nv_wr32(priv, 0x409100, 0x00000002);
if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001))
nv_error(priv, "0x409800 wait failed\n");
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x409500, 0x7fffffff);
nv_wr32(priv, 0x409504, 0x00000021);
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x409500, 0x00000000);
nv_wr32(priv, 0x409504, 0x00000010);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x10 timeout\n");
return -EBUSY;
}
priv->size = nv_rd32(priv, 0x409800);
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x409500, 0x00000000);
nv_wr32(priv, 0x409504, 0x00000025);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x25 timeout\n");
return -EBUSY;
}
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x409500, 0x00000000);
nv_wr32(priv, 0x409504, 0x00000016);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x16 timeout\n");
return -EBUSY;
}
nv_wr32(priv, 0x409800, 0x00000000);
nv_wr32(priv, 0x409500, 0x00000001);
nv_wr32(priv, 0x409504, 0x00000030);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x30 timeout\n");
return -EBUSY;
}
nv_wr32(priv, 0x409840, 0xffffffff);
nv_wr32(priv, 0x409500, 0x00000000);
nv_wr32(priv, 0x409504, 0x00000025);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x25 timeout\n");
return -EBUSY;
nv_wr32(priv, 0x409810, 0xb00095c8);
nv_wr32(priv, 0x409800, 0x00000000);
nv_wr32(priv, 0x409500, 0x00000001);
nv_wr32(priv, 0x409504, 0x00000031);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x31 timeout\n");
return -EBUSY;
}
nv_wr32(priv, 0x409810, 0x00080420);
nv_wr32(priv, 0x409800, 0x00000000);
nv_wr32(priv, 0x409500, 0x00000001);
nv_wr32(priv, 0x409504, 0x00000032);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x32 timeout\n");
return -EBUSY;
}
nv_wr32(priv, 0x409614, 0x00000070);
nv_wr32(priv, 0x409614, 0x00000770);
nv_wr32(priv, 0x40802c, 0x00000001);
if (priv->data == NULL) {
int ret = nve0_grctx_generate(priv);
if (ret) {
nv_error(priv, "failed to construct context\n");
return ret;
}
}
return 0;
}
nv_wr32(priv, 0x409800, 0x00000000);
nv_wr32(priv, 0x409500, 0x00000001);
nv_wr32(priv, 0x409504, 0x00000030);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x30 timeout\n");
return -EBUSY;
/* load HUB microcode */
r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
nv_wr32(priv, 0x4091c0, 0x01000000);
for (i = 0; i < sizeof(nve0_grhub_data) / 4; i++)
nv_wr32(priv, 0x4091c4, nve0_grhub_data[i]);
nv_wr32(priv, 0x409180, 0x01000000);
for (i = 0; i < sizeof(nve0_grhub_code) / 4; i++) {
if ((i & 0x3f) == 0)
nv_wr32(priv, 0x409188, i >> 6);
nv_wr32(priv, 0x409184, nve0_grhub_code[i]);
}
nv_wr32(priv, 0x409810, 0xb00095c8);
nv_wr32(priv, 0x409800, 0x00000000);
nv_wr32(priv, 0x409500, 0x00000001);
nv_wr32(priv, 0x409504, 0x00000031);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x31 timeout\n");
return -EBUSY;
/* load GPC microcode */
nv_wr32(priv, 0x41a1c0, 0x01000000);
for (i = 0; i < sizeof(nve0_grgpc_data) / 4; i++)
nv_wr32(priv, 0x41a1c4, nve0_grgpc_data[i]);
nv_wr32(priv, 0x41a180, 0x01000000);
for (i = 0; i < sizeof(nve0_grgpc_code) / 4; i++) {
if ((i & 0x3f) == 0)
nv_wr32(priv, 0x41a188, i >> 6);
nv_wr32(priv, 0x41a184, nve0_grgpc_code[i]);
}
nv_wr32(priv, 0x000260, r000260);
nv_wr32(priv, 0x409810, 0x00080420);
nv_wr32(priv, 0x409800, 0x00000000);
nv_wr32(priv, 0x409500, 0x00000001);
nv_wr32(priv, 0x409504, 0x00000032);
if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
nv_error(priv, "fuc09 req 0x32 timeout\n");
/* start HUB ucode running, it'll init the GPCs */
nv_wr32(priv, 0x409800, nv_device(priv)->chipset);
nv_wr32(priv, 0x40910c, 0x00000000);
nv_wr32(priv, 0x409100, 0x00000002);
if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
nv_error(priv, "HUB_INIT timed out\n");
nvc0_graph_ctxctl_debug(priv);
return -EBUSY;
}
nv_wr32(priv, 0x409614, 0x00000070);
nv_wr32(priv, 0x409614, 0x00000770);
nv_wr32(priv, 0x40802c, 0x00000001);
priv->size = nv_rd32(priv, 0x409804);
if (priv->data == NULL) {
int ret = nve0_grctx_generate(priv);
if (ret) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment