freedreno: Decode a650+ CP_START_BIN/CP_END_BIN packets

The blob uses them for GMEM renderpasses.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12184>
This commit is contained in:
Connor Abbott 2021-08-03 15:34:56 +02:00 committed by Marge Bot
parent 726fdf3385
commit d9c90eee8b
4 changed files with 81 additions and 5 deletions

View File

@ -213,8 +213,8 @@ CP_SET_DRAW_INIT_FLAGS:
CP_SCRATCH_TO_REG:
CP_DRAW_PRED_SET:
CP_MEM_WRITE_CNTR:
UNKN80:
CP_SET_BIN_SELECT:
CP_START_BIN:
CP_END_BIN:
CP_WAIT_REG_EQ:
CP_SMMU_TABLE_UPDATE:
UNKN84:

View File

@ -274,8 +274,8 @@ CP_SET_DRAW_INIT_FLAGS:
CP_SCRATCH_TO_REG:
CP_DRAW_PRED_SET:
CP_MEM_WRITE_CNTR:
UNKN80:
CP_SET_BIN_SELECT:
CP_START_BIN:
CP_END_BIN:
CP_WAIT_REG_EQ:
CP_SMMU_TABLE_UPDATE:
UNKN84:

View File

@ -2189,6 +2189,50 @@ cp_indirect(uint32_t *dwords, uint32_t sizedwords, int level)
}
}
static void
cp_start_bin(uint32_t *dwords, uint32_t sizedwords, int level)
{
uint64_t ibaddr;
uint32_t ibsize;
uint32_t loopcount;
uint32_t *ptr = NULL;
loopcount = dwords[0];
ibaddr = dwords[1];
ibaddr |= ((uint64_t)dwords[2]) << 32;
ibsize = dwords[3];
/* map gpuaddr back to hostptr: */
ptr = hostptr(ibaddr);
if (ptr) {
/* If the GPU hung within the target IB, the trigger point will be
* just after the current CP_START_BIN. Because the IB is
* executed but never returns. Account for this by checking if
* the IB returned:
*/
highlight_gpuaddr(gpuaddr(&dwords[5]));
/* TODO: we should duplicate the body of the loop after each bin, so
* that draws get the correct state. We should also figure out if there
* are any registers that can tell us what bin we're in when we hang so
* that crashdec points to the right place.
*/
ib++;
for (uint32_t i = 0; i < loopcount; i++) {
ibs[ib].base = ibaddr;
ibs[ib].size = ibsize;
printf("%sbin %u\n", levels[level], i);
dump_commands(ptr, ibsize, level);
ibaddr += ibsize;
ptr += ibsize;
}
ib--;
} else {
fprintf(stderr, "could not find: %016" PRIx64 " (%d)\n", ibaddr, ibsize);
}
}
static void
cp_wfi(uint32_t *dwords, uint32_t sizedwords, int level)
{
@ -2646,6 +2690,8 @@ static const struct type3_op {
CP(REG_WRITE, cp_reg_write),
CP(SET_CTXSWITCH_IB, cp_set_ctxswitch_ib),
CP(START_BIN, cp_start_bin),
};
static void

View File

@ -240,7 +240,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
<doc>sets the 64-bit BIN_MASK register in the PFP</doc>
<value name="CP_SET_BIN_MASK" value="0x50" varset="chip" variants="A2XX-A4XX"/>
<doc>sets the 64-bit BIN_SELECT register in the PFP</doc>
<value name="CP_SET_BIN_SELECT" value="0x51"/>
<value name="CP_SET_BIN_SELECT" value="0x51" varset="chip" variants="A2XX-A4XX"/>
<doc>updates the current context, if needed</doc>
<value name="CP_CONTEXT_UPDATE" value="0x5e"/>
<doc>generate interrupt from the command stream</doc>
@ -478,6 +478,20 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
-->
<value name="CP_REG_WRITE" value="0x6d" varset="chip" variants="A6XX"/>
<doc>
These first appear in a650_sqe.bin. They can in theory be used
to loop any sequence of IB1 commands, but in practice they are
used to loop over bins. There is a fixed-size per-iteration
prefix, used to set per-bin state, and then the following IB1
commands are executed until CP_END_BIN which are always the same
for each iteration and usually contain a list of
CP_INDIRECT_BUFFER calls to IB2 commands which setup state and
execute restore/draw/save commands. This replaces the previous
technique of just repeating the CP_INDIRECT_BUFFER calls and
"unrolling" the loop.
</doc>
<value name="CP_START_BIN" value="0x50" varset="chip" variants="A6XX"/>
<value name="CP_END_BIN" value="0x51" varset="chip" variants="A6XX"/>
</enum>
@ -1758,5 +1772,21 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords)
</reg32>
</domain>
<domain name="CP_START_BIN" width="32">
<reg32 offset="0" name="BIN_COUNT" type="uint"/>
<reg64 offset="1" name="PREFIX_ADDR" type="address"/>
<reg32 offset="3" name="PREFIX_DWORDS">
<doc>
Size of prefix for each bin. For each bin index i, the
prefix commands at PREFIX_ADDR + i * PREFIX_DWORDS are
executed in an IB2 before the IB1 commands following
this packet.
</doc>
</reg32>
<reg32 offset="4" name="BODY_DWORDS">
<doc>Number of dwords after this packet until CP_END_BIN</doc>
</reg32>
</domain>
</database>