diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2021-02-27 22:05:11 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2021-03-02 00:36:01 +0000 |
commit | 73cee8f17702d0fdc3e0508e8cf7193faae5f015 (patch) | |
tree | d83cb08541a2f78f1e7512de7abd0ce788eb8eb5 | |
parent | 7418ec5009a0203b562bcf128713ef741815fe0e (diff) | |
download | rockbox-73cee8f17702d0fdc3e0508e8cf7193faae5f015.tar.gz rockbox-73cee8f17702d0fdc3e0508e8cf7193faae5f015.zip |
Add RegGen-NG tool and definitions for Ingenic X1000
Change-Id: Ib9ec35c068e1cff8dcf120a13cfe3f5f58908a95
-rwxr-xr-x | utils/reggen-ng/reggen-ng.py | 465 | ||||
-rw-r--r-- | utils/reggen-ng/x1000.reggen | 742 |
2 files changed, 1207 insertions, 0 deletions
diff --git a/utils/reggen-ng/reggen-ng.py b/utils/reggen-ng/reggen-ng.py new file mode 100755 index 0000000000..09549d6fa4 --- /dev/null +++ b/utils/reggen-ng/reggen-ng.py | |||
@@ -0,0 +1,465 @@ | |||
1 | #!/usr/bin/python3 | ||
2 | # | ||
3 | # Tool to generate XML files for Rockbox regtools. The syntax is pretty simple | ||
4 | # and much less verbose than XML; see the '.reggen' files next to this script. | ||
5 | # | ||
6 | # Currently this tool expects a 'reggen' file on standard input and writes the | ||
7 | # equivalent XML to standard output. | ||
8 | # | ||
9 | # TODO: document this better and improve the command line usage | ||
10 | |||
11 | from lxml import etree as ET | ||
12 | from lxml.builder import E | ||
13 | import functools | ||
14 | |||
15 | class Soc: | ||
16 | def __init__(self): | ||
17 | self.name = None | ||
18 | self.title = None | ||
19 | self.desc = None | ||
20 | self.isa = None | ||
21 | self.version = None | ||
22 | self.authors = [] | ||
23 | self.nodes = [] | ||
24 | |||
25 | def gen(self): | ||
26 | node = E("soc", version="2") | ||
27 | if self.name is not None: | ||
28 | node.append(E("name", self.name)) | ||
29 | if self.desc is not None: | ||
30 | node.append(E("desc", self.desc)) | ||
31 | if self.isa is not None: | ||
32 | node.append(E("isa", self.isa)) | ||
33 | if self.isa is not None: | ||
34 | node.append(E("version", self.version)) | ||
35 | for a in self.authors: | ||
36 | node.append(E("author", a)) | ||
37 | for n in self.nodes: | ||
38 | node.append(n.gen()) | ||
39 | return node | ||
40 | |||
41 | class Node: | ||
42 | def __init__(self, name): | ||
43 | self.name = name | ||
44 | self.title = None | ||
45 | self.desc = None | ||
46 | self.instances = [] | ||
47 | self.children = [] | ||
48 | self.register_width = None | ||
49 | self.fields = [] | ||
50 | |||
51 | def gen(self): | ||
52 | node = E("node", E("name", self.name)) | ||
53 | |||
54 | if self.title is not None: | ||
55 | node.append(E("title", self.title)) | ||
56 | |||
57 | if self.desc is not None: | ||
58 | node.append(E("desc", self.desc)) | ||
59 | |||
60 | for i in self.instances: | ||
61 | node.append(i.gen()) | ||
62 | |||
63 | for c in self.children: | ||
64 | node.append(c.gen()) | ||
65 | |||
66 | if self.register_width is not None: | ||
67 | reg = E("register", | ||
68 | E("width", self.register_width)) | ||
69 | for f in self.fields: | ||
70 | reg.append(f.gen()) | ||
71 | node.append(reg) | ||
72 | |||
73 | return node | ||
74 | |||
75 | class Instance: | ||
76 | def __init__(self, name, addr, stride=None, count=None): | ||
77 | self.name = name | ||
78 | self.address = addr | ||
79 | self.stride = stride | ||
80 | self.count = count | ||
81 | |||
82 | def gen(self): | ||
83 | node = E("instance", E("name", self.name)) | ||
84 | |||
85 | if self.stride is not None: | ||
86 | node.append(E("range", | ||
87 | E("first", "0"), | ||
88 | E("count", self.count), | ||
89 | E("base", self.address), | ||
90 | E("stride", self.stride))) | ||
91 | else: | ||
92 | node.append(E("address", self.address)) | ||
93 | |||
94 | return node | ||
95 | |||
96 | class Field: | ||
97 | def __init__(self, name, msb, lsb): | ||
98 | self.name = name | ||
99 | self.desc = None | ||
100 | self.msb = int(msb) | ||
101 | self.lsb = int(lsb) | ||
102 | self.enums = [] | ||
103 | |||
104 | def gen(self): | ||
105 | node = E("field", | ||
106 | E("name", self.name), | ||
107 | E("position", "%d" % self.lsb)) | ||
108 | |||
109 | if self.desc is not None: | ||
110 | node.append(E("desc", self.desc)) | ||
111 | |||
112 | if self.msb != self.lsb: | ||
113 | node.append(E("width", str(self.msb - self.lsb + 1))) | ||
114 | |||
115 | for n, v in self.enums: | ||
116 | node.append(E("enum", E("name", n), E("value", v))) | ||
117 | |||
118 | return node | ||
119 | |||
120 | class Variant: | ||
121 | def __init__(self, ty, offset): | ||
122 | self.type = ty | ||
123 | self.offset = offset | ||
124 | |||
125 | def gen(self): | ||
126 | return E("variant", | ||
127 | E("type", self.type), | ||
128 | E("offset", self.offset)) | ||
129 | |||
130 | class Parser: | ||
131 | def __init__(self, f): | ||
132 | self.input = f | ||
133 | self.line = 1 | ||
134 | self.eolstop = False | ||
135 | self.next() | ||
136 | |||
137 | def parse(self): | ||
138 | self.skipws() | ||
139 | results = self.parse_block_inner({ | ||
140 | 'name': (self.parse_string, 1), | ||
141 | 'title': (self.parse_string, 1), | ||
142 | 'desc': (self.parse_string, 1), | ||
143 | 'isa': (self.parse_string, 1), | ||
144 | 'version': (self.parse_string, 1), | ||
145 | 'author': self.parse_string, | ||
146 | 'node': self.parse_node, | ||
147 | 'reg': self.parse_register, | ||
148 | }) | ||
149 | |||
150 | ret = Soc() | ||
151 | |||
152 | if 'name' in results: | ||
153 | ret.name = results['name'][0] | ||
154 | else: | ||
155 | self.err('missing "name" statement at toplevel') | ||
156 | |||
157 | if 'title' in results: | ||
158 | ret.title = results['title'][0] | ||
159 | if 'desc' in results: | ||
160 | ret.desc = results['desc'][0] | ||
161 | if 'isa' in results: | ||
162 | ret.isa = results['isa'][0] | ||
163 | if 'version' in results: | ||
164 | ret.version = results['version'][0] | ||
165 | if 'author' in results: | ||
166 | ret.authors += results['author'] | ||
167 | if 'node' in results: | ||
168 | ret.nodes += results['node'] | ||
169 | if 'reg' in results: | ||
170 | ret.nodes += results['reg'] | ||
171 | |||
172 | return ret | ||
173 | |||
174 | def parse_node(self): | ||
175 | name = self.parse_ident() | ||
176 | ret, results = self.parse_node_block(name, { | ||
177 | 'title': (self.parse_string, 1), | ||
178 | 'node': self.parse_node, | ||
179 | 'reg': self.parse_register, | ||
180 | }) | ||
181 | |||
182 | if 'title' in results: | ||
183 | ret.title = results['title'][0] | ||
184 | if 'node' in results: | ||
185 | ret.children += results['node'] | ||
186 | if 'reg' in results: | ||
187 | ret.children += results['reg'] | ||
188 | |||
189 | return ret | ||
190 | |||
191 | def parse_register(self): | ||
192 | words, has_block = self.parse_wordline(True) | ||
193 | name = words[0] | ||
194 | width = "32" | ||
195 | addr = None | ||
196 | |||
197 | if len(words) == 1: | ||
198 | # reg NAME | ||
199 | pass | ||
200 | elif len(words) == 2: | ||
201 | # reg NAME ADDR | ||
202 | addr = words[1] | ||
203 | elif len(words) == 3: | ||
204 | # reg WIDTH NAME ADDR | ||
205 | name = words[1] | ||
206 | width = words[0] | ||
207 | addr = words[2] | ||
208 | else: | ||
209 | self.err('malformed register statement') | ||
210 | |||
211 | if has_block: | ||
212 | ret, results = self.parse_node_block(name, { | ||
213 | 'field': self.parse_field, | ||
214 | 'fld': self.parse_field, | ||
215 | 'bit': self.parse_field, | ||
216 | 'variant': self.parse_variant, | ||
217 | }) | ||
218 | |||
219 | if 'field' in results: | ||
220 | ret.fields += results['field'] | ||
221 | if 'fld' in results: | ||
222 | ret.fields += results['fld'] | ||
223 | if 'bit' in results: | ||
224 | ret.fields += results['bit'] | ||
225 | if 'variant' in results: | ||
226 | ret.fields += results['variant'] | ||
227 | else: | ||
228 | ret = Node(name) | ||
229 | |||
230 | if len(ret.instances) == 0: | ||
231 | if addr is None: | ||
232 | self.err("no address specified for register") | ||
233 | ret.instances.append(Instance(ret.name, addr)) | ||
234 | elif addr: | ||
235 | self.err("duplicate address specification for register") | ||
236 | |||
237 | ret.register_width = width | ||
238 | return ret | ||
239 | |||
240 | def parse_node_block(self, name, extra_parsers): | ||
241 | parsers = { | ||
242 | 'desc': (self.parse_string, 1), | ||
243 | 'addr': (self.parse_printable, 1), | ||
244 | 'instance': functools.partial(self.parse_instance, name), | ||
245 | } | ||
246 | |||
247 | parsers.update(extra_parsers) | ||
248 | results = self.parse_block(parsers) | ||
249 | ret = Node(name) | ||
250 | |||
251 | if 'desc' in results: | ||
252 | ret.desc = results['desc'][0] | ||
253 | if 'addr' in results: | ||
254 | ret.instances.append(Instance(ret.name, results['addr'][0])) | ||
255 | if 'instance' in results: | ||
256 | if 'addr' in results: | ||
257 | self.err('instance statement not allowed when addr is given') | ||
258 | |||
259 | ret.instances += results['instance'] | ||
260 | |||
261 | return ret, results | ||
262 | |||
263 | def parse_instance(self, default_name): | ||
264 | words = self.parse_wordline(False)[0] | ||
265 | |||
266 | if len(words) == 1: | ||
267 | # instance ADDR | ||
268 | return Instance(default_name, words[0]) | ||
269 | elif len(words) == 2: | ||
270 | # instance NAME ADDR | ||
271 | return Instance(words[0], words[1]) | ||
272 | elif len(words) == 3: | ||
273 | # instance ADDR STRIDE COUNT | ||
274 | return Instance(default_name, words[0], words[1], words[2]) | ||
275 | elif len(words) == 4: | ||
276 | # instance NAME ADDR STRIDE COUNT | ||
277 | return Instance(words[0], words[1], words[2], words[3]) | ||
278 | else: | ||
279 | self.err('malformed instance statement') | ||
280 | |||
281 | def parse_field(self): | ||
282 | words, has_block = self.parse_wordline(True) | ||
283 | name = None | ||
284 | msb = None | ||
285 | lsb = None | ||
286 | |||
287 | if len(words) == 2: | ||
288 | # field BIT NAME | ||
289 | lsb = msb = words[0] | ||
290 | name = words[1] | ||
291 | elif len(words) == 3: | ||
292 | # field MSB LSB NAME | ||
293 | msb = words[0] | ||
294 | lsb = words[1] | ||
295 | name = words[2] | ||
296 | else: | ||
297 | self.err('malformed field statement') | ||
298 | |||
299 | try: | ||
300 | int(msb) | ||
301 | int(lsb) | ||
302 | except: | ||
303 | self.err('field MSB/LSB must be integers') | ||
304 | |||
305 | ret = Field(name, msb, lsb) | ||
306 | if has_block: | ||
307 | results = self.parse_block({ | ||
308 | 'desc': self.parse_string, | ||
309 | 'enum': self.parse_enum, | ||
310 | }) | ||
311 | |||
312 | if 'desc' in results: | ||
313 | if len(results['desc']) > 1: | ||
314 | self.err("only one description allowed") | ||
315 | ret.desc = results['desc'][0] | ||
316 | |||
317 | if 'enum' in results: | ||
318 | ret.enums += results['enum'] | ||
319 | |||
320 | return ret | ||
321 | |||
322 | def parse_wordline(self, allow_block=False): | ||
323 | words = [] | ||
324 | self.eolstop = True | ||
325 | while(self.chr != '{' and self.chr != '}' and | ||
326 | self.chr != '\n' and self.chr != ';'): | ||
327 | words.append(self.parse_printable()) | ||
328 | self.eolstop = False | ||
329 | |||
330 | if len(words) == 0: | ||
331 | self.err('this type of statement cannot be empty') | ||
332 | |||
333 | if self.chr == '{': | ||
334 | if not allow_block: | ||
335 | self.err('this type of statement does not accept blocks') | ||
336 | has_block = True | ||
337 | else: | ||
338 | has_block = False | ||
339 | self.skipws() | ||
340 | |||
341 | return words, has_block | ||
342 | |||
343 | def parse_variant(self): | ||
344 | ty = self.parse_printable() | ||
345 | off = self.parse_printable() | ||
346 | return Variant(ty, off) | ||
347 | |||
348 | def parse_enum(self): | ||
349 | name = self.parse_printable() | ||
350 | value = self.parse_printable() | ||
351 | return (name, value) | ||
352 | |||
353 | def parse_block(self, parsers): | ||
354 | if self.chr != '{': | ||
355 | self.err("expected '{'") | ||
356 | self.next() | ||
357 | self.skipws() | ||
358 | |||
359 | ret = self.parse_block_inner(parsers) | ||
360 | |||
361 | assert self.chr == '}' | ||
362 | self.next() | ||
363 | self.skipws() | ||
364 | return ret | ||
365 | |||
366 | def parse_block_inner(self, parsers): | ||
367 | ret = {} | ||
368 | cnt = {} | ||
369 | while self.chr != '}' and self.chr != '\0': | ||
370 | kwd = self.parse_ident() | ||
371 | if kwd not in parsers: | ||
372 | self.err("invalid keyword for block") | ||
373 | |||
374 | if kwd not in ret: | ||
375 | ret[kwd] = [] | ||
376 | cnt[kwd] = 0 | ||
377 | |||
378 | pentry = parsers[kwd] | ||
379 | if type(pentry) is tuple and len(pentry) == 2: | ||
380 | pfunc = pentry[0] | ||
381 | max_cnt = pentry[1] | ||
382 | else: | ||
383 | pfunc = pentry | ||
384 | max_cnt = 0 | ||
385 | |||
386 | if max_cnt > 0 and cnt[kwd] == max_cnt: | ||
387 | if max_cnt == 1: | ||
388 | self.err("at most one '%s' statement allowed in this block" % kwd) | ||
389 | else: | ||
390 | self.err("at most %d '%s' statements allowed in this block" % (max_cnt, kwd)) | ||
391 | |||
392 | ret[kwd].append(pfunc()) | ||
393 | cnt[kwd] += 1 | ||
394 | |||
395 | return ret | ||
396 | |||
397 | def parse_ident(self): | ||
398 | ident = '' | ||
399 | while self.chr.isalnum() or self.chr == '_': | ||
400 | ident += self.chr | ||
401 | self.next() | ||
402 | |||
403 | if len(ident) == 0: | ||
404 | self.err("expected identifier") | ||
405 | |||
406 | self.skipws() | ||
407 | return ident | ||
408 | |||
409 | def parse_string(self): | ||
410 | if self.chr != '"': | ||
411 | self.err("expected string") | ||
412 | self.next() | ||
413 | |||
414 | s = '' | ||
415 | while self.chr != '"': | ||
416 | s += self.chr | ||
417 | self.next() | ||
418 | self.next() | ||
419 | |||
420 | self.skipws() | ||
421 | return s | ||
422 | |||
423 | def parse_printable(self): | ||
424 | s = '' | ||
425 | while not self.chr.isspace() and self.chr != ';': | ||
426 | s += self.chr | ||
427 | self.next() | ||
428 | |||
429 | self.skipws() | ||
430 | return s | ||
431 | |||
432 | def skipws(self): | ||
433 | while True: | ||
434 | if self.chr == '#': | ||
435 | while self.chr != '\n': | ||
436 | self.next() | ||
437 | if self.eolstop: | ||
438 | break | ||
439 | self.next() | ||
440 | elif self.chr == '\n' or self.chr == ';': | ||
441 | if self.eolstop: | ||
442 | break | ||
443 | self.next() | ||
444 | elif self.chr.isspace(): | ||
445 | self.next() | ||
446 | else: | ||
447 | break | ||
448 | |||
449 | def next(self): | ||
450 | self.chr = self.input.read(1) | ||
451 | if len(self.chr) == 0: | ||
452 | self.chr = '\0' | ||
453 | if self.chr == '\n': | ||
454 | self.line += 1 | ||
455 | return self.chr | ||
456 | |||
457 | def err(self, msg): | ||
458 | raise ValueError("on line %d: %s" % (self.line, msg)) | ||
459 | |||
460 | if __name__ == '__main__': | ||
461 | import sys | ||
462 | p = Parser(sys.stdin) | ||
463 | r = p.parse() | ||
464 | print('<?xml version="1.0"?>') | ||
465 | ET.dump(r.gen()) | ||
diff --git a/utils/reggen-ng/x1000.reggen b/utils/reggen-ng/x1000.reggen new file mode 100644 index 0000000000..3e5d976a0b --- /dev/null +++ b/utils/reggen-ng/x1000.reggen | |||
@@ -0,0 +1,742 @@ | |||
1 | name "x1000" | ||
2 | title "Ingenic X1000" | ||
3 | isa "mips" | ||
4 | version "1.0" | ||
5 | author "Aidan MacDonald" | ||
6 | |||
7 | node LCD { | ||
8 | title "LCD controller" | ||
9 | addr 0xb3050000 | ||
10 | |||
11 | reg CFG 0x00 { | ||
12 | bit 17 INVDAT | ||
13 | } | ||
14 | |||
15 | reg CTRL 0x30 { | ||
16 | fld 30 28 BURST { enum 4WORD 0; enum 8WORD 1; enum 16WORD 2; | ||
17 | enum 32WORD 3; enum 64WORD 4; } | ||
18 | bit 13 EOFM | ||
19 | bit 12 SOFM | ||
20 | bit 10 IFUM | ||
21 | bit 7 QDM | ||
22 | bit 6 BEDN | ||
23 | bit 5 PEDN | ||
24 | bit 3 ENABLE | ||
25 | fld 2 0 BPP { | ||
26 | enum 15BIT_OR_16BIT 4 | ||
27 | enum 18BIT_OR_24BIT 5 | ||
28 | enum 24BIT_COMPRESSED 6 | ||
29 | enum 30BIT 7 | ||
30 | } | ||
31 | } | ||
32 | |||
33 | reg STATE 0x34 { | ||
34 | bit 7 QD | ||
35 | bit 5 EOF | ||
36 | bit 4 SOF | ||
37 | bit 2 IFU | ||
38 | } | ||
39 | |||
40 | reg OSDCTRL 0x104 | ||
41 | reg BGC 0x10c | ||
42 | reg DAH 0x10 | ||
43 | reg DAV 0x14 | ||
44 | reg VAT 0x0c | ||
45 | reg VSYNC 0x04 | ||
46 | reg HSYNC 0x08 | ||
47 | |||
48 | reg IID 0x38 | ||
49 | reg DA 0x40 | ||
50 | |||
51 | reg MCFG 0xa0 { | ||
52 | # other fields are useless according to Ingenic | ||
53 | field 9 8 CWIDTH { | ||
54 | enum 16BIT_OR_9BIT 0 | ||
55 | enum 8BIT 1 | ||
56 | enum 18BIT 2 | ||
57 | enum 24BIT 3 | ||
58 | } | ||
59 | } | ||
60 | |||
61 | reg MCFG_NEW 0xb8 { | ||
62 | field 15 13 DWIDTH { | ||
63 | enum 8BIT 0 | ||
64 | enum 9BIT 1 | ||
65 | enum 16BIT 2 | ||
66 | enum 18BIT 3 | ||
67 | enum 24BIT 4 | ||
68 | } | ||
69 | |||
70 | field 9 8 DTIMES { | ||
71 | enum 1TIME 0 | ||
72 | enum 2TIME 1 | ||
73 | enum 3TIME 2 | ||
74 | } | ||
75 | |||
76 | bit 11 6800_MODE | ||
77 | bit 10 CMD_9BIT | ||
78 | bit 5 CSPLY | ||
79 | bit 4 RSPLY | ||
80 | bit 3 CLKPLY | ||
81 | bit 2 DTYPE { enum SERIAL 1; enum PARALLEL 0 } | ||
82 | bit 1 CTYPE { enum SERIAL 1; enum PARALLEL 0 } | ||
83 | bit 0 FMT_CONV | ||
84 | } | ||
85 | |||
86 | reg MCTRL 0xa4 { | ||
87 | bit 10 NARROW_TE | ||
88 | bit 9 TE_INV | ||
89 | bit 8 NOT_USE_TE | ||
90 | bit 7 DCSI_SEL | ||
91 | bit 6 MIPI_SLCD | ||
92 | bit 4 FAST_MODE | ||
93 | bit 3 GATE_MASK | ||
94 | bit 2 DMA_MODE | ||
95 | bit 1 DMA_START | ||
96 | bit 0 DMA_TX_EN | ||
97 | } | ||
98 | |||
99 | reg MSTATE 0xa8 { | ||
100 | fld 31 16 LCD_ID | ||
101 | bit 0 BUSY | ||
102 | } | ||
103 | |||
104 | reg MDATA 0xac { | ||
105 | fld 31 30 TYPE { enum CMD 1; enum DAT 0 } | ||
106 | fld 23 0 DATA | ||
107 | } | ||
108 | |||
109 | reg WTIME 0xb0 { | ||
110 | fld 31 24 DHTIME | ||
111 | fld 23 16 DLTIME | ||
112 | fld 15 8 CHTIME | ||
113 | fld 7 0 CLTIME | ||
114 | } | ||
115 | |||
116 | reg TASH 0xb4 { | ||
117 | fld 15 8 TAH | ||
118 | fld 7 0 TAS | ||
119 | } | ||
120 | |||
121 | reg SMWT 0xbc | ||
122 | } | ||
123 | |||
124 | node DDRC { | ||
125 | title "DDR controller AHB2 group" | ||
126 | desc "note: incomplete, only lists registers used by DDR init code" | ||
127 | addr 0xb34f0000 | ||
128 | |||
129 | reg STATUS 0x00 | ||
130 | reg CFG 0x04 | ||
131 | reg CTRL 0x08 | ||
132 | reg TIMING1 0x60 | ||
133 | reg TIMING2 0x64 | ||
134 | reg TIMING3 0x68 | ||
135 | reg TIMING4 0x6c | ||
136 | reg TIMING5 0x70 | ||
137 | reg TIMING6 0x74 | ||
138 | reg REFCNT 0x18 | ||
139 | reg MMAP0 0x24 | ||
140 | reg MMAP1 0x28 | ||
141 | reg DLP 0xbc | ||
142 | reg REMAP1 0x9c | ||
143 | reg REMAP2 0xa0 | ||
144 | reg REMAP3 0xa4 | ||
145 | reg REMAP4 0xa8 | ||
146 | reg REMAP5 0xac | ||
147 | reg AUTOSR_CNT 0x308 | ||
148 | reg AUTOSR_EN 0x304 | ||
149 | } | ||
150 | |||
151 | node DDRC_APB { | ||
152 | title "DDR controller APB group" | ||
153 | desc "note: incomplete, only lists registers used by DDR init code" | ||
154 | addr 0xb3012000 | ||
155 | |||
156 | reg CLKSTP_CFG 0x68 | ||
157 | reg PHYRST_CFG 0x80 | ||
158 | } | ||
159 | |||
160 | node DDRPHY { | ||
161 | title "DDR PHY group" | ||
162 | desc "note: incomplete, only lists registers used by DDR init code" | ||
163 | addr 0xb3011000 | ||
164 | |||
165 | reg PIR 0x04 | ||
166 | reg PGCR 0x08 | ||
167 | reg PGSR 0x0c | ||
168 | reg DLLGCR 0x10 | ||
169 | reg ACDLLCR 0x14 | ||
170 | reg PTR0 0x18 | ||
171 | reg PTR1 0x1c | ||
172 | reg PTR2 0x20 | ||
173 | reg ACIOCR 0x24 | ||
174 | reg DXCCR 0x28 | ||
175 | reg DSGCR 0x2c | ||
176 | reg DCR 0x30 | ||
177 | reg DTPR0 0x34 | ||
178 | reg DTPR1 0x38 | ||
179 | reg DTPR2 0x3c | ||
180 | reg MR0 0x40 | ||
181 | reg MR1 0x44 | ||
182 | reg MR2 0x48 | ||
183 | reg MR3 0x4c | ||
184 | reg DTAR 0x54 | ||
185 | reg DXGCR { instance 0x1c0 0x40 4 } | ||
186 | } | ||
187 | |||
188 | node CPM { | ||
189 | title "Clock, Reset and Power Manager" | ||
190 | addr 0xb0000000 | ||
191 | |||
192 | reg CCR 0x00 { | ||
193 | fld 31 30 SEL_SRC { enum STOP 0; enum EXCLK 1; enum APLL 2; } | ||
194 | fld 29 28 SEL_CPLL { enum STOP 0; enum SCLK_A 1; enum MPLL 2; } | ||
195 | fld 27 26 SEL_H0PLL { enum STOP 0; enum SCLK_A 1; enum MPLL 2; } | ||
196 | fld 25 24 SEL_H2PLL { enum STOP 0; enum SCLK_A 1; enum MPLL 2; } | ||
197 | bit 23 GATE_SCLKA | ||
198 | bit 22 CE_CPU | ||
199 | bit 21 CE_AHB0 | ||
200 | bit 20 CE_AHB2 | ||
201 | fld 19 16 PDIV | ||
202 | fld 15 12 H2DIV | ||
203 | fld 11 8 H0DIV | ||
204 | fld 7 4 L2DIV | ||
205 | fld 3 0 CDIV | ||
206 | } | ||
207 | |||
208 | reg CSR 0xd4 { | ||
209 | bit 31 SRC_MUX | ||
210 | bit 30 CPU_MUX | ||
211 | bit 29 AHB0_MUX | ||
212 | bit 28 AHB2_MUX | ||
213 | bit 27 DDR_MUX | ||
214 | bit 2 H2DIV_BUSY | ||
215 | bit 1 H0DIV_BUSY | ||
216 | bit 0 CDIV_BUSY | ||
217 | } | ||
218 | |||
219 | reg DDRCDR 0x2c { | ||
220 | fld 31 30 CLKSRC { enum STOP 0; enum SCLK_A 1; enum MPLL 2; } | ||
221 | bit 29 CE | ||
222 | bit 28 BUSY | ||
223 | bit 27 STOP | ||
224 | bit 26 GATE_EN | ||
225 | bit 25 CHANGE_EN | ||
226 | bit 24 FLAG | ||
227 | fld 3 0 CLKDIV | ||
228 | } | ||
229 | |||
230 | reg LPCDR 0x64 { | ||
231 | bit 31 CLKSRC { enum SCLK_A 0; enum MPLL 1; } | ||
232 | bit 28 CE | ||
233 | bit 27 BUSY | ||
234 | bit 26 STOP | ||
235 | fld 7 0 CLKDIV | ||
236 | } | ||
237 | |||
238 | reg MSC0CDR 0x68 { | ||
239 | bit 31 CLKSRC { enum SCLK_A 0; enum MPLL 1; } | ||
240 | bit 29 CE | ||
241 | bit 28 BUSY | ||
242 | bit 27 STOP | ||
243 | bit 15 S_CLK0_SEL { enum 90DEG 0; enum 180DEG 1; } | ||
244 | fld 7 0 CLKDIV | ||
245 | } | ||
246 | |||
247 | reg MSC1CDR 0xa4 { | ||
248 | bit 29 CE | ||
249 | bit 28 BUSY | ||
250 | bit 27 STOP | ||
251 | bit 15 S_CLK1_SEL { enum 90DEG 0; enum 180DEG 1; } | ||
252 | fld 7 0 CLKDIV | ||
253 | } | ||
254 | |||
255 | reg DRCG 0xd0 | ||
256 | |||
257 | reg APCR 0x10 { | ||
258 | bit 31 BS | ||
259 | fld 30 24 PLLM | ||
260 | fld 22 18 PLLN | ||
261 | fld 17 16 PLLOD | ||
262 | bit 15 LOCK | ||
263 | bit 10 ON | ||
264 | bit 9 BYPASS | ||
265 | bit 8 ENABLE | ||
266 | fld 7 0 PLLST | ||
267 | } | ||
268 | |||
269 | reg MPCR 0x14 { | ||
270 | bit 31 BS | ||
271 | fld 30 24 PLLM | ||
272 | fld 22 18 PLLN | ||
273 | fld 17 16 PLLOD | ||
274 | bit 7 ENABLE | ||
275 | bit 6 BYPASS | ||
276 | bit 1 LOCK | ||
277 | bit 0 ON | ||
278 | } | ||
279 | |||
280 | reg LCR 0x04 { | ||
281 | fld 19 8 PST | ||
282 | fld 1 0 LPM { enum IDLE 0; enum SLEEP 1 } | ||
283 | } | ||
284 | |||
285 | reg PSWC0ST 0x90 | ||
286 | reg PSWC1ST 0x94 | ||
287 | reg PSWC2ST 0x98 | ||
288 | reg PSWC3ST 0x9c | ||
289 | |||
290 | reg CLKGR 0x20 { | ||
291 | desc "Clock gate register" | ||
292 | bit 31 DDR | ||
293 | bit 30 CPU_BIT # can't be called CPU because Rockbox #defines that | ||
294 | bit 29 AHB0 | ||
295 | bit 28 APB0 | ||
296 | bit 27 RTC | ||
297 | bit 26 PCM | ||
298 | bit 25 MAC | ||
299 | bit 24 AES | ||
300 | bit 23 LCD | ||
301 | bit 22 CIM | ||
302 | bit 21 PDMA | ||
303 | bit 20 OST | ||
304 | bit 19 SSI | ||
305 | bit 18 TCU | ||
306 | bit 17 DMIC | ||
307 | bit 16 UART2 | ||
308 | bit 15 UART1 | ||
309 | bit 14 UART0 | ||
310 | bit 12 JPEG | ||
311 | bit 11 AIC | ||
312 | bit 9 I2C2 | ||
313 | bit 8 I2C1 | ||
314 | bit 7 I2C0 | ||
315 | bit 6 SCC | ||
316 | bit 5 MSC1 | ||
317 | bit 4 MSC0 | ||
318 | bit 3 OTG | ||
319 | bit 2 SFC | ||
320 | bit 1 EFUSE | ||
321 | } | ||
322 | } | ||
323 | |||
324 | node TCU { | ||
325 | title "Timer/counter unit" | ||
326 | addr 0xb0002000 | ||
327 | |||
328 | reg STATUS 0xf0 { variant set 4; variant clr 8 } | ||
329 | reg STOP 0x1c { variant set 0x10; variant clr 0x20 } | ||
330 | reg ENABLE 0x10 { variant set 4; variant clr 8 } | ||
331 | reg FLAG 0x20 { variant set 4; variant clr 8 } | ||
332 | reg MASK 0x30 { variant set 4; variant clr 8 } | ||
333 | reg CMP_FULL { | ||
334 | desc "called Data FULL by Ingenic" | ||
335 | instance 0x40 0x10 8 | ||
336 | } | ||
337 | reg CMP_HALF { | ||
338 | desc "called Data HALF by Ingenic" | ||
339 | instance 0x44 0x10 8 | ||
340 | } | ||
341 | reg COUNT { | ||
342 | instance 0x48 0x10 8 | ||
343 | } | ||
344 | reg CTRL { | ||
345 | instance 0x4c 0x10 8 | ||
346 | bit 11 BYPASS | ||
347 | bit 10 CLRZ | ||
348 | bit 9 SHUTDOWN { enum GRACEFUL 0; enum ABRUPT 1; } | ||
349 | bit 8 INIT_LVL | ||
350 | bit 7 PWM_EN | ||
351 | bit 6 PWM_IN_EN | ||
352 | fld 5 3 PRESCALE { enum BY_1 0; enum BY_4 1; enum BY_16 2; | ||
353 | enum BY_64 3; enum BY_256 4; enum BY_1024 5; } | ||
354 | fld 2 0 SOURCE { enum EXT 4; enum RTC 2; enum PCLK 1; } | ||
355 | } | ||
356 | } | ||
357 | |||
358 | node OST { | ||
359 | title "Operating system timer" | ||
360 | addr 0xb2000000 | ||
361 | |||
362 | reg CTRL 0x00 { | ||
363 | field 5 3 PRESCALE2 { enum BY_1 0; enum BY_4 1; enum BY_16 2; } | ||
364 | field 2 0 PRESCALE1 { enum BY_1 0; enum BY_4 1; enum BY_16 2; } | ||
365 | } | ||
366 | |||
367 | reg ENABLE 0x04 { | ||
368 | variant set 0x30 | ||
369 | variant clr 0x34 | ||
370 | bit 0 OST1 | ||
371 | bit 1 OST2 | ||
372 | } | ||
373 | |||
374 | reg CLEAR 0x08 { | ||
375 | bit 0 OST1 | ||
376 | bit 1 OST2 | ||
377 | } | ||
378 | |||
379 | reg 1FLG 0x0c | ||
380 | reg 1MSK 0x10 | ||
381 | reg 1DFR 0x14 | ||
382 | reg 1CNT 0x18 | ||
383 | |||
384 | reg 2CNTH 0x1c | ||
385 | reg 2CNTL 0x20 | ||
386 | reg 2CNTHB 0x24 | ||
387 | } | ||
388 | |||
389 | node INTC { | ||
390 | title "Interrupt controller" | ||
391 | # Documented address in Ingenic's manual is a typo (= GPIO base address). | ||
392 | # This is the correct address from their Linux source. | ||
393 | addr 0xb0001000 | ||
394 | |||
395 | reg SRC { instance 0x00 0x20 2 } | ||
396 | reg MSK { instance 0x04 0x20 2; variant set 4; variant clr 8 } | ||
397 | reg PND { instance 0x10 0x20 2 } | ||
398 | } | ||
399 | |||
400 | node WDT { | ||
401 | title "Watchdog timer" | ||
402 | addr 0xb0002000 | ||
403 | |||
404 | reg DATA 0x00 | ||
405 | reg ENABLE 0x04 | ||
406 | reg COUNT 0x08 | ||
407 | |||
408 | reg CTRL 0x0c { | ||
409 | field 5 3 PRESCALE { enum BY_1 0; enum BY_4 1; enum BY_16 2; | ||
410 | enum BY_64 3; enum BY_256 4; enum BY_1024 5; } | ||
411 | field 2 0 SOURCE { enum EXT 4; enum RTC 2; enum PLCK 1; } | ||
412 | } | ||
413 | } | ||
414 | |||
415 | node RTC { | ||
416 | title "Realtime clock" | ||
417 | addr 0xb0003000 | ||
418 | |||
419 | reg CR 0x00 | ||
420 | reg SR 0x04 | ||
421 | reg SAR 0x08 | ||
422 | reg GR 0x0c | ||
423 | reg HCR 0x20 | ||
424 | reg WFCR 0x24 | ||
425 | reg RCR 0x28 | ||
426 | reg WCR 0x2c | ||
427 | reg RSR 0x30 | ||
428 | reg SPR 0x34 | ||
429 | reg WENR 0x3c | ||
430 | reg WKUPPINCR 0x48 | ||
431 | } | ||
432 | |||
433 | node GPIO { | ||
434 | title "General purpose I/O" | ||
435 | addr 0xb0010000 | ||
436 | |||
437 | # Note: only instances 0-3 and 7 are instantiated in hardware | ||
438 | reg PIN { instance 0x00 0x100 8 } | ||
439 | reg INT { instance 0x10 0x100 8; variant set 4; variant clr 8 } | ||
440 | reg MSK { instance 0x20 0x100 8; variant set 4; variant clr 8 } | ||
441 | reg PAT1 { instance 0x30 0x100 8; variant set 4; variant clr 8 } | ||
442 | reg PAT0 { instance 0x40 0x100 8; variant set 4; variant clr 8 } | ||
443 | reg FLAG { instance 0x50 0x100 8; variant clr 8 } | ||
444 | reg PULL { instance 0x70 0x100 8; variant set 4; variant clr 8 } | ||
445 | |||
446 | node C_GLITCH { | ||
447 | desc "GPIO port C: glitch filter registers" | ||
448 | addr 0x200 | ||
449 | reg CFG0 0x800 { variant set 4; variant clr 8 } | ||
450 | reg CFG1 0x810 { variant set 4; variant clr 8 } | ||
451 | reg CFG2 0x820 { variant set 4; variant clr 8 } | ||
452 | reg CFG3 0x830 { variant set 4; variant clr 8 } | ||
453 | } | ||
454 | |||
455 | reg Z_GID2LD { | ||
456 | desc "GPIO port Z: atomic load register" | ||
457 | addr 0x7f0 | ||
458 | } | ||
459 | } | ||
460 | |||
461 | node I2C { | ||
462 | title "I2C bus controller" | ||
463 | instance 0xb0050000 0x1000 3 | ||
464 | |||
465 | reg CON 0x00 { | ||
466 | bit 6 SLVDIS | ||
467 | bit 5 RESTART | ||
468 | bit 4 MATP | ||
469 | bit 3 SATP | ||
470 | fld 2 1 SPEED { enum 100K 1; enum 400K 2; } | ||
471 | bit 0 MD | ||
472 | } | ||
473 | |||
474 | reg DC 0x10 { | ||
475 | bit 10 RESTART | ||
476 | bit 9 STOP | ||
477 | bit 8 CMD | ||
478 | fld 7 0 DAT | ||
479 | } | ||
480 | |||
481 | reg INTST 0x2c { | ||
482 | bit 11 GC | ||
483 | bit 10 STT | ||
484 | bit 9 STP | ||
485 | bit 8 ACT | ||
486 | bit 7 RXDN | ||
487 | bit 6 TXABT | ||
488 | bit 5 RDREQ | ||
489 | bit 4 TXEMP | ||
490 | bit 3 TXOF | ||
491 | bit 2 RXFL | ||
492 | bit 1 RXOF | ||
493 | bit 0 RXUF | ||
494 | } | ||
495 | |||
496 | reg INTMSK 0x30 { | ||
497 | bit 11 GC | ||
498 | bit 10 STT | ||
499 | bit 9 STP | ||
500 | bit 8 ACT | ||
501 | bit 7 RXDN | ||
502 | bit 6 TXABT | ||
503 | bit 5 RDREQ | ||
504 | bit 4 TXEMP | ||
505 | bit 3 TXOF | ||
506 | bit 2 RXFL | ||
507 | bit 1 RXOF | ||
508 | bit 0 RXUF | ||
509 | } | ||
510 | |||
511 | reg RINTST 0x34 { | ||
512 | bit 11 GC | ||
513 | bit 10 STT | ||
514 | bit 9 STP | ||
515 | bit 8 ACT | ||
516 | bit 7 RXDN | ||
517 | bit 6 TXABT | ||
518 | bit 5 RDREQ | ||
519 | bit 4 TXEMP | ||
520 | bit 3 TXOF | ||
521 | bit 2 RXFL | ||
522 | bit 1 RXOF | ||
523 | bit 0 RXUF | ||
524 | } | ||
525 | |||
526 | reg ENABLE 0x6c { | ||
527 | bit 1 ABORT | ||
528 | bit 0 ACTIVE | ||
529 | } | ||
530 | |||
531 | reg STATUS 0x70 { | ||
532 | bit 6 SLVACT | ||
533 | bit 5 MSTACT | ||
534 | bit 4 RFF | ||
535 | bit 3 RFNE | ||
536 | bit 2 TFE | ||
537 | bit 1 TFNF | ||
538 | bit 0 ACT | ||
539 | } | ||
540 | |||
541 | reg ENBST 0x9c { | ||
542 | bit 2 SLVRDLST | ||
543 | bit 1 SLVDISB | ||
544 | bit 0 ACTIVE | ||
545 | } | ||
546 | |||
547 | reg TAR 0x04 | ||
548 | reg SAR 0x08 | ||
549 | reg SHCNT 0x14 | ||
550 | reg SLCNT 0x18 | ||
551 | reg FHCNT 0x1c | ||
552 | reg FLCNT 0x20 | ||
553 | reg RXTL 0x38 | ||
554 | reg TXTL 0x3c | ||
555 | reg TXFLR 0x74 | ||
556 | reg RXFLR 0x78 | ||
557 | reg SDAHD 0x7c | ||
558 | reg ABTSRC 0x80 | ||
559 | reg DMACR 0x88 | ||
560 | reg DMATDLR 0x8c | ||
561 | reg DMARDLR 0x90 | ||
562 | reg SDASU 0x94 | ||
563 | reg ACKGC 0x98 | ||
564 | reg FLT 0xa0 | ||
565 | |||
566 | reg CINT 0x40 | ||
567 | reg CRXUF 0x44 | ||
568 | reg CRXOF 0x48 | ||
569 | reg CTXOF 0x4c | ||
570 | reg CRXREQ 0x50 | ||
571 | reg CTXABT 0x54 | ||
572 | reg CRXDN 0x58 | ||
573 | reg CACT 0x5c | ||
574 | reg CSTP 0x60 | ||
575 | reg CSTT 0x64 | ||
576 | reg CGC 0x68 | ||
577 | } | ||
578 | |||
579 | node MSC { | ||
580 | title "MMC/SD/CE-ATA controller" | ||
581 | instance 0xb3450000 0x10000 2 | ||
582 | |||
583 | reg CTRL 0x00 { | ||
584 | bit 15 SEND_CCSD | ||
585 | bit 14 SEND_AS_CCSD | ||
586 | bit 7 EXIT_MULTIPLE | ||
587 | bit 6 EXIT_TRANSFER | ||
588 | bit 5 START_READ_WAIT | ||
589 | bit 4 STOP_READ_WAIT | ||
590 | bit 3 RESET | ||
591 | bit 2 START_OP | ||
592 | fld 1 0 CLOCK { enum DO_NOTHING 0; enum STOP 1; enum START 2; } | ||
593 | } | ||
594 | |||
595 | reg STAT 0x04 { | ||
596 | bit 31 AUTO_CMD12_DONE | ||
597 | fld 28 24 PINS | ||
598 | bit 20 BCE | ||
599 | bit 19 BDE | ||
600 | bit 18 BAE | ||
601 | bit 17 BAR | ||
602 | bit 16 DMAEND | ||
603 | bit 15 IS_RESETTING | ||
604 | bit 14 SDIO_INT_ACTIVE | ||
605 | bit 13 PROG_DONE | ||
606 | bit 12 DATA_TRAN_DONE | ||
607 | bit 11 END_CMD_RES | ||
608 | bit 10 DATA_FIFO_AFULL | ||
609 | bit 9 IS_READ_WAIT | ||
610 | bit 8 CLOCK_EN | ||
611 | bit 7 DATA_FIFO_FULL | ||
612 | bit 6 DATA_FIFO_EMPTY | ||
613 | bit 5 CRC_RES_ERROR | ||
614 | bit 4 CRC_READ_ERROR | ||
615 | fld 3 2 CRC_WRITE_ERROR { enum NONE 0; enum BADDATA 1; enum NOCRC 2 } | ||
616 | bit 1 TIME_OUT_RES | ||
617 | bit 0 TIME_OUT_READ | ||
618 | } | ||
619 | |||
620 | reg CMDAT 0x0c { | ||
621 | bit 31 CCS_EXPECTED | ||
622 | bit 30 READ_CEATA | ||
623 | bit 27 DIS_BOOT | ||
624 | bit 25 EXP_BOOT_ACK | ||
625 | bit 24 BOOT_MODE | ||
626 | bit 17 SDIO_PRDT | ||
627 | bit 16 AUTO_CMD12 | ||
628 | fld 15 14 RTRG { enum GE16 0; enum GE32 1; enum GE64 2; enum GE96 3 } | ||
629 | fld 13 12 TTRG { enum LE16 0; enum LE32 1; enum LE64 2; enum LE96 3 } | ||
630 | bit 11 IO_ABORT | ||
631 | fld 10 9 BUS_WIDTH { enum 1BIT 0; enum 4BIT 2; enum 8BIT 3; } | ||
632 | bit 7 INIT | ||
633 | bit 6 BUSY | ||
634 | bit 5 STREAM_BLOCK | ||
635 | bit 4 WRITE_READ | ||
636 | bit 3 DATA_EN | ||
637 | fld 2 0 RESP_FMT | ||
638 | } | ||
639 | |||
640 | reg IMASK 0x24 { | ||
641 | bit 31 DMA_DATA_DONE | ||
642 | fld 28 24 PINS | ||
643 | bit 23 WR_ALL_DONE | ||
644 | bit 20 BCE | ||
645 | bit 19 BDE | ||
646 | bit 18 BAE | ||
647 | bit 17 BAR | ||
648 | bit 16 DMAEND | ||
649 | bit 15 AUTO_CMD12_DONE | ||
650 | bit 14 DATA_FIFO_FULL | ||
651 | bit 13 DATA_FIFO_EMPTY | ||
652 | bit 12 CRC_RES_ERROR | ||
653 | bit 11 CRC_READ_ERROR | ||
654 | bit 10 CRC_WRITE_ERROR | ||
655 | bit 9 TIME_OUT_RES | ||
656 | bit 8 TIME_OUT_READ | ||
657 | bit 7 SDIO | ||
658 | bit 6 TXFIFO_WR_REQ | ||
659 | bit 5 RXFIFO_RD_REQ | ||
660 | bit 2 END_CMD_RES | ||
661 | bit 1 PROG_DONE | ||
662 | bit 0 DATA_TRAN_DONE | ||
663 | } | ||
664 | |||
665 | reg IFLAG 0x28 { | ||
666 | bit 31 DMA_DATA_DONE | ||
667 | fld 28 24 PINS | ||
668 | bit 23 WR_ALL_DONE | ||
669 | bit 20 BCE | ||
670 | bit 19 BDE | ||
671 | bit 18 BAE | ||
672 | bit 17 BAR | ||
673 | bit 16 DMAEND | ||
674 | bit 15 AUTO_CMD12_DONE | ||
675 | bit 14 DATA_FIFO_FULL | ||
676 | bit 13 DATA_FIFO_EMPTY | ||
677 | bit 12 CRC_RES_ERROR | ||
678 | bit 11 CRC_READ_ERROR | ||
679 | bit 10 CRC_WRITE_ERROR | ||
680 | bit 9 TIME_OUT_RES | ||
681 | bit 8 TIME_OUT_READ | ||
682 | bit 7 SDIO | ||
683 | bit 6 TXFIFO_WR_REQ | ||
684 | bit 5 RXFIFO_RD_REQ | ||
685 | bit 2 END_CMD_RES | ||
686 | bit 1 PROG_DONE | ||
687 | bit 0 DATA_TRAN_DONE | ||
688 | } | ||
689 | |||
690 | reg LPM 0x40 { | ||
691 | fld 31 30 DRV_SEL { | ||
692 | enum FALL_EDGE 0 | ||
693 | enum RISE_EDGE_DELAY_1NS 1 | ||
694 | enum RISE_EDGE_DELAY_QTR_PHASE 2 | ||
695 | } | ||
696 | |||
697 | fld 29 28 SMP_SEL { | ||
698 | enum RISE_EDGE 0 | ||
699 | enum RISE_EDGE_DELAYED 1 | ||
700 | } | ||
701 | |||
702 | bit 0 ENABLE | ||
703 | } | ||
704 | |||
705 | reg DMAC 0x44 { | ||
706 | bit 7 MODE_SEL | ||
707 | fld 6 5 ADDR_OFFSET | ||
708 | bit 4 ALIGN_EN | ||
709 | fld 3 2 INCR | ||
710 | bit 1 DMASEL | ||
711 | bit 0 ENABLE | ||
712 | } | ||
713 | |||
714 | reg CTRL2 0x58 { | ||
715 | fld 28 24 PIN_INT_POLARITY | ||
716 | bit 4 STPRM | ||
717 | fld 2 0 SPEED { | ||
718 | enum DEFAULT 0 | ||
719 | enum HIGHSPEED 1 | ||
720 | enum SDR12 2 | ||
721 | enum SDR25 3 | ||
722 | enum SDR50 4 | ||
723 | } | ||
724 | } | ||
725 | |||
726 | reg CLKRT 0x08 | ||
727 | reg RESTO 0x10 | ||
728 | reg RDTO 0x14 | ||
729 | reg BLKLEN 0x18 | ||
730 | reg NOB 0x1c | ||
731 | reg SNOB 0x20 | ||
732 | reg CMD 0x2c | ||
733 | reg ARG 0x30 | ||
734 | reg RES 0x34 | ||
735 | reg RXFIFO 0x38 | ||
736 | reg TXFIFO 0x3c | ||
737 | reg DMANDA 0x48 | ||
738 | reg DMADA 0x4c | ||
739 | reg DMALEN 0x50 | ||
740 | reg DMACMD 0x54 | ||
741 | reg RTCNT 0x5c | ||
742 | } | ||