From nobody Wed Oct 1 22:37:05 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DBAF2D47E8 for ; Sat, 27 Sep 2025 08:49:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758962976; cv=none; b=kA5TdI1VK0Y+9AkDTpZcbauJEf/AyeHTzH7FmR2qWbFvAcOKCc9eCMjgIN8q/g2b79szYvOyVY1IsQUHkpx0Z1od30dapzQAS4nvgxSDNkC+Uqyk8JhuidM8vyRmbOdpiSldFnKXW4nw1OqmdYKKB0lwZQKWLZ2DJyoYjm3qi6c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758962976; c=relaxed/simple; bh=PrNdObNwK8MyVUSlXClOFNlkhDifhAVkWnm+Rf0inck=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s/4hWyvpVp/Xn6CiscY60DovtAGej9JhQ+bkdtU6UvSRNqGVCep5/OBOb5OIvwSf/jjbW2e72xRCwAvq++jP+KCiYij3idepB4fSPEwNEAjItvNLavZmr5+jnz/0DJx7wxXeOPqYUiCwPvTR4UdO81g7KYCC06VcjtYvnx20t0g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=EXB7B932; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="EXB7B932" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758962972; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/lFxR1925+K2SMQxPr1ghXoGOdc0XoB4pfQ2tyX/Lkg=; b=EXB7B932fJ7tQBzgjVhNnUGIoyGXb9+eLddPfApZv6A9gR9TpeUnoD40orQA1rH4wefesG 16WBXrIKVzZMyewe+1CIqnuAyCyqYwFHlZBaa6ruQENhzUFf/CNRXEukw+ipapctYdjRVb ByM6QoeBCpBtgbgtELzn3OZdOWS6bNE= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-632-GUGZ5QBaMEymXpL8dDUnQQ-1; Sat, 27 Sep 2025 04:49:28 -0400 X-MC-Unique: GUGZ5QBaMEymXpL8dDUnQQ-1 X-Mimecast-MFC-AGG-ID: GUGZ5QBaMEymXpL8dDUnQQ_1758962967 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3E4431800378; Sat, 27 Sep 2025 08:49:26 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.45.225.247]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B6CFE19560A2; Sat, 27 Sep 2025 08:49:20 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Vadim Fedorenko , Arkadiusz Kubalewski , Jiri Pirko , Jonathan Corbet , Donald Hunter , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Prathosh Satish , Chuck Lever , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Michal Schmidt , Petr Oros Subject: [PATCH net-next v2 1/3] dpll: add phase-offset-avg-factor device attribute to netlink spec Date: Sat, 27 Sep 2025 10:49:10 +0200 Message-ID: <20250927084912.2343597-2-ivecera@redhat.com> In-Reply-To: <20250927084912.2343597-1-ivecera@redhat.com> References: <20250927084912.2343597-1-ivecera@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Add dpll device level attribute DPLL_A_PHASE_OFFSET_AVG_FACTOR to allow control over a calculation of reported phase offset value. Attribute is present, if the driver provides such capability, otherwise attribute shall not be present. Signed-off-by: Ivan Vecera Reviewed-by: Vadim Fedorenko --- Documentation/driver-api/dpll.rst | 18 +++++++++++++++++- Documentation/netlink/specs/dpll.yaml | 6 ++++++ drivers/dpll/dpll_nl.c | 5 +++-- include/uapi/linux/dpll.h | 1 + 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/d= pll.rst index eca72d9b9ed87..be1fc643b645e 100644 --- a/Documentation/driver-api/dpll.rst +++ b/Documentation/driver-api/dpll.rst @@ -179,7 +179,23 @@ Phase offset measurement and adjustment Device may provide ability to measure a phase difference between signals on a pin and its parent dpll device. If pin-dpll phase offset measurement is supported, it shall be provided with ``DPLL_A_PIN_PHASE_OFFSET`` -attribute for each parent dpll device. +attribute for each parent dpll device. The reported phase offset may be +computed as the average of prior values and the current measurement, using +the following formula: + +.. math:: + curr\_avg =3D prev\_avg * \frac{2^N-1}{2^N} + new\_val * \frac{1}{2^N} + +where `curr_avg` is the current reported phase offset, `prev_avg` is the +previously reported value, `new_val` is the current measurement, and `N` is +the averaging factor. Configured averaging factor value is provided with +``DPLL_A_PHASE_OFFSET_AVG_FACTOR`` attribute of a device and value change = can +be requested with the same attribute with ``DPLL_CMD_DEVICE_SET`` command. + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + ``DPLL_A_PHASE_OFFSET_AVG_FACTOR`` attr configured value of phase offset + averaging factor + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 Device may also provide ability to adjust a signal phase on a pin. If pin phase adjustment is supported, minimal and maximal values that pin diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/= specs/dpll.yaml index 5decee61a2c4c..cafb4ec20447e 100644 --- a/Documentation/netlink/specs/dpll.yaml +++ b/Documentation/netlink/specs/dpll.yaml @@ -315,6 +315,10 @@ attribute-sets: If enabled, dpll device shall monitor and notify all currently available inputs for changes of their phase offset against the dpll device. + - + name: phase-offset-avg-factor + type: u32 + doc: Averaging factor applied to calculation of reported phase off= set. - name: pin enum-name: dpll_a_pin @@ -523,6 +527,7 @@ operations: - clock-id - type - phase-offset-monitor + - phase-offset-avg-factor =20 dump: reply: *dev-attrs @@ -540,6 +545,7 @@ operations: attributes: - id - phase-offset-monitor + - phase-offset-avg-factor - name: device-create-ntf doc: Notification about device appearing diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c index 9f2efaf252688..3c6d570babf89 100644 --- a/drivers/dpll/dpll_nl.c +++ b/drivers/dpll/dpll_nl.c @@ -42,9 +42,10 @@ static const struct nla_policy dpll_device_get_nl_policy= [DPLL_A_ID + 1] =3D { }; =20 /* DPLL_CMD_DEVICE_SET - do */ -static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_PHASE_OFFS= ET_MONITOR + 1] =3D { +static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_PHASE_OFFS= ET_AVG_FACTOR + 1] =3D { [DPLL_A_ID] =3D { .type =3D NLA_U32, }, [DPLL_A_PHASE_OFFSET_MONITOR] =3D NLA_POLICY_MAX(NLA_U32, 1), + [DPLL_A_PHASE_OFFSET_AVG_FACTOR] =3D { .type =3D NLA_U32, }, }; =20 /* DPLL_CMD_PIN_ID_GET - do */ @@ -112,7 +113,7 @@ static const struct genl_split_ops dpll_nl_ops[] =3D { .doit =3D dpll_nl_device_set_doit, .post_doit =3D dpll_post_doit, .policy =3D dpll_device_set_nl_policy, - .maxattr =3D DPLL_A_PHASE_OFFSET_MONITOR, + .maxattr =3D DPLL_A_PHASE_OFFSET_AVG_FACTOR, .flags =3D GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h index 37b438ce8efc4..ab1725a954d74 100644 --- a/include/uapi/linux/dpll.h +++ b/include/uapi/linux/dpll.h @@ -216,6 +216,7 @@ enum dpll_a { DPLL_A_LOCK_STATUS_ERROR, DPLL_A_CLOCK_QUALITY_LEVEL, DPLL_A_PHASE_OFFSET_MONITOR, + DPLL_A_PHASE_OFFSET_AVG_FACTOR, =20 __DPLL_A_MAX, DPLL_A_MAX =3D (__DPLL_A_MAX - 1) --=20 2.49.1 From nobody Wed Oct 1 22:37:05 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 433492D59E8 for ; Sat, 27 Sep 2025 08:49:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758962980; cv=none; b=uwHC8Fi11/jSngZTFS5EPzTJXxs3sFmhhd110rFSf47F/Lephmz0NyIc8RDd6FiIIoTgyb9U5rZNbsob/S+QIdXgKj7FKRg6ixvG0NggrqvHhZHngHOo/T6r1Gs/OtCOcyURrawKhZP0SHny8iLdED64aPjU1Ih49WSFCkA+PVI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758962980; c=relaxed/simple; bh=cRUDVTzhvUt3cZRMJciHl/Pqt0TO8UCUstDUWC56C6c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GuZmi9RM1Mv64uHdK53TcqppXMm48GulL5wlNCElMKLjc0EPbUcJyGbNxyHayST/nfXS9j8N3Xw2NZ6NG+sjlSoqs3AUD2qDLXIIl4e/m7q/4vx7aBwGNhbWWTDTLJsmZd2zZ71C6WSGz4QLKf6CRd747/pA38s02t3i74JXibc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ZC7aEbgz; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ZC7aEbgz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758962978; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zxl0TxLf25xUAMm4j2lJ8TNVEvxXadGeeqzjsC9P7KU=; b=ZC7aEbgzAfB7jGFF5HijcEZpKjVndM93uBmu4t6SYQAOCl5M9bAxGnWmhZnOjemYF6EoDl hIPnkyom6nNisPWV4A8NczlOI3690+5R9KUz4/BmcrnxOrJxXY6UUdtZs4yZYCLfvfMu7c zEoK7x2UQl7Bl5MRZKsgGAJGSTABKfY= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-543-v_1g_-S9NnK1glnByDxCzg-1; Sat, 27 Sep 2025 04:49:34 -0400 X-MC-Unique: v_1g_-S9NnK1glnByDxCzg-1 X-Mimecast-MFC-AGG-ID: v_1g_-S9NnK1glnByDxCzg_1758962972 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 14C34180034C; Sat, 27 Sep 2025 08:49:32 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.45.225.247]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 96E7F19560AB; Sat, 27 Sep 2025 08:49:26 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Vadim Fedorenko , Arkadiusz Kubalewski , Jiri Pirko , Jonathan Corbet , Donald Hunter , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Prathosh Satish , Chuck Lever , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Michal Schmidt , Petr Oros Subject: [PATCH net-next v2 2/3] dpll: add phase_offset_avg_factor_get/set callback ops Date: Sat, 27 Sep 2025 10:49:11 +0200 Message-ID: <20250927084912.2343597-3-ivecera@redhat.com> In-Reply-To: <20250927084912.2343597-1-ivecera@redhat.com> References: <20250927084912.2343597-1-ivecera@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Add new callback operations for a dpll device: - phase_offset_avg_factor_get(...) - to obtain current phase offset averaging factor from dpll device, - phase_offset_avg_factor_set(...) - to set phase offset averaging factor Obtain the factor value using the get callback and provide it to the user if the device driver implement this callback. Execute the set callback upon user requests, if the driver implement it. Signed-off-by: Ivan Vecera v2: * do not require 'set' callback to retrieve current value * always call 'set' callback regardless of current value Reviewed-by: Vadim Fedorenko --- drivers/dpll/dpll_netlink.c | 66 +++++++++++++++++++++++++++++++++---- include/linux/dpll.h | 6 ++++ 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 0a852011653c4..74c1f0ca95f24 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -164,6 +164,27 @@ dpll_msg_add_phase_offset_monitor(struct sk_buff *msg,= struct dpll_device *dpll, return 0; } =20 +static int +dpll_msg_add_phase_offset_avg_factor(struct sk_buff *msg, + struct dpll_device *dpll, + struct netlink_ext_ack *extack) +{ + const struct dpll_device_ops *ops =3D dpll_device_ops(dpll); + u32 factor; + int ret; + + if (ops->phase_offset_avg_factor_get) { + ret =3D ops->phase_offset_avg_factor_get(dpll, dpll_priv(dpll), + &factor, extack); + if (ret) + return ret; + if (nla_put_u32(msg, DPLL_A_PHASE_OFFSET_AVG_FACTOR, factor)) + return -EMSGSIZE; + } + + return 0; +} + static int dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll, struct netlink_ext_ack *extack) @@ -675,6 +696,9 @@ dpll_device_get_one(struct dpll_device *dpll, struct sk= _buff *msg, if (nla_put_u32(msg, DPLL_A_TYPE, dpll->type)) return -EMSGSIZE; ret =3D dpll_msg_add_phase_offset_monitor(msg, dpll, extack); + if (ret) + return ret; + ret =3D dpll_msg_add_phase_offset_avg_factor(msg, dpll, extack); if (ret) return ret; =20 @@ -839,6 +863,23 @@ dpll_phase_offset_monitor_set(struct dpll_device *dpll= , struct nlattr *a, extack); } =20 +static int +dpll_phase_offset_avg_factor_set(struct dpll_device *dpll, struct nlattr *= a, + struct netlink_ext_ack *extack) +{ + const struct dpll_device_ops *ops =3D dpll_device_ops(dpll); + u32 factor =3D nla_get_u32(a); + + if (!ops->phase_offset_avg_factor_set) { + NL_SET_ERR_MSG_ATTR(extack, a, + "device not capable of changing phase offset average factor"); + return -EOPNOTSUPP; + } + + return ops->phase_offset_avg_factor_set(dpll, dpll_priv(dpll), factor, + extack); +} + static int dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a, struct netlink_ext_ack *extack) @@ -1736,14 +1777,25 @@ int dpll_nl_device_get_doit(struct sk_buff *skb, st= ruct genl_info *info) static int dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info) { - int ret; - - if (info->attrs[DPLL_A_PHASE_OFFSET_MONITOR]) { - struct nlattr *a =3D info->attrs[DPLL_A_PHASE_OFFSET_MONITOR]; + struct nlattr *a; + int rem, ret; =20 - ret =3D dpll_phase_offset_monitor_set(dpll, a, info->extack); - if (ret) - return ret; + nla_for_each_attr(a, genlmsg_data(info->genlhdr), + genlmsg_len(info->genlhdr), rem) { + switch (nla_type(a)) { + case DPLL_A_PHASE_OFFSET_MONITOR: + ret =3D dpll_phase_offset_monitor_set(dpll, a, + info->extack); + if (ret) + return ret; + break; + case DPLL_A_PHASE_OFFSET_AVG_FACTOR: + ret =3D dpll_phase_offset_avg_factor_set(dpll, a, + info->extack); + if (ret) + return ret; + break; + } } =20 return 0; diff --git a/include/linux/dpll.h b/include/linux/dpll.h index fa1e76920d0ee..25be745bf41f1 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -38,6 +38,12 @@ struct dpll_device_ops { void *dpll_priv, enum dpll_feature_state *state, struct netlink_ext_ack *extack); + int (*phase_offset_avg_factor_set)(const struct dpll_device *dpll, + void *dpll_priv, u32 factor, + struct netlink_ext_ack *extack); + int (*phase_offset_avg_factor_get)(const struct dpll_device *dpll, + void *dpll_priv, u32 *factor, + struct netlink_ext_ack *extack); }; =20 struct dpll_pin_ops { --=20 2.49.1 From nobody Wed Oct 1 22:37:05 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A4222D77E0 for ; Sat, 27 Sep 2025 08:49:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758962986; cv=none; b=EgnBnQeue/Yv9xEqNcUYRAFTSjTTFuofqzycnsV9pratJylG2MIC2bAPWXeCBLExO2ZYxjGwmltO9e4VQiqLrnMXjFSgbWdWXrELKsxZXpySkSRmYojR2xaptWZtY+WB+KWapPYMRU3A6gRJ62MwUmeiYRR7h4pX28TXcB5mTag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758962986; c=relaxed/simple; bh=/IgQnJCnGX6fG3NdzsNmxjlgcsRzIXp0vXJ8NzAyuSs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=r7yK80MCTNZkJVVfeUaei2CJSZ1IEmw5xC1MDfbJ01xO2P6+ueJIqMjkUGHYv7DynqXtqPke0YFdvDe64nn7VgliUd5PVAV2DRxY6FDt3XmsBHbw/fsQ/MlviL3jBHKPToEESQWg84L5IBGePGuJI2iU7a4ow8oFSeZQm6SVHI4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=EBBj4no1; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="EBBj4no1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758962983; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=r8T4PaaPN7zfedDHydP2IIt2YeJgWHExSLyVVowMgVM=; b=EBBj4no1vAVc8yXHmAAxU2allb50AVTBBkVqmqpRXpEpcO+7XHmAXApOGGTg014E4WC+tO Q93GrAbaFcnXTS9H2M5CIWZDWjhGL7iolC9d3sD60kPi9Pe+3SMb9+oO1P5yH3FPs8R6i3 IlNbYAjNzWy2bGQ5dBElmzLXzSdrenI= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-586-RbjiFlwVNxiemWPmJgzSQA-1; Sat, 27 Sep 2025 04:49:40 -0400 X-MC-Unique: RbjiFlwVNxiemWPmJgzSQA-1 X-Mimecast-MFC-AGG-ID: RbjiFlwVNxiemWPmJgzSQA_1758962978 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C949719560BB; Sat, 27 Sep 2025 08:49:37 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.45.225.247]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 871F019560A2; Sat, 27 Sep 2025 08:49:32 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Vadim Fedorenko , Arkadiusz Kubalewski , Jiri Pirko , Jonathan Corbet , Donald Hunter , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Prathosh Satish , Chuck Lever , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Michal Schmidt , Petr Oros Subject: [PATCH net-next v2 3/3] dpll: zl3073x: Allow to configure phase offset averaging factor Date: Sat, 27 Sep 2025 10:49:12 +0200 Message-ID: <20250927084912.2343597-4-ivecera@redhat.com> In-Reply-To: <20250927084912.2343597-1-ivecera@redhat.com> References: <20250927084912.2343597-1-ivecera@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 The DPLL phase measurement block uses an exponential moving average with a configurable averaging factor. Measurements are taken at approximately 40=E2=80=AFHz or at the reference frequency, whichever is lower. Currently, factor=3D2 is used to prioritize fast response for dynamic phase changes. For applications needing a stable, precise average phase offset where rapid changes are unlikely, a higher factor is recommended. Implement the .phase_offset_avg_factor_get/set callbacks to allow a user to adjust this factor. Signed-off-by: Ivan Vecera Reviewed-by: Vadim Fedorenko --- v2: * INIT_WORK moved to zl3073x_dpll_alloc() --- drivers/dpll/zl3073x/core.c | 38 +++++++++++++++++++++--- drivers/dpll/zl3073x/core.h | 15 ++++++++-- drivers/dpll/zl3073x/dpll.c | 58 +++++++++++++++++++++++++++++++++++++ drivers/dpll/zl3073x/dpll.h | 2 ++ 4 files changed, 107 insertions(+), 6 deletions(-) diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c index e96095baac657..092e7027948a4 100644 --- a/drivers/dpll/zl3073x/core.c +++ b/drivers/dpll/zl3073x/core.c @@ -956,6 +956,32 @@ zl3073x_dev_periodic_work(struct kthread_work *work) msecs_to_jiffies(500)); } =20 +int zl3073x_dev_phase_avg_factor_set(struct zl3073x_dev *zldev, u8 factor) +{ + u8 dpll_meas_ctrl, value; + int rc; + + /* Read DPLL phase measurement control register */ + rc =3D zl3073x_read_u8(zldev, ZL_REG_DPLL_MEAS_CTRL, &dpll_meas_ctrl); + if (rc) + return rc; + + /* Convert requested factor to register value */ + value =3D (factor + 1) & 0x0f; + + /* Update phase measurement control register */ + dpll_meas_ctrl &=3D ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR; + dpll_meas_ctrl |=3D FIELD_PREP(ZL_DPLL_MEAS_CTRL_AVG_FACTOR, value); + rc =3D zl3073x_write_u8(zldev, ZL_REG_DPLL_MEAS_CTRL, dpll_meas_ctrl); + if (rc) + return rc; + + /* Save the new factor */ + zldev->phase_avg_factor =3D factor; + + return 0; +} + /** * zl3073x_dev_phase_meas_setup - setup phase offset measurement * @zldev: pointer to zl3073x_dev structure @@ -972,15 +998,16 @@ zl3073x_dev_phase_meas_setup(struct zl3073x_dev *zlde= v) u8 dpll_meas_ctrl, mask =3D 0; int rc; =20 + /* Setup phase measurement averaging factor */ + rc =3D zl3073x_dev_phase_avg_factor_set(zldev, zldev->phase_avg_factor); + if (rc) + return rc; + /* Read DPLL phase measurement control register */ rc =3D zl3073x_read_u8(zldev, ZL_REG_DPLL_MEAS_CTRL, &dpll_meas_ctrl); if (rc) return rc; =20 - /* Setup phase measurement averaging factor */ - dpll_meas_ctrl &=3D ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR; - dpll_meas_ctrl |=3D FIELD_PREP(ZL_DPLL_MEAS_CTRL_AVG_FACTOR, 3); - /* Enable DPLL measurement block */ dpll_meas_ctrl |=3D ZL_DPLL_MEAS_CTRL_EN; =20 @@ -1208,6 +1235,9 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev, */ zldev->clock_id =3D get_random_u64(); =20 + /* Default phase offset averaging factor */ + zldev->phase_avg_factor =3D 2; + /* Initialize mutex for operations where multiple reads, writes * and/or polls are required to be done atomically. */ diff --git a/drivers/dpll/zl3073x/core.h b/drivers/dpll/zl3073x/core.h index 128fb899cafc3..1dca4ddcf2350 100644 --- a/drivers/dpll/zl3073x/core.h +++ b/drivers/dpll/zl3073x/core.h @@ -68,19 +68,19 @@ struct zl3073x_synth { * @dev: pointer to device * @regmap: regmap to access device registers * @multiop_lock: to serialize multiple register operations - * @clock_id: clock id of the device * @ref: array of input references' invariants * @out: array of outs' invariants * @synth: array of synths' invariants * @dplls: list of DPLLs * @kworker: thread for periodic work * @work: periodic work + * @clock_id: clock id of the device + * @phase_avg_factor: phase offset measurement averaging factor */ struct zl3073x_dev { struct device *dev; struct regmap *regmap; struct mutex multiop_lock; - u64 clock_id; =20 /* Invariants */ struct zl3073x_ref ref[ZL3073X_NUM_REFS]; @@ -93,6 +93,10 @@ struct zl3073x_dev { /* Monitor */ struct kthread_worker *kworker; struct kthread_delayed_work work; + + /* Devlink parameters */ + u64 clock_id; + u8 phase_avg_factor; }; =20 struct zl3073x_chip_info { @@ -115,6 +119,13 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev, int zl3073x_dev_start(struct zl3073x_dev *zldev, bool full); void zl3073x_dev_stop(struct zl3073x_dev *zldev); =20 +static inline u8 zl3073x_dev_phase_avg_factor_get(struct zl3073x_dev *zlde= v) +{ + return zldev->phase_avg_factor; +} + +int zl3073x_dev_phase_avg_factor_set(struct zl3073x_dev *zldev, u8 factor); + /********************** * Registers operations **********************/ diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c index 3e42e9e7fd272..93dc93eec79ed 100644 --- a/drivers/dpll/zl3073x/dpll.c +++ b/drivers/dpll/zl3073x/dpll.c @@ -1576,6 +1576,59 @@ zl3073x_dpll_mode_get(const struct dpll_device *dpll= , void *dpll_priv, return 0; } =20 +static int +zl3073x_dpll_phase_offset_avg_factor_get(const struct dpll_device *dpll, + void *dpll_priv, u32 *factor, + struct netlink_ext_ack *extack) +{ + struct zl3073x_dpll *zldpll =3D dpll_priv; + + *factor =3D zl3073x_dev_phase_avg_factor_get(zldpll->dev); + + return 0; +} + +static void +zl3073x_dpll_change_work(struct work_struct *work) +{ + struct zl3073x_dpll *zldpll; + + zldpll =3D container_of(work, struct zl3073x_dpll, change_work); + dpll_device_change_ntf(zldpll->dpll_dev); +} + +static int +zl3073x_dpll_phase_offset_avg_factor_set(const struct dpll_device *dpll, + void *dpll_priv, u32 factor, + struct netlink_ext_ack *extack) +{ + struct zl3073x_dpll *item, *zldpll =3D dpll_priv; + int rc; + + if (factor > 15) { + NL_SET_ERR_MSG_FMT(extack, + "Phase offset average factor has to be from range <0,15>"); + return -EINVAL; + } + + rc =3D zl3073x_dev_phase_avg_factor_set(zldpll->dev, factor); + if (rc) { + NL_SET_ERR_MSG_FMT(extack, + "Failed to set phase offset averaging factor"); + return rc; + } + + /* The averaging factor is common for all DPLL channels so after change + * we have to send a notification for other DPLL devices. + */ + list_for_each_entry(item, &zldpll->dev->dplls, list) { + if (item !=3D zldpll) + schedule_work(&item->change_work); + } + + return 0; +} + static int zl3073x_dpll_phase_offset_monitor_get(const struct dpll_device *dpll, void *dpll_priv, @@ -1635,6 +1688,8 @@ static const struct dpll_pin_ops zl3073x_dpll_output_= pin_ops =3D { static const struct dpll_device_ops zl3073x_dpll_device_ops =3D { .lock_status_get =3D zl3073x_dpll_lock_status_get, .mode_get =3D zl3073x_dpll_mode_get, + .phase_offset_avg_factor_get =3D zl3073x_dpll_phase_offset_avg_factor_get, + .phase_offset_avg_factor_set =3D zl3073x_dpll_phase_offset_avg_factor_set, .phase_offset_monitor_get =3D zl3073x_dpll_phase_offset_monitor_get, .phase_offset_monitor_set =3D zl3073x_dpll_phase_offset_monitor_set, }; @@ -1983,6 +2038,8 @@ zl3073x_dpll_device_unregister(struct zl3073x_dpll *z= ldpll) { WARN(!zldpll->dpll_dev, "DPLL device is not registered\n"); =20 + cancel_work_sync(&zldpll->change_work); + dpll_device_unregister(zldpll->dpll_dev, &zl3073x_dpll_device_ops, zldpll); dpll_device_put(zldpll->dpll_dev); @@ -2258,6 +2315,7 @@ zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch) zldpll->dev =3D zldev; zldpll->id =3D ch; INIT_LIST_HEAD(&zldpll->pins); + INIT_WORK(&zldpll->change_work, zl3073x_dpll_change_work); =20 return zldpll; } diff --git a/drivers/dpll/zl3073x/dpll.h b/drivers/dpll/zl3073x/dpll.h index 304910ffc9c07..e8c39b44b356c 100644 --- a/drivers/dpll/zl3073x/dpll.h +++ b/drivers/dpll/zl3073x/dpll.h @@ -20,6 +20,7 @@ * @dpll_dev: pointer to registered DPLL device * @lock_status: last saved DPLL lock status * @pins: list of pins + * @change_work: device change notification work */ struct zl3073x_dpll { struct list_head list; @@ -32,6 +33,7 @@ struct zl3073x_dpll { struct dpll_device *dpll_dev; enum dpll_lock_status lock_status; struct list_head pins; + struct work_struct change_work; }; =20 struct zl3073x_dpll *zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch); --=20 2.49.1