script: Add support for output format linux and uboot
authorNikhil Devshatwar <nikhil.nd@ti.com>
Wed, 12 Aug 2015 15:54:21 +0000 (21:24 +0530)
committerNikhil Devshatwar <nikhil.nd@ti.com>
Wed, 12 Aug 2015 15:54:24 +0000 (21:24 +0530)
Add a command line option to select the output format.
Format the pad and delay dump differently based on the format
selected by user.

Along with the padconf and delayconf lists(which are sorted address wise)
maintain a dictonary which has entries grouped for a specific module.

Use padconf in uboot format to generate one big array.
Use per_padconf in linux format to generate DTS entries for each module.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
iodelay-autogen.py

index 221074bc357fb2586f069eb043d465e781c98273..24f2330691d2a0a0128cfecac344672542ee4724 100755 (executable)
@@ -37,6 +37,10 @@ parser.add_argument('-i', '--interactive', dest='interactive',
        action='store', type=int, choices=[0, 1], default=1,
        help='run interactively with menus for resolving conflicts')
 
+parser.add_argument('-f', '--format', dest='format',
+       action='store', type=str, choices=["linux", "uboot"], default="uboot",
+       help='select the output format to be used')
+
 args = parser.parse_args()
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 
@@ -179,7 +183,7 @@ def xml_find_delaymodes(pad_name, muxmode):
 # Decision point of the script
 # For each pad/pin, decide what delay method is used
 # Lookup in the selection file or ask user with a menu
-def select_mode(pad, pin, virt, man, modehelp, sel):
+def select_mode(pad, pin, module, virt, man, modehelp, sel):
        modelist = []
        for modename in virt.keys():
                modelist.append(modename)
@@ -190,8 +194,6 @@ def select_mode(pad, pin, virt, man, modehelp, sel):
        if (len(modelist) == 0):
                return "LEGACY"
 
-       # Find out if the delaymode for this module is already selected
-       module = re.match("([^_]+)_.*", pin).groups(0)[0]
        if (module in sel.keys()):
                mode = sel[module]
                if (mode == "SKIP" or mode in modelist):
@@ -200,7 +202,7 @@ def select_mode(pad, pin, virt, man, modehelp, sel):
                        print("ERR: Invalid delaymode '%s' for module '%s'" & (mode, module))
 
        if (args.interactive == 0):
-               print "WARN: No delay modes for %s:%s found, skipping" % (pad, pin)
+               print "WARN: No delay modes for %s found, skipping" % module
                mode = "SKIP"
                sel[module] = mode
                return mode
@@ -254,8 +256,31 @@ def pad_dump_gpio(addr, offset, pin_name):
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 
 # Generate the final pad and delay data in the required format
-# This can be changed to work for linux / u-boot / QNX / other format
-def format_pin_info(val):
+def format_pad_regs(padconf, per_padconf):
+       print "###########################################"
+       print "Pad data for u-boot (with the delay modes):"
+       print "###########################################"
+       if (args.format == "uboot"):
+               uboot_format_pad_regs(padconf, per_padconf)
+       elif (args.format == "linux"):
+               linux_format_pad_regs(padconf, per_padconf)
+       else:
+               print "ERR: Format %s not suppported" % args.format
+       print "###########################################"
+
+def format_delay_regs(delayconf, per_delayconf):
+       print "#########################################"
+       print "Delay data for u-boot (for manual modes):"
+       print "#########################################"
+       if (args.format == "uboot"):
+               uboot_format_delay_regs(delayconf, per_delayconf)
+       elif (args.format == "linux"):
+               linux_format_delay_regs(delayconf, per_delayconf)
+       else:
+               print "ERR: Format %s not suppported" % args.format
+       print "###########################################"
+
+def get_pin_info(val):
        inp_en = (val >> 18) & 0x1
        pulltype = (val >> 17) & 0x1
        pull_dis = (val >> 16) & 0x1
@@ -271,16 +296,15 @@ def format_pin_info(val):
                        pin += "_PULLDOWN"
        return pin
 
-def format_pad_regs(padconf):
-       # Generate the padmux data in kernel format
-       print "###########################################"
-       print "Pad data for u-boot (with the delay modes):"
-       print "###########################################"
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+# Generate output in u-boot format
+def uboot_format_pad_regs(padconf, per_padconf):
        print "\nconst struct pad_conf_entry dra74x_core_padconf_array[] = {"
        for i in padconf:
-               (pad_name, pin_name, addr, val, delaydata) = i
+               (pad_name, pin_name, addr, val, delayinfo) = i
                muxmode = val & 0xf
-               (method, data) = delaydata
+               (method, data) = delayinfo
                if (method == "LEGACY"):
                        extramode = ""
                elif (method == "VIRTUAL"):
@@ -291,24 +315,79 @@ def format_pad_regs(padconf):
                else:
                        print "ERR: Invalid method %s" % method
 
-               pin_info = format_pin_info(val) + extramode
+               pin_info = get_pin_info(val) + extramode
                pad_short = re.sub("CTRL_CORE_PAD_", "", pad_name)
                comment = (pad_short + "." + pin_name).lower()
                print "\t{ %s, (M%d | %s) },\t/* %s */" % (pad_short, muxmode, pin_info, comment)
        print "};\n"
 
-def format_delay_regs(delayconf):
-       # Generate the delay data in kernel format
-       print "#########################################"
-       print "Delay data for u-boot (for manual modes):"
-       print "#########################################"
+def uboot_format_delay_regs(delayconf, per_delayconf):
        print "\nconst struct iodelay_cfg_entry dra742_iodelay_cfg_array[] = {"
        for i in delayconf:
-               (pad_name, pin_name, regname, del_offset, adel, gdel) = i
+               (pad_name, pin_name, regname, del_offset, man_name, adel, gdel) = i
                print "\t{ 0x%04X, %5d, %5d },\t/* %s */" % (del_offset, adel, gdel, regname)
        print "};\n"
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 
+# Generate output in linux format
+def linux_format_pad_regs(padconf, per_padconf):
+       print "&dra7_pmx_core {"
+       for per in per_padconf:
+
+               if (re.match("MMC.*", per) == None):
+                       print "ERR: Only MMC padconf is recommended in kernel"
+                       continue
+
+               dtsnode = ("%s_pins_default" % per).lower()
+               print ""
+               print "\t%s: %s {" % (dtsnode, dtsnode)
+               print "\t\tpinctrl-single,pins = <"
+               for i in per_padconf[per]:
+                       (pad_name, pin_name, addr, val, delayinfo) = i
+                       muxmode = val & 0xf
+                       (method, data) = delayinfo
+                       if (method == "LEGACY"):
+                               extramode = ""
+                       elif (method == "VIRTUAL"):
+                               delaymode = data
+                               extramode = " | VIRTUAL_MODE%d" % delaymode
+                       elif (method == "MANUAL"):
+                               extramode = " | MANUAL_MODE"
+                       else:
+                               print "ERR: Invalid method %s" % method
+
+                       pin_info = get_pin_info(val) + extramode
+                       pad_short = re.sub("CTRL_CORE_PAD_", "", pad_name)
+                       offset = addr - 0x4a003400
+                       comment = (pad_short + "." + pin_name).lower()
+                       print "\t\t\t0x%03X\t(%s | MUM_MODE%d)\t/* %s */" % (offset, pin_info, muxmode, comment)
+               print "\t\t>;"
+               print "\t};"
+       print "};\n"
+
+
+def linux_format_delay_regs(delayconf, per_delayconf):
+       print "&dra7_iodelay_core {"
+       for per in per_delayconf.keys():
+
+               if (re.match("MMC.*", per) == None):
+                       print "ERR: Only MMC delayconf is recommended in kernel"
+                       continue
+
+               # Get the mode from the first entry
+               (pad_name, pin_name, regname, del_offset, mode, adel, gdel) = per_delayconf[per][0]
+               dtsnode = ("%s_iodelay_%s_conf" % (per, mode)).lower()
+               print "\t%s: %s {" % (dtsnode, dtsnode)
+               print "\t\tpinctrl-single,pins = <"
+               for i in per_delayconf[per]:
+                       (pad_name, pin_name, regname, del_offset, mode, adel, gdel) = i
+                       print "\t\t\t0x%03X A_DELAY(%d) | G_DELAY(%d)\t/* %s */" % (del_offset, adel, gdel, regname)
+               print "\t\t>;"
+               print "\t};"
+       print "};\n"
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
 # Main execution starts here
 # * Parse all the XML files - Get the pad data and IOdelay data
 # * Iterate over the pad register dumps
@@ -322,7 +401,7 @@ def format_delay_regs(delayconf):
 #     => Update the selection for the whole of the peripheral module
 #   - Worst case, skip the delaymode for this pad
 # * Build the pad and delay register information
-# * Create the dump for pad and delay data in kernel/u-boot format
+# * Create the dump for pad and delay data in linux/u-boot format
 # * Dump the delaymode selection for each peripheral
 # * Dump the GPIO script for each peripheral (all pads grouped together)
 #
@@ -333,9 +412,14 @@ 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)
 delayconf = []
-padinfo = []
+# Dictionary of pads grouped by peripheral/module
+per_padconf = {}
+# Dictionary of delay registers grouped by peripheral/module
+per_delayconf = {}
 
 # Start iterating over each pad
 for i in range(0, 260):
@@ -360,7 +444,9 @@ for i in range(0, 260):
        if (pin_name == "DRIVER OFF"):
                continue
 
-       padinfo.append((pad_name, pin_name, addr, offset, val))
+       # Find out if the delaymode for this module is already selected
+       module = re.match("([^_]+)_.*", pin_name).groups(0)[0]
+
        if (args.debug >= 1):
                print "\nPAD: %s: Addr= 0x%08X Value = 0x%08X \"%s\"" \
                % (pad_name, addr, val, pin_name)
@@ -369,23 +455,27 @@ for i in range(0, 260):
        (virt, man) = xml_find_delaymodes(pad_name, muxmode)
 
        # Need to select one out of allowed modes
-       mode = select_mode(pad_name, pin_name, virt, man, modehelp, sel)
+       mode = select_mode(pad_name, pin_name, module, virt, man, modehelp, sel)
        if (mode == "SKIP"):
                continue
 
        if (mode == "LEGACY"):
-               delaydata = ("LEGACY", "")
+               delayinfo = ("LEGACY", "")
        elif (mode in virt):
-               delaydata = ("VIRTUAL", virt[mode])
+               delayinfo = ("VIRTUAL", virt[mode])
        elif (mode in man):
-               delaydata = ("MANUAL", man[mode])
+               delayinfo = ("MANUAL", man[mode])
        else:
                print "ERR: Unknown mode '%s' selected" % mode
                continue
 
        if (args.debug >= 1):
                print "  => Using mode %s" % mode
-       padconf.append((pad_name, pin_name, addr, val, delaydata))
+       paddata = (pad_name, pin_name, addr, val, delayinfo)
+       if (module not in per_padconf.keys()):
+               per_padconf[module] = []
+       padconf.append(paddata)
+       per_padconf[module].append(paddata)
 
        if(mode not in man):
                continue
@@ -399,15 +489,19 @@ for i in range(0, 260):
                        break
                if (args.debug >= 1):
                        print "  => Manual delay[%s] = (%d, %d)" % (regname, adel, gdel)
-               delayconf.append((pad_name, pin_name, regname, del_offset, adel, gdel))
+               delaydata = (pad_name, pin_name, regname, del_offset, mode, adel, gdel)
+               if (module not in per_delayconf.keys()):
+                       per_delayconf[module] = []
+               delayconf.append(delaydata)
+               per_delayconf[module].append(delaydata)
 
 print ""
 print "Total PAD registers: %d" % len(padconf)
 print "Total DELAY registers: %d" % len(delayconf)
 print ""
 
-format_pad_regs(padconf)
-format_delay_regs(delayconf)
+format_pad_regs(padconf, per_padconf)
+format_delay_regs(delayconf, per_delayconf)
 
 # Dump the final selection for reuse
 print "Selected modes for each peripheral module\n"