#!/usr/bin/env python3 # SPDX-License-Identifier: MIT import sys, pathlib import serial sys.path.append(str(pathlib.Path(__file__).resolve().parents[1])) import argparse, pathlib from m1n1 import adt parser = argparse.ArgumentParser(description='Convert ADT PMGR nodes to Device Tree format') parser.add_argument("-m", "--multidie", action="store_true") parser.add_argument('input', type=pathlib.Path) args = parser.parse_args() adt_data = args.input.read_bytes() dt = adt.load_adt(adt_data) pmgr = dt["/arm-io/pmgr"] dev_by_id = {dev.id: dev for dev in pmgr.devices} blocks = {} maxaddr = {} def die_node(s): if args.multidie: return f"DIE_NODE({s})" else: return s def die_label(s): if args.multidie: return f"DIE_LABEL({s})" else: return s for i, dev in enumerate(pmgr.devices): if dev.flags.no_ps: continue ps = pmgr.ps_regs[dev.psreg] block = pmgr.get_reg(ps.reg) blocks.setdefault(block, []).append(dev) offset = ps.offset + dev.psidx * 8 maxaddr[block[0]] = max(maxaddr.get(block[0], 0), offset) pmgr_compat = pmgr.compatible[0].split(",")[1] compatible = f'"apple,{pmgr_compat}-pmgr", "apple,pmgr", "syscon", "simple-mfd"' ps_compatible = f'"apple,{pmgr_compat}-pmgr-pwrstate", "apple,pmgr-pwrstate"' for i, ((base, size), devices) in enumerate(sorted(blocks.items())): size = min(size, (maxaddr[base] + 0x3fff) & ~0x3fff) print(f"pmgr{i}: power-management@{base:x} {{") print(f"\tcompatible = {compatible};") print( "\t#address-cells = <1>;") print( "\t#size-cells = <1>;") print() print(f"\treg = <{base >> 32:#x} {base & 0xffffffff:#x} 0 {size:#x}>;") print( "};") print() for i, ((base, size), devices) in enumerate(sorted(blocks.items())): print(f"&pmgr{i} {{") for dev in sorted(devices, key=lambda d: pmgr.ps_regs[d.psreg].offset + dev.psidx * 8): if dev.flags.no_ps: continue ps = pmgr.ps_regs[dev.psreg] offset = ps.offset + dev.psidx * 8 addr = pmgr.get_reg(ps.reg)[0] + offset assert base <= addr <= (base + size) print() print(f"\t{die_node('ps_' + dev.name.lower())}: power-controller@{offset:x} {{") print(f"\t\tcompatible = {ps_compatible};") print(f"\t\treg = <{offset:#x} 4>;") print( "\t\t#power-domain-cells = <0>;") print( "\t\t#reset-cells = <0>;") print(f'\t\tlabel = {die_label(dev.name.lower())};') if dev.flags.critical: print("\t\tapple,always-on;") if any(dev.parents): domains = [f"<&{die_node('ps_'+dev_by_id[idx].name.lower())}>" for idx in dev.parents if idx] print(f"\t\tpower-domains = {', '.join(domains)};") print( "\t};") print( "};") print()