# 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. import collections import os.path from tegra_pmx_parser_utils import * script_dir = os.path.dirname(os.path.abspath(__file__)) configs_dir = os.path.join(script_dir, 'configs') class PinBase(ReprDictObj): def __init__(self, soc, signal, gpio, num, data): self.signal = signal self.gpio = gpio self.num = num fields = [] if self.signal: fields += (self.signal,) if self.gpio: fields += ('p' + self.gpio,) self.fullname = '_'.join((fields)) if self.signal: self.shortname = self.signal else: self.shortname = self.gpio self.define = 'TEGRA_PIN_' + '_'.join(fields).upper() self.desc = ' '.join(fields).upper() if not data: self.reg = None return fields = ('reg', 'f0', 'f1', 'f2', 'f3',) if soc.soc_pins_all_have_od: self.od = True elif soc.soc_pins_have_od: fields += ('od',) if soc.soc_pins_have_ior: fields += ('ior',) if soc.soc_pins_have_rcv_sel: fields += ('rcv_sel', ) if soc.soc_pins_have_hsm: fields += ('hsm', ) if soc.soc_pins_all_have_schmitt: self.schmitt = True elif soc.soc_pins_have_schmitt: fields += ('schmitt', ) if soc.soc_pins_have_drvtype: fields += ('drvtype', ) if soc.soc_pins_have_e_io_hv: fields += ('e_io_hv', ) for i, field in enumerate(fields): self.__setattr__(field, data[i]) self.funcs = (self.f0, self.f1, self.f2, self.f3) self.per_pin_drive_group = None def set_per_pin_drive_group(self, g): self.per_pin_drive_group = g def sort_by_num_key(self): return (self.__class__ == Pin, self.num) def _gpio_number(gpion): if len(gpion) == 2: bank = ord(gpion[0]) - ord('a') index = ord(gpion[1]) - ord('0') else: bank = ord(gpion[0]) - ord('a') + 26 index = ord(gpion[2]) - ord('0') return (bank * 8) + index class Gpio(PinBase): def __init__(self, soc, data): num = _gpio_number(data[1]) PinBase.__init__(self, soc, data[0], data[1], num, data[2:]) class Pin(PinBase): def __init__(self, soc, num, data): PinBase.__init__(self, soc, data[0], '', num, data[1:]) class DriveGroup(ReprDictObj): def __init__(self, soc, data, gpios_pins): fields = ('name', 'reg', ) if soc.soc_drvgroups_have_hsm: fields += ('hsm_b',) if soc.soc_drvgroups_have_schmitt: fields += ('schmitt_b',) if soc.soc_drvgroups_have_lpmd: fields += ('lpmd_b',) if soc.soc_drvgroups_have_parked: fields += ('prk_mask',) fields += ('drvdn_b', 'drvdn_w', 'drvup_b', 'drvup_w', 'slwr_b', 'slwr_w', 'slwf_b', 'slwf_w') if soc.soc_drvgroups_have_drvtype: fields += ('drvtype', ) for i, field in enumerate(fields): self.__setattr__(field, data[i]) self.gpios_pins = gpios_pins self.fullname = 'drive_' + self.name self.has_matching_pin = ( soc.soc_combine_pin_drvgroup and (len(gpios_pins) == 1) and (gpios_pins[0].shortname == self.name) ) if self.has_matching_pin: gpios_pins[0].set_per_pin_drive_group(self) class MipiPadCtrlGroup(ReprDictObj): def __init__(self, soc, data, gpios_pins): fields = ('name', 'reg', 'bit', 'f0', 'f1') for i, field in enumerate(fields): self.__setattr__(field, data[i]) self.gpios_pins = gpios_pins self.fullname = 'mipi_pad_ctrl_' + self.name self.funcs = (self.f0, self.f1) class Function(ReprDictObj): def __init__(self, name): self.name = name self.pins = [] def _add_pin(self, pin): self.pins.append(pin) class Soc(TopLevelParsedObj): def __init__(self, name, data): copy_attrs = ( ('kernel_copyright_years', 2014), ('kernel_author', 'NVIDIA'), ('uboot_copyright_years', 2014), ('soc_has_io_clamping', None), ('soc_combine_pin_drvgroup', None), ('soc_rsvd_base', None), ('soc_drvgroups_have_drvtype', None), ('soc_drvgroups_have_hsm', None), ('soc_drvgroups_have_lpmd', None), ('soc_drvgroups_have_parked', None), ('soc_drvgroups_have_schmitt', None), ('soc_pins_all_have_od', None), ('soc_pins_all_have_parked', None), ('soc_pins_all_have_schmitt', None), ('soc_pins_have_drvtype', None), ('soc_pins_have_e_io_hv', None), ('soc_pins_have_hsm', None), ('soc_pins_have_ior', None), ('soc_pins_have_od', None), ('soc_pins_have_rcv_sel', None), ('soc_pins_have_schmitt', None), ('soc_drv_reg_base', None), ('soc_mipipadctrl_reg_base', 0), ('soc_einput_b', None), ('soc_odrain_b', None), ('soc_parked_bit', None), ) TopLevelParsedObj.__init__(self, name, copy_attrs, data) gpios_pins_by_fullname = {} gpios_pins_by_shortname = {} self._gpios = [] for gpiodata in data['gpios']: gpio = Gpio(self, gpiodata) gpios_pins_by_fullname[gpio.fullname] = gpio gpios_pins_by_shortname[gpio.shortname] = gpio self._gpios.append(gpio) self._pins = [] for num, pindata in enumerate(data['pins']): pin = Pin(self, num, pindata) gpios_pins_by_fullname[pin.fullname] = pin gpios_pins_by_shortname[pin.shortname] = pin self._pins.append(pin) self._drive_groups = [] for drive_group in data['drive_groups']: names = data['drive_group_pins'][drive_group[0]] gpios_pins = [] for name in names: gpios_pins.append(gpios_pins_by_fullname[name]) self._drive_groups.append(DriveGroup(self, drive_group, gpios_pins)) self._mipi_pad_ctrl_groups = [] for group in data.get('mipi_pad_ctrl_groups', []): names = data['mipi_pad_ctrl_group_pins'][group[0]] gpios_pins = [] for name in names: gpios_pins.append(gpios_pins_by_fullname[name]) self._mipi_pad_ctrl_groups.append(MipiPadCtrlGroup(self, group, gpios_pins)) self._generate_derived_data() def _generate_derived_data(self): self._gpios_by_num = sorted(self._gpios, key=lambda gpio: gpio.num) self._pins_by_num = sorted(self._pins, key=lambda pin: pin.num) self._gpios_pins_by_num = sorted(self._gpios + self._pins, key=lambda gpio_pin: gpio_pin.sort_by_num_key()) gpios_with_reg = [gpio for gpio in self._gpios if gpio.reg] pins_with_reg = [pin for pin in self._pins if pin.reg] self._gpios_by_reg = sorted(gpios_with_reg, key=lambda gpio: gpio.reg) self._pins_by_reg = sorted(pins_with_reg, key=lambda pin: pin.reg) self._gpios_pins_by_reg = sorted(gpios_with_reg + pins_with_reg, key=lambda gpio_pin: gpio_pin.reg) self._drive_groups_by_reg = sorted(self._drive_groups, key=lambda drive_group: drive_group.reg) self._drive_groups_by_alpha = sorted(self._drive_groups, key=lambda drive_group: drive_group.name) self._mipi_pad_ctrl_groups_by_reg = sorted(self._mipi_pad_ctrl_groups, key=lambda group: group.reg) self._mipi_pad_ctrl_groups_by_alpha = sorted(self._mipi_pad_ctrl_groups, key=lambda group: group.name) functions = collections.OrderedDict() for pin in self._gpios + self._pins: if not pin.reg: continue for func in pin.funcs: if func not in functions: functions[func] = Function(func) functions[func]._add_pin(pin) for group in self._mipi_pad_ctrl_groups: for func in (group.f0, group.f1): if func not in functions: functions[func] = Function(func) self._functions = functions.values() self._functions_by_alpha = sorted(self._functions, key=lambda f: f.name) def gpios_by_conf_order(self): return self._gpios def gpios_by_num(self): return self._gpios_by_num def gpios_by_reg(self): return self._gpios_by_reg def pins_by_conf_order(self): return self._pins def pins_by_num(self): return self._pins_by_num def pins_by_reg(self): return self._pins_by_reg def gpios_pins_by_num(self): return self._gpios_pins_by_num def gpios_pins_by_reg(self): return self._gpios_pins_by_reg def gpio_or_pin_by_name(self, name): for gpio_pin in self._gpios_pins_by_num: if name == gpio_pin.signal: return gpio_pin if name == 'gpio_p' + gpio_pin.gpio: return gpio_pin return None def gpio_or_pin_by_fullname(self, name): for gpio_pin in self._gpios_pins_by_num: if name == gpio_pin.fullname: return gpio_pin return None def drive_groups_by_conf_order(self): return self._drive_groups def drive_groups_by_reg(self): return self._drive_groups_by_reg def drive_groups_by_alpha(self): return self._drive_groups_by_alpha def mipi_pad_ctrl_groups_by_conf_order(self): return self._mipi_pad_ctrl_groups def mipi_pad_ctrl_groups_by_reg(self): return self._mipi_pad_ctrl_groups_by_reg def mipi_pad_ctrl_groups_by_alpha(self): return self._mipi_pad_ctrl_groups_by_alpha def mipi_pad_ctrl_group_by_name(self, name): for mipi_pad_ctrl in self._mipi_pad_ctrl_groups: if name == mipi_pad_ctrl.name: return mipi_pad_ctrl return None def functions(self): return self._functions def functions_by_alpha(self): return self._functions_by_alpha def load_soc(socname): fn = os.path.join(configs_dir, socname + '.soc') d = {} with open(fn) as f: code = compile(f.read(), fn, 'exec') exec(code, globals(), d) return Soc(socname, d)