1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2019 Google, Inc.
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #ifndef FD6_PACK_H
7*61046927SAndroid Build Coastguard Worker #define FD6_PACK_H
8*61046927SAndroid Build Coastguard Worker
9*61046927SAndroid Build Coastguard Worker #include "a6xx.xml.h"
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker struct fd_reg_pair {
12*61046927SAndroid Build Coastguard Worker uint32_t reg;
13*61046927SAndroid Build Coastguard Worker uint64_t value;
14*61046927SAndroid Build Coastguard Worker struct fd_bo *bo;
15*61046927SAndroid Build Coastguard Worker bool is_address;
16*61046927SAndroid Build Coastguard Worker bool bo_write;
17*61046927SAndroid Build Coastguard Worker uint32_t bo_offset;
18*61046927SAndroid Build Coastguard Worker uint32_t bo_shift;
19*61046927SAndroid Build Coastguard Worker uint32_t bo_low;
20*61046927SAndroid Build Coastguard Worker };
21*61046927SAndroid Build Coastguard Worker
22*61046927SAndroid Build Coastguard Worker #define __bo_type struct fd_bo *
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "a6xx-pack.xml.h"
25*61046927SAndroid Build Coastguard Worker #include "adreno-pm4-pack.xml.h"
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker #define __assert_eq(a, b) \
28*61046927SAndroid Build Coastguard Worker do { \
29*61046927SAndroid Build Coastguard Worker if ((a) != (b)) { \
30*61046927SAndroid Build Coastguard Worker fprintf(stderr, "assert failed: " #a " (0x%x) != " #b " (0x%x)\n", a, \
31*61046927SAndroid Build Coastguard Worker b); \
32*61046927SAndroid Build Coastguard Worker assert((a) == (b)); \
33*61046927SAndroid Build Coastguard Worker } \
34*61046927SAndroid Build Coastguard Worker } while (0)
35*61046927SAndroid Build Coastguard Worker
36*61046927SAndroid Build Coastguard Worker #if !FD_BO_NO_HARDPIN
37*61046927SAndroid Build Coastguard Worker # error 'Hardpin unsupported'
38*61046927SAndroid Build Coastguard Worker #endif
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker static inline uint64_t
__reg_iova(const struct fd_reg_pair * reg)41*61046927SAndroid Build Coastguard Worker __reg_iova(const struct fd_reg_pair *reg)
42*61046927SAndroid Build Coastguard Worker {
43*61046927SAndroid Build Coastguard Worker uint64_t iova = __reloc_iova((struct fd_bo *)reg->bo,
44*61046927SAndroid Build Coastguard Worker reg->bo_offset, 0,
45*61046927SAndroid Build Coastguard Worker -reg->bo_shift);
46*61046927SAndroid Build Coastguard Worker return iova << reg->bo_low;
47*61046927SAndroid Build Coastguard Worker }
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker #define __ONE_REG(ring, i, ...) \
50*61046927SAndroid Build Coastguard Worker do { \
51*61046927SAndroid Build Coastguard Worker const struct fd_reg_pair __regs[] = {__VA_ARGS__}; \
52*61046927SAndroid Build Coastguard Worker /* NOTE: allow __regs[0].reg==0, this happens in OUT_PKT() */ \
53*61046927SAndroid Build Coastguard Worker if (i < ARRAY_SIZE(__regs) && (i == 0 || __regs[i].reg > 0)) { \
54*61046927SAndroid Build Coastguard Worker __assert_eq(__regs[0].reg + i, __regs[i].reg); \
55*61046927SAndroid Build Coastguard Worker if (__regs[i].bo) { \
56*61046927SAndroid Build Coastguard Worker uint64_t *__p64 = (uint64_t *)__p; \
57*61046927SAndroid Build Coastguard Worker *__p64 = __reg_iova(&__regs[i]) | __regs[i].value; \
58*61046927SAndroid Build Coastguard Worker __p += 2; \
59*61046927SAndroid Build Coastguard Worker fd_ringbuffer_assert_attached(ring, __regs[i].bo); \
60*61046927SAndroid Build Coastguard Worker } else { \
61*61046927SAndroid Build Coastguard Worker *__p++ = __regs[i].value; \
62*61046927SAndroid Build Coastguard Worker if (__regs[i].is_address) \
63*61046927SAndroid Build Coastguard Worker *__p++ = __regs[i].value >> 32; \
64*61046927SAndroid Build Coastguard Worker } \
65*61046927SAndroid Build Coastguard Worker } \
66*61046927SAndroid Build Coastguard Worker } while (0)
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker #define OUT_REG(ring, ...) \
69*61046927SAndroid Build Coastguard Worker do { \
70*61046927SAndroid Build Coastguard Worker const struct fd_reg_pair __regs[] = {__VA_ARGS__}; \
71*61046927SAndroid Build Coastguard Worker unsigned count = ARRAY_SIZE(__regs); \
72*61046927SAndroid Build Coastguard Worker \
73*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(__regs) > 0); \
74*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(__regs) <= 16); \
75*61046927SAndroid Build Coastguard Worker \
76*61046927SAndroid Build Coastguard Worker BEGIN_RING(ring, count + 1); \
77*61046927SAndroid Build Coastguard Worker uint32_t *__p = ring->cur; \
78*61046927SAndroid Build Coastguard Worker *__p++ = pm4_pkt4_hdr((uint16_t)__regs[0].reg, (uint16_t)count); \
79*61046927SAndroid Build Coastguard Worker \
80*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 0, __VA_ARGS__); \
81*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 1, __VA_ARGS__); \
82*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 2, __VA_ARGS__); \
83*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 3, __VA_ARGS__); \
84*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 4, __VA_ARGS__); \
85*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 5, __VA_ARGS__); \
86*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 6, __VA_ARGS__); \
87*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 7, __VA_ARGS__); \
88*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 8, __VA_ARGS__); \
89*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 9, __VA_ARGS__); \
90*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 10, __VA_ARGS__); \
91*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 11, __VA_ARGS__); \
92*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 12, __VA_ARGS__); \
93*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 13, __VA_ARGS__); \
94*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 14, __VA_ARGS__); \
95*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 15, __VA_ARGS__); \
96*61046927SAndroid Build Coastguard Worker ring->cur = __p; \
97*61046927SAndroid Build Coastguard Worker } while (0)
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker #define OUT_PKT(ring, opcode, ...) \
100*61046927SAndroid Build Coastguard Worker do { \
101*61046927SAndroid Build Coastguard Worker const struct fd_reg_pair __regs[] = {__VA_ARGS__}; \
102*61046927SAndroid Build Coastguard Worker unsigned count = ARRAY_SIZE(__regs); \
103*61046927SAndroid Build Coastguard Worker \
104*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(__regs) <= 16); \
105*61046927SAndroid Build Coastguard Worker \
106*61046927SAndroid Build Coastguard Worker BEGIN_RING(ring, count + 1); \
107*61046927SAndroid Build Coastguard Worker uint32_t *__p = ring->cur; \
108*61046927SAndroid Build Coastguard Worker *__p++ = pm4_pkt7_hdr(opcode, count); \
109*61046927SAndroid Build Coastguard Worker \
110*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 0, __VA_ARGS__); \
111*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 1, __VA_ARGS__); \
112*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 2, __VA_ARGS__); \
113*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 3, __VA_ARGS__); \
114*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 4, __VA_ARGS__); \
115*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 5, __VA_ARGS__); \
116*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 6, __VA_ARGS__); \
117*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 7, __VA_ARGS__); \
118*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 8, __VA_ARGS__); \
119*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 9, __VA_ARGS__); \
120*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 10, __VA_ARGS__); \
121*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 11, __VA_ARGS__); \
122*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 12, __VA_ARGS__); \
123*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 13, __VA_ARGS__); \
124*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 14, __VA_ARGS__); \
125*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 15, __VA_ARGS__); \
126*61046927SAndroid Build Coastguard Worker ring->cur = __p; \
127*61046927SAndroid Build Coastguard Worker } while (0)
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker /* similar to OUT_PKT() but appends specified # of dwords
130*61046927SAndroid Build Coastguard Worker * copied for buf to the end of the packet (ie. for use-
131*61046927SAndroid Build Coastguard Worker * cases like CP_LOAD_STATE)
132*61046927SAndroid Build Coastguard Worker */
133*61046927SAndroid Build Coastguard Worker #define OUT_PKTBUF(ring, opcode, dwords, sizedwords, ...) \
134*61046927SAndroid Build Coastguard Worker do { \
135*61046927SAndroid Build Coastguard Worker const struct fd_reg_pair __regs[] = {__VA_ARGS__}; \
136*61046927SAndroid Build Coastguard Worker unsigned count = ARRAY_SIZE(__regs); \
137*61046927SAndroid Build Coastguard Worker \
138*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(__regs) <= 16); \
139*61046927SAndroid Build Coastguard Worker count += sizedwords; \
140*61046927SAndroid Build Coastguard Worker \
141*61046927SAndroid Build Coastguard Worker BEGIN_RING(ring, count + 1); \
142*61046927SAndroid Build Coastguard Worker uint32_t *__p = ring->cur; \
143*61046927SAndroid Build Coastguard Worker *__p++ = pm4_pkt7_hdr(opcode, count); \
144*61046927SAndroid Build Coastguard Worker \
145*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 0, __VA_ARGS__); \
146*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 1, __VA_ARGS__); \
147*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 2, __VA_ARGS__); \
148*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 3, __VA_ARGS__); \
149*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 4, __VA_ARGS__); \
150*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 5, __VA_ARGS__); \
151*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 6, __VA_ARGS__); \
152*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 7, __VA_ARGS__); \
153*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 8, __VA_ARGS__); \
154*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 9, __VA_ARGS__); \
155*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 10, __VA_ARGS__); \
156*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 11, __VA_ARGS__); \
157*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 12, __VA_ARGS__); \
158*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 13, __VA_ARGS__); \
159*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 14, __VA_ARGS__); \
160*61046927SAndroid Build Coastguard Worker __ONE_REG(ring, 15, __VA_ARGS__); \
161*61046927SAndroid Build Coastguard Worker memcpy(__p, dwords, 4 * sizedwords); \
162*61046927SAndroid Build Coastguard Worker __p += sizedwords; \
163*61046927SAndroid Build Coastguard Worker ring->cur = __p; \
164*61046927SAndroid Build Coastguard Worker } while (0)
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker #define OUT_BUF(ring, dwords, sizedwords) \
167*61046927SAndroid Build Coastguard Worker do { \
168*61046927SAndroid Build Coastguard Worker uint32_t *__p = ring->cur; \
169*61046927SAndroid Build Coastguard Worker memcpy(__p, dwords, 4 * sizedwords); \
170*61046927SAndroid Build Coastguard Worker __p += sizedwords; \
171*61046927SAndroid Build Coastguard Worker ring->cur = __p; \
172*61046927SAndroid Build Coastguard Worker } while (0)
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker #endif /* FD6_PACK_H */
175