diff options
author | Stephen Warren <swarren@nvidia.com> | 2015-02-11 12:25:38 -0700 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2015-02-25 15:58:04 -0700 |
commit | ca5bbef466b5c7ba899fbf69078049d6abbcce96 (patch) | |
tree | 5d4e78dcf01528132bfe73514ba7dec63bd62629 /csv-to-board.py | |
parent | 32ceb32d4f3babf4ad97dbd4d7002ee7a59f32ba (diff) | |
download | tegra-pinmux-scripts-ca5bbef466b5c7ba899fbf69078049d6abbcce96.tar.gz |
Support Tegra210
Tegra210 changes the pinmux HW in a few ways; at least:
- The set of drive groups is much more 1:1 with the set of pins. Most
pins have an associated drive group register as well as an associated
pinmux register, and most drive groups cover a single pin.
- Some register fields have moved from the drive group registers into
the pinmux registers.
- The set of available options for each pin and group varies relative to
previous chips, and hence the register layouts vary a bit too.
This patch updates tegra-pinmux-scripts minimally to handle these
changes, to a level equivalent to the support for previous chips. For
example, some new options such as per-pin schmitt aren't handled since
the syseng-supplied pinmux spreadsheets don't provide a value for this
option.
csv-to-board-tegra124-xlsx.py is renamed to csv-to-board.py since it now
supports boards using different SoCs, and it's not worth encoding all
supported SoCs in the filename (Tegra30/114 aren't supported by it, hence
the previous naming).
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'csv-to-board.py')
-rwxr-xr-x | csv-to-board.py | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/csv-to-board.py b/csv-to-board.py new file mode 100755 index 0000000..2860c02 --- /dev/null +++ b/csv-to-board.py @@ -0,0 +1,297 @@ +#!/usr/bin/python3 + +# Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +# This parses a CSV version of Logan_customer_pinmux_release.xlsm + +import argparse +import csv +import os +import os.path +import sys +import tegra_pmx_soc_parser +from tegra_pmx_utils import * + +dbg = False + +parser = argparse.ArgumentParser(description='Create a board config' + + 'from a CSV version of the Venice2 pinmux spreadsheet') +parser.add_argument('--debug', action='store_true', help='Turn on debugging prints') +parser.add_argument('--csv', default=argparse.SUPPRESS, help='CSV file to parse') +parser.add_argument('--csv-rsvd-0based', action='store_true', dest='csv_rsvd_0based', default=argparse.SUPPRESS, help='Assume 0-based RSVD numbering') +parser.add_argument('--csv-rsvd-1based', action='store_false', dest='csv_rsvd_0based', default=argparse.SUPPRESS, help='Assume 1-based RSVD numbering') +parser.add_argument('board', help='Board name') +args = parser.parse_args() +if args.debug: + dbg = True +if dbg: print(args) + +supported_boards = { + 'jetson-tk1': { + # Jetson_TK1_customer_pinmux.xlsm worksheet Jetson TK1 Configuration (1-based rsvd) from: + # https://developer.nvidia.com/hardware-design-and-development + 'filename': 'csv/jetson-tk1.csv', + 'rsvd_base': 1, + 'soc': 'tegra124', + }, + 'norrin': { + # PM370_T124_customer_pinmux_1.1.xlsm worksheet Customer_Configuration (0-based rsvd) + 'filename': 'nv-internal-data/PM370_T124_customer_pinmux_1.1.csv', + 'rsvd_base': 0, + 'soc': 'tegra124', + }, + 'venice2': { + # Venice2_T124_customer_pinmux_based_on_P4_rev47_2013-07-12.xlsm worksheet Customer_Configuration (0-based rsvd) + 'filename': 'nv-internal-data/Venice2_T124_customer_pinmux_based_on_P4_rev47_2013-07-12.csv', + 'rsvd_base': 0, + 'soc': 'tegra124', + }, +} + +if not args.board in supported_boards: + print('ERROR: Unsupported board %s' % args.board, file=sys.stderr) + sys.exit(1) +board_conf = supported_boards[args.board] +if 'csv' in args: + board_conf['filename'] = args.csv +if 'csv_rsvd_0based' in args: + board_conf['rsvd_base'] = {True: 0, False: 1}[args.csv_rsvd_0based] +if dbg: print(board_conf) + +soc = tegra_pmx_soc_parser.load_soc(board_conf['soc']) + +COL_BALL_NAME = 0 +COL_BALL_MID = 1 +COL_BALL_DSC = 2 +COL_GPIO = 3 +COL_F0 = 4 +COL_F1 = 5 +COL_F2 = 6 +COL_F3 = 7 +COL_FS = 8 +COL_MUX = 9 +COL_PUPD = 10 +COL_TRI = 11 +COL_E_INPUT = 12 +COL_GPIO_INIT_VAL = 13 +COL_DIRECTION = 14 +COL_RCV_SEL = 15 + +col_names = { + COL_BALL_NAME: 'Ball Name', + COL_BALL_MID: 'MID', + COL_BALL_DSC: 'DSC', + COL_GPIO: 'GPIO', + COL_F0: 'F0', + COL_F1: 'F1', + COL_F2: 'F2', + COL_F3: 'F3', + COL_FS: 'FS', + COL_MUX: 'Pin Group', + COL_PUPD: 'PUPD', + COL_TRI: 'Tristate', + COL_E_INPUT: 'E_Input', + COL_GPIO_INIT_VAL: 'GPIO Init Value', + COL_DIRECTION: 'Pin Direction', +} + +if soc.soc_pins_have_rcv_sel: + col_names[COL_RCV_SEL] = 'High or Normal VIL/VIH' + +if soc.soc_pins_have_e_io_hv: + col_names[COL_RCV_SEL] = '3.3V Tolerance Enable' + +cols = {} + +def func_munge(f): + if board_conf['soc'] == 'tegra124': + if f in ('sdmmc2a', 'sdmmc2b'): + return 'sdmmc2' + if f in ('ir3_rxd', 'ir3_txd'): + return 'irda' + if soc.soc_rsvd_base != board_conf['rsvd_base']: + if soc.soc_rsvd_base: + return rsvd_0base_to_1base(f) + else: + raise Exception('CSV 1-based to SoC 0-based not supported') + return f + +def pupd_munge(d): + return { + 'NORMAL': 'none', + 'PULL_UP': 'up', + 'PULL_DOWN': 'down', + }[d] + +def tri_munge(d): + return { + 'NORMAL': False, + 'TRISTATE': True, + }[d] + +def e_input_munge(d): + return { + 'DISABLE': False, + 'ENABLE': True, + }[d] + +def gpio_init_val_munge(d): + return { + '0': 'out0', + '1': 'out1', + }[d] + +def od_from_direction(d): + return d == 'Open-Drain' + +def rcv_sel_munge(d): + return { + '': False, + 'NORMAL': False, + 'HIGH': True, + 'Disable': False, + 'Enable': True, + }[d] + +found_header = False +pin_table = [] +with open(board_conf['filename'], newline='') as fh: + csv = csv.reader(fh) + lnum = 0 + for row in csv: + lnum += 1 + + # Header rows + if not found_header: + if row[0] != 'Ball Name': + if lnum > 25: + print('ERROR: Header row not found', file=sys.stderr) + sys.exit(1) + continue + for colid, coltext in col_names.items(): + try: + cols[colid] = row.index(coltext) + except: + if board_conf['soc'] != 'tegra124': + raise + if colid != COL_RCV_SEL: + print('ERROR: Header column "%s" not found' % coltext, file=sys.stderr) + sys.exit(1) + cols[colid] = None + found_header = True + continue + + ball_name = row[cols[COL_BALL_NAME]].lower() + ball_mid = row[cols[COL_BALL_MID]] + ball_dsc = row[cols[COL_BALL_DSC]] + + # Section title row + if not ball_mid and not ball_dsc: + continue + + mux = func_munge(row[cols[COL_MUX]].lower()) + + # Pin not affected by pinmux + if mux in ('', '0', '#n/a'): + continue + + if dbg: print(ball_name) + + gpio = row[cols[COL_GPIO]].lower() + f0 = func_munge(row[cols[COL_F0]].lower()) + f1 = func_munge(row[cols[COL_F1]].lower()) + f2 = func_munge(row[cols[COL_F2]].lower()) + f3 = func_munge(row[cols[COL_F3]].lower()) + fs = func_munge(row[cols[COL_FS]].lower()) + pupd = pupd_munge(row[cols[COL_PUPD]]) + tri = tri_munge(row[cols[COL_TRI]]) + e_input = e_input_munge(row[cols[COL_E_INPUT]]) + od = od_from_direction(row[cols[COL_DIRECTION]]) + if cols[COL_RCV_SEL]: + rcv_sel = rcv_sel_munge(row[cols[COL_RCV_SEL]]) + else: + rcv_sel = False + + mux_gpio = mux.startswith('gpio_p') or (mux == gpio) + if mux_gpio: + mux = None + if e_input: + gpio_init = 'in' + else: + gpio_init = gpio_init_val_munge(row[cols[COL_GPIO_INIT_VAL]]) + else: + gpio_init = None + + gpio_pin = soc.gpio_or_pin_by_name(ball_name) + for i, func in enumerate((f0, f1, f2, f3)): + if func != gpio_pin.funcs[i]: + print('WARNING: %s: F%d mismatch CSV %s vs SOC %s' % (ball_name, i, repr(func), repr(gpio_pin.funcs[i])), file=sys.stderr) + for i, func in enumerate((f0, f1, f2, f3)): + if func not in gpio_pin.funcs: + print('ERROR: %s: F%d CSV %s not in SOC list %s' % (ball_name, i, repr(func), repr(gpio_pin.funcs)), file=sys.stderr) + sys.exit(1) + if fs not in (f0, f1, f2, f3): + print('ERROR: %s: FSAFE CSV %s not in CSV F0..3 %s' % (ball_name, fs, repr((f0, f1, f2, f3))), file=sys.stderr) + sys.exit(1) + if mux and mux not in (f0, f1, f2, f3): + print('ERROR: %s: MUX CSV %s not in CSV F0..3 %s' % (ball_name, mux, repr((f0, f1, f2, f3))), file=sys.stderr) + sys.exit(1) + if mux and mux not in gpio_pin.funcs: + print('ERROR: %s: MUX CSV %s not in SOC F0..3 %s' % (ball_name, mux, repr(gpio_pin.funcs)), file=sys.stderr) + sys.exit(1) + + if (board_conf['soc'] == 'tegra124') and (ball_name in ('reset_out_n', 'owr', 'hdmi_int', 'ddc_scl', 'ddc_sda')): + # These balls' pad type is always OD, so we don't need to set it + # FIXME: The SoC data structure should tell us the pad type instead of hard-coding it + od = False + + if od and not gpio_pin.od: + print('WARNING: %s: OD in board file, but pin has no OD' % ball_name, file=sys.stderr) + od = False + pin_has_rcv_sel = False + if soc.soc_pins_have_rcv_sel: + pin_has_rcv_sel = gpio_pin.rcv_sel + if soc.soc_pins_have_e_io_hv: + pin_has_rcv_sel = gpio_pin.e_io_hv + if rcv_sel and not pin_has_rcv_sel: + print('WARNING: %s: RCV_SEL/E_IO_HV in board file, but pin does not support it' % ball_name, file=sys.stderr) + rcv_sel = False + + pin_table.append((repr(gpio_pin.fullname), repr(mux), repr(gpio_init), repr(pupd), repr(tri), repr(e_input), repr(od), repr(rcv_sel))) + +headings = ('pin', 'mux', 'gpio_init', 'pull', 'tri', 'e_inp', 'od') +if soc.soc_pins_have_e_io_hv: + headings += ('e_io_hv',) +if soc.soc_pins_have_rcv_sel: + headings += ('rcv_sel',) + +cfgfile = os.path.join('configs', args.board + '.board') +with open(cfgfile, 'wt') as fh: + print('soc = \'%s\'' % board_conf['soc'], file=fh) + print(file=fh) + print('pins = (', file=fh) + + dump_py_table(headings, pin_table, file=fh) + + print(')', file=fh) + print('', file=fh) + print('drive_groups = (', file=fh) + print(')', file=fh) |