Ok .. some progress, I've gotten the first ExecList to submit, GT registers now read back without returning 0's and I can see the values specified in the execlist in the registers!
The issue WAS the forcewake + BCS reset. The forcewake uses masked registers and posted reads, otherwise it doesn't work.
Also there are different ACK registers depending on the generation.
The problem now is - I don't know if the contents of the execlist are correct, and I don't seem to be able to get a 2nd execlist submit to do anything.
I setup the Context ID in both packets with SW Counter as 1, 2 and it stays stuck on 1. Not sure if a broken context in 1 causes 2 to never work.
It seems like you have to submit a new context every time you update the ring buffer, then in the context modify the ring.tail position.
The BCS reset and forcewake needs these registers (undocumented mostly):
Code: Select all
FORCEWAKE_GT EQU 0xa188
FORCEWAKE_RENDER EQU 0xa278
FORCEWAKE_ACK_GT EQU 0x130044
FORCEWAKE_ACK_GT_MTL EQU 0xdfc ; Use this one if your hw is GEN 12.7+
FORCEWAKE_ACK_RENDER EQU 0xd84
RESET_CTRL_BCSUNIT EQU 0x220d0
GDRST EQU 0x0941c ; bit 2 = blitter, 1 to initiate domain reset, cleared by CP once reset complete.
For gen 12.5 there is a register you can read to get the GT version like 1250 1270 etc, if not, you have to fall back to a table of device ids.
The reset process involves writing RESET_CTRL_BCSUNIT first and waiting for the hw is ready to reset flag.
Then you write GDRST to triger the actual soft reset.
This can ONLY be done after forcewake.
Forcewake requires writing 0x00010001 (ie masked high 16 bits specify which low 16 bit values can change) to the FORCEWAKE registers
then you poll on the ACK register bit 0=1. This brings the GT domain online as it's offline after reset - what you're left with from UEFI/GOP etc.
You MUST read the FORCEWAKE register back immediately after writing it so it posts.