script: Add support for additional mux in model XML
authorNikhil Devshatwar <nikhil.nd@ti.com>
Tue, 31 Jan 2017 09:26:02 +0000 (14:56 +0530)
committerNikhil Devshatwar <nikhil.nd@ti.com>
Tue, 31 Jan 2017 09:31:53 +0000 (15:01 +0530)
Some of the DRA72x pads have multiple signals available at
same muxmode. The selection happens via internal control module
registers.

To support these pads, XML file syntax has been modified to add
new nodes for AdditionalMux and describe the mux registers to refer

Modify the script to handle these additional modes
- Add utility function to extract register values based on names
- Iterate through different options, match the fields and select right signal
- Move the file read before XML parsing functions
- Add fatal error to force exit the script

Also add a simple script to ease experimenting with XML parsing

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
iodelay-autogen.py
simple-XML-parse.py [new file with mode: 0755]

index 0e72671a36b0ef0f0dce924bbd8955a5c3aecd32..57d6286dd383c58eba71a4862a53f71558d40d18 100755 (executable)
@@ -30,7 +30,7 @@ parser.add_argument('-p', '--part', dest='part',
        help='select the device part')
 
 parser.add_argument('-r', '--revision', dest='revision',
-       action='store', type=str, choices=["1.0", "1.1", "2.0"], default="1.1",
+       action='store', type=str, choices=["1.0", "1.1", "2.0"], default="2.0",
        help='select the silicon revision')
 
 parser.add_argument('-m', '--module', dest='module',
@@ -107,6 +107,9 @@ def warn(msg):
        trace(1, "WARN: " + msg)
 def error(msg):
        trace(0, "ERR: " + msg)
+def fatal(msg):
+       trace(0, "FATAL: " + msg)
+       exit()
 
 if (args.interactive):
        print "iodelay-autogen.py - Python script to generate the IOdelay data."
@@ -150,7 +153,7 @@ def read_selmodes(fname):
 
 def read_pad_dump(file):
        regmap = {}
-       pattern = re.compile('.*(0x[0-9A-F]+).*(0x[0-9A-F]+).*')
+       pattern = re.compile('.*(0x[0-9A-Fa-f]+).*(0x[0-9A-Fa-f]+).*')
        f = open(file, 'r')
        for line in f:
                list = re.match(pattern, line)
@@ -161,6 +164,14 @@ def read_pad_dump(file):
                verbose("XML pad-reg: Addr = %08x Value = %08x" % (addr, val))
                regmap[addr] = val
        return regmap
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Read all the input files and parse the required info
+modehelp = read_guidelines(modehelp_file)
+sel = read_selmodes(sel_file)
+regmap = read_pad_dump(pad_file)
+reglist = regmap.keys()
+
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 
 # Helper functions to parse XML nodes and get the desired data
@@ -175,6 +186,13 @@ def xml_pad_get_name(offset):
        else:
                return padlist[0].get("id")
 
+def xml_pad_get_offset(name):
+       padlist = pad_xml.findall("register[@id='%s']" % name)
+       if (len(padlist) == 0):
+               return None
+       else:
+               return int(padlist[0].get("offset"), 16)
+
 def xml_pad_get_slew(offset):
        padlist = pad_xml.findall("register[@offset='0x%X']" % offset)
        if (len(padlist) == 0):
@@ -263,6 +281,52 @@ def xml_get_manual(mode):
                        debug("    * MANUAL: %s [%s] => delay[%s] = %d, %d" % (signal, man_name, regname, adel, gdel))
        return mmodes
 
+def xml_get_additional_mode(orig):
+       additional_mux = orig.findall("additionalMux/confregisters")
+       if (len(additional_mux) == 0):
+               return orig
+       else:
+               additional_mux = additional_mux[0]
+               mux_reg_name = additional_mux.findtext("register")
+               offset = xml_pad_get_offset(mux_reg_name)
+
+               if (offset == None):
+                       error("Could not find register address for register '%s'" % mux_reg_name)
+                       fatal("This pin may have virtual/manual modes, Fix XML file")
+
+               addr = 0x4a002000 + offset
+               if (addr not in reglist):
+                       error("register dump lacks data for additional muxes")
+                       warn("using default values")
+                       muxval = 0x0
+               else:
+                       muxval = regmap[addr]
+
+               values = additional_mux.findall("value")
+               for value in values:
+
+                       option = int(value.findtext("option"))
+                       fieldpos = value.findtext("fieldPos")
+                       signal = value.findtext("signal").upper()
+                       matchlist = re.match("([0-9]+)[:]*([0-9]*)", fieldpos)
+
+                       verbose("++++ Additional mux %s possible" % signal)
+                       end = int(matchlist.groups(0)[0])
+                       if (matchlist.groups(0)[1] == ""):
+                               start = end
+                       else:
+                               start = int(matchlist.groups(0)[1])
+
+                       muxval = muxval & (1 << end)
+                       muxval = muxval >> start
+
+                       if (muxval == option):
+                               debug(">>>> Additional mux %s[%s] = %d" % (mux_reg_name, fieldpos, option))
+                               debug(">>>> Effective signal = %s" % signal)
+                               return value
+               error("None of the additional Mux value matched, using default")
+               return values[0]
+
 def xml_find_delaymodes(pad_name, muxmode):
        padlist = model_xml.findall("padDB/clockNode/type/pad")
        for pad in padlist:
@@ -273,6 +337,7 @@ def xml_find_delaymodes(pad_name, muxmode):
                return None
        for mode in muxmodes:
                if ("%d" % muxmode == mode.findtext("mode")):
+                       mode = xml_get_additional_mode(mode)
                        virt = xml_get_virtual(mode)
                        man = xml_get_manual(mode)
                        return (virt, man)
@@ -690,12 +755,6 @@ def bios_format_delay_regs(delayconf, per_delayconf):
 # * Dump the GPIO script for each peripheral (all pads grouped together)
 #
 
-# Read all the input files and parse the required info
-modehelp = read_guidelines(modehelp_file)
-sel = read_selmodes(sel_file)
-regmap = read_pad_dump(pad_file)
-reglist = regmap.keys()
-
 # List of all the pads being configured
 padconf = []
 # List of all the delay registers being configured (for manual mode)
@@ -747,7 +806,7 @@ for i in range(0, 260):
        if (args.resetslew):
                val |= (xml_pad_get_slew(offset) & 0x1) << 19
 
-       debug("\nPAD: %s: Addr= 0x%08X Value = 0x%08X \"%s\"" \
+       debug("PAD: %s: Addr= 0x%08X Value = 0x%08X \"%s\"" \
                % (pad_name, addr, val, pin_name))
 
        # Find out all the possible virtual, manual modes fot the specific pad -> pin combination
diff --git a/simple-XML-parse.py b/simple-XML-parse.py
new file mode 100755 (executable)
index 0000000..8045748
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+# Python script to experiment with XML parsing
+# Author:- Nikhil Devshatwar
+
+# Do not use this script to generate values for iodelay
+# This is helpful to develop the iodelay-autogen.py whenever
+# the XML file syntax changes
+
+import xml.etree.ElementTree as ET
+import re
+
+XML_PATH = "XMLFiles/DRA72x"
+
+pad_data_xml   = XML_PATH + "/CTRL_MODULE_CORE.xml"
+iod_data_xml   = XML_PATH + "/IODELAYCONFIG.xml"
+model_data_xml = XML_PATH + "/model_DRA72x_SR1.0_v1.0.9.xml"
+
+pad_xml = ET.parse(pad_data_xml).getroot()
+iod_xml = ET.parse(iod_data_xml).getroot()
+model_xml = ET.parse(model_data_xml).getroot()
+
+padlist = model_xml.findall("padDB/clockNode/type/pad")