Skip to content

Commit 5b0a80c

Browse files
committed
test: DTS-parity test + XSA reference fixture for ADRV9371+ZC706
Extend the offline DT-emission parity framework to the second hw board in CI. Commits the XSA-pipeline output DTS from a passing ``hw-direct (bq)`` artifact as ``test/devices/fixtures/adrv9371_zc706_xsa_reference.dts``, and adds a new parametrized test ``test/devices/test_system_adrv9371_zc706_dts_parity.py`` that pins 31 kernel-relevant properties where the System-API and XSA paths already agree (AD9371 top-level + AD9528 clock-chip PLL/SYSREF configuration). Four properties the System-API path is known to miss vs XSA — ``ad9371:clocks``, ``ad9371:clock-names``, ``ad9371:jesd204-inputs``, ``ad9371:jesd204-link-ids`` — are recorded as ``@pytest.mark.xfail`` with reasons referencing the gap noted in ``test/hw/test_adrv9371_zc706_hw.py`` (System API doesn't yet emit the XCVR/TPL-core/clkgen overlay for ZC706). Each xfail becomes a regression guard the moment the System-API starts emitting the property. Along the way, extend ``adidt.tools.dts_inspect`` so the parser covers this board's DTS too: - ``_GROUPING_ANCESTORS`` gains ``ad9371-phy``, ``adrv9009-phy``, ``ad9528-1``, ``ad9523-1``, ``axi-adxcvr``, ``axi-clkgen``, and the JESD204 TPL core nodes. ``_ANCESTOR_ALIAS`` strips the ``-phy`` / ``-1`` suffix so keys stay canonical (``ad9371:compatible`` regardless of whether the node is ``ad9371`` or ``ad9371-phy@1``). - ``extract_props`` now normalises the ``}; foo: bar@0 {`` multi-node-on-one-line pattern that appears in merged DTS output by splitting on ``};`` before the line-oriented matchers run. Without the split the parser leaves the previous node open and misattributes the next node's properties to it — the AD9371's clocks/gpios were landing under ``ad9528:`` before this change. FMCDAQ3+VCU118 doesn't ship a DT generation path (boots a prebuilt simpleImage via JTAG), so no parity fixture is possible for that board. 31 parity keys * ADRV9371 + 14 parity keys * AD9081 now run in <0.5 s locally — keeps the "catch DT-emission regressions before hw" story covered for the two boards with a generated DT path.
1 parent 2a26fbc commit 5b0a80c

3 files changed

Lines changed: 496 additions & 3 deletions

File tree

adidt/tools/dts_inspect.py

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,33 @@
103103
"channel@13",
104104
"adi,tx-dacs",
105105
"adi,rx-adcs",
106+
# Converter / transceiver top-level nodes. ``@addr`` is stripped
107+
# in ``_choose_prefix`` so ``ad9081@0`` keys as ``ad9081``.
106108
"ad9081",
109+
"ad9084",
110+
"ad9371-phy",
111+
"ad9371",
112+
"adrv9009-phy",
113+
"adrv9009",
114+
# Clock distributor / synthesizer chips.
115+
"ad9523-1",
116+
"ad9528-1",
117+
"ad9528",
107118
"hmc7044",
119+
# FPGA-side JESD204 IP blocks + TPL cores.
120+
"axi-adxcvr",
121+
"axi-clkgen",
122+
"ad_ip_jesd204_tpl_adc",
123+
"ad_ip_jesd204_tpl_dac",
108124
)
109125

110-
# Normalise ancestor names that include a ``adi,`` prefix or ``@addr``
111-
# suffix to the short form used as a key prefix.
126+
# Normalise ancestor names to the short form used as a key prefix.
112127
_ANCESTOR_ALIAS: dict[str, str] = {
113128
"adi,tx-dacs": "tx-dacs",
114129
"adi,rx-adcs": "rx-adcs",
130+
"ad9528-1": "ad9528",
131+
"ad9371-phy": "ad9371",
132+
"adrv9009-phy": "adrv9009",
115133
}
116134

117135

@@ -142,11 +160,31 @@ def extract_props(dts_text: str) -> dict[str, str]:
142160
rather than whatever the innermost node happens to be (e.g.
143161
``link@0``). First-occurrence wins; the base node's value is what
144162
the kernel sees at probe time before any ``&label`` overlays.
163+
164+
The parser normalises multi-node-on-one-line patterns (common in
165+
merged DTS output: ``}; foo: bar@0 {``) by splitting
166+
those onto separate logical lines before the line-oriented match
167+
step runs.
145168
"""
146169
node_stack: list[str] = []
147170
out: dict[str, str] = {}
148171

149-
for line in dts_text.splitlines():
172+
# Normalise multi-brace-per-line DTS shapes so the line-oriented
173+
# matchers below see one structural event per line:
174+
# ``}; foo: bar@0 {`` → ``};\n\tfoo: bar@0 {``
175+
normalised: list[str] = []
176+
for raw in dts_text.splitlines():
177+
# Split on ``};`` (keeping the match itself as a standalone line).
178+
parts = re.split(r"(\};)", raw)
179+
for part in parts:
180+
if part == "":
181+
continue
182+
if part == "};":
183+
normalised.append("};")
184+
else:
185+
normalised.append(part)
186+
187+
for line in normalised:
150188
stripped = line.strip()
151189
if not stripped:
152190
continue
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
/*
2+
* ADI Device Tree (merged) — adrv937x_zc706
3+
*
4+
* Generated by pyadi-dt from XSA. Do not edit manually — re-run
5+
* the pipeline to regenerate from the XSA source.
6+
*
7+
* Compile with:
8+
* dtc -I dts -O dtb -o system.dtb adrv937x_zc706.dts
9+
*/
10+
/dts-v1/;
11+
#include "zynq-7000.dtsi"
12+
#include "pl.dtsi"
13+
#include "pcw.dtsi"
14+
/delete-node/ &axi_hdmi_clkgen;
15+
16+
/ {
17+
board = "zc706";
18+
compatible = "xlnx,zynq-7000";
19+
device_id = "7z045";
20+
slrcount = <1>;
21+
family = "Zynq";
22+
speed_grade = "2";
23+
ps7_qspi_linear_0_memory: memory@fc000000 {
24+
compatible = "xlnx,ps7-qspi-linear-1.00.a-memory";
25+
xlnx,ip-name = "ps7_qspi_linear";
26+
memory_type = "linear_flash";
27+
reg = <0xfc000000 0x2000000>;
28+
};
29+
ps7_ddr_0_memory: memory@00100000 {
30+
compatible = "xlnx,ps7-ddr-1.00.a";
31+
xlnx,ip-name = "ps7_ddr";
32+
device_type = "memory";
33+
memory_type = "memory";
34+
reg = <0x00100000 0x3FF00000>;
35+
};
36+
ps7_ram_0_memory: memory@0 {
37+
compatible = "xlnx,ps7-ram-1.00.a";
38+
xlnx,ip-name = "ps7_ram";
39+
memory_type = "memory";
40+
reg = <0x0 0x30000>;
41+
};
42+
ps7_ram_1_memory: memory@ffff0000 {
43+
compatible = "xlnx,ps7-ram-1.00.a";
44+
xlnx,ip-name = "ps7_ram";
45+
memory_type = "memory";
46+
reg = <0xffff0000 0xfe00>;
47+
};
48+
chosen {
49+
stdout-path = "serial0:115200n8";
50+
bootargs = "earlycon";
51+
};
52+
aliases {
53+
serial0 = &uart1;
54+
spi0 = &qspi;
55+
serial1 = &coresight;
56+
i2c0 = &axi_iic_main;
57+
i2c1 = &i2c0;
58+
ethernet0 = &gem0;
59+
};
60+
cpus_a9: cpus-a9@0 {
61+
compatible = "cpus,cluster";
62+
address-map = <0xf0000000 &amba 0xf0000000 0x10000000>,
63+
<0x00100000 &ps7_ddr_0_memory 0x00100000 0x3FF00000>,
64+
<0x0 &ps7_ram_0_memory 0x0 0x30000>,
65+
<0xffff0000 &ps7_ram_1_memory 0xffff0000 0xfe00>,
66+
<0x41600000 &axi_iic_main 0x41600000 0x1000>,
67+
<0x43000000 &axi_hdmi_dma 0x43000000 0x1000>,
68+
<0x43c00000 &axi_ad9371_tx_clkgen 0x43c00000 0x10000>,
69+
<0x43c10000 &axi_ad9371_rx_clkgen 0x43c10000 0x10000>,
70+
<0x43c20000 &axi_ad9371_rx_os_clkgen 0x43c20000 0x10000>,
71+
<0x44a00000 &rx_ad9371_tpl_core_adc_tpl_core 0x44a00000 0x2000>,
72+
<0x44a04000 &tx_ad9371_tpl_core_dac_tpl_core 0x44a04000 0x2000>,
73+
<0x44a08000 &rx_os_ad9371_tpl_core_adc_tpl_core 0x44a08000 0x2000>,
74+
<0x44a50000 &axi_ad9371_rx_os_xcvr 0x44a50000 0x10000>,
75+
<0x44a60000 &axi_ad9371_rx_xcvr 0x44a60000 0x10000>,
76+
<0x44a80000 &axi_ad9371_tx_xcvr 0x44a80000 0x10000>,
77+
<0x44a90000 &axi_ad9371_tx_jesd_tx_axi 0x44a90000 0x4000>,
78+
<0x44aa0000 &axi_ad9371_rx_jesd_rx_axi 0x44aa0000 0x4000>,
79+
<0x44ab0000 &axi_ad9371_rx_os_jesd_rx_axi 0x44ab0000 0x4000>,
80+
<0x45000000 &axi_sysid_0 0x45000000 0x10000>,
81+
<0x70e00000 &axi_hdmi_core 0x70e00000 0x10000>,
82+
<0x75c00000 &axi_spdif_tx_core 0x75c00000 0x10000>,
83+
<0x79000000 &axi_hdmi_clkgen 0x79000000 0x10000>,
84+
<0x7c400000 &axi_ad9371_rx_dma 0x7c400000 0x1000>,
85+
<0x7c420000 &axi_ad9371_tx_dma 0x7c420000 0x1000>,
86+
<0x7c440000 &axi_ad9371_rx_os_dma 0x7c440000 0x1000>,
87+
<0xf8008000 &ps7_afi_0 0xf8008000 0x1000>,
88+
<0xf8009000 &ps7_afi_1 0xf8009000 0x1000>,
89+
<0xf800a000 &ps7_afi_2 0xf800a000 0x1000>,
90+
<0xf800b000 &ps7_afi_3 0xf800b000 0x1000>,
91+
<0xf8800000 &coresight 0xf8800000 0x100000>,
92+
<0xf8006000 &mc 0xf8006000 0x1000>,
93+
<0xf8007000 &devcfg 0xf8007000 0x100>,
94+
<0xf8004000 &ps7_dma_ns 0xf8004000 0x1000>,
95+
<0xf8003000 &dmac_s 0xf8003000 0x1000>,
96+
<0xe000b000 &gem0 0xe000b000 0x1000>,
97+
<0xf8f00200 &global_timer 0xf8f00200 0x100>,
98+
<0xe000a000 &gpio0 0xe000a000 0x1000>,
99+
<0xf8900000 &ps7_gpv_0 0xf8900000 0x100000>,
100+
<0xe0004000 &i2c0 0xe0004000 0x1000>,
101+
<0xf8f01000 &intc 0xf8f01000 0x1000>,
102+
<0xe0200000 &ps7_iop_bus_config_0 0xe0200000 0x1000>,
103+
<0xf8f02000 &L2 0xf8f02000 0x1000>,
104+
<0xf800c000 &ps7_ocmc_0 0xf800c000 0x1000>,
105+
<0xf8891000 &ps7_pmu_0 0xf8891000 0x1000>,
106+
<0xe000d000 &qspi 0xe000d000 0x1000>,
107+
<0xfc000000 &ps7_qspi_linear_0_memory 0xfc000000 0x2000000>,
108+
<0xf8f00000 &ps7_scuc_0 0xf8f00000 0xfd>,
109+
<0xf8f00600 &scutimer 0xf8f00600 0x20>,
110+
<0xf8f00620 &scuwdt 0xf8f00620 0xe0>,
111+
<0xe0100000 &sdhci0 0xe0100000 0x1000>,
112+
<0xf8000000 &slcr 0xf8000000 0x1000>,
113+
<0xe0006000 &spi0 0xe0006000 0x1000>,
114+
<0xe0007000 &spi1 0xe0007000 0x1000>,
115+
<0xe0001000 &uart1 0xe0001000 0x1000>,
116+
<0xe0002000 &usb0 0xe0002000 0x1000>,
117+
<0xf8007100 &adc 0xf8007100 0x21>;
118+
#ranges-address-cells = <0x1>;
119+
#ranges-size-cells = <0x1>;
120+
};
121+
};
122+
123+
&amba {
124+
/* --- Clock Generators --- */
125+
axi_hdmi_clkgen: axi-clkgen@79000000 {
126+
compatible = "adi,axi-clkgen-2.00.a";
127+
reg = <0x79000000 0x10000>;
128+
#clock-cells = <1>;
129+
clocks = <&clkc 15>, <&clkc 15>;
130+
clock-names = "clkin1", "s_axi_aclk";
131+
clock-output-names = "axi_hdmi_clkgen_0", "axi_hdmi_clkgen_1";
132+
};
133+
};
134+
135+
&misc_clk_0 {
136+
compatible = "fixed-clock";
137+
#clock-cells = <0>;
138+
clock-frequency = <245760000>;
139+
};
140+
&axi_ad9371_rx_clkgen {
141+
compatible = "adi,axi-clkgen-2.00.a";
142+
#clock-cells = <0>;
143+
clock-output-names = "axi_ad9371_rx_clkgen";
144+
clock-names = "clkin1", "s_axi_aclk";
145+
};
146+
&axi_ad9371_tx_clkgen {
147+
compatible = "adi,axi-clkgen-2.00.a";
148+
#clock-cells = <0>;
149+
clock-output-names = "axi_ad9371_tx_clkgen";
150+
clock-names = "clkin1", "s_axi_aclk";
151+
};
152+
&axi_ad9371_rx_xcvr {
153+
compatible = "adi,axi-adxcvr-1.0";
154+
clocks = <&axi_ad9371_rx_clkgen>, <&axi_ad9371_rx_clkgen>;
155+
clock-names = "conv", "div40";
156+
#clock-cells = <1>;
157+
clock-output-names = "rx_gt_clk", "rx_out_clk";
158+
jesd204-device;
159+
#jesd204-cells = <2>;
160+
};
161+
&axi_ad9371_tx_xcvr {
162+
compatible = "adi,axi-adxcvr-1.0";
163+
clocks = <&axi_ad9371_tx_clkgen>, <&axi_ad9371_tx_clkgen>;
164+
clock-names = "conv", "div40";
165+
#clock-cells = <1>;
166+
clock-output-names = "tx_gt_clk", "tx_out_clk";
167+
jesd204-device;
168+
#jesd204-cells = <2>;
169+
};
170+
&rx_ad9371_tpl_core_adc_tpl_core {
171+
compatible = "adi,axi-ad9371-rx-1.0";
172+
adi,axi-decimation-core-available;
173+
dmas = <&axi_ad9371_rx_dma 0>;
174+
dma-names = "rx";
175+
};
176+
&tx_ad9371_tpl_core_dac_tpl_core {
177+
compatible = "adi,axi-ad9371-tx-1.0";
178+
adi,axi-interpolation-core-available;
179+
dmas = <&axi_ad9371_tx_dma 0>;
180+
dma-names = "tx";
181+
clocks = <&clkc 15>;
182+
clock-names = "sampl_clk";
183+
};
184+
&spi0 {
185+
status = "okay";
186+
#address-cells = <1>;
187+
#size-cells = <0>;
188+
clk0_ad9528: ad9528-1@0 {
189+
compatible = "adi,ad9528";
190+
#address-cells = <1>;
191+
#size-cells = <0>;
192+
#clock-cells = <1>;
193+
adi,pll1-feedback-div = <4>;
194+
adi,pll1-charge-pump-current-nA = <5000>;
195+
adi,pll2-vco-div-m1 = <3>;
196+
adi,pll2-n2-div = <10>;
197+
adi,pll2-r1-div = <1>;
198+
adi,pll2-charge-pump-current-nA = <805000>;
199+
adi,refa-r-div = <1>;
200+
adi,sysref-src = <2>;
201+
adi,sysref-pattern-mode = <1>;
202+
adi,sysref-k-div = <512>;
203+
adi,sysref-nshot-mode = <3>;
204+
adi,sysref-request-trigger-mode = <0>;
205+
adi,status-mon-pin0-function-select = <1>;
206+
adi,status-mon-pin1-function-select = <7>;
207+
adi,refa-enable;
208+
adi,refa-diff-rcv-enable;
209+
adi,osc-in-cmos-neg-inp-enable;
210+
adi,sysref-request-enable;
211+
reg = <0>;
212+
spi-max-frequency = <10000000>;
213+
adi,vcxo-freq = <122880000>;
214+
clock-output-names = "ad9528-1_out0", "ad9528-1_out1", "ad9528-1_out2", "ad9528-1_out3", "ad9528-1_out4", "ad9528-1_out5", "ad9528-1_out6", "ad9528-1_out7", "ad9528-1_out8", "ad9528-1_out9", "ad9528-1_out10", "ad9528-1_out11", "ad9528-1_out12", "ad9528-1_out13";
215+
}; trx0_ad9371: ad9371-phy@1 {
216+
#clock-cells = <1>;
217+
clock-output-names = "rx_sampl_clk", "rx_os_sampl_clk", "tx_sampl_clk";
218+
#jesd204-cells = <2>;
219+
jesd204-top-device = <0>;
220+
jesd204-device;
221+
reg = <1>;
222+
clocks = <&clk0_ad9528 13>, <&clk0_ad9528 1>, <&clk0_ad9528 12>, <&clk0_ad9528 3>;
223+
clock-names = "dev_clk", "fmc_clk", "sysref_dev_clk", "sysref_fmc_clk";
224+
reset-gpios = <&gpio0 130 0>;
225+
sysref-req-gpios = <&gpio0 136 0>;
226+
jesd204-link-ids = <1 0>;
227+
jesd204-inputs = <&axi_ad9371_rx_xcvr 0 1>, <&axi_ad9371_tx_xcvr 0 0>;
228+
compatible = "adi,ad9371";
229+
spi-max-frequency = <25000000>;
230+
};
231+
};
232+
&axi_ad9371_rx_dma {
233+
/delete-property/ compatible;
234+
compatible = "adi,axi-dmac-1.00.a";
235+
#dma-cells = <1>;
236+
#clock-cells = <0>;
237+
};
238+
&axi_ad9371_tx_dma {
239+
/delete-property/ compatible;
240+
compatible = "adi,axi-dmac-1.00.a";
241+
#dma-cells = <1>;
242+
#clock-cells = <0>;
243+
};
244+
&axi_ad9371_rx_jesd_rx_axi {
245+
/delete-property/ compatible;
246+
/delete-property/ clocks;
247+
/delete-property/ clock-names;
248+
/delete-property/ #clock-cells;
249+
/delete-property/ adi,octets-per-frame;
250+
/delete-property/ adi,frames-per-multiframe;
251+
#clock-cells = <0>;
252+
#jesd204-cells = <2>;
253+
jesd204-device;
254+
clocks = <&clkc 15>, <&axi_ad9371_rx_clkgen>, <&axi_ad9371_rx_xcvr 0>;
255+
clock-names = "s_axi_aclk", "device_clk", "lane_clk";
256+
jesd204-inputs = <&axi_ad9371_rx_xcvr 0 1>;
257+
compatible = "adi,axi-jesd204-rx-1.0";
258+
adi,octets-per-frame = <4>;
259+
adi,frames-per-multiframe = <32>;
260+
};
261+
&axi_ad9371_tx_jesd_tx_axi {
262+
/delete-property/ compatible;
263+
/delete-property/ clocks;
264+
/delete-property/ clock-names;
265+
/delete-property/ #clock-cells;
266+
/delete-property/ adi,octets-per-frame;
267+
/delete-property/ adi,frames-per-multiframe;
268+
#clock-cells = <0>;
269+
#jesd204-cells = <2>;
270+
jesd204-device;
271+
clocks = <&clkc 15>, <&axi_ad9371_tx_clkgen>, <&axi_ad9371_tx_xcvr 0>;
272+
clock-names = "s_axi_aclk", "device_clk", "lane_clk";
273+
jesd204-inputs = <&axi_ad9371_tx_xcvr 0 0>;
274+
compatible = "adi,axi-jesd204-tx-1.0";
275+
adi,octets-per-frame = <2>;
276+
adi,frames-per-multiframe = <32>;
277+
adi,converter-resolution = <14>;
278+
adi,bits-per-sample = <16>;
279+
adi,converters-per-device = <4>;
280+
adi,control-bits-per-sample = <2>;
281+
};
282+
&rx_ad9371_tpl_core_adc_tpl_core {
283+
spibus-connected = <&trx0_ad9371>;
284+
};
285+
&tx_ad9371_tpl_core_dac_tpl_core {
286+
spibus-connected = <&trx0_ad9371>;
287+
clocks = <&trx0_ad9371 2>;
288+
clock-names = "sampl_clk";
289+
};

0 commit comments

Comments
 (0)