xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/crashdec-hfi.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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