summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-02-27 22:05:11 +0000
committerAidan MacDonald <amachronic@protonmail.com>2021-03-02 00:36:01 +0000
commit73cee8f17702d0fdc3e0508e8cf7193faae5f015 (patch)
treed83cb08541a2f78f1e7512de7abd0ce788eb8eb5
parent7418ec5009a0203b562bcf128713ef741815fe0e (diff)
downloadrockbox-73cee8f17702d0fdc3e0508e8cf7193faae5f015.tar.gz
rockbox-73cee8f17702d0fdc3e0508e8cf7193faae5f015.zip
Add RegGen-NG tool and definitions for Ingenic X1000
Change-Id: Ib9ec35c068e1cff8dcf120a13cfe3f5f58908a95
-rwxr-xr-xutils/reggen-ng/reggen-ng.py465
-rw-r--r--utils/reggen-ng/x1000.reggen742
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
11from lxml import etree as ET
12from lxml.builder import E
13import functools
14
15class 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
41class 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
75class 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
96class 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
120class 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
130class 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
460if __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 @@
1name "x1000"
2title "Ingenic X1000"
3isa "mips"
4version "1.0"
5author "Aidan MacDonald"
6
7node 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
124node 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
151node 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
160node 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
188node 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
324node 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
358node 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
389node 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
400node 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
415node 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
433node 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
461node 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
579node 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}