• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2019 Google, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #ifndef FD6_PACK_H
25 #define FD6_PACK_H
26 
27 #include "a6xx.xml.h"
28 
29 struct fd_reg_pair {
30    uint32_t reg;
31    uint64_t value;
32    struct fd_bo *bo;
33    bool is_address;
34    bool bo_write;
35    uint32_t bo_offset;
36    uint32_t bo_shift;
37 };
38 
39 #define __bo_type struct fd_bo *
40 
41 #include "a6xx-pack.xml.h"
42 #include "adreno-pm4-pack.xml.h"
43 
44 #define __assert_eq(a, b)                                                      \
45    do {                                                                        \
46       if ((a) != (b)) {                                                        \
47          fprintf(stderr, "assert failed: " #a " (0x%x) != " #b " (0x%x)\n", a, \
48                  b);                                                           \
49          assert((a) == (b));                                                   \
50       }                                                                        \
51    } while (0)
52 
53 #define __ONE_REG(i, ...)                                                      \
54    do {                                                                        \
55       const struct fd_reg_pair regs[] = {__VA_ARGS__};                         \
56       /* NOTE: allow regs[0].reg==0, this happens in OUT_PKT() */              \
57       if (i < ARRAY_SIZE(regs) && (i == 0 || regs[i].reg > 0)) {               \
58          __assert_eq(regs[0].reg + i, regs[i].reg);                            \
59          if (regs[i].bo) {                                                     \
60             ring->cur = p;                                                     \
61             p += 2;                                                            \
62             OUT_RELOC(ring, regs[i].bo, regs[i].bo_offset, regs[i].value,      \
63                       regs[i].bo_shift);                                       \
64          } else {                                                              \
65             *p++ = regs[i].value;                                              \
66             if (regs[i].is_address)                                            \
67                *p++ = regs[i].value >> 32;                                     \
68          }                                                                     \
69       }                                                                        \
70    } while (0)
71 
72 #define OUT_REG(ring, ...)                                                     \
73    do {                                                                        \
74       const struct fd_reg_pair regs[] = {__VA_ARGS__};                         \
75       unsigned count = ARRAY_SIZE(regs);                                       \
76                                                                                \
77       STATIC_ASSERT(ARRAY_SIZE(regs) > 0);                                     \
78       STATIC_ASSERT(ARRAY_SIZE(regs) <= 16);                                   \
79                                                                                \
80       BEGIN_RING(ring, count + 1);                                             \
81       uint32_t *p = ring->cur;                                                 \
82       *p++ = pm4_pkt4_hdr(regs[0].reg, count);                                 \
83                                                                                \
84       __ONE_REG(0, __VA_ARGS__);                                               \
85       __ONE_REG(1, __VA_ARGS__);                                               \
86       __ONE_REG(2, __VA_ARGS__);                                               \
87       __ONE_REG(3, __VA_ARGS__);                                               \
88       __ONE_REG(4, __VA_ARGS__);                                               \
89       __ONE_REG(5, __VA_ARGS__);                                               \
90       __ONE_REG(6, __VA_ARGS__);                                               \
91       __ONE_REG(7, __VA_ARGS__);                                               \
92       __ONE_REG(8, __VA_ARGS__);                                               \
93       __ONE_REG(9, __VA_ARGS__);                                               \
94       __ONE_REG(10, __VA_ARGS__);                                              \
95       __ONE_REG(11, __VA_ARGS__);                                              \
96       __ONE_REG(12, __VA_ARGS__);                                              \
97       __ONE_REG(13, __VA_ARGS__);                                              \
98       __ONE_REG(14, __VA_ARGS__);                                              \
99       __ONE_REG(15, __VA_ARGS__);                                              \
100       ring->cur = p;                                                           \
101    } while (0)
102 
103 #define OUT_PKT(ring, opcode, ...)                                             \
104    do {                                                                        \
105       const struct fd_reg_pair regs[] = {__VA_ARGS__};                         \
106       unsigned count = ARRAY_SIZE(regs);                                       \
107                                                                                \
108       STATIC_ASSERT(ARRAY_SIZE(regs) <= 16);                                   \
109                                                                                \
110       BEGIN_RING(ring, count + 1);                                             \
111       uint32_t *p = ring->cur;                                                 \
112       *p++ = pm4_pkt7_hdr(opcode, count);                                      \
113                                                                                \
114       __ONE_REG(0, __VA_ARGS__);                                               \
115       __ONE_REG(1, __VA_ARGS__);                                               \
116       __ONE_REG(2, __VA_ARGS__);                                               \
117       __ONE_REG(3, __VA_ARGS__);                                               \
118       __ONE_REG(4, __VA_ARGS__);                                               \
119       __ONE_REG(5, __VA_ARGS__);                                               \
120       __ONE_REG(6, __VA_ARGS__);                                               \
121       __ONE_REG(7, __VA_ARGS__);                                               \
122       __ONE_REG(8, __VA_ARGS__);                                               \
123       __ONE_REG(9, __VA_ARGS__);                                               \
124       __ONE_REG(10, __VA_ARGS__);                                              \
125       __ONE_REG(11, __VA_ARGS__);                                              \
126       __ONE_REG(12, __VA_ARGS__);                                              \
127       __ONE_REG(13, __VA_ARGS__);                                              \
128       __ONE_REG(14, __VA_ARGS__);                                              \
129       __ONE_REG(15, __VA_ARGS__);                                              \
130       ring->cur = p;                                                           \
131    } while (0)
132 
133 /* similar to OUT_PKT() but appends specified # of dwords
134  * copied for buf to the end of the packet (ie. for use-
135  * cases like CP_LOAD_STATE)
136  */
137 #define OUT_PKTBUF(ring, opcode, dwords, sizedwords, ...)                      \
138    do {                                                                        \
139       const struct fd_reg_pair regs[] = {__VA_ARGS__};                         \
140       unsigned count = ARRAY_SIZE(regs);                                       \
141                                                                                \
142       STATIC_ASSERT(ARRAY_SIZE(regs) <= 16);                                   \
143       count += sizedwords;                                                     \
144                                                                                \
145       BEGIN_RING(ring, count + 1);                                             \
146       uint32_t *p = ring->cur;                                                 \
147       *p++ = pm4_pkt7_hdr(opcode, count);                                      \
148                                                                                \
149       __ONE_REG(0, __VA_ARGS__);                                               \
150       __ONE_REG(1, __VA_ARGS__);                                               \
151       __ONE_REG(2, __VA_ARGS__);                                               \
152       __ONE_REG(3, __VA_ARGS__);                                               \
153       __ONE_REG(4, __VA_ARGS__);                                               \
154       __ONE_REG(5, __VA_ARGS__);                                               \
155       __ONE_REG(6, __VA_ARGS__);                                               \
156       __ONE_REG(7, __VA_ARGS__);                                               \
157       __ONE_REG(8, __VA_ARGS__);                                               \
158       __ONE_REG(9, __VA_ARGS__);                                               \
159       __ONE_REG(10, __VA_ARGS__);                                              \
160       __ONE_REG(11, __VA_ARGS__);                                              \
161       __ONE_REG(12, __VA_ARGS__);                                              \
162       __ONE_REG(13, __VA_ARGS__);                                              \
163       __ONE_REG(14, __VA_ARGS__);                                              \
164       __ONE_REG(15, __VA_ARGS__);                                              \
165       memcpy(p, dwords, 4 * sizedwords);                                       \
166       p += sizedwords;                                                         \
167       ring->cur = p;                                                           \
168    } while (0)
169 
170 #endif /* FD6_PACK_H */
171