diff --git a/src/freedreno/registers/adreno_pm4.xml b/src/freedreno/registers/adreno_pm4.xml
index 3735b59992d..fb2d8f4f639 100644
--- a/src/freedreno/registers/adreno_pm4.xml
+++ b/src/freedreno/registers/adreno_pm4.xml
@@ -623,6 +623,7 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords)
+
@@ -705,13 +706,14 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords)
+
-
+
@@ -721,13 +723,19 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords)
-
-
-
+
+
+
+
+
+
+
+
+
@@ -752,6 +760,7 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords)
+
@@ -762,6 +771,7 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords)
+
diff --git a/src/freedreno/registers/meson.build b/src/freedreno/registers/meson.build
index 33a9fce3202..26335ce608d 100644
--- a/src/freedreno/registers/meson.build
+++ b/src/freedreno/registers/meson.build
@@ -47,3 +47,10 @@ freedreno_xml_header_files += custom_target(
command : [prog_python, '@INPUT@', '--pack-structs'],
capture : true,
)
+freedreno_xml_header_files += custom_target(
+ 'adreno-pm4-pack.xml.h',
+ input : ['gen_header.py', 'adreno_pm4.xml'],
+ output : 'adreno-pm4-pack.xml.h',
+ command : [prog_python, '@INPUT@', '--pack-structs'],
+ capture : true,
+ )
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_pack.h b/src/gallium/drivers/freedreno/a6xx/fd6_pack.h
index b3b9bf9244d..f9063122bfc 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_pack.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_pack.h
@@ -39,6 +39,7 @@ struct fd_reg_pair {
#define __bo_type struct fd_bo *
#include "a6xx-pack.xml.h"
+#include "adreno-pm4-pack.xml.h"
#define __assert_eq(a, b) \
do { \
@@ -51,7 +52,8 @@ struct fd_reg_pair {
#define __ONE_REG(i, ...) \
do { \
const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
- if (i < ARRAY_SIZE(regs) && regs[i].reg > 0) { \
+ /* NOTE: allow regs[0].reg==0, this happens in OUT_PKT() */ \
+ if (i < ARRAY_SIZE(regs) && (i == 0 || regs[i].reg > 0)) { \
__assert_eq(regs[0].reg + i, regs[i].reg); \
if (regs[i].bo) { \
struct fd_reloc reloc = { \
@@ -109,4 +111,77 @@ struct fd_reg_pair {
ring->cur = p; \
} while (0)
+#define OUT_PKT(ring, opcode, ...) \
+ do { \
+ const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
+ unsigned count = ARRAY_SIZE(regs); \
+ \
+ STATIC_ASSERT(count <= 16); \
+ \
+ BEGIN_RING(ring, count + 1); \
+ uint32_t *p = ring->cur; \
+ *p++ = CP_TYPE7_PKT | count | \
+ (_odd_parity_bit(count) << 15) | \
+ ((opcode & 0x7f) << 16) | \
+ ((_odd_parity_bit(opcode) << 23)); \
+ \
+ __ONE_REG( 0, __VA_ARGS__); \
+ __ONE_REG( 1, __VA_ARGS__); \
+ __ONE_REG( 2, __VA_ARGS__); \
+ __ONE_REG( 3, __VA_ARGS__); \
+ __ONE_REG( 4, __VA_ARGS__); \
+ __ONE_REG( 5, __VA_ARGS__); \
+ __ONE_REG( 6, __VA_ARGS__); \
+ __ONE_REG( 7, __VA_ARGS__); \
+ __ONE_REG( 8, __VA_ARGS__); \
+ __ONE_REG( 9, __VA_ARGS__); \
+ __ONE_REG(10, __VA_ARGS__); \
+ __ONE_REG(11, __VA_ARGS__); \
+ __ONE_REG(12, __VA_ARGS__); \
+ __ONE_REG(13, __VA_ARGS__); \
+ __ONE_REG(14, __VA_ARGS__); \
+ __ONE_REG(15, __VA_ARGS__); \
+ ring->cur = p; \
+ } while (0)
+
+/* similar to OUT_PKT() but appends specified # of dwords
+ * copied for buf to the end of the packet (ie. for use-
+ * cases like CP_LOAD_STATE)
+ */
+#define OUT_PKTBUF(ring, opcode, dwords, sizedwords, ...) \
+ do { \
+ const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
+ unsigned count = ARRAY_SIZE(regs); \
+ \
+ STATIC_ASSERT(count <= 16); \
+ count += sizedwords; \
+ \
+ BEGIN_RING(ring, count + 1); \
+ uint32_t *p = ring->cur; \
+ *p++ = CP_TYPE7_PKT | count | \
+ (_odd_parity_bit(count) << 15) | \
+ ((opcode & 0x7f) << 16) | \
+ ((_odd_parity_bit(opcode) << 23)); \
+ \
+ __ONE_REG( 0, __VA_ARGS__); \
+ __ONE_REG( 1, __VA_ARGS__); \
+ __ONE_REG( 2, __VA_ARGS__); \
+ __ONE_REG( 3, __VA_ARGS__); \
+ __ONE_REG( 4, __VA_ARGS__); \
+ __ONE_REG( 5, __VA_ARGS__); \
+ __ONE_REG( 6, __VA_ARGS__); \
+ __ONE_REG( 7, __VA_ARGS__); \
+ __ONE_REG( 8, __VA_ARGS__); \
+ __ONE_REG( 9, __VA_ARGS__); \
+ __ONE_REG(10, __VA_ARGS__); \
+ __ONE_REG(11, __VA_ARGS__); \
+ __ONE_REG(12, __VA_ARGS__); \
+ __ONE_REG(13, __VA_ARGS__); \
+ __ONE_REG(14, __VA_ARGS__); \
+ __ONE_REG(15, __VA_ARGS__); \
+ memcpy(p, dwords, 4 * sizedwords); \
+ p += sizedwords; \
+ ring->cur = p; \
+ } while (0)
+
#endif /* FD6_PACK_H */