1#!/usr/bin/env python
2
3"""
4Copyright (c) 2024 Silicon Laboratories Inc.
5
6SPDX-License-Identifier: Apache-2.0
7"""
8import argparse
9import re
10from pathlib import Path
11
12devices = {
13	"xg21": {
14		"bits": "platform/Device/SiliconLabs/EFR32MG21/Include/efr32mg21_cmu.h",
15  },
16	"xg22": {
17		"bits": "platform/Device/SiliconLabs/EFR32BG22/Include/efr32bg22_cmu.h",
18		"nodes": "platform/service/device_manager/clocks/sl_device_clock_efr32xg22.c"
19  },
20	"xg23": {
21		"bits": "platform/Device/SiliconLabs/EFR32FG23/Include/efr32fg23_cmu.h",
22		"nodes": "platform/service/device_manager/clocks/sl_device_clock_efr32xg23.c"
23  },
24	"xg24": {
25		"bits": "platform/Device/SiliconLabs/EFR32MG24/Include/efr32mg24_cmu.h",
26		"nodes": "platform/service/device_manager/clocks/sl_device_clock_efr32xg24.c"
27  },
28	"xg27": {
29		"bits": "platform/Device/SiliconLabs/EFR32BG27/Include/efr32bg27_cmu.h",
30		"nodes": "platform/service/device_manager/clocks/sl_device_clock_efr32xg27.c"
31  },
32	"xg29": {
33		"bits": "platform/Device/SiliconLabs/EFR32BG29/Include/efr32bg29_cmu.h",
34		"nodes": "platform/service/device_manager/clocks/sl_device_clock_efr32xg29.c"
35  },
36}
37
38clocks = {
39  "BUS_CLOCK_CLKEN0": 0,
40  "BUS_CLOCK_CLKEN1": 1,
41  "BUS_CLOCK_CLKEN2": 2,
42  "BUS_CLOCK_CLKENHV": 3,
43}
44
45if __name__ == "__main__":
46  parser = argparse.ArgumentParser(description="Generate headers for Clock Control for Series 2 "
47                                   "devices. The headers are used from DeviceTree, and represent "
48                                   "every clock enable bit as a DT compatible macro.")
49  parser.add_argument("--out", "-o", type=Path, default=Path(__file__).parent / "out",
50                      help="Output directory. Defaults to the directory ./out/ relative to the "
51                      "script. Set to $ZEPHYR_BASE/include/zephyr/dt-bindings/clock/silabs/ "
52                      "to directly generate output into the expected location within the Zephyr "
53                      "main tree.")
54  parser.add_argument("--sdk", "-s", type=Path, default=Path(__file__).parent.parent / "simplicity_sdk",
55                      help="Path to Simplicity SDK to extract data from. Defaults to the directory "
56                       "../simplicity_sdk relative to the script.")
57  args = parser.parse_args()
58
59  args.out.mkdir(exist_ok=True)
60
61  for device, data_sources in devices.items():
62    print(f"Generate clock control binding for {device}")
63    bits_file = (args.sdk / data_sources["bits"]).resolve()
64    bits = {}
65    with bits_file.open() as f:
66      for line in f:
67        if m := re.match(r"#define (_CMU_CLKEN.*_SHIFT)\s+(\d+)", line):
68          bits[m.group(1)] = m.group(2)
69
70    nodes = []
71    if "nodes" in data_sources:
72      node_file = (args.sdk / data_sources["nodes"]).resolve(strict=True)
73      with node_file.open() as f:
74        for line in f:
75          if m := re.match(r".*uint32_t SL_BUS_(.*)_VALUE = \(([^\s]+).*(_CMU[^\s]+SHIFT)", line):
76            try:
77              nodes.append(f"#define {m.group(1)}"
78                          f"{' ' * (20 - len(m.group(1)))}"
79                          f"(FIELD_PREP(CLOCK_REG_MASK, {clocks[m.group(2)]}) | "
80                          f"FIELD_PREP(CLOCK_BIT_MASK, {bits[m.group(3)]}))"
81              )
82            except KeyError as e:
83              print(f"WARN: Failed to emit clock node: {e}")
84    else:
85      # xg21 has on-demand automatic clock requests, there are no enable bits
86      nodes.append("#define CLOCK_AUTO 0xFFFFFFFFUL")
87
88    file = [
89      "/*",
90      " * Copyright (c) 2024 Silicon Laboratories Inc.",
91      " *",
92      " * SPDX-License-Identifier: Apache-2.0",
93      " *",
94      f" * This file was generated by the script {Path(__file__).name} in the hal_silabs module.",
95      " * Do not manually edit.",
96      " */",
97      "",
98      f"#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_{device.upper()}_CLOCK_H_",
99      f"#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_{device.upper()}_CLOCK_H_",
100      "",
101      "#include <zephyr/dt-bindings/dt-util.h>",
102      "#include \"common-clock.h\"",
103      "",
104      "/*",
105      " * DT macros for clock tree nodes.",
106      " * Defined as:",
107      " *  0..5 - Bit within CLKEN register",
108      " *  6..8 - CLKEN register number",
109      " * Must stay in sync with equivalent SL_BUS_*_VALUE constants in the Silicon Labs HAL to be",
110      " * interpreted correctly by the clock control driver.",
111      " */",
112    ] + nodes + [
113      "",
114      f"#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_{device.upper()}_CLOCK_H_ */",
115      "",
116    ]
117
118    outfile = args.out / f"{device}-clock.h"
119    outfile.write_text("\n".join(file))
120