Skip to content

Commit 976f12b

Browse files
gen_domain: assign conventional Zephyr TTC label
Zephyr's ZynqMP and Versal R5 timer configuration refers to the ttc0 nodelabel, while an SDT domain can retain a differently labeled TTC or more than one TTC. Normalize the domain-local result instead of making Zephyr select an arbitrary compatible instance. Preserve an explicitly mapped ttc0 and otherwise promote the first TTC retained by domain access. Accept both cdns,ttc and xlnx,ttcps inputs, update the symbols node, and cover single, multiple, compatible, and non-R5 cases. Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
1 parent fd4be07 commit 976f12b

2 files changed

Lines changed: 97 additions & 0 deletions

File tree

lopper/assists/gen_domain_dts.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,39 @@
2727
from openamp_xlnx import xlnx_openamp_keep_node
2828

2929

30+
def _xlnx_zephyr_assign_ttc0(tree, machine):
31+
"""Give the Zephyr-selected ZynqMP/Versal R5 TTC a stable label.
32+
33+
Domain access has already removed devices that are not assigned to the
34+
target. Preserve an explicit ``ttc0`` selection. If none exists, promote
35+
the first TTC retained for this domain so Zephyr has its conventional
36+
timer label.
37+
"""
38+
if not ("psu_cortexr5" in machine or "psv_cortexr5" in machine):
39+
return
40+
41+
ttc_compatibles = {"cdns,ttc", "xlnx,ttcps"}
42+
ttc_nodes = []
43+
for node in tree.nodes('.*'):
44+
compatibles = set(node.propval("compatible", list))
45+
if compatibles & ttc_compatibles:
46+
ttc_nodes.append(node)
47+
48+
if any(node.label == "ttc0" for node in ttc_nodes):
49+
return
50+
if not ttc_nodes:
51+
return
52+
53+
ttc = ttc_nodes[0]
54+
ttc.label_set("ttc0")
55+
try:
56+
symbols = tree["/__symbols__"]
57+
except KeyError:
58+
symbols = LopperNode(-1, "/__symbols__")
59+
tree + symbols
60+
symbols["ttc0"] = ttc.abs_path
61+
62+
3063
def xlnx_zephyr_fixup_rpu_memory_names(tree, machine, memory_nodes):
3164
"""Match R5/R52 Zephyr memory unit addresses to their local reg view."""
3265
if not ("cortexr5" in machine or "cortexr52" in machine):
@@ -801,6 +834,7 @@ def xlnx_generate_domain_dts(tgt_node, sdt, options):
801834
if zephyr_dt:
802835
if "r52" in machine or "a78" in machine or "a72" in machine or "r5" in machine or "a53" in machine:
803836
xlnx_generate_zephyr_domain_dts_arm(tgt_node, sdt, options, machine)
837+
_xlnx_zephyr_assign_ttc0(sdt.tree, machine)
804838
if "a78" in machine or "a72" in machine:
805839
new_dst_node = LopperNode()
806840
new_dst_node['compatible'] = "arm,psci-1.1"

tests/test_xlnx_gen_domain.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,69 @@
2121
from lopper.tree import LopperNode, LopperTree
2222

2323

24+
def _ttc_tree(*labels, compatible="xlnx,ttcps"):
25+
"""Create a minimal tree containing TTC nodes with optional labels."""
26+
tree = LopperTree()
27+
tree + LopperNode(-1, "/__symbols__")
28+
nodes = []
29+
for index, label in enumerate(labels):
30+
node = LopperNode(-1, f"/axi/timer@ff1{index}0000")
31+
node["compatible"] = [compatible]
32+
if label:
33+
node.label = label
34+
tree + node
35+
nodes.append(node)
36+
return tree, nodes
37+
38+
39+
def test_zephyr_r5_labels_sole_selected_ttc_as_ttc0():
40+
"""A sole domain-selected TTC gets Zephyr's stable ttc0 label."""
41+
tree, nodes = _ttc_tree("ttc2")
42+
43+
gen_domain_dts._xlnx_zephyr_assign_ttc0(tree, "psu_cortexr5_0")
44+
45+
assert nodes[0].label == "ttc0"
46+
assert tree["/__symbols__"].propval("ttc0", list) == [nodes[0].abs_path]
47+
48+
49+
def test_zephyr_r5_preserves_explicit_ttc0_with_multiple_ttcs():
50+
"""An explicitly selected ttc0 wins without relying on tree order."""
51+
tree, nodes = _ttc_tree("ttc1", "ttc0")
52+
53+
gen_domain_dts._xlnx_zephyr_assign_ttc0(tree, "psv_cortexr5_0")
54+
55+
assert [node.label for node in nodes] == ["ttc1", "ttc0"]
56+
57+
58+
def test_zephyr_r5_labels_first_domain_ttc_when_no_ttc0_exists():
59+
"""The first domain-retained TTC becomes ttc0 when none is explicit."""
60+
tree, _ = _ttc_tree("ttc1", "ttc2")
61+
62+
gen_domain_dts._xlnx_zephyr_assign_ttc0(tree, "psu_cortexr5_0")
63+
64+
assert tree["/axi/timer@ff100000"].label == "ttc0"
65+
assert tree["/axi/timer@ff110000"].label == "ttc2"
66+
67+
68+
def test_zephyr_r5_accepts_sdt_cdns_ttc_compatible():
69+
"""ZynqMP's SDT-side cdns,ttc node participates in label selection."""
70+
tree, nodes = _ttc_tree("ttc1", compatible="cdns,ttc")
71+
72+
gen_domain_dts._xlnx_zephyr_assign_ttc0(tree, "psu_cortexr5_0")
73+
74+
assert nodes[0].label == "ttc0"
75+
76+
77+
def test_ttc_label_normalization_is_r5_platform_specific():
78+
"""Other Zephyr processor families retain their original TTC labels."""
79+
tree, nodes = _ttc_tree("ttc2")
80+
81+
gen_domain_dts._xlnx_zephyr_assign_ttc0(tree, "cortexr52_0")
82+
83+
assert nodes[0].label == "ttc2"
84+
assert tree["/__symbols__"].propval("ttc0") == ['']
85+
86+
2487
def test_rpu_memory_rename_refreshes_path_and_phandle_references():
2588
"""RPU local-view renames preserve chosen, symbol, and phandle refs."""
2689
tree = LopperTree()

0 commit comments

Comments
 (0)