forked from len0rd/rockbox
Add RegGen-NG tool and definitions for Ingenic X1000
Change-Id: Ib9ec35c068e1cff8dcf120a13cfe3f5f58908a95
This commit is contained in:
parent
7418ec5009
commit
73cee8f177
2 changed files with 1207 additions and 0 deletions
465
utils/reggen-ng/reggen-ng.py
Executable file
465
utils/reggen-ng/reggen-ng.py
Executable file
|
@ -0,0 +1,465 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
#
|
||||||
|
# Tool to generate XML files for Rockbox regtools. The syntax is pretty simple
|
||||||
|
# and much less verbose than XML; see the '.reggen' files next to this script.
|
||||||
|
#
|
||||||
|
# Currently this tool expects a 'reggen' file on standard input and writes the
|
||||||
|
# equivalent XML to standard output.
|
||||||
|
#
|
||||||
|
# TODO: document this better and improve the command line usage
|
||||||
|
|
||||||
|
from lxml import etree as ET
|
||||||
|
from lxml.builder import E
|
||||||
|
import functools
|
||||||
|
|
||||||
|
class Soc:
|
||||||
|
def __init__(self):
|
||||||
|
self.name = None
|
||||||
|
self.title = None
|
||||||
|
self.desc = None
|
||||||
|
self.isa = None
|
||||||
|
self.version = None
|
||||||
|
self.authors = []
|
||||||
|
self.nodes = []
|
||||||
|
|
||||||
|
def gen(self):
|
||||||
|
node = E("soc", version="2")
|
||||||
|
if self.name is not None:
|
||||||
|
node.append(E("name", self.name))
|
||||||
|
if self.desc is not None:
|
||||||
|
node.append(E("desc", self.desc))
|
||||||
|
if self.isa is not None:
|
||||||
|
node.append(E("isa", self.isa))
|
||||||
|
if self.isa is not None:
|
||||||
|
node.append(E("version", self.version))
|
||||||
|
for a in self.authors:
|
||||||
|
node.append(E("author", a))
|
||||||
|
for n in self.nodes:
|
||||||
|
node.append(n.gen())
|
||||||
|
return node
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
self.title = None
|
||||||
|
self.desc = None
|
||||||
|
self.instances = []
|
||||||
|
self.children = []
|
||||||
|
self.register_width = None
|
||||||
|
self.fields = []
|
||||||
|
|
||||||
|
def gen(self):
|
||||||
|
node = E("node", E("name", self.name))
|
||||||
|
|
||||||
|
if self.title is not None:
|
||||||
|
node.append(E("title", self.title))
|
||||||
|
|
||||||
|
if self.desc is not None:
|
||||||
|
node.append(E("desc", self.desc))
|
||||||
|
|
||||||
|
for i in self.instances:
|
||||||
|
node.append(i.gen())
|
||||||
|
|
||||||
|
for c in self.children:
|
||||||
|
node.append(c.gen())
|
||||||
|
|
||||||
|
if self.register_width is not None:
|
||||||
|
reg = E("register",
|
||||||
|
E("width", self.register_width))
|
||||||
|
for f in self.fields:
|
||||||
|
reg.append(f.gen())
|
||||||
|
node.append(reg)
|
||||||
|
|
||||||
|
return node
|
||||||
|
|
||||||
|
class Instance:
|
||||||
|
def __init__(self, name, addr, stride=None, count=None):
|
||||||
|
self.name = name
|
||||||
|
self.address = addr
|
||||||
|
self.stride = stride
|
||||||
|
self.count = count
|
||||||
|
|
||||||
|
def gen(self):
|
||||||
|
node = E("instance", E("name", self.name))
|
||||||
|
|
||||||
|
if self.stride is not None:
|
||||||
|
node.append(E("range",
|
||||||
|
E("first", "0"),
|
||||||
|
E("count", self.count),
|
||||||
|
E("base", self.address),
|
||||||
|
E("stride", self.stride)))
|
||||||
|
else:
|
||||||
|
node.append(E("address", self.address))
|
||||||
|
|
||||||
|
return node
|
||||||
|
|
||||||
|
class Field:
|
||||||
|
def __init__(self, name, msb, lsb):
|
||||||
|
self.name = name
|
||||||
|
self.desc = None
|
||||||
|
self.msb = int(msb)
|
||||||
|
self.lsb = int(lsb)
|
||||||
|
self.enums = []
|
||||||
|
|
||||||
|
def gen(self):
|
||||||
|
node = E("field",
|
||||||
|
E("name", self.name),
|
||||||
|
E("position", "%d" % self.lsb))
|
||||||
|
|
||||||
|
if self.desc is not None:
|
||||||
|
node.append(E("desc", self.desc))
|
||||||
|
|
||||||
|
if self.msb != self.lsb:
|
||||||
|
node.append(E("width", str(self.msb - self.lsb + 1)))
|
||||||
|
|
||||||
|
for n, v in self.enums:
|
||||||
|
node.append(E("enum", E("name", n), E("value", v)))
|
||||||
|
|
||||||
|
return node
|
||||||
|
|
||||||
|
class Variant:
|
||||||
|
def __init__(self, ty, offset):
|
||||||
|
self.type = ty
|
||||||
|
self.offset = offset
|
||||||
|
|
||||||
|
def gen(self):
|
||||||
|
return E("variant",
|
||||||
|
E("type", self.type),
|
||||||
|
E("offset", self.offset))
|
||||||
|
|
||||||
|
class Parser:
|
||||||
|
def __init__(self, f):
|
||||||
|
self.input = f
|
||||||
|
self.line = 1
|
||||||
|
self.eolstop = False
|
||||||
|
self.next()
|
||||||
|
|
||||||
|
def parse(self):
|
||||||
|
self.skipws()
|
||||||
|
results = self.parse_block_inner({
|
||||||
|
'name': (self.parse_string, 1),
|
||||||
|
'title': (self.parse_string, 1),
|
||||||
|
'desc': (self.parse_string, 1),
|
||||||
|
'isa': (self.parse_string, 1),
|
||||||
|
'version': (self.parse_string, 1),
|
||||||
|
'author': self.parse_string,
|
||||||
|
'node': self.parse_node,
|
||||||
|
'reg': self.parse_register,
|
||||||
|
})
|
||||||
|
|
||||||
|
ret = Soc()
|
||||||
|
|
||||||
|
if 'name' in results:
|
||||||
|
ret.name = results['name'][0]
|
||||||
|
else:
|
||||||
|
self.err('missing "name" statement at toplevel')
|
||||||
|
|
||||||
|
if 'title' in results:
|
||||||
|
ret.title = results['title'][0]
|
||||||
|
if 'desc' in results:
|
||||||
|
ret.desc = results['desc'][0]
|
||||||
|
if 'isa' in results:
|
||||||
|
ret.isa = results['isa'][0]
|
||||||
|
if 'version' in results:
|
||||||
|
ret.version = results['version'][0]
|
||||||
|
if 'author' in results:
|
||||||
|
ret.authors += results['author']
|
||||||
|
if 'node' in results:
|
||||||
|
ret.nodes += results['node']
|
||||||
|
if 'reg' in results:
|
||||||
|
ret.nodes += results['reg']
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def parse_node(self):
|
||||||
|
name = self.parse_ident()
|
||||||
|
ret, results = self.parse_node_block(name, {
|
||||||
|
'title': (self.parse_string, 1),
|
||||||
|
'node': self.parse_node,
|
||||||
|
'reg': self.parse_register,
|
||||||
|
})
|
||||||
|
|
||||||
|
if 'title' in results:
|
||||||
|
ret.title = results['title'][0]
|
||||||
|
if 'node' in results:
|
||||||
|
ret.children += results['node']
|
||||||
|
if 'reg' in results:
|
||||||
|
ret.children += results['reg']
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def parse_register(self):
|
||||||
|
words, has_block = self.parse_wordline(True)
|
||||||
|
name = words[0]
|
||||||
|
width = "32"
|
||||||
|
addr = None
|
||||||
|
|
||||||
|
if len(words) == 1:
|
||||||
|
# reg NAME
|
||||||
|
pass
|
||||||
|
elif len(words) == 2:
|
||||||
|
# reg NAME ADDR
|
||||||
|
addr = words[1]
|
||||||
|
elif len(words) == 3:
|
||||||
|
# reg WIDTH NAME ADDR
|
||||||
|
name = words[1]
|
||||||
|
width = words[0]
|
||||||
|
addr = words[2]
|
||||||
|
else:
|
||||||
|
self.err('malformed register statement')
|
||||||
|
|
||||||
|
if has_block:
|
||||||
|
ret, results = self.parse_node_block(name, {
|
||||||
|
'field': self.parse_field,
|
||||||
|
'fld': self.parse_field,
|
||||||
|
'bit': self.parse_field,
|
||||||
|
'variant': self.parse_variant,
|
||||||
|
})
|
||||||
|
|
||||||
|
if 'field' in results:
|
||||||
|
ret.fields += results['field']
|
||||||
|
if 'fld' in results:
|
||||||
|
ret.fields += results['fld']
|
||||||
|
if 'bit' in results:
|
||||||
|
ret.fields += results['bit']
|
||||||
|
if 'variant' in results:
|
||||||
|
ret.fields += results['variant']
|
||||||
|
else:
|
||||||
|
ret = Node(name)
|
||||||
|
|
||||||
|
if len(ret.instances) == 0:
|
||||||
|
if addr is None:
|
||||||
|
self.err("no address specified for register")
|
||||||
|
ret.instances.append(Instance(ret.name, addr))
|
||||||
|
elif addr:
|
||||||
|
self.err("duplicate address specification for register")
|
||||||
|
|
||||||
|
ret.register_width = width
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def parse_node_block(self, name, extra_parsers):
|
||||||
|
parsers = {
|
||||||
|
'desc': (self.parse_string, 1),
|
||||||
|
'addr': (self.parse_printable, 1),
|
||||||
|
'instance': functools.partial(self.parse_instance, name),
|
||||||
|
}
|
||||||
|
|
||||||
|
parsers.update(extra_parsers)
|
||||||
|
results = self.parse_block(parsers)
|
||||||
|
ret = Node(name)
|
||||||
|
|
||||||
|
if 'desc' in results:
|
||||||
|
ret.desc = results['desc'][0]
|
||||||
|
if 'addr' in results:
|
||||||
|
ret.instances.append(Instance(ret.name, results['addr'][0]))
|
||||||
|
if 'instance' in results:
|
||||||
|
if 'addr' in results:
|
||||||
|
self.err('instance statement not allowed when addr is given')
|
||||||
|
|
||||||
|
ret.instances += results['instance']
|
||||||
|
|
||||||
|
return ret, results
|
||||||
|
|
||||||
|
def parse_instance(self, default_name):
|
||||||
|
words = self.parse_wordline(False)[0]
|
||||||
|
|
||||||
|
if len(words) == 1:
|
||||||
|
# instance ADDR
|
||||||
|
return Instance(default_name, words[0])
|
||||||
|
elif len(words) == 2:
|
||||||
|
# instance NAME ADDR
|
||||||
|
return Instance(words[0], words[1])
|
||||||
|
elif len(words) == 3:
|
||||||
|
# instance ADDR STRIDE COUNT
|
||||||
|
return Instance(default_name, words[0], words[1], words[2])
|
||||||
|
elif len(words) == 4:
|
||||||
|
# instance NAME ADDR STRIDE COUNT
|
||||||
|
return Instance(words[0], words[1], words[2], words[3])
|
||||||
|
else:
|
||||||
|
self.err('malformed instance statement')
|
||||||
|
|
||||||
|
def parse_field(self):
|
||||||
|
words, has_block = self.parse_wordline(True)
|
||||||
|
name = None
|
||||||
|
msb = None
|
||||||
|
lsb = None
|
||||||
|
|
||||||
|
if len(words) == 2:
|
||||||
|
# field BIT NAME
|
||||||
|
lsb = msb = words[0]
|
||||||
|
name = words[1]
|
||||||
|
elif len(words) == 3:
|
||||||
|
# field MSB LSB NAME
|
||||||
|
msb = words[0]
|
||||||
|
lsb = words[1]
|
||||||
|
name = words[2]
|
||||||
|
else:
|
||||||
|
self.err('malformed field statement')
|
||||||
|
|
||||||
|
try:
|
||||||
|
int(msb)
|
||||||
|
int(lsb)
|
||||||
|
except:
|
||||||
|
self.err('field MSB/LSB must be integers')
|
||||||
|
|
||||||
|
ret = Field(name, msb, lsb)
|
||||||
|
if has_block:
|
||||||
|
results = self.parse_block({
|
||||||
|
'desc': self.parse_string,
|
||||||
|
'enum': self.parse_enum,
|
||||||
|
})
|
||||||
|
|
||||||
|
if 'desc' in results:
|
||||||
|
if len(results['desc']) > 1:
|
||||||
|
self.err("only one description allowed")
|
||||||
|
ret.desc = results['desc'][0]
|
||||||
|
|
||||||
|
if 'enum' in results:
|
||||||
|
ret.enums += results['enum']
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def parse_wordline(self, allow_block=False):
|
||||||
|
words = []
|
||||||
|
self.eolstop = True
|
||||||
|
while(self.chr != '{' and self.chr != '}' and
|
||||||
|
self.chr != '\n' and self.chr != ';'):
|
||||||
|
words.append(self.parse_printable())
|
||||||
|
self.eolstop = False
|
||||||
|
|
||||||
|
if len(words) == 0:
|
||||||
|
self.err('this type of statement cannot be empty')
|
||||||
|
|
||||||
|
if self.chr == '{':
|
||||||
|
if not allow_block:
|
||||||
|
self.err('this type of statement does not accept blocks')
|
||||||
|
has_block = True
|
||||||
|
else:
|
||||||
|
has_block = False
|
||||||
|
self.skipws()
|
||||||
|
|
||||||
|
return words, has_block
|
||||||
|
|
||||||
|
def parse_variant(self):
|
||||||
|
ty = self.parse_printable()
|
||||||
|
off = self.parse_printable()
|
||||||
|
return Variant(ty, off)
|
||||||
|
|
||||||
|
def parse_enum(self):
|
||||||
|
name = self.parse_printable()
|
||||||
|
value = self.parse_printable()
|
||||||
|
return (name, value)
|
||||||
|
|
||||||
|
def parse_block(self, parsers):
|
||||||
|
if self.chr != '{':
|
||||||
|
self.err("expected '{'")
|
||||||
|
self.next()
|
||||||
|
self.skipws()
|
||||||
|
|
||||||
|
ret = self.parse_block_inner(parsers)
|
||||||
|
|
||||||
|
assert self.chr == '}'
|
||||||
|
self.next()
|
||||||
|
self.skipws()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def parse_block_inner(self, parsers):
|
||||||
|
ret = {}
|
||||||
|
cnt = {}
|
||||||
|
while self.chr != '}' and self.chr != '\0':
|
||||||
|
kwd = self.parse_ident()
|
||||||
|
if kwd not in parsers:
|
||||||
|
self.err("invalid keyword for block")
|
||||||
|
|
||||||
|
if kwd not in ret:
|
||||||
|
ret[kwd] = []
|
||||||
|
cnt[kwd] = 0
|
||||||
|
|
||||||
|
pentry = parsers[kwd]
|
||||||
|
if type(pentry) is tuple and len(pentry) == 2:
|
||||||
|
pfunc = pentry[0]
|
||||||
|
max_cnt = pentry[1]
|
||||||
|
else:
|
||||||
|
pfunc = pentry
|
||||||
|
max_cnt = 0
|
||||||
|
|
||||||
|
if max_cnt > 0 and cnt[kwd] == max_cnt:
|
||||||
|
if max_cnt == 1:
|
||||||
|
self.err("at most one '%s' statement allowed in this block" % kwd)
|
||||||
|
else:
|
||||||
|
self.err("at most %d '%s' statements allowed in this block" % (max_cnt, kwd))
|
||||||
|
|
||||||
|
ret[kwd].append(pfunc())
|
||||||
|
cnt[kwd] += 1
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def parse_ident(self):
|
||||||
|
ident = ''
|
||||||
|
while self.chr.isalnum() or self.chr == '_':
|
||||||
|
ident += self.chr
|
||||||
|
self.next()
|
||||||
|
|
||||||
|
if len(ident) == 0:
|
||||||
|
self.err("expected identifier")
|
||||||
|
|
||||||
|
self.skipws()
|
||||||
|
return ident
|
||||||
|
|
||||||
|
def parse_string(self):
|
||||||
|
if self.chr != '"':
|
||||||
|
self.err("expected string")
|
||||||
|
self.next()
|
||||||
|
|
||||||
|
s = ''
|
||||||
|
while self.chr != '"':
|
||||||
|
s += self.chr
|
||||||
|
self.next()
|
||||||
|
self.next()
|
||||||
|
|
||||||
|
self.skipws()
|
||||||
|
return s
|
||||||
|
|
||||||
|
def parse_printable(self):
|
||||||
|
s = ''
|
||||||
|
while not self.chr.isspace() and self.chr != ';':
|
||||||
|
s += self.chr
|
||||||
|
self.next()
|
||||||
|
|
||||||
|
self.skipws()
|
||||||
|
return s
|
||||||
|
|
||||||
|
def skipws(self):
|
||||||
|
while True:
|
||||||
|
if self.chr == '#':
|
||||||
|
while self.chr != '\n':
|
||||||
|
self.next()
|
||||||
|
if self.eolstop:
|
||||||
|
break
|
||||||
|
self.next()
|
||||||
|
elif self.chr == '\n' or self.chr == ';':
|
||||||
|
if self.eolstop:
|
||||||
|
break
|
||||||
|
self.next()
|
||||||
|
elif self.chr.isspace():
|
||||||
|
self.next()
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
def next(self):
|
||||||
|
self.chr = self.input.read(1)
|
||||||
|
if len(self.chr) == 0:
|
||||||
|
self.chr = '\0'
|
||||||
|
if self.chr == '\n':
|
||||||
|
self.line += 1
|
||||||
|
return self.chr
|
||||||
|
|
||||||
|
def err(self, msg):
|
||||||
|
raise ValueError("on line %d: %s" % (self.line, msg))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
p = Parser(sys.stdin)
|
||||||
|
r = p.parse()
|
||||||
|
print('<?xml version="1.0"?>')
|
||||||
|
ET.dump(r.gen())
|
742
utils/reggen-ng/x1000.reggen
Normal file
742
utils/reggen-ng/x1000.reggen
Normal file
|
@ -0,0 +1,742 @@
|
||||||
|
name "x1000"
|
||||||
|
title "Ingenic X1000"
|
||||||
|
isa "mips"
|
||||||
|
version "1.0"
|
||||||
|
author "Aidan MacDonald"
|
||||||
|
|
||||||
|
node LCD {
|
||||||
|
title "LCD controller"
|
||||||
|
addr 0xb3050000
|
||||||
|
|
||||||
|
reg CFG 0x00 {
|
||||||
|
bit 17 INVDAT
|
||||||
|
}
|
||||||
|
|
||||||
|
reg CTRL 0x30 {
|
||||||
|
fld 30 28 BURST { enum 4WORD 0; enum 8WORD 1; enum 16WORD 2;
|
||||||
|
enum 32WORD 3; enum 64WORD 4; }
|
||||||
|
bit 13 EOFM
|
||||||
|
bit 12 SOFM
|
||||||
|
bit 10 IFUM
|
||||||
|
bit 7 QDM
|
||||||
|
bit 6 BEDN
|
||||||
|
bit 5 PEDN
|
||||||
|
bit 3 ENABLE
|
||||||
|
fld 2 0 BPP {
|
||||||
|
enum 15BIT_OR_16BIT 4
|
||||||
|
enum 18BIT_OR_24BIT 5
|
||||||
|
enum 24BIT_COMPRESSED 6
|
||||||
|
enum 30BIT 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reg STATE 0x34 {
|
||||||
|
bit 7 QD
|
||||||
|
bit 5 EOF
|
||||||
|
bit 4 SOF
|
||||||
|
bit 2 IFU
|
||||||
|
}
|
||||||
|
|
||||||
|
reg OSDCTRL 0x104
|
||||||
|
reg BGC 0x10c
|
||||||
|
reg DAH 0x10
|
||||||
|
reg DAV 0x14
|
||||||
|
reg VAT 0x0c
|
||||||
|
reg VSYNC 0x04
|
||||||
|
reg HSYNC 0x08
|
||||||
|
|
||||||
|
reg IID 0x38
|
||||||
|
reg DA 0x40
|
||||||
|
|
||||||
|
reg MCFG 0xa0 {
|
||||||
|
# other fields are useless according to Ingenic
|
||||||
|
field 9 8 CWIDTH {
|
||||||
|
enum 16BIT_OR_9BIT 0
|
||||||
|
enum 8BIT 1
|
||||||
|
enum 18BIT 2
|
||||||
|
enum 24BIT 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reg MCFG_NEW 0xb8 {
|
||||||
|
field 15 13 DWIDTH {
|
||||||
|
enum 8BIT 0
|
||||||
|
enum 9BIT 1
|
||||||
|
enum 16BIT 2
|
||||||
|
enum 18BIT 3
|
||||||
|
enum 24BIT 4
|
||||||
|
}
|
||||||
|
|
||||||
|
field 9 8 DTIMES {
|
||||||
|
enum 1TIME 0
|
||||||
|
enum 2TIME 1
|
||||||
|
enum 3TIME 2
|
||||||
|
}
|
||||||
|
|
||||||
|
bit 11 6800_MODE
|
||||||
|
bit 10 CMD_9BIT
|
||||||
|
bit 5 CSPLY
|
||||||
|
bit 4 RSPLY
|
||||||
|
bit 3 CLKPLY
|
||||||
|
bit 2 DTYPE { enum SERIAL 1; enum PARALLEL 0 }
|
||||||
|
bit 1 CTYPE { enum SERIAL 1; enum PARALLEL 0 }
|
||||||
|
bit 0 FMT_CONV
|
||||||
|
}
|
||||||
|
|
||||||
|
reg MCTRL 0xa4 {
|
||||||
|
bit 10 NARROW_TE
|
||||||
|
bit 9 TE_INV
|
||||||
|
bit 8 NOT_USE_TE
|
||||||
|
bit 7 DCSI_SEL
|
||||||
|
bit 6 MIPI_SLCD
|
||||||
|
bit 4 FAST_MODE
|
||||||
|
bit 3 GATE_MASK
|
||||||
|
bit 2 DMA_MODE
|
||||||
|
bit 1 DMA_START
|
||||||
|
bit 0 DMA_TX_EN
|
||||||
|
}
|
||||||
|
|
||||||
|
reg MSTATE 0xa8 {
|
||||||
|
fld 31 16 LCD_ID
|
||||||
|
bit 0 BUSY
|
||||||
|
}
|
||||||
|
|
||||||
|
reg MDATA 0xac {
|
||||||
|
fld 31 30 TYPE { enum CMD 1; enum DAT 0 }
|
||||||
|
fld 23 0 DATA
|
||||||
|
}
|
||||||
|
|
||||||
|
reg WTIME 0xb0 {
|
||||||
|
fld 31 24 DHTIME
|
||||||
|
fld 23 16 DLTIME
|
||||||
|
fld 15 8 CHTIME
|
||||||
|
fld 7 0 CLTIME
|
||||||
|
}
|
||||||
|
|
||||||
|
reg TASH 0xb4 {
|
||||||
|
fld 15 8 TAH
|
||||||
|
fld 7 0 TAS
|
||||||
|
}
|
||||||
|
|
||||||
|
reg SMWT 0xbc
|
||||||
|
}
|
||||||
|
|
||||||
|
node DDRC {
|
||||||
|
title "DDR controller AHB2 group"
|
||||||
|
desc "note: incomplete, only lists registers used by DDR init code"
|
||||||
|
addr 0xb34f0000
|
||||||
|
|
||||||
|
reg STATUS 0x00
|
||||||
|
reg CFG 0x04
|
||||||
|
reg CTRL 0x08
|
||||||
|
reg TIMING1 0x60
|
||||||
|
reg TIMING2 0x64
|
||||||
|
reg TIMING3 0x68
|
||||||
|
reg TIMING4 0x6c
|
||||||
|
reg TIMING5 0x70
|
||||||
|
reg TIMING6 0x74
|
||||||
|
reg REFCNT 0x18
|
||||||
|
reg MMAP0 0x24
|
||||||
|
reg MMAP1 0x28
|
||||||
|
reg DLP 0xbc
|
||||||
|
reg REMAP1 0x9c
|
||||||
|
reg REMAP2 0xa0
|
||||||
|
reg REMAP3 0xa4
|
||||||
|
reg REMAP4 0xa8
|
||||||
|
reg REMAP5 0xac
|
||||||
|
reg AUTOSR_CNT 0x308
|
||||||
|
reg AUTOSR_EN 0x304
|
||||||
|
}
|
||||||
|
|
||||||
|
node DDRC_APB {
|
||||||
|
title "DDR controller APB group"
|
||||||
|
desc "note: incomplete, only lists registers used by DDR init code"
|
||||||
|
addr 0xb3012000
|
||||||
|
|
||||||
|
reg CLKSTP_CFG 0x68
|
||||||
|
reg PHYRST_CFG 0x80
|
||||||
|
}
|
||||||
|
|
||||||
|
node DDRPHY {
|
||||||
|
title "DDR PHY group"
|
||||||
|
desc "note: incomplete, only lists registers used by DDR init code"
|
||||||
|
addr 0xb3011000
|
||||||
|
|
||||||
|
reg PIR 0x04
|
||||||
|
reg PGCR 0x08
|
||||||
|
reg PGSR 0x0c
|
||||||
|
reg DLLGCR 0x10
|
||||||
|
reg ACDLLCR 0x14
|
||||||
|
reg PTR0 0x18
|
||||||
|
reg PTR1 0x1c
|
||||||
|
reg PTR2 0x20
|
||||||
|
reg ACIOCR 0x24
|
||||||
|
reg DXCCR 0x28
|
||||||
|
reg DSGCR 0x2c
|
||||||
|
reg DCR 0x30
|
||||||
|
reg DTPR0 0x34
|
||||||
|
reg DTPR1 0x38
|
||||||
|
reg DTPR2 0x3c
|
||||||
|
reg MR0 0x40
|
||||||
|
reg MR1 0x44
|
||||||
|
reg MR2 0x48
|
||||||
|
reg MR3 0x4c
|
||||||
|
reg DTAR 0x54
|
||||||
|
reg DXGCR { instance 0x1c0 0x40 4 }
|
||||||
|
}
|
||||||
|
|
||||||
|
node CPM {
|
||||||
|
title "Clock, Reset and Power Manager"
|
||||||
|
addr 0xb0000000
|
||||||
|
|
||||||
|
reg CCR 0x00 {
|
||||||
|
fld 31 30 SEL_SRC { enum STOP 0; enum EXCLK 1; enum APLL 2; }
|
||||||
|
fld 29 28 SEL_CPLL { enum STOP 0; enum SCLK_A 1; enum MPLL 2; }
|
||||||
|
fld 27 26 SEL_H0PLL { enum STOP 0; enum SCLK_A 1; enum MPLL 2; }
|
||||||
|
fld 25 24 SEL_H2PLL { enum STOP 0; enum SCLK_A 1; enum MPLL 2; }
|
||||||
|
bit 23 GATE_SCLKA
|
||||||
|
bit 22 CE_CPU
|
||||||
|
bit 21 CE_AHB0
|
||||||
|
bit 20 CE_AHB2
|
||||||
|
fld 19 16 PDIV
|
||||||
|
fld 15 12 H2DIV
|
||||||
|
fld 11 8 H0DIV
|
||||||
|
fld 7 4 L2DIV
|
||||||
|
fld 3 0 CDIV
|
||||||
|
}
|
||||||
|
|
||||||
|
reg CSR 0xd4 {
|
||||||
|
bit 31 SRC_MUX
|
||||||
|
bit 30 CPU_MUX
|
||||||
|
bit 29 AHB0_MUX
|
||||||
|
bit 28 AHB2_MUX
|
||||||
|
bit 27 DDR_MUX
|
||||||
|
bit 2 H2DIV_BUSY
|
||||||
|
bit 1 H0DIV_BUSY
|
||||||
|
bit 0 CDIV_BUSY
|
||||||
|
}
|
||||||
|
|
||||||
|
reg DDRCDR 0x2c {
|
||||||
|
fld 31 30 CLKSRC { enum STOP 0; enum SCLK_A 1; enum MPLL 2; }
|
||||||
|
bit 29 CE
|
||||||
|
bit 28 BUSY
|
||||||
|
bit 27 STOP
|
||||||
|
bit 26 GATE_EN
|
||||||
|
bit 25 CHANGE_EN
|
||||||
|
bit 24 FLAG
|
||||||
|
fld 3 0 CLKDIV
|
||||||
|
}
|
||||||
|
|
||||||
|
reg LPCDR 0x64 {
|
||||||
|
bit 31 CLKSRC { enum SCLK_A 0; enum MPLL 1; }
|
||||||
|
bit 28 CE
|
||||||
|
bit 27 BUSY
|
||||||
|
bit 26 STOP
|
||||||
|
fld 7 0 CLKDIV
|
||||||
|
}
|
||||||
|
|
||||||
|
reg MSC0CDR 0x68 {
|
||||||
|
bit 31 CLKSRC { enum SCLK_A 0; enum MPLL 1; }
|
||||||
|
bit 29 CE
|
||||||
|
bit 28 BUSY
|
||||||
|
bit 27 STOP
|
||||||
|
bit 15 S_CLK0_SEL { enum 90DEG 0; enum 180DEG 1; }
|
||||||
|
fld 7 0 CLKDIV
|
||||||
|
}
|
||||||
|
|
||||||
|
reg MSC1CDR 0xa4 {
|
||||||
|
bit 29 CE
|
||||||
|
bit 28 BUSY
|
||||||
|
bit 27 STOP
|
||||||
|
bit 15 S_CLK1_SEL { enum 90DEG 0; enum 180DEG 1; }
|
||||||
|
fld 7 0 CLKDIV
|
||||||
|
}
|
||||||
|
|
||||||
|
reg DRCG 0xd0
|
||||||
|
|
||||||
|
reg APCR 0x10 {
|
||||||
|
bit 31 BS
|
||||||
|
fld 30 24 PLLM
|
||||||
|
fld 22 18 PLLN
|
||||||
|
fld 17 16 PLLOD
|
||||||
|
bit 15 LOCK
|
||||||
|
bit 10 ON
|
||||||
|
bit 9 BYPASS
|
||||||
|
bit 8 ENABLE
|
||||||
|
fld 7 0 PLLST
|
||||||
|
}
|
||||||
|
|
||||||
|
reg MPCR 0x14 {
|
||||||
|
bit 31 BS
|
||||||
|
fld 30 24 PLLM
|
||||||
|
fld 22 18 PLLN
|
||||||
|
fld 17 16 PLLOD
|
||||||
|
bit 7 ENABLE
|
||||||
|
bit 6 BYPASS
|
||||||
|
bit 1 LOCK
|
||||||
|
bit 0 ON
|
||||||
|
}
|
||||||
|
|
||||||
|
reg LCR 0x04 {
|
||||||
|
fld 19 8 PST
|
||||||
|
fld 1 0 LPM { enum IDLE 0; enum SLEEP 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
reg PSWC0ST 0x90
|
||||||
|
reg PSWC1ST 0x94
|
||||||
|
reg PSWC2ST 0x98
|
||||||
|
reg PSWC3ST 0x9c
|
||||||
|
|
||||||
|
reg CLKGR 0x20 {
|
||||||
|
desc "Clock gate register"
|
||||||
|
bit 31 DDR
|
||||||
|
bit 30 CPU_BIT # can't be called CPU because Rockbox #defines that
|
||||||
|
bit 29 AHB0
|
||||||
|
bit 28 APB0
|
||||||
|
bit 27 RTC
|
||||||
|
bit 26 PCM
|
||||||
|
bit 25 MAC
|
||||||
|
bit 24 AES
|
||||||
|
bit 23 LCD
|
||||||
|
bit 22 CIM
|
||||||
|
bit 21 PDMA
|
||||||
|
bit 20 OST
|
||||||
|
bit 19 SSI
|
||||||
|
bit 18 TCU
|
||||||
|
bit 17 DMIC
|
||||||
|
bit 16 UART2
|
||||||
|
bit 15 UART1
|
||||||
|
bit 14 UART0
|
||||||
|
bit 12 JPEG
|
||||||
|
bit 11 AIC
|
||||||
|
bit 9 I2C2
|
||||||
|
bit 8 I2C1
|
||||||
|
bit 7 I2C0
|
||||||
|
bit 6 SCC
|
||||||
|
bit 5 MSC1
|
||||||
|
bit 4 MSC0
|
||||||
|
bit 3 OTG
|
||||||
|
bit 2 SFC
|
||||||
|
bit 1 EFUSE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node TCU {
|
||||||
|
title "Timer/counter unit"
|
||||||
|
addr 0xb0002000
|
||||||
|
|
||||||
|
reg STATUS 0xf0 { variant set 4; variant clr 8 }
|
||||||
|
reg STOP 0x1c { variant set 0x10; variant clr 0x20 }
|
||||||
|
reg ENABLE 0x10 { variant set 4; variant clr 8 }
|
||||||
|
reg FLAG 0x20 { variant set 4; variant clr 8 }
|
||||||
|
reg MASK 0x30 { variant set 4; variant clr 8 }
|
||||||
|
reg CMP_FULL {
|
||||||
|
desc "called Data FULL by Ingenic"
|
||||||
|
instance 0x40 0x10 8
|
||||||
|
}
|
||||||
|
reg CMP_HALF {
|
||||||
|
desc "called Data HALF by Ingenic"
|
||||||
|
instance 0x44 0x10 8
|
||||||
|
}
|
||||||
|
reg COUNT {
|
||||||
|
instance 0x48 0x10 8
|
||||||
|
}
|
||||||
|
reg CTRL {
|
||||||
|
instance 0x4c 0x10 8
|
||||||
|
bit 11 BYPASS
|
||||||
|
bit 10 CLRZ
|
||||||
|
bit 9 SHUTDOWN { enum GRACEFUL 0; enum ABRUPT 1; }
|
||||||
|
bit 8 INIT_LVL
|
||||||
|
bit 7 PWM_EN
|
||||||
|
bit 6 PWM_IN_EN
|
||||||
|
fld 5 3 PRESCALE { enum BY_1 0; enum BY_4 1; enum BY_16 2;
|
||||||
|
enum BY_64 3; enum BY_256 4; enum BY_1024 5; }
|
||||||
|
fld 2 0 SOURCE { enum EXT 4; enum RTC 2; enum PCLK 1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node OST {
|
||||||
|
title "Operating system timer"
|
||||||
|
addr 0xb2000000
|
||||||
|
|
||||||
|
reg CTRL 0x00 {
|
||||||
|
field 5 3 PRESCALE2 { enum BY_1 0; enum BY_4 1; enum BY_16 2; }
|
||||||
|
field 2 0 PRESCALE1 { enum BY_1 0; enum BY_4 1; enum BY_16 2; }
|
||||||
|
}
|
||||||
|
|
||||||
|
reg ENABLE 0x04 {
|
||||||
|
variant set 0x30
|
||||||
|
variant clr 0x34
|
||||||
|
bit 0 OST1
|
||||||
|
bit 1 OST2
|
||||||
|
}
|
||||||
|
|
||||||
|
reg CLEAR 0x08 {
|
||||||
|
bit 0 OST1
|
||||||
|
bit 1 OST2
|
||||||
|
}
|
||||||
|
|
||||||
|
reg 1FLG 0x0c
|
||||||
|
reg 1MSK 0x10
|
||||||
|
reg 1DFR 0x14
|
||||||
|
reg 1CNT 0x18
|
||||||
|
|
||||||
|
reg 2CNTH 0x1c
|
||||||
|
reg 2CNTL 0x20
|
||||||
|
reg 2CNTHB 0x24
|
||||||
|
}
|
||||||
|
|
||||||
|
node INTC {
|
||||||
|
title "Interrupt controller"
|
||||||
|
# Documented address in Ingenic's manual is a typo (= GPIO base address).
|
||||||
|
# This is the correct address from their Linux source.
|
||||||
|
addr 0xb0001000
|
||||||
|
|
||||||
|
reg SRC { instance 0x00 0x20 2 }
|
||||||
|
reg MSK { instance 0x04 0x20 2; variant set 4; variant clr 8 }
|
||||||
|
reg PND { instance 0x10 0x20 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
node WDT {
|
||||||
|
title "Watchdog timer"
|
||||||
|
addr 0xb0002000
|
||||||
|
|
||||||
|
reg DATA 0x00
|
||||||
|
reg ENABLE 0x04
|
||||||
|
reg COUNT 0x08
|
||||||
|
|
||||||
|
reg CTRL 0x0c {
|
||||||
|
field 5 3 PRESCALE { enum BY_1 0; enum BY_4 1; enum BY_16 2;
|
||||||
|
enum BY_64 3; enum BY_256 4; enum BY_1024 5; }
|
||||||
|
field 2 0 SOURCE { enum EXT 4; enum RTC 2; enum PLCK 1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node RTC {
|
||||||
|
title "Realtime clock"
|
||||||
|
addr 0xb0003000
|
||||||
|
|
||||||
|
reg CR 0x00
|
||||||
|
reg SR 0x04
|
||||||
|
reg SAR 0x08
|
||||||
|
reg GR 0x0c
|
||||||
|
reg HCR 0x20
|
||||||
|
reg WFCR 0x24
|
||||||
|
reg RCR 0x28
|
||||||
|
reg WCR 0x2c
|
||||||
|
reg RSR 0x30
|
||||||
|
reg SPR 0x34
|
||||||
|
reg WENR 0x3c
|
||||||
|
reg WKUPPINCR 0x48
|
||||||
|
}
|
||||||
|
|
||||||
|
node GPIO {
|
||||||
|
title "General purpose I/O"
|
||||||
|
addr 0xb0010000
|
||||||
|
|
||||||
|
# Note: only instances 0-3 and 7 are instantiated in hardware
|
||||||
|
reg PIN { instance 0x00 0x100 8 }
|
||||||
|
reg INT { instance 0x10 0x100 8; variant set 4; variant clr 8 }
|
||||||
|
reg MSK { instance 0x20 0x100 8; variant set 4; variant clr 8 }
|
||||||
|
reg PAT1 { instance 0x30 0x100 8; variant set 4; variant clr 8 }
|
||||||
|
reg PAT0 { instance 0x40 0x100 8; variant set 4; variant clr 8 }
|
||||||
|
reg FLAG { instance 0x50 0x100 8; variant clr 8 }
|
||||||
|
reg PULL { instance 0x70 0x100 8; variant set 4; variant clr 8 }
|
||||||
|
|
||||||
|
node C_GLITCH {
|
||||||
|
desc "GPIO port C: glitch filter registers"
|
||||||
|
addr 0x200
|
||||||
|
reg CFG0 0x800 { variant set 4; variant clr 8 }
|
||||||
|
reg CFG1 0x810 { variant set 4; variant clr 8 }
|
||||||
|
reg CFG2 0x820 { variant set 4; variant clr 8 }
|
||||||
|
reg CFG3 0x830 { variant set 4; variant clr 8 }
|
||||||
|
}
|
||||||
|
|
||||||
|
reg Z_GID2LD {
|
||||||
|
desc "GPIO port Z: atomic load register"
|
||||||
|
addr 0x7f0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node I2C {
|
||||||
|
title "I2C bus controller"
|
||||||
|
instance 0xb0050000 0x1000 3
|
||||||
|
|
||||||
|
reg CON 0x00 {
|
||||||
|
bit 6 SLVDIS
|
||||||
|
bit 5 RESTART
|
||||||
|
bit 4 MATP
|
||||||
|
bit 3 SATP
|
||||||
|
fld 2 1 SPEED { enum 100K 1; enum 400K 2; }
|
||||||
|
bit 0 MD
|
||||||
|
}
|
||||||
|
|
||||||
|
reg DC 0x10 {
|
||||||
|
bit 10 RESTART
|
||||||
|
bit 9 STOP
|
||||||
|
bit 8 CMD
|
||||||
|
fld 7 0 DAT
|
||||||
|
}
|
||||||
|
|
||||||
|
reg INTST 0x2c {
|
||||||
|
bit 11 GC
|
||||||
|
bit 10 STT
|
||||||
|
bit 9 STP
|
||||||
|
bit 8 ACT
|
||||||
|
bit 7 RXDN
|
||||||
|
bit 6 TXABT
|
||||||
|
bit 5 RDREQ
|
||||||
|
bit 4 TXEMP
|
||||||
|
bit 3 TXOF
|
||||||
|
bit 2 RXFL
|
||||||
|
bit 1 RXOF
|
||||||
|
bit 0 RXUF
|
||||||
|
}
|
||||||
|
|
||||||
|
reg INTMSK 0x30 {
|
||||||
|
bit 11 GC
|
||||||
|
bit 10 STT
|
||||||
|
bit 9 STP
|
||||||
|
bit 8 ACT
|
||||||
|
bit 7 RXDN
|
||||||
|
bit 6 TXABT
|
||||||
|
bit 5 RDREQ
|
||||||
|
bit 4 TXEMP
|
||||||
|
bit 3 TXOF
|
||||||
|
bit 2 RXFL
|
||||||
|
bit 1 RXOF
|
||||||
|
bit 0 RXUF
|
||||||
|
}
|
||||||
|
|
||||||
|
reg RINTST 0x34 {
|
||||||
|
bit 11 GC
|
||||||
|
bit 10 STT
|
||||||
|
bit 9 STP
|
||||||
|
bit 8 ACT
|
||||||
|
bit 7 RXDN
|
||||||
|
bit 6 TXABT
|
||||||
|
bit 5 RDREQ
|
||||||
|
bit 4 TXEMP
|
||||||
|
bit 3 TXOF
|
||||||
|
bit 2 RXFL
|
||||||
|
bit 1 RXOF
|
||||||
|
bit 0 RXUF
|
||||||
|
}
|
||||||
|
|
||||||
|
reg ENABLE 0x6c {
|
||||||
|
bit 1 ABORT
|
||||||
|
bit 0 ACTIVE
|
||||||
|
}
|
||||||
|
|
||||||
|
reg STATUS 0x70 {
|
||||||
|
bit 6 SLVACT
|
||||||
|
bit 5 MSTACT
|
||||||
|
bit 4 RFF
|
||||||
|
bit 3 RFNE
|
||||||
|
bit 2 TFE
|
||||||
|
bit 1 TFNF
|
||||||
|
bit 0 ACT
|
||||||
|
}
|
||||||
|
|
||||||
|
reg ENBST 0x9c {
|
||||||
|
bit 2 SLVRDLST
|
||||||
|
bit 1 SLVDISB
|
||||||
|
bit 0 ACTIVE
|
||||||
|
}
|
||||||
|
|
||||||
|
reg TAR 0x04
|
||||||
|
reg SAR 0x08
|
||||||
|
reg SHCNT 0x14
|
||||||
|
reg SLCNT 0x18
|
||||||
|
reg FHCNT 0x1c
|
||||||
|
reg FLCNT 0x20
|
||||||
|
reg RXTL 0x38
|
||||||
|
reg TXTL 0x3c
|
||||||
|
reg TXFLR 0x74
|
||||||
|
reg RXFLR 0x78
|
||||||
|
reg SDAHD 0x7c
|
||||||
|
reg ABTSRC 0x80
|
||||||
|
reg DMACR 0x88
|
||||||
|
reg DMATDLR 0x8c
|
||||||
|
reg DMARDLR 0x90
|
||||||
|
reg SDASU 0x94
|
||||||
|
reg ACKGC 0x98
|
||||||
|
reg FLT 0xa0
|
||||||
|
|
||||||
|
reg CINT 0x40
|
||||||
|
reg CRXUF 0x44
|
||||||
|
reg CRXOF 0x48
|
||||||
|
reg CTXOF 0x4c
|
||||||
|
reg CRXREQ 0x50
|
||||||
|
reg CTXABT 0x54
|
||||||
|
reg CRXDN 0x58
|
||||||
|
reg CACT 0x5c
|
||||||
|
reg CSTP 0x60
|
||||||
|
reg CSTT 0x64
|
||||||
|
reg CGC 0x68
|
||||||
|
}
|
||||||
|
|
||||||
|
node MSC {
|
||||||
|
title "MMC/SD/CE-ATA controller"
|
||||||
|
instance 0xb3450000 0x10000 2
|
||||||
|
|
||||||
|
reg CTRL 0x00 {
|
||||||
|
bit 15 SEND_CCSD
|
||||||
|
bit 14 SEND_AS_CCSD
|
||||||
|
bit 7 EXIT_MULTIPLE
|
||||||
|
bit 6 EXIT_TRANSFER
|
||||||
|
bit 5 START_READ_WAIT
|
||||||
|
bit 4 STOP_READ_WAIT
|
||||||
|
bit 3 RESET
|
||||||
|
bit 2 START_OP
|
||||||
|
fld 1 0 CLOCK { enum DO_NOTHING 0; enum STOP 1; enum START 2; }
|
||||||
|
}
|
||||||
|
|
||||||
|
reg STAT 0x04 {
|
||||||
|
bit 31 AUTO_CMD12_DONE
|
||||||
|
fld 28 24 PINS
|
||||||
|
bit 20 BCE
|
||||||
|
bit 19 BDE
|
||||||
|
bit 18 BAE
|
||||||
|
bit 17 BAR
|
||||||
|
bit 16 DMAEND
|
||||||
|
bit 15 IS_RESETTING
|
||||||
|
bit 14 SDIO_INT_ACTIVE
|
||||||
|
bit 13 PROG_DONE
|
||||||
|
bit 12 DATA_TRAN_DONE
|
||||||
|
bit 11 END_CMD_RES
|
||||||
|
bit 10 DATA_FIFO_AFULL
|
||||||
|
bit 9 IS_READ_WAIT
|
||||||
|
bit 8 CLOCK_EN
|
||||||
|
bit 7 DATA_FIFO_FULL
|
||||||
|
bit 6 DATA_FIFO_EMPTY
|
||||||
|
bit 5 CRC_RES_ERROR
|
||||||
|
bit 4 CRC_READ_ERROR
|
||||||
|
fld 3 2 CRC_WRITE_ERROR { enum NONE 0; enum BADDATA 1; enum NOCRC 2 }
|
||||||
|
bit 1 TIME_OUT_RES
|
||||||
|
bit 0 TIME_OUT_READ
|
||||||
|
}
|
||||||
|
|
||||||
|
reg CMDAT 0x0c {
|
||||||
|
bit 31 CCS_EXPECTED
|
||||||
|
bit 30 READ_CEATA
|
||||||
|
bit 27 DIS_BOOT
|
||||||
|
bit 25 EXP_BOOT_ACK
|
||||||
|
bit 24 BOOT_MODE
|
||||||
|
bit 17 SDIO_PRDT
|
||||||
|
bit 16 AUTO_CMD12
|
||||||
|
fld 15 14 RTRG { enum GE16 0; enum GE32 1; enum GE64 2; enum GE96 3 }
|
||||||
|
fld 13 12 TTRG { enum LE16 0; enum LE32 1; enum LE64 2; enum LE96 3 }
|
||||||
|
bit 11 IO_ABORT
|
||||||
|
fld 10 9 BUS_WIDTH { enum 1BIT 0; enum 4BIT 2; enum 8BIT 3; }
|
||||||
|
bit 7 INIT
|
||||||
|
bit 6 BUSY
|
||||||
|
bit 5 STREAM_BLOCK
|
||||||
|
bit 4 WRITE_READ
|
||||||
|
bit 3 DATA_EN
|
||||||
|
fld 2 0 RESP_FMT
|
||||||
|
}
|
||||||
|
|
||||||
|
reg IMASK 0x24 {
|
||||||
|
bit 31 DMA_DATA_DONE
|
||||||
|
fld 28 24 PINS
|
||||||
|
bit 23 WR_ALL_DONE
|
||||||
|
bit 20 BCE
|
||||||
|
bit 19 BDE
|
||||||
|
bit 18 BAE
|
||||||
|
bit 17 BAR
|
||||||
|
bit 16 DMAEND
|
||||||
|
bit 15 AUTO_CMD12_DONE
|
||||||
|
bit 14 DATA_FIFO_FULL
|
||||||
|
bit 13 DATA_FIFO_EMPTY
|
||||||
|
bit 12 CRC_RES_ERROR
|
||||||
|
bit 11 CRC_READ_ERROR
|
||||||
|
bit 10 CRC_WRITE_ERROR
|
||||||
|
bit 9 TIME_OUT_RES
|
||||||
|
bit 8 TIME_OUT_READ
|
||||||
|
bit 7 SDIO
|
||||||
|
bit 6 TXFIFO_WR_REQ
|
||||||
|
bit 5 RXFIFO_RD_REQ
|
||||||
|
bit 2 END_CMD_RES
|
||||||
|
bit 1 PROG_DONE
|
||||||
|
bit 0 DATA_TRAN_DONE
|
||||||
|
}
|
||||||
|
|
||||||
|
reg IFLAG 0x28 {
|
||||||
|
bit 31 DMA_DATA_DONE
|
||||||
|
fld 28 24 PINS
|
||||||
|
bit 23 WR_ALL_DONE
|
||||||
|
bit 20 BCE
|
||||||
|
bit 19 BDE
|
||||||
|
bit 18 BAE
|
||||||
|
bit 17 BAR
|
||||||
|
bit 16 DMAEND
|
||||||
|
bit 15 AUTO_CMD12_DONE
|
||||||
|
bit 14 DATA_FIFO_FULL
|
||||||
|
bit 13 DATA_FIFO_EMPTY
|
||||||
|
bit 12 CRC_RES_ERROR
|
||||||
|
bit 11 CRC_READ_ERROR
|
||||||
|
bit 10 CRC_WRITE_ERROR
|
||||||
|
bit 9 TIME_OUT_RES
|
||||||
|
bit 8 TIME_OUT_READ
|
||||||
|
bit 7 SDIO
|
||||||
|
bit 6 TXFIFO_WR_REQ
|
||||||
|
bit 5 RXFIFO_RD_REQ
|
||||||
|
bit 2 END_CMD_RES
|
||||||
|
bit 1 PROG_DONE
|
||||||
|
bit 0 DATA_TRAN_DONE
|
||||||
|
}
|
||||||
|
|
||||||
|
reg LPM 0x40 {
|
||||||
|
fld 31 30 DRV_SEL {
|
||||||
|
enum FALL_EDGE 0
|
||||||
|
enum RISE_EDGE_DELAY_1NS 1
|
||||||
|
enum RISE_EDGE_DELAY_QTR_PHASE 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fld 29 28 SMP_SEL {
|
||||||
|
enum RISE_EDGE 0
|
||||||
|
enum RISE_EDGE_DELAYED 1
|
||||||
|
}
|
||||||
|
|
||||||
|
bit 0 ENABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
reg DMAC 0x44 {
|
||||||
|
bit 7 MODE_SEL
|
||||||
|
fld 6 5 ADDR_OFFSET
|
||||||
|
bit 4 ALIGN_EN
|
||||||
|
fld 3 2 INCR
|
||||||
|
bit 1 DMASEL
|
||||||
|
bit 0 ENABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
reg CTRL2 0x58 {
|
||||||
|
fld 28 24 PIN_INT_POLARITY
|
||||||
|
bit 4 STPRM
|
||||||
|
fld 2 0 SPEED {
|
||||||
|
enum DEFAULT 0
|
||||||
|
enum HIGHSPEED 1
|
||||||
|
enum SDR12 2
|
||||||
|
enum SDR25 3
|
||||||
|
enum SDR50 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reg CLKRT 0x08
|
||||||
|
reg RESTO 0x10
|
||||||
|
reg RDTO 0x14
|
||||||
|
reg BLKLEN 0x18
|
||||||
|
reg NOB 0x1c
|
||||||
|
reg SNOB 0x20
|
||||||
|
reg CMD 0x2c
|
||||||
|
reg ARG 0x30
|
||||||
|
reg RES 0x34
|
||||||
|
reg RXFIFO 0x38
|
||||||
|
reg TXFIFO 0x3c
|
||||||
|
reg DMANDA 0x48
|
||||||
|
reg DMADA 0x4c
|
||||||
|
reg DMALEN 0x50
|
||||||
|
reg DMACMD 0x54
|
||||||
|
reg RTCNT 0x5c
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue