From: Petr Oros <poros@redhat.com>
To: netdev@vger.kernel.org
Cc: Petr Oros <poros@redhat.com>, Ivan Vecera <ivecera@redhat.com>,
Jiri Pirko <jiri@nvidia.com>, Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Shuah Khan <shuah@kernel.org>,
Randy Dunlap <rdunlap@infradead.org>,
Jani Nikula <jani.nikula@intel.com>,
Vadim Fedorenko <vadim.fedorenko@linux.dev>,
Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>,
Jiri Pirko <jiri@resnulli.us>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [PATCH net-next v4 12/14] selftests: dpll: add pin phase adjust test
Date: Thu, 12 Nov 2026 14:03:57 +0100 [thread overview]
Message-ID: <20261112130359.840795-13-poros@redhat.com> (raw)
In-Reply-To: <20261112130359.840795-1-poros@redhat.com>
Add a test that reads the phase adjustment range and granularity a
pin advertises, picks the largest multiple of the granularity inside
the range, or the smallest one when that is already the current value,
sets it, reads it back and restores the original value. It skips when
the dpll tool lacks the phase-adjust keyword of pin set and when the
range is too narrow to pick a different value. A pin that reports no
phase adjustment or no range is a skip on a device provided by the user
and a failure on the device the script created, whose pins report
both.
The core refuses a value outside the advertised range and one that is
not a multiple of the granularity a driver reports, the current value
included, so a pin that sits at such a value could not be put back. The
test bails out on either before it schedules the restore, which is
deferred right after so that an interrupted run restores the value too.
The granularity is only reported by drivers that have the core enforce
one. Without it the target is computed with a granularity of 1, and a
driver may refuse it for a granularity of its own or for any other
constraint the interface does not advertise. A refused set is therefore
a skip on a device provided by the user, with the reason the tool
reported, and a failure on the device the script created, whose
simulator accepts every value its range and granularity allow. The
test ends there, a value that was not set has nothing to read back.
Reviewed-by: Ivan Vecera <ivecera@redhat.com>
Acked-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Petr Oros <poros@redhat.com>
---
v4:
- bail out when the current value lies outside the advertised range,
it could not be restored
- tell a failed query from a pin without a phase adjust or a range and
log a deferred restore that fails
v3:
- follow the move of the selftests to
tools/testing/selftests/drivers/dpll
v3: https://lore.kernel.org/all/20261109093523.931201-13-poros@redhat.com/
v2: https://lore.kernel.org/all/20261105151852.1844305-13-poros@redhat.com/
v1: https://lore.kernel.org/all/20261103093910.596225-13-poros@redhat.com/
---
.../selftests/drivers/dpll/dpll_features.sh | 102 ++++++++++++++++++
.../selftests/drivers/dpll/dpll_lib.sh | 15 +++
2 files changed, 117 insertions(+)
diff --git a/tools/testing/selftests/drivers/dpll/dpll_features.sh b/tools/testing/selftests/drivers/dpll/dpll_features.sh
index ebb52c85262016..7b7e077073db58 100755
--- a/tools/testing/selftests/drivers/dpll/dpll_features.sh
+++ b/tools/testing/selftests/drivers/dpll/dpll_features.sh
@@ -29,6 +29,7 @@ ALL_TESTS="
test_pin_state_transitions
test_pin_priority_get_set
test_pin_frequency_set_get
+ test_pin_phase_adjust_set_get
"
##############################################################################
@@ -298,6 +299,107 @@ test_pin_state_transitions()
log_test "DPLL pin state transitions"
}
+test_pin_phase_adjust_set_get()
+{
+ local before target after json min max gran reason
+
+ RET=0
+
+ if [ -z "$PIN_TUNE_ID" ]; then
+ dpll_log_test_skip_or_fail "DPLL pin phase-adjust set/get" \
+ "no spare input pin"
+ return
+ fi
+ if ! dpll_pin_set_supports phase-adjust; then
+ log_test_skip "DPLL pin phase-adjust set/get" \
+ "dpll tool lacks pin set phase-adjust"
+ return
+ fi
+
+ # A query that failed is not a pin without a phase adjust.
+ if ! before=$(dpll_pin_get_phase_adjust "$PIN_TUNE_ID") ||
+ ! json=$(dpll_pin_json "$PIN_TUNE_ID"); then
+ check_err 1 "pin $PIN_TUNE_ID query failed"
+ log_test "DPLL pin phase-adjust set/get"
+ return
+ fi
+ if [ -z "$before" ]; then
+ dpll_log_test_skip_or_fail "DPLL pin phase-adjust set/get" \
+ "phase adjust not reported"
+ return
+ fi
+ if ! [[ "$before" =~ ^-?[0-9]+$ ]]; then
+ check_err 1 "phase adjust '$before' is not a number"
+ log_test "DPLL pin phase-adjust set/get"
+ return
+ fi
+
+ # Pick a target inside the advertised range different from the
+ # current value, a multiple of the granularity, which is taken as 1
+ # when the driver reports none.
+ min=$(jq -r '.["phase-adjust-min"] // empty' <<< "$json")
+ max=$(jq -r '.["phase-adjust-max"] // empty' <<< "$json")
+ gran=$(jq -r '.["phase-adjust-gran"] // empty' <<< "$json")
+ if [ -z "$min" ] || [ -z "$max" ]; then
+ dpll_log_test_skip_or_fail "DPLL pin phase-adjust set/get" \
+ "no adjust range"
+ return
+ fi
+ # The core refuses a value outside the range or off the
+ # granularity, the current one included. A pin that sits at such a
+ # value could not be put back, so bail out before the restore is
+ # scheduled.
+ if [ "$before" -lt "$min" ] || [ "$before" -gt "$max" ]; then
+ dpll_log_test_skip_or_fail "DPLL pin phase-adjust set/get" \
+ "current phase adjust outside the adjust range"
+ return
+ fi
+ if [ -n "$gran" ] && [ $((before % gran)) -ne 0 ]; then
+ dpll_log_test_skip_or_fail "DPLL pin phase-adjust set/get" \
+ "current phase adjust not a granularity multiple"
+ return
+ fi
+ [ -n "$gran" ] || gran=1
+ defer dpll_restore dpll_pin_set_phase_adjust "$PIN_TUNE_ID" "$before"
+
+ # Shell division truncates towards zero, so round the bounds towards
+ # the inside of the range explicitly, which matters for negative ones.
+ target=$((max / gran * gran))
+ [ "$target" -gt "$max" ] && target=$((target - gran))
+ if [ "$target" = "$before" ]; then
+ target=$((min / gran * gran))
+ [ "$target" -lt "$min" ] && target=$((target + gran))
+ fi
+ if [ "$target" = "$before" ] || [ "$target" -gt "$max" ] ||
+ [ "$target" -lt "$min" ]; then
+ log_test_skip "DPLL pin phase-adjust set/get" "range too narrow"
+ return
+ fi
+
+ # A driver may enforce a granularity it does not report or another
+ # constraint, a skip on a device the user provided, the simulator
+ # accepts every value its range and granularity allow.
+ if ! dpll_pin_set_phase_adjust "$PIN_TUNE_ID" "$target"; then
+ reason=${DPLL_LAST_ERR%%$'\n'*}
+ dpll_log_test_skip_or_fail "DPLL pin phase-adjust set/get" \
+ "cannot set phase-adjust=$target${reason:+, $reason}"
+ return
+ fi
+ after=$(dpll_pin_get_phase_adjust "$PIN_TUNE_ID")
+ if [ "$after" != "$target" ]; then
+ check_err 1 "phase-adjust expected $target, got '$after'"
+ fi
+
+ dpll_pin_set_phase_adjust "$PIN_TUNE_ID" "$before"
+ check_err $? "cannot restore phase-adjust"
+ after=$(dpll_pin_get_phase_adjust "$PIN_TUNE_ID")
+ if [ "$after" != "$before" ]; then
+ check_err 1 "phase-adjust not restored, got '$after'"
+ fi
+
+ log_test "DPLL pin phase-adjust set/get"
+}
+
test_pin_frequency_set_get()
{
local before target after reason json
diff --git a/tools/testing/selftests/drivers/dpll/dpll_lib.sh b/tools/testing/selftests/drivers/dpll/dpll_lib.sh
index fa1895ab17f518..6b99dae5a4f379 100644
--- a/tools/testing/selftests/drivers/dpll/dpll_lib.sh
+++ b/tools/testing/selftests/drivers/dpll/dpll_lib.sh
@@ -442,6 +442,11 @@ dpll_pin_get_prio()
__dpll_pin_dev_field "$1" "$2" '.prio'
}
+dpll_pin_get_phase_adjust()
+{
+ __dpll_pin_field "$1" '.["phase-adjust"]'
+}
+
##############################################################################
# Pin setters
#
@@ -496,6 +501,16 @@ dpll_pin_set_frequency()
2>&1 >/dev/null)
}
+# $2: phase adjust in ps
+dpll_pin_set_phase_adjust()
+{
+ local pin_id=$1
+ local phase_adjust=$2
+
+ DPLL_LAST_ERR=$(dpll pin set id "$pin_id" phase-adjust \
+ "$phase_adjust" 2>&1 >/dev/null)
+}
+
##############################################################################
# dpllsim configfs interface
#
--
2.56.0
next prev parent reply other threads:[~2026-11-12 13:05 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 13:03 [PATCH net-next v4 00/14] dpll: add a simulated DPLL device driver Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 01/14] dpll: dpllsim: Add " Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 02/14] selftests: dpll: add test library and device lifecycle tests Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 03/14] dpll: dpllsim: Add configurable pins Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 04/14] selftests: dpll: add pin enumeration and property tests Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 05/14] dpll: dpllsim: Add support to set input pin state Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 06/14] selftests: dpll: add pin state tests Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 07/14] dpll: dpllsim: Add support to get/set priority on input pins Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 08/14] selftests: dpll: add pin priority test Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 09/14] dpll: dpllsim: Add support to set frequency on pins Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 10/14] selftests: dpll: add pin frequency test Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 11/14] dpll: dpllsim: Add support to adjust phase Petr Oros
2026-11-12 13:03 ` Petr Oros [this message]
2026-11-12 13:03 ` [PATCH net-next v4 13/14] selftests: dpll: add concurrency stress tests Petr Oros
2026-11-12 13:03 ` [PATCH net-next v4 14/14] selftests: dpll: add reference leak tests Petr Oros
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261112130359.840795-13-poros@redhat.com \
--to=poros@redhat.com \
--cc=andrew+netdev@lunn.ch \
--cc=arkadiusz.kubalewski@intel.com \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=ivecera@redhat.com \
--cc=jani.nikula@intel.com \
--cc=jiri@nvidia.com \
--cc=jiri@resnulli.us \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rdunlap@infradead.org \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=vadim.fedorenko@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox