1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2021 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 #include "util/macros.h"
7*61046927SAndroid Build Coastguard Worker #include "crashdec.h"
8*61046927SAndroid Build Coastguard Worker
9*61046927SAndroid Build Coastguard Worker static const char *hfi_msg_name(unsigned msgid);
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker /*
12*61046927SAndroid Build Coastguard Worker * Decode HFI queues
13*61046927SAndroid Build Coastguard Worker */
14*61046927SAndroid Build Coastguard Worker
15*61046927SAndroid Build Coastguard Worker /* HFI message types */
16*61046927SAndroid Build Coastguard Worker
17*61046927SAndroid Build Coastguard Worker #define HFI_MSG_CMD 0
18*61046927SAndroid Build Coastguard Worker #define HFI_MSG_ACK 1
19*61046927SAndroid Build Coastguard Worker #define HFI_MSG_ACK_V1 2
20*61046927SAndroid Build Coastguard Worker
21*61046927SAndroid Build Coastguard Worker #define HFI_HEADER_ID(msg) ((msg) & 0xff)
22*61046927SAndroid Build Coastguard Worker /* Note that header size includes the header itself: */
23*61046927SAndroid Build Coastguard Worker #define HFI_HEADER_SIZE(msg) (((msg) >> 8) & 0xff)
24*61046927SAndroid Build Coastguard Worker #define HFI_HEADER_TYPE(msg) (((msg) >> 16) & 0xf)
25*61046927SAndroid Build Coastguard Worker #define HFI_HEADER_SEQNUM(msg) (((msg) >> 20) & 0xfff)
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_header {
28*61046927SAndroid Build Coastguard Worker uint32_t status;
29*61046927SAndroid Build Coastguard Worker uint32_t iova;
30*61046927SAndroid Build Coastguard Worker uint32_t type;
31*61046927SAndroid Build Coastguard Worker uint32_t size;
32*61046927SAndroid Build Coastguard Worker uint32_t msg_size;
33*61046927SAndroid Build Coastguard Worker uint32_t dropped;
34*61046927SAndroid Build Coastguard Worker uint32_t rx_watermark;
35*61046927SAndroid Build Coastguard Worker uint32_t tx_watermark;
36*61046927SAndroid Build Coastguard Worker uint32_t rx_request;
37*61046927SAndroid Build Coastguard Worker uint32_t tx_request;
38*61046927SAndroid Build Coastguard Worker uint32_t read_index;
39*61046927SAndroid Build Coastguard Worker uint32_t write_index;
40*61046927SAndroid Build Coastguard Worker };
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_table_header {
43*61046927SAndroid Build Coastguard Worker uint32_t version;
44*61046927SAndroid Build Coastguard Worker uint32_t size; /* Size of the queue table in dwords */
45*61046927SAndroid Build Coastguard Worker uint32_t qhdr0_offset; /* Offset of the first queue header */
46*61046927SAndroid Build Coastguard Worker uint32_t qhdr_size; /* Size of the queue headers */
47*61046927SAndroid Build Coastguard Worker uint32_t num_queues; /* Number of total queues */
48*61046927SAndroid Build Coastguard Worker uint32_t active_queues; /* Number of active queues */
49*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_header queue[];
50*61046927SAndroid Build Coastguard Worker };
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker /*
53*61046927SAndroid Build Coastguard Worker * HFI message definitions:
54*61046927SAndroid Build Coastguard Worker */
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker #define HFI_F2H_MSG_ACK 126
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_response {
59*61046927SAndroid Build Coastguard Worker uint32_t header;
60*61046927SAndroid Build Coastguard Worker uint32_t ret_header;
61*61046927SAndroid Build Coastguard Worker uint32_t error;
62*61046927SAndroid Build Coastguard Worker uint32_t payload[16];
63*61046927SAndroid Build Coastguard Worker };
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker static void
decode_F2H_MSG_ACK(struct a6xx_hfi_msg_response * msg)66*61046927SAndroid Build Coastguard Worker decode_F2H_MSG_ACK(struct a6xx_hfi_msg_response *msg)
67*61046927SAndroid Build Coastguard Worker {
68*61046927SAndroid Build Coastguard Worker unsigned msgid = HFI_HEADER_ID(msg->ret_header);
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tret_header: %s (id=%u, size=%u, type=%u, seqnum=%u)\n",
71*61046927SAndroid Build Coastguard Worker hfi_msg_name(msgid), msgid, HFI_HEADER_SIZE(msg->ret_header),
72*61046927SAndroid Build Coastguard Worker HFI_HEADER_TYPE(msg->ret_header), HFI_HEADER_SEQNUM(msg->ret_header));
73*61046927SAndroid Build Coastguard Worker printf("\t\t\t\terror: %u\n", msg->error);
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker #define HFI_F2H_MSG_ERROR 100
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_error {
79*61046927SAndroid Build Coastguard Worker uint32_t header;
80*61046927SAndroid Build Coastguard Worker uint32_t code;
81*61046927SAndroid Build Coastguard Worker uint32_t payload[2];
82*61046927SAndroid Build Coastguard Worker };
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker static void
decode_F2H_MSG_ERROR(struct a6xx_hfi_msg_error * msg)85*61046927SAndroid Build Coastguard Worker decode_F2H_MSG_ERROR(struct a6xx_hfi_msg_error *msg)
86*61046927SAndroid Build Coastguard Worker {
87*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tcode: %u\n", msg->code);
88*61046927SAndroid Build Coastguard Worker }
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_INIT 0
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_gmu_init_cmd {
93*61046927SAndroid Build Coastguard Worker uint32_t header;
94*61046927SAndroid Build Coastguard Worker uint32_t seg_id;
95*61046927SAndroid Build Coastguard Worker uint32_t dbg_buffer_addr;
96*61046927SAndroid Build Coastguard Worker uint32_t dbg_buffer_size;
97*61046927SAndroid Build Coastguard Worker uint32_t boot_state;
98*61046927SAndroid Build Coastguard Worker };
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_INIT(struct a6xx_hfi_msg_gmu_init_cmd * msg)101*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_INIT(struct a6xx_hfi_msg_gmu_init_cmd *msg)
102*61046927SAndroid Build Coastguard Worker {
103*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tseg_id: %u\n", msg->seg_id);
104*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tdbg_buffer_addr: 0x%08x\n", msg->dbg_buffer_addr);
105*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tdbg_buffer_size: %u\n", msg->dbg_buffer_size);
106*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tboot_state: %u\n", msg->boot_state);
107*61046927SAndroid Build Coastguard Worker }
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_FW_VERSION 1
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_fw_version {
112*61046927SAndroid Build Coastguard Worker uint32_t header;
113*61046927SAndroid Build Coastguard Worker uint32_t supported_version;
114*61046927SAndroid Build Coastguard Worker };
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_FW_VERSION(struct a6xx_hfi_msg_fw_version * msg)117*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_FW_VERSION(struct a6xx_hfi_msg_fw_version *msg)
118*61046927SAndroid Build Coastguard Worker {
119*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tsupported_version: 0x%x\n", msg->supported_version);
120*61046927SAndroid Build Coastguard Worker }
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_PERF_TABLE 4
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker struct perf_level {
125*61046927SAndroid Build Coastguard Worker uint32_t vote;
126*61046927SAndroid Build Coastguard Worker uint32_t freq;
127*61046927SAndroid Build Coastguard Worker };
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker struct perf_gx_level {
130*61046927SAndroid Build Coastguard Worker uint32_t vote;
131*61046927SAndroid Build Coastguard Worker uint32_t acd;
132*61046927SAndroid Build Coastguard Worker uint32_t freq;
133*61046927SAndroid Build Coastguard Worker };
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_perf_table_v1 {
136*61046927SAndroid Build Coastguard Worker uint32_t header;
137*61046927SAndroid Build Coastguard Worker uint32_t num_gpu_levels;
138*61046927SAndroid Build Coastguard Worker uint32_t num_gmu_levels;
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker struct perf_level gx_votes[16];
141*61046927SAndroid Build Coastguard Worker struct perf_level cx_votes[4];
142*61046927SAndroid Build Coastguard Worker };
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_perf_table {
145*61046927SAndroid Build Coastguard Worker uint32_t header;
146*61046927SAndroid Build Coastguard Worker uint32_t num_gpu_levels;
147*61046927SAndroid Build Coastguard Worker uint32_t num_gmu_levels;
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker struct perf_gx_level gx_votes[16];
150*61046927SAndroid Build Coastguard Worker struct perf_level cx_votes[4];
151*61046927SAndroid Build Coastguard Worker };
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_PERF_TABLE(void * _msg)154*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_PERF_TABLE(void *_msg)
155*61046927SAndroid Build Coastguard Worker {
156*61046927SAndroid Build Coastguard Worker if (is_gmu_legacy()) {
157*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_perf_table_v1 *msg = _msg;
158*61046927SAndroid Build Coastguard Worker unsigned i;
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tnum_gpu_levels: %u\n", msg->num_gpu_levels);
161*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tnum_gmu_levels: %u\n", msg->num_gmu_levels);
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker assert(msg->num_gpu_levels <= ARRAY_SIZE(msg->gx_votes));
164*61046927SAndroid Build Coastguard Worker for (i = 0; i < msg->num_gpu_levels; i++) {
165*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tgx_vote[%u]: vote=%u, freq=%u\n", i,
166*61046927SAndroid Build Coastguard Worker msg->gx_votes[i].vote, msg->gx_votes[i].freq);
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker for (; i < ARRAY_SIZE(msg->gx_votes); i++) {
170*61046927SAndroid Build Coastguard Worker assert(!msg->gx_votes[i].vote);
171*61046927SAndroid Build Coastguard Worker assert(!msg->gx_votes[i].freq);
172*61046927SAndroid Build Coastguard Worker }
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker assert(msg->num_gmu_levels <= ARRAY_SIZE(msg->cx_votes));
175*61046927SAndroid Build Coastguard Worker for (i = 0; i < msg->num_gmu_levels; i++) {
176*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tcx_vote[%u]: vote=%u, freq=%u\n", i,
177*61046927SAndroid Build Coastguard Worker msg->cx_votes[i].vote, msg->cx_votes[i].freq);
178*61046927SAndroid Build Coastguard Worker }
179*61046927SAndroid Build Coastguard Worker
180*61046927SAndroid Build Coastguard Worker for (; i < ARRAY_SIZE(msg->cx_votes); i++) {
181*61046927SAndroid Build Coastguard Worker assert(!msg->cx_votes[i].vote);
182*61046927SAndroid Build Coastguard Worker assert(!msg->cx_votes[i].freq);
183*61046927SAndroid Build Coastguard Worker }
184*61046927SAndroid Build Coastguard Worker } else {
185*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_perf_table *msg = _msg;
186*61046927SAndroid Build Coastguard Worker unsigned i;
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tnum_gpu_levels: %u\n", msg->num_gpu_levels);
189*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tnum_gmu_levels: %u\n", msg->num_gmu_levels);
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker assert(msg->num_gpu_levels <= ARRAY_SIZE(msg->gx_votes));
192*61046927SAndroid Build Coastguard Worker for (i = 0; i < msg->num_gpu_levels; i++) {
193*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tgx_vote[%u]: vote=%u, acd=%u, freq=%u\n", i,
194*61046927SAndroid Build Coastguard Worker msg->gx_votes[i].vote, msg->gx_votes[i].acd,
195*61046927SAndroid Build Coastguard Worker msg->gx_votes[i].freq);
196*61046927SAndroid Build Coastguard Worker }
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker for (; i < ARRAY_SIZE(msg->gx_votes); i++) {
199*61046927SAndroid Build Coastguard Worker assert(!msg->gx_votes[i].vote);
200*61046927SAndroid Build Coastguard Worker assert(!msg->gx_votes[i].acd);
201*61046927SAndroid Build Coastguard Worker assert(!msg->gx_votes[i].freq);
202*61046927SAndroid Build Coastguard Worker }
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker assert(msg->num_gmu_levels <= ARRAY_SIZE(msg->cx_votes));
205*61046927SAndroid Build Coastguard Worker for (i = 0; i < msg->num_gmu_levels; i++) {
206*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tcx_vote[%u]: vote=%u, freq=%u\n", i,
207*61046927SAndroid Build Coastguard Worker msg->cx_votes[i].vote, msg->cx_votes[i].freq);
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker
210*61046927SAndroid Build Coastguard Worker for (; i < ARRAY_SIZE(msg->cx_votes); i++) {
211*61046927SAndroid Build Coastguard Worker assert(!msg->cx_votes[i].vote);
212*61046927SAndroid Build Coastguard Worker assert(!msg->cx_votes[i].freq);
213*61046927SAndroid Build Coastguard Worker }
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker }
216*61046927SAndroid Build Coastguard Worker
217*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_BW_TABLE 3
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_bw_table {
220*61046927SAndroid Build Coastguard Worker uint32_t header;
221*61046927SAndroid Build Coastguard Worker uint32_t bw_level_num;
222*61046927SAndroid Build Coastguard Worker uint32_t cnoc_cmds_num;
223*61046927SAndroid Build Coastguard Worker uint32_t ddr_cmds_num;
224*61046927SAndroid Build Coastguard Worker uint32_t cnoc_wait_bitmask;
225*61046927SAndroid Build Coastguard Worker uint32_t ddr_wait_bitmask;
226*61046927SAndroid Build Coastguard Worker uint32_t cnoc_cmds_addrs[6];
227*61046927SAndroid Build Coastguard Worker uint32_t cnoc_cmds_data[2][6];
228*61046927SAndroid Build Coastguard Worker uint32_t ddr_cmds_addrs[8];
229*61046927SAndroid Build Coastguard Worker uint32_t ddr_cmds_data[16][8];
230*61046927SAndroid Build Coastguard Worker };
231*61046927SAndroid Build Coastguard Worker
232*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_BW_TABLE(struct a6xx_hfi_msg_bw_table * msg)233*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_BW_TABLE(struct a6xx_hfi_msg_bw_table *msg)
234*61046927SAndroid Build Coastguard Worker {
235*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tbw_level_num: %u\n", msg->bw_level_num);
236*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tcnoc_cmds_num: %u\n", msg->cnoc_cmds_num);
237*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tddr_cmds_num: %u\n", msg->ddr_cmds_num);
238*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tcnoc_wait_bitmask: 0x%x\n", msg->cnoc_wait_bitmask);
239*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tddr_wait_bitmask: 0x%x\n", msg->ddr_wait_bitmask);
240*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tcnoc_cmds_addrs: %08x %08x %08x %08x %08x %08x\n",
241*61046927SAndroid Build Coastguard Worker msg->cnoc_cmds_addrs[0], msg->cnoc_cmds_addrs[1], msg->cnoc_cmds_addrs[2],
242*61046927SAndroid Build Coastguard Worker msg->cnoc_cmds_addrs[3], msg->cnoc_cmds_addrs[4], msg->cnoc_cmds_addrs[5]);
243*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(msg->cnoc_cmds_data); i++) {
244*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tcnoc_cmds_data[%u]: %08x %08x %08x %08x %08x %08x\n", i,
245*61046927SAndroid Build Coastguard Worker msg->cnoc_cmds_data[i][0], msg->cnoc_cmds_data[i][1], msg->cnoc_cmds_data[i][2],
246*61046927SAndroid Build Coastguard Worker msg->cnoc_cmds_data[i][3], msg->cnoc_cmds_data[i][4], msg->cnoc_cmds_data[i][5]);
247*61046927SAndroid Build Coastguard Worker }
248*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tddr_cmds_addrs: %08x %08x %08x %08x %08x %08x %08x %08x\n",
249*61046927SAndroid Build Coastguard Worker msg->ddr_cmds_addrs[0], msg->ddr_cmds_addrs[1], msg->ddr_cmds_addrs[2],
250*61046927SAndroid Build Coastguard Worker msg->ddr_cmds_addrs[3], msg->ddr_cmds_addrs[4], msg->ddr_cmds_addrs[5],
251*61046927SAndroid Build Coastguard Worker msg->ddr_cmds_addrs[6], msg->ddr_cmds_addrs[7]);
252*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(msg->ddr_cmds_data); i++) {
253*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tddr_cmds_data[%u]: %08x %08x %08x %08x %08x %08x %08x %08x\n", i,
254*61046927SAndroid Build Coastguard Worker msg->ddr_cmds_data[i][0], msg->ddr_cmds_data[i][1], msg->ddr_cmds_data[i][2],
255*61046927SAndroid Build Coastguard Worker msg->ddr_cmds_data[i][3], msg->ddr_cmds_data[i][4], msg->ddr_cmds_data[i][5],
256*61046927SAndroid Build Coastguard Worker msg->ddr_cmds_data[i][6], msg->ddr_cmds_data[i][7]);
257*61046927SAndroid Build Coastguard Worker }
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_TEST 5
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_test {
263*61046927SAndroid Build Coastguard Worker uint32_t header;
264*61046927SAndroid Build Coastguard Worker };
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_TEST(struct a6xx_hfi_msg_test * msg)267*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_TEST(struct a6xx_hfi_msg_test *msg)
268*61046927SAndroid Build Coastguard Worker {
269*61046927SAndroid Build Coastguard Worker }
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_START 10
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_start {
274*61046927SAndroid Build Coastguard Worker uint32_t header;
275*61046927SAndroid Build Coastguard Worker };
276*61046927SAndroid Build Coastguard Worker
277*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_START(struct a6xx_hfi_msg_start * msg)278*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_START(struct a6xx_hfi_msg_start *msg)
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker }
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_CORE_FW_START 14
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_msg_core_fw_start {
285*61046927SAndroid Build Coastguard Worker uint32_t header;
286*61046927SAndroid Build Coastguard Worker uint32_t handle;
287*61046927SAndroid Build Coastguard Worker };
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_CORE_FW_START(struct a6xx_hfi_msg_core_fw_start * msg)290*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_CORE_FW_START(struct a6xx_hfi_msg_core_fw_start *msg)
291*61046927SAndroid Build Coastguard Worker {
292*61046927SAndroid Build Coastguard Worker printf("\t\t\t\thandle: %u\n", msg->handle);
293*61046927SAndroid Build Coastguard Worker }
294*61046927SAndroid Build Coastguard Worker
295*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_GX_BW_PERF_VOTE 30
296*61046927SAndroid Build Coastguard Worker
297*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_gx_bw_perf_vote_cmd {
298*61046927SAndroid Build Coastguard Worker uint32_t header;
299*61046927SAndroid Build Coastguard Worker uint32_t ack_type;
300*61046927SAndroid Build Coastguard Worker uint32_t freq;
301*61046927SAndroid Build Coastguard Worker uint32_t bw;
302*61046927SAndroid Build Coastguard Worker };
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_GX_BW_PERF_VOTE(struct a6xx_hfi_gx_bw_perf_vote_cmd * msg)305*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_GX_BW_PERF_VOTE(struct a6xx_hfi_gx_bw_perf_vote_cmd *msg)
306*61046927SAndroid Build Coastguard Worker {
307*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tack_type: %u\n", msg->ack_type);
308*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tfreq: %u\n", msg->freq);
309*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tbw: %u\n", msg->bw);
310*61046927SAndroid Build Coastguard Worker }
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker #define HFI_H2F_MSG_PREPARE_SLUMBER 33
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_prep_slumber_cmd {
315*61046927SAndroid Build Coastguard Worker uint32_t header;
316*61046927SAndroid Build Coastguard Worker uint32_t bw;
317*61046927SAndroid Build Coastguard Worker uint32_t freq;
318*61046927SAndroid Build Coastguard Worker };
319*61046927SAndroid Build Coastguard Worker
320*61046927SAndroid Build Coastguard Worker static void
decode_H2F_MSG_PREPARE_SLUMBER(struct a6xx_hfi_prep_slumber_cmd * msg)321*61046927SAndroid Build Coastguard Worker decode_H2F_MSG_PREPARE_SLUMBER(struct a6xx_hfi_prep_slumber_cmd *msg)
322*61046927SAndroid Build Coastguard Worker {
323*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tbw: %u\n", msg->bw);
324*61046927SAndroid Build Coastguard Worker printf("\t\t\t\tfreq: %u\n", msg->freq);
325*61046927SAndroid Build Coastguard Worker }
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker static struct {
328*61046927SAndroid Build Coastguard Worker const char *name;
329*61046927SAndroid Build Coastguard Worker void (*decode)(void *);
330*61046927SAndroid Build Coastguard Worker } hfi_msgs[] = {
331*61046927SAndroid Build Coastguard Worker #define HFI_MSG(name) [HFI_ ## name] = { #name, (void (*)(void *))decode_ ## name }
332*61046927SAndroid Build Coastguard Worker HFI_MSG(F2H_MSG_ACK),
333*61046927SAndroid Build Coastguard Worker HFI_MSG(F2H_MSG_ERROR),
334*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_INIT),
335*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_FW_VERSION),
336*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_PERF_TABLE),
337*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_BW_TABLE),
338*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_TEST),
339*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_START),
340*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_CORE_FW_START),
341*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_GX_BW_PERF_VOTE),
342*61046927SAndroid Build Coastguard Worker HFI_MSG(H2F_MSG_PREPARE_SLUMBER),
343*61046927SAndroid Build Coastguard Worker };
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker static bool
is_valid_msg_type(unsigned type)346*61046927SAndroid Build Coastguard Worker is_valid_msg_type(unsigned type)
347*61046927SAndroid Build Coastguard Worker {
348*61046927SAndroid Build Coastguard Worker switch (type) {
349*61046927SAndroid Build Coastguard Worker case HFI_MSG_CMD:
350*61046927SAndroid Build Coastguard Worker case HFI_MSG_ACK:
351*61046927SAndroid Build Coastguard Worker case HFI_MSG_ACK_V1:
352*61046927SAndroid Build Coastguard Worker return true;
353*61046927SAndroid Build Coastguard Worker default:
354*61046927SAndroid Build Coastguard Worker return false;
355*61046927SAndroid Build Coastguard Worker }
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker static const char *
hfi_msg_name(unsigned msgid)359*61046927SAndroid Build Coastguard Worker hfi_msg_name(unsigned msgid)
360*61046927SAndroid Build Coastguard Worker {
361*61046927SAndroid Build Coastguard Worker if (msgid < ARRAY_SIZE(hfi_msgs))
362*61046927SAndroid Build Coastguard Worker return hfi_msgs[msgid].name;
363*61046927SAndroid Build Coastguard Worker return NULL;
364*61046927SAndroid Build Coastguard Worker }
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker static bool
is_valid_decode_start(struct a6xx_hfi_state * hfi,unsigned qidx,int32_t read_index)367*61046927SAndroid Build Coastguard Worker is_valid_decode_start(struct a6xx_hfi_state *hfi, unsigned qidx, int32_t read_index)
368*61046927SAndroid Build Coastguard Worker {
369*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_table_header *table = hfi->buf;
370*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_header *queue = &table->queue[qidx];
371*61046927SAndroid Build Coastguard Worker uint32_t offset = queue->iova - hfi->iova;
372*61046927SAndroid Build Coastguard Worker uint32_t *dw = (uint32_t *)(((uint8_t *)hfi->buf) + offset);
373*61046927SAndroid Build Coastguard Worker int last_seqno = -1;
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker if (read_index < 0)
376*61046927SAndroid Build Coastguard Worker return false;
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker while (read_index != queue->write_index) {
379*61046927SAndroid Build Coastguard Worker uint32_t hdr = dw[read_index];
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker if (!is_valid_msg_type(HFI_HEADER_TYPE(hdr)))
382*61046927SAndroid Build Coastguard Worker return false;
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker if (!hfi_msg_name(HFI_HEADER_ID(hdr)))
385*61046927SAndroid Build Coastguard Worker return false;
386*61046927SAndroid Build Coastguard Worker
387*61046927SAndroid Build Coastguard Worker /* Header size should be at least 1, and not extend past the write_index: */
388*61046927SAndroid Build Coastguard Worker unsigned sz = HFI_HEADER_SIZE(hdr);
389*61046927SAndroid Build Coastguard Worker if (!is_gmu_legacy())
390*61046927SAndroid Build Coastguard Worker sz = ALIGN_POT(sz, 4);
391*61046927SAndroid Build Coastguard Worker int remaining = ((read_index + sz) + (queue->size - 1) -
392*61046927SAndroid Build Coastguard Worker queue->write_index) % queue->size;
393*61046927SAndroid Build Coastguard Worker if ((sz == 0) || (remaining < 0))
394*61046927SAndroid Build Coastguard Worker return false;
395*61046927SAndroid Build Coastguard Worker
396*61046927SAndroid Build Coastguard Worker /* Seqno should be one more than previous seqno: */
397*61046927SAndroid Build Coastguard Worker unsigned seqno = HFI_HEADER_SEQNUM(hdr);
398*61046927SAndroid Build Coastguard Worker if ((last_seqno != -1) && (((last_seqno + 1) & 0xfff) != seqno))
399*61046927SAndroid Build Coastguard Worker return false;
400*61046927SAndroid Build Coastguard Worker
401*61046927SAndroid Build Coastguard Worker last_seqno = seqno;
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker read_index = (read_index + sz) % queue->size;
404*61046927SAndroid Build Coastguard Worker }
405*61046927SAndroid Build Coastguard Worker
406*61046927SAndroid Build Coastguard Worker return true;
407*61046927SAndroid Build Coastguard Worker }
408*61046927SAndroid Build Coastguard Worker
409*61046927SAndroid Build Coastguard Worker static void
decode_hfi(struct a6xx_hfi_state * hfi,unsigned qidx,int32_t read_index)410*61046927SAndroid Build Coastguard Worker decode_hfi(struct a6xx_hfi_state *hfi, unsigned qidx, int32_t read_index)
411*61046927SAndroid Build Coastguard Worker {
412*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_table_header *table = hfi->buf;
413*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_header *queue = &table->queue[qidx];
414*61046927SAndroid Build Coastguard Worker uint32_t offset = queue->iova - hfi->iova;
415*61046927SAndroid Build Coastguard Worker uint32_t *dw = (uint32_t *)(((uint8_t *)hfi->buf) + offset);
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker while (read_index != queue->write_index) {
418*61046927SAndroid Build Coastguard Worker uint32_t hdr = dw[read_index];
419*61046927SAndroid Build Coastguard Worker unsigned msgid = HFI_HEADER_ID(hdr);
420*61046927SAndroid Build Coastguard Worker unsigned sz = HFI_HEADER_SIZE(hdr);
421*61046927SAndroid Build Coastguard Worker unsigned type = HFI_HEADER_TYPE(hdr);
422*61046927SAndroid Build Coastguard Worker unsigned seqno = HFI_HEADER_SEQNUM(hdr);
423*61046927SAndroid Build Coastguard Worker
424*61046927SAndroid Build Coastguard Worker assert(is_valid_msg_type(type));
425*61046927SAndroid Build Coastguard Worker assert(hfi_msg_name(msgid));
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker printf("\t\t\t------ %s (id=%u, size=%u, type=%u, seqnum=%u)\n",
428*61046927SAndroid Build Coastguard Worker hfi_msg_name(msgid), msgid, sz, type, seqno);
429*61046927SAndroid Build Coastguard Worker
430*61046927SAndroid Build Coastguard Worker if (!is_gmu_legacy())
431*61046927SAndroid Build Coastguard Worker sz = ALIGN_POT(sz, 4);
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker uint32_t buf[sz];
434*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < sz; i++) {
435*61046927SAndroid Build Coastguard Worker buf[i] = dw[(read_index + i) % queue->size];
436*61046927SAndroid Build Coastguard Worker }
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker if (type == HFI_MSG_CMD)
439*61046927SAndroid Build Coastguard Worker hfi_msgs[msgid].decode(buf);
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker dump_hex_ascii(buf, sz*4, 4);
442*61046927SAndroid Build Coastguard Worker
443*61046927SAndroid Build Coastguard Worker read_index = (read_index + sz) % queue->size;
444*61046927SAndroid Build Coastguard Worker }
445*61046927SAndroid Build Coastguard Worker }
446*61046927SAndroid Build Coastguard Worker
447*61046927SAndroid Build Coastguard Worker /* Search backwards from the most recent (last) history entry to try to
448*61046927SAndroid Build Coastguard Worker * find start of the oldest HFI message which has not been overwritten
449*61046927SAndroid Build Coastguard Worker * due to ringbuffer wraparound.
450*61046927SAndroid Build Coastguard Worker */
451*61046927SAndroid Build Coastguard Worker static int32_t
find_decode_start(struct a6xx_hfi_state * hfi,unsigned qidx)452*61046927SAndroid Build Coastguard Worker find_decode_start(struct a6xx_hfi_state *hfi, unsigned qidx)
453*61046927SAndroid Build Coastguard Worker {
454*61046927SAndroid Build Coastguard Worker int i;
455*61046927SAndroid Build Coastguard Worker
456*61046927SAndroid Build Coastguard Worker for (i = ARRAY_SIZE(hfi->history[qidx]) - 1; i >= 0; i--) {
457*61046927SAndroid Build Coastguard Worker if (!is_valid_decode_start(hfi, qidx, hfi->history[qidx][i]))
458*61046927SAndroid Build Coastguard Worker break;
459*61046927SAndroid Build Coastguard Worker }
460*61046927SAndroid Build Coastguard Worker
461*61046927SAndroid Build Coastguard Worker /* Last entry was invalid, or we decremented below zero, so advance
462*61046927SAndroid Build Coastguard Worker * the index by one:
463*61046927SAndroid Build Coastguard Worker */
464*61046927SAndroid Build Coastguard Worker i++;
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker if (i >= ARRAY_SIZE(hfi->history[qidx]))
467*61046927SAndroid Build Coastguard Worker return -1;
468*61046927SAndroid Build Coastguard Worker
469*61046927SAndroid Build Coastguard Worker return hfi->history[qidx][i];
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker void
dump_gmu_hfi(struct a6xx_hfi_state * hfi)473*61046927SAndroid Build Coastguard Worker dump_gmu_hfi(struct a6xx_hfi_state *hfi)
474*61046927SAndroid Build Coastguard Worker {
475*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_table_header *table = hfi->buf;
476*61046927SAndroid Build Coastguard Worker
477*61046927SAndroid Build Coastguard Worker printf("\tversion: %u\n", table->version);
478*61046927SAndroid Build Coastguard Worker printf("\tsize: %u\n", table->size);
479*61046927SAndroid Build Coastguard Worker printf("\tqhdr0_offset: %u\n", table->qhdr0_offset);
480*61046927SAndroid Build Coastguard Worker printf("\tqhdr_size: %u\n", table->qhdr_size);
481*61046927SAndroid Build Coastguard Worker printf("\tnum_queues: %u\n", table->num_queues);
482*61046927SAndroid Build Coastguard Worker printf("\tactive_queues: %u\n", table->active_queues);
483*61046927SAndroid Build Coastguard Worker
484*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < table->num_queues; i++) {
485*61046927SAndroid Build Coastguard Worker struct a6xx_hfi_queue_header *queue = &table->queue[i];
486*61046927SAndroid Build Coastguard Worker
487*61046927SAndroid Build Coastguard Worker printf("\tqueue[%u]:\n", i);
488*61046927SAndroid Build Coastguard Worker printf("\t\tstatus: 0x%x\n", queue->status);
489*61046927SAndroid Build Coastguard Worker printf("\t\tiova: 0x%x\n", queue->iova);
490*61046927SAndroid Build Coastguard Worker printf("\t\ttype: 0x%x\n", queue->type);
491*61046927SAndroid Build Coastguard Worker printf("\t\tsize: %u\n", queue->size);
492*61046927SAndroid Build Coastguard Worker printf("\t\tmsg_size: %u\n", queue->msg_size);
493*61046927SAndroid Build Coastguard Worker printf("\t\tdropped: %u\n", queue->dropped);
494*61046927SAndroid Build Coastguard Worker printf("\t\trx_watermark: 0x%x\n", queue->rx_watermark);
495*61046927SAndroid Build Coastguard Worker printf("\t\ttx_watermark: 0x%x\n", queue->tx_watermark);
496*61046927SAndroid Build Coastguard Worker printf("\t\trx_request: 0x%x\n", queue->rx_request);
497*61046927SAndroid Build Coastguard Worker printf("\t\ttx_request: 0x%x\n", queue->tx_request);
498*61046927SAndroid Build Coastguard Worker printf("\t\tread_index: %u\n", queue->read_index);
499*61046927SAndroid Build Coastguard Worker printf("\t\twrite_index: %u\n", queue->write_index);
500*61046927SAndroid Build Coastguard Worker
501*61046927SAndroid Build Coastguard Worker int32_t read_index = find_decode_start(hfi, i);
502*61046927SAndroid Build Coastguard Worker if (read_index >= 0)
503*61046927SAndroid Build Coastguard Worker decode_hfi(hfi, i, read_index);
504*61046927SAndroid Build Coastguard Worker }
505*61046927SAndroid Build Coastguard Worker }
506