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:
parent
726fdf3385
commit
d9c90eee8b
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue