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