m1n1/proxyclient/tools/pmgr_adt2dt.py

93 lines
2.7 KiB
Python
Raw Permalink Normal View History

#!/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()