xref: /aosp_15_r20/external/mesa3d/src/freedreno/afuc/util.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 <err.h>
7*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
8*61046927SAndroid Build Coastguard Worker #include <stdio.h>
9*61046927SAndroid Build Coastguard Worker #include <string.h>
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "rnn.h"
12*61046927SAndroid Build Coastguard Worker #include "rnndec.h"
13*61046927SAndroid Build Coastguard Worker 
14*61046927SAndroid Build Coastguard Worker #include "afuc.h"
15*61046927SAndroid Build Coastguard Worker #include "util.h"
16*61046927SAndroid Build Coastguard Worker 
17*61046927SAndroid Build Coastguard Worker static struct rnndeccontext *ctx;
18*61046927SAndroid Build Coastguard Worker static struct rnndb *db;
19*61046927SAndroid Build Coastguard Worker static struct rnndomain *control_regs;
20*61046927SAndroid Build Coastguard Worker static struct rnndomain *sqe_regs;
21*61046927SAndroid Build Coastguard Worker static struct rnndomain *pipe_regs;
22*61046927SAndroid Build Coastguard Worker struct rnndomain *dom[2];
23*61046927SAndroid Build Coastguard Worker static struct rnnenum *pm4_packets;
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker static int
find_reg(struct rnndomain * dom,const char * name)26*61046927SAndroid Build Coastguard Worker find_reg(struct rnndomain *dom, const char *name)
27*61046927SAndroid Build Coastguard Worker {
28*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < dom->subelemsnum; i++)
29*61046927SAndroid Build Coastguard Worker       if (!strcmp(name, dom->subelems[i]->name))
30*61046927SAndroid Build Coastguard Worker          return dom->subelems[i]->offset;
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker    return -1;
33*61046927SAndroid Build Coastguard Worker }
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker static unsigned
reg(struct rnndomain * dom,const char * type,const char * name)36*61046927SAndroid Build Coastguard Worker reg(struct rnndomain *dom, const char *type, const char *name)
37*61046927SAndroid Build Coastguard Worker {
38*61046927SAndroid Build Coastguard Worker    int val = find_reg(dom, name);
39*61046927SAndroid Build Coastguard Worker    if (val < 0) {
40*61046927SAndroid Build Coastguard Worker       char *endptr = NULL;
41*61046927SAndroid Build Coastguard Worker       val = strtol(name, &endptr, 0);
42*61046927SAndroid Build Coastguard Worker       if (endptr && *endptr) {
43*61046927SAndroid Build Coastguard Worker          printf("invalid %s reg: %s\n", type, name);
44*61046927SAndroid Build Coastguard Worker          exit(2);
45*61046927SAndroid Build Coastguard Worker       }
46*61046927SAndroid Build Coastguard Worker    }
47*61046927SAndroid Build Coastguard Worker    return (unsigned)val;
48*61046927SAndroid Build Coastguard Worker }
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker static char *
reg_name(struct rnndomain * dom,unsigned id)51*61046927SAndroid Build Coastguard Worker reg_name(struct rnndomain *dom, unsigned id)
52*61046927SAndroid Build Coastguard Worker {
53*61046927SAndroid Build Coastguard Worker    if (rnndec_checkaddr(ctx, dom, id, 0)) {
54*61046927SAndroid Build Coastguard Worker       struct rnndecaddrinfo *info = rnndec_decodeaddr(ctx, dom, id, 0);
55*61046927SAndroid Build Coastguard Worker       char *name = info->name;
56*61046927SAndroid Build Coastguard Worker       free(info);
57*61046927SAndroid Build Coastguard Worker       return name;
58*61046927SAndroid Build Coastguard Worker    } else {
59*61046927SAndroid Build Coastguard Worker       return NULL;
60*61046927SAndroid Build Coastguard Worker    }
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker /**
64*61046927SAndroid Build Coastguard Worker  * Map control reg name to offset.
65*61046927SAndroid Build Coastguard Worker  */
66*61046927SAndroid Build Coastguard Worker unsigned
afuc_control_reg(const char * name)67*61046927SAndroid Build Coastguard Worker afuc_control_reg(const char *name)
68*61046927SAndroid Build Coastguard Worker {
69*61046927SAndroid Build Coastguard Worker    return reg(control_regs, "control", name);
70*61046927SAndroid Build Coastguard Worker }
71*61046927SAndroid Build Coastguard Worker 
72*61046927SAndroid Build Coastguard Worker /**
73*61046927SAndroid Build Coastguard Worker  * Map offset to SQE reg name (or NULL), caller frees
74*61046927SAndroid Build Coastguard Worker  */
75*61046927SAndroid Build Coastguard Worker char *
afuc_sqe_reg_name(unsigned id)76*61046927SAndroid Build Coastguard Worker afuc_sqe_reg_name(unsigned id)
77*61046927SAndroid Build Coastguard Worker {
78*61046927SAndroid Build Coastguard Worker    return reg_name(sqe_regs, id);
79*61046927SAndroid Build Coastguard Worker }
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker /**
82*61046927SAndroid Build Coastguard Worker  * Map SQE reg name to offset.
83*61046927SAndroid Build Coastguard Worker  */
84*61046927SAndroid Build Coastguard Worker unsigned
afuc_sqe_reg(const char * name)85*61046927SAndroid Build Coastguard Worker afuc_sqe_reg(const char *name)
86*61046927SAndroid Build Coastguard Worker {
87*61046927SAndroid Build Coastguard Worker    return reg(sqe_regs, "SQE", name);
88*61046927SAndroid Build Coastguard Worker }
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker /**
91*61046927SAndroid Build Coastguard Worker  * Map offset to control reg name (or NULL), caller frees
92*61046927SAndroid Build Coastguard Worker  */
93*61046927SAndroid Build Coastguard Worker char *
afuc_control_reg_name(unsigned id)94*61046927SAndroid Build Coastguard Worker afuc_control_reg_name(unsigned id)
95*61046927SAndroid Build Coastguard Worker {
96*61046927SAndroid Build Coastguard Worker    return reg_name(control_regs, id);
97*61046927SAndroid Build Coastguard Worker }
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker /**
100*61046927SAndroid Build Coastguard Worker  * Map pipe reg name to offset.
101*61046927SAndroid Build Coastguard Worker  */
102*61046927SAndroid Build Coastguard Worker unsigned
afuc_pipe_reg(const char * name)103*61046927SAndroid Build Coastguard Worker afuc_pipe_reg(const char *name)
104*61046927SAndroid Build Coastguard Worker {
105*61046927SAndroid Build Coastguard Worker    return reg(pipe_regs, "pipe", name);
106*61046927SAndroid Build Coastguard Worker }
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker /**
109*61046927SAndroid Build Coastguard Worker  * "void" pipe regs don't have a value written, the $addr right is
110*61046927SAndroid Build Coastguard Worker  * enough to trigger what they do
111*61046927SAndroid Build Coastguard Worker  */
112*61046927SAndroid Build Coastguard Worker bool
afuc_pipe_reg_is_void(unsigned id)113*61046927SAndroid Build Coastguard Worker afuc_pipe_reg_is_void(unsigned id)
114*61046927SAndroid Build Coastguard Worker {
115*61046927SAndroid Build Coastguard Worker    if (rnndec_checkaddr(ctx, pipe_regs, id, 0)) {
116*61046927SAndroid Build Coastguard Worker       struct rnndecaddrinfo *info = rnndec_decodeaddr(ctx, pipe_regs, id, 0);
117*61046927SAndroid Build Coastguard Worker       free(info->name);
118*61046927SAndroid Build Coastguard Worker       bool ret = !strcmp(info->typeinfo->name, "void");
119*61046927SAndroid Build Coastguard Worker       free(info);
120*61046927SAndroid Build Coastguard Worker       return ret;
121*61046927SAndroid Build Coastguard Worker    } else {
122*61046927SAndroid Build Coastguard Worker       return false;
123*61046927SAndroid Build Coastguard Worker    }
124*61046927SAndroid Build Coastguard Worker }
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker /**
127*61046927SAndroid Build Coastguard Worker  * Map offset to pipe reg name (or NULL), caller frees
128*61046927SAndroid Build Coastguard Worker  */
129*61046927SAndroid Build Coastguard Worker char *
afuc_pipe_reg_name(unsigned id)130*61046927SAndroid Build Coastguard Worker afuc_pipe_reg_name(unsigned id)
131*61046927SAndroid Build Coastguard Worker {
132*61046927SAndroid Build Coastguard Worker    return reg_name(pipe_regs, id);
133*61046927SAndroid Build Coastguard Worker }
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker /**
136*61046927SAndroid Build Coastguard Worker  * Map GPU reg name to offset.
137*61046927SAndroid Build Coastguard Worker  */
138*61046927SAndroid Build Coastguard Worker unsigned
afuc_gpu_reg(const char * name)139*61046927SAndroid Build Coastguard Worker afuc_gpu_reg(const char *name)
140*61046927SAndroid Build Coastguard Worker {
141*61046927SAndroid Build Coastguard Worker    int val = find_reg(dom[0], name);
142*61046927SAndroid Build Coastguard Worker    if (val < 0)
143*61046927SAndroid Build Coastguard Worker       val = find_reg(dom[1], name);
144*61046927SAndroid Build Coastguard Worker    if (val < 0) {
145*61046927SAndroid Build Coastguard Worker       char *endptr = NULL;
146*61046927SAndroid Build Coastguard Worker       val = strtol(name, &endptr, 0);
147*61046927SAndroid Build Coastguard Worker       if (endptr && *endptr) {
148*61046927SAndroid Build Coastguard Worker          printf("invalid control reg: %s\n", name);
149*61046927SAndroid Build Coastguard Worker          exit(2);
150*61046927SAndroid Build Coastguard Worker       }
151*61046927SAndroid Build Coastguard Worker    }
152*61046927SAndroid Build Coastguard Worker    return (unsigned)val;
153*61046927SAndroid Build Coastguard Worker }
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker /**
156*61046927SAndroid Build Coastguard Worker  * Map offset to gpu reg name (or NULL), caller frees
157*61046927SAndroid Build Coastguard Worker  */
158*61046927SAndroid Build Coastguard Worker char *
afuc_gpu_reg_name(unsigned id)159*61046927SAndroid Build Coastguard Worker afuc_gpu_reg_name(unsigned id)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker    struct rnndomain *d = NULL;
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker    if (rnndec_checkaddr(ctx, dom[0], id, 0)) {
164*61046927SAndroid Build Coastguard Worker       d = dom[0];
165*61046927SAndroid Build Coastguard Worker    } else if (rnndec_checkaddr(ctx, dom[1], id, 0)) {
166*61046927SAndroid Build Coastguard Worker       d = dom[1];
167*61046927SAndroid Build Coastguard Worker    }
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker    if (d) {
170*61046927SAndroid Build Coastguard Worker       struct rnndecaddrinfo *info = rnndec_decodeaddr(ctx, d, id, 0);
171*61046927SAndroid Build Coastguard Worker       if (info) {
172*61046927SAndroid Build Coastguard Worker          char *name = info->name;
173*61046927SAndroid Build Coastguard Worker          free(info);
174*61046927SAndroid Build Coastguard Worker          return name;
175*61046927SAndroid Build Coastguard Worker       }
176*61046927SAndroid Build Coastguard Worker    }
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker    return NULL;
179*61046927SAndroid Build Coastguard Worker }
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker unsigned
afuc_gpr_reg(const char * name)182*61046927SAndroid Build Coastguard Worker afuc_gpr_reg(const char *name)
183*61046927SAndroid Build Coastguard Worker {
184*61046927SAndroid Build Coastguard Worker    /* If it starts with '$' just swallow it: */
185*61046927SAndroid Build Coastguard Worker    if (name[0] == '$')
186*61046927SAndroid Build Coastguard Worker       name++;
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker    /* handle aliases: */
189*61046927SAndroid Build Coastguard Worker    if (!strcmp(name, "rem")) {
190*61046927SAndroid Build Coastguard Worker       return REG_REM;
191*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(name, "memdata")) {
192*61046927SAndroid Build Coastguard Worker       return REG_MEMDATA;
193*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(name, "addr")) {
194*61046927SAndroid Build Coastguard Worker       return REG_ADDR;
195*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(name, "regdata")) {
196*61046927SAndroid Build Coastguard Worker       return REG_REGDATA;
197*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(name, "usraddr")) {
198*61046927SAndroid Build Coastguard Worker       return REG_USRADDR;
199*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(name, "data")) {
200*61046927SAndroid Build Coastguard Worker       return REG_DATA;
201*61046927SAndroid Build Coastguard Worker    } else {
202*61046927SAndroid Build Coastguard Worker       char *endptr = NULL;
203*61046927SAndroid Build Coastguard Worker       unsigned val = strtol(name, &endptr, 16);
204*61046927SAndroid Build Coastguard Worker       if (endptr && *endptr) {
205*61046927SAndroid Build Coastguard Worker          printf("invalid gpr reg: %s\n", name);
206*61046927SAndroid Build Coastguard Worker          exit(2);
207*61046927SAndroid Build Coastguard Worker       }
208*61046927SAndroid Build Coastguard Worker       return val;
209*61046927SAndroid Build Coastguard Worker    }
210*61046927SAndroid Build Coastguard Worker }
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker static int
find_enum_val(struct rnnenum * en,const char * name)213*61046927SAndroid Build Coastguard Worker find_enum_val(struct rnnenum *en, const char *name)
214*61046927SAndroid Build Coastguard Worker {
215*61046927SAndroid Build Coastguard Worker    int i;
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker    for (i = 0; i < en->valsnum; i++)
218*61046927SAndroid Build Coastguard Worker       if (en->vals[i]->valvalid && !strcmp(name, en->vals[i]->name))
219*61046927SAndroid Build Coastguard Worker          return en->vals[i]->value;
220*61046927SAndroid Build Coastguard Worker 
221*61046927SAndroid Build Coastguard Worker    return -1;
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker /**
225*61046927SAndroid Build Coastguard Worker  * Map pm4 packet name to id
226*61046927SAndroid Build Coastguard Worker  */
227*61046927SAndroid Build Coastguard Worker int
afuc_pm4_id(const char * name)228*61046927SAndroid Build Coastguard Worker afuc_pm4_id(const char *name)
229*61046927SAndroid Build Coastguard Worker {
230*61046927SAndroid Build Coastguard Worker    return find_enum_val(pm4_packets, name);
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker const char *
afuc_pm_id_name(unsigned id)234*61046927SAndroid Build Coastguard Worker afuc_pm_id_name(unsigned id)
235*61046927SAndroid Build Coastguard Worker {
236*61046927SAndroid Build Coastguard Worker    return rnndec_decode_enum(ctx, "adreno_pm4_type3_packets", id);
237*61046927SAndroid Build Coastguard Worker }
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker void
afuc_printc(enum afuc_color c,const char * fmt,...)240*61046927SAndroid Build Coastguard Worker afuc_printc(enum afuc_color c, const char *fmt, ...)
241*61046927SAndroid Build Coastguard Worker {
242*61046927SAndroid Build Coastguard Worker    va_list args;
243*61046927SAndroid Build Coastguard Worker    if (c == AFUC_ERR) {
244*61046927SAndroid Build Coastguard Worker       printf("%s", ctx->colors->err);
245*61046927SAndroid Build Coastguard Worker    } else if (c == AFUC_LBL) {
246*61046927SAndroid Build Coastguard Worker       printf("%s", ctx->colors->btarg);
247*61046927SAndroid Build Coastguard Worker    }
248*61046927SAndroid Build Coastguard Worker    va_start(args, fmt);
249*61046927SAndroid Build Coastguard Worker    vprintf(fmt, args);
250*61046927SAndroid Build Coastguard Worker    va_end(args);
251*61046927SAndroid Build Coastguard Worker    printf("%s", ctx->colors->reset);
252*61046927SAndroid Build Coastguard Worker }
253*61046927SAndroid Build Coastguard Worker 
afuc_util_init(enum afuc_fwid fw_id,int * gpuver_out,bool colors)254*61046927SAndroid Build Coastguard Worker int afuc_util_init(enum afuc_fwid fw_id, int *gpuver_out, bool colors)
255*61046927SAndroid Build Coastguard Worker {
256*61046927SAndroid Build Coastguard Worker    char *name, *control_reg_name, *variant;
257*61046927SAndroid Build Coastguard Worker    char *pipe_reg_name = NULL;
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker    switch (fw_id) {
260*61046927SAndroid Build Coastguard Worker    case AFUC_A750:
261*61046927SAndroid Build Coastguard Worker       name = "A6XX";
262*61046927SAndroid Build Coastguard Worker       variant = "A7XX";
263*61046927SAndroid Build Coastguard Worker       control_reg_name = "A7XX_GEN3_CONTROL_REG";
264*61046927SAndroid Build Coastguard Worker       pipe_reg_name = "A7XX_PIPE_REG";
265*61046927SAndroid Build Coastguard Worker       *gpuver_out = 7;
266*61046927SAndroid Build Coastguard Worker       break;
267*61046927SAndroid Build Coastguard Worker    case AFUC_A730:
268*61046927SAndroid Build Coastguard Worker    case AFUC_A740:
269*61046927SAndroid Build Coastguard Worker       name = "A6XX";
270*61046927SAndroid Build Coastguard Worker       variant = "A7XX";
271*61046927SAndroid Build Coastguard Worker       control_reg_name = "A7XX_CONTROL_REG";
272*61046927SAndroid Build Coastguard Worker       pipe_reg_name = "A7XX_PIPE_REG";
273*61046927SAndroid Build Coastguard Worker       *gpuver_out = 7;
274*61046927SAndroid Build Coastguard Worker       break;
275*61046927SAndroid Build Coastguard Worker    case AFUC_A630:
276*61046927SAndroid Build Coastguard Worker    case AFUC_A650:
277*61046927SAndroid Build Coastguard Worker    case AFUC_A660:
278*61046927SAndroid Build Coastguard Worker       name = "A6XX";
279*61046927SAndroid Build Coastguard Worker       variant = "A6XX";
280*61046927SAndroid Build Coastguard Worker       control_reg_name = "A6XX_CONTROL_REG";
281*61046927SAndroid Build Coastguard Worker       pipe_reg_name = "A6XX_PIPE_REG";
282*61046927SAndroid Build Coastguard Worker       *gpuver_out = 6;
283*61046927SAndroid Build Coastguard Worker       break;
284*61046927SAndroid Build Coastguard Worker    case AFUC_A530:
285*61046927SAndroid Build Coastguard Worker       name = "A5XX";
286*61046927SAndroid Build Coastguard Worker       variant = "A5XX";
287*61046927SAndroid Build Coastguard Worker       control_reg_name = "A5XX_CONTROL_REG";
288*61046927SAndroid Build Coastguard Worker       pipe_reg_name = "A5XX_PIPE_REG";
289*61046927SAndroid Build Coastguard Worker       *gpuver_out = 5;
290*61046927SAndroid Build Coastguard Worker       break;
291*61046927SAndroid Build Coastguard Worker    default:
292*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "unknown GPU version %03x!\n", fw_id);
293*61046927SAndroid Build Coastguard Worker       return -1;
294*61046927SAndroid Build Coastguard Worker    }
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker    rnn_init();
297*61046927SAndroid Build Coastguard Worker    db = rnn_newdb();
298*61046927SAndroid Build Coastguard Worker 
299*61046927SAndroid Build Coastguard Worker    ctx = rnndec_newcontext(db);
300*61046927SAndroid Build Coastguard Worker    ctx->colors = colors ? &envy_def_colors : &envy_null_colors;
301*61046927SAndroid Build Coastguard Worker 
302*61046927SAndroid Build Coastguard Worker    rnn_parsefile(db, "adreno.xml");
303*61046927SAndroid Build Coastguard Worker    rnn_prepdb(db);
304*61046927SAndroid Build Coastguard Worker    if (db->estatus)
305*61046927SAndroid Build Coastguard Worker       errx(db->estatus, "failed to parse register database");
306*61046927SAndroid Build Coastguard Worker    dom[0] = rnn_finddomain(db, name);
307*61046927SAndroid Build Coastguard Worker    dom[1] = rnn_finddomain(db, "AXXX");
308*61046927SAndroid Build Coastguard Worker    control_regs = rnn_finddomain(db, control_reg_name);
309*61046927SAndroid Build Coastguard Worker    sqe_regs = rnn_finddomain(db, "A6XX_SQE_REG");
310*61046927SAndroid Build Coastguard Worker    pipe_regs = rnn_finddomain(db, pipe_reg_name);
311*61046927SAndroid Build Coastguard Worker 
312*61046927SAndroid Build Coastguard Worker    rnndec_varadd(ctx, "chip", variant);
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker    pm4_packets = rnn_findenum(ctx->db, "adreno_pm4_type3_packets");
315*61046927SAndroid Build Coastguard Worker 
316*61046927SAndroid Build Coastguard Worker    return 0;
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker 
319