Skip to content

Commit e305d55

Browse files
committed
WRITEME daigen
1 parent 56d8298 commit e305d55

File tree

2 files changed

+196
-0
lines changed

2 files changed

+196
-0
lines changed

src/platform/mtk/tools/build.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/sh
2+
set -ex
3+
4+
PLATFORMS="$*"
5+
if [ -z "$PLATFORMS" ]; then
6+
PLATFORMS="mt8195 mt8188 mt8186 mt8196"
7+
fi
8+
9+
SOF=`cd ../../../..; /bin/pwd`
10+
11+
for p in $PLATFORMS; do
12+
13+
SRCS="$SOF/src/platform/$p/lib/dai.c $SOF/src/platform/$p/afe-platform.c"
14+
15+
INCS="-I$SOF/src/include -I$SOF/src/platform/posix/include -I$SOF/posix/include -I$SOF/src/arch/host/include -I$SOF/src/platform/$p/include/platform -I$SOF/src/platform/$p/include"
16+
17+
DEFS="-DRELATIVE_FILE=\"mt-dai-gen.c\" -DCONFIG_CORE_COUNT=1 -DCONFIG_IPC_MAJOR_3=1"
18+
19+
touch uuid-registry.h
20+
INCS="$INCS -I."
21+
22+
gcc -g -Wall -Werror -m32 -o mt-dai-gen mt-dai-gen.c $SRCS $INCS $DEFS
23+
24+
./mt-dai-gen > afe-${p}.dts
25+
done
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#include <sof/lib/dai-legacy.h>
2+
#include <sof/drivers/afe-drv.h>
3+
#include <stdio.h>
4+
5+
/* DIY assertion, an "assert()" is already defined in platform headers */
6+
#define CHECK(expr) if(!(expr)) { \
7+
printf("FAILED: " #expr " at line %d\n", __LINE__); *(int*)0=0; }
8+
9+
/* These are the symbols we need to enumerate */
10+
extern struct mtk_base_afe_platform mtk_afe_platform;
11+
extern const struct dai_info lib_dai;
12+
13+
/* Call this to initialize the dai arrays */
14+
int dai_init(struct sof *sof);
15+
16+
/* Debug hook in some versions of MTK firmware */
17+
void printf_(void) {}
18+
19+
/* Just need a pointer to a symbol with this name */
20+
int afe_dai_driver;
21+
22+
/* So dai_init() can write to something */
23+
struct sof sof;
24+
25+
unsigned int afe_base_addr;
26+
27+
void symify(char *s)
28+
{
29+
for(; *s; s++) {
30+
if (*s >= 'A' && *s <= 'Z')
31+
*s += 'a' - 'A';
32+
CHECK((*s >= 'a' && *s <= 'z') || (*s >= '0' && *s <= '9') || *s == '_');
33+
}
34+
}
35+
36+
/* The AFE driver has some... idiosyncratic defaulting. The existing
37+
* configurations have a varying set of conventions to encode "no
38+
* value is set":
39+
*
40+
* ch_num is skipped if the stored reg value is negative
41+
* quad_ch is skipped if the mask is zero
42+
* int_odd: <=0 reg
43+
* mono: <=0 reg OR <=0 shift
44+
* msb: <=0 reg
45+
* msb2: <=0 reg
46+
* agent_disable: <=0 reg
47+
* fs: never skipped
48+
* hd: never skipped
49+
* enable: never skipped
50+
*
51+
* We detect the union of those conditions and elide the setting (it
52+
* will be defaulted to reg=-1/shift=0/mask=0 in the driver DTS macros)
53+
*/
54+
void print_fld(const char *name, int reg, int shift, int lomask)
55+
{
56+
if (reg <= 0 || shift < 0 || lomask == 0) {
57+
return;
58+
}
59+
60+
int bits = __builtin_ffs(lomask + 1) - 1;
61+
62+
CHECK(((lomask + 1) & lomask) == 0); // must be power of two
63+
CHECK(lomask); // and not zero
64+
CHECK(shift >= 0 && (shift + bits) <= 32); // and shift doesn't overrun
65+
66+
printf("\t\t" "%s = <0x%8.8x %d %d>;\n",
67+
name, reg + afe_base_addr, shift, bits);
68+
}
69+
70+
unsigned int msbaddr(int val)
71+
{
72+
return val ? val + afe_base_addr : 0;
73+
}
74+
75+
int main(void)
76+
{
77+
dai_init(&sof);
78+
79+
afe_base_addr = mtk_afe_platform.base_addr;
80+
81+
// The DAI order here is immutable: the indexes are known to and
82+
// used by the kernel driver. And these point to the memif array
83+
// via an index stored in the low byte (?!) of the first fifo's
84+
// "handshake" (it's not a DMA handshake value at all). So we
85+
// invert the mapping and store the dai index along with the AFE
86+
// record.
87+
int dai_memif[64];
88+
int num_dais = 0;
89+
for (int t = 0; t < lib_dai.num_dai_types; t++) {
90+
for (int i = 0; i < lib_dai.dai_type_array[t].num_dais; i++) {
91+
int idx = lib_dai.dai_type_array[t].dai_array[i].index;
92+
int hs = lib_dai.dai_type_array[t].dai_array[i].plat_data.fifo[0].handshake;
93+
94+
CHECK(idx == num_dais);
95+
dai_memif[num_dais++] = hs >> 16;
96+
}
97+
}
98+
99+
// Quick check that the dai/memif mapping is unique
100+
for(int i=0; i<num_dais; i++) {
101+
int n = 0;
102+
for(int j=0; j<num_dais; j++)
103+
if(dai_memif[j] == i)
104+
n++;
105+
CHECK(n == 1);
106+
}
107+
108+
for (int i = 0; i < mtk_afe_platform.memif_size; i++) {
109+
const struct mtk_base_memif_data *m = &mtk_afe_platform.memif_datas[i];
110+
111+
int dai_id = -1;
112+
for (int j = 0; j < num_dais; j++) {
113+
if (dai_memif[j] == i) {
114+
dai_id = j;
115+
break;
116+
}
117+
}
118+
CHECK(dai_id >= 0);
119+
120+
// We use the UL/DL naming to detect direction, make sure it isn't broken
121+
bool uplink = !!strstr(m->name, "UL");
122+
bool downlink = !!strstr(m->name, "DL");
123+
CHECK(uplink != downlink);
124+
125+
// Validate and lower-case the name to make a DTS symbol
126+
char sym[64];
127+
CHECK(strlen(m->name) < sizeof(sym));
128+
strcpy(sym, m->name);
129+
symify(sym);
130+
131+
//printf("memif %d %s dai %d %s\n", i, sym, dai_id, downlink ? "downlink" : "");
132+
133+
printf("\t" "afe_%s: afe_%s {\n", sym, sym);
134+
printf("\t\t" "compatible = \"mediatek,afe\";\n");
135+
printf("\t\t" "afe_name = \"%s\";\n", m->name);
136+
printf("\t\t" "dai_id = <%d>;\n", dai_id);
137+
if (downlink)
138+
printf("\t\t" "downlink;\n");
139+
140+
/* Register pairs containing the high and low words of
141+
* bus/host addresses. The first (high) register is allowed
142+
* to be zero indicating all addresses will be 32 bit.
143+
*/
144+
printf("\t\t" "base = <0x%8.8x 0x%8.8x>;\n",
145+
msbaddr(m->reg_ofs_base_msb), m->reg_ofs_base + afe_base_addr);
146+
printf("\t\t" "cur = <0x%8.8x 0x%8.8x>;\n",
147+
msbaddr(m->reg_ofs_cur_msb), m->reg_ofs_cur + afe_base_addr);
148+
printf("\t\t" "end = <0x%8.8x 0x%8.8x>;\n",
149+
msbaddr(m->reg_ofs_end_msb), m->reg_ofs_end + afe_base_addr);
150+
151+
print_fld("fs", m->fs_reg, m->fs_shift, m->fs_maskbit);
152+
print_fld("mono", m->mono_reg, m->mono_shift, 1);
153+
if (m->mono_invert)
154+
printf("\t\t" "mono_invert;\n");
155+
print_fld("quad_ch", m->quad_ch_reg, m->quad_ch_shift, m->quad_ch_mask);
156+
print_fld("int_odd", m->int_odd_flag_reg, m->int_odd_flag_shift, 1);
157+
print_fld("enable", m->enable_reg, m->enable_shift, 1);
158+
print_fld("hd", m->hd_reg, m->hd_shift, 1);
159+
print_fld("msb", m->msb_reg, m->msb_shift, 1);
160+
print_fld("msb2", m->msb2_reg, m->msb2_shift, 1);
161+
print_fld("agent_disable", m->agent_disable_reg, m->agent_disable_shift, 1);
162+
print_fld("ch_num", m->ch_num_reg, m->ch_num_shift, m->ch_num_maskbit);
163+
164+
// Note: there are also "pbuf" and "minlen" registers defined
165+
// in the memif_data struct, but they are unused by the
166+
// existing driver.
167+
168+
printf("\t" "};\n\n");
169+
}
170+
}
171+

0 commit comments

Comments
 (0)