From nobody Tue Jun 16 19:41:10 2026 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 8FE4D37756A for ; Wed, 29 Apr 2026 15:08:40 +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=1777475323; cv=none; b=CjQP0v4rFyFt55MOmGpKKLF4SEbOK020B7047pQ1KLM/1KYhmBJDhaXq189EevcVY0AdCQnrTcx8F4A+tLzHXSYn6shjlfih38Yu2RxbOUsD2ZvgYU4M0tTRIsIrJzNOqTJYrjV6Ap9S1STGQuCSyMKKs/oUaiJ60vtfbFMEcX0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777475323; c=relaxed/simple; bh=Cgk26zhspHfqfwxOHyhMK8lLVzI437xa0GK9jLMsjQU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TNiemM2T96VLqIC/j1Az2CW+KIDPO4saxj5AwUomKXSRWoZmjB2MzW8OLUvzSVgUGf4zDMkpqOIZ3edOMIJB6o/pAu+vy6ACaarh6GTyfQOka4EL98nzObe2vtOCY8RRKkpAXdm6B1lm8pQBHQF5fkUC/DcszGvApd700j4y0Ms= 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=XwKquoDE; 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="XwKquoDE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777475319; 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=3Cm3MImWm9x03kFVsqEHaLTNu8IGHhIOFxE20gbhobU=; b=XwKquoDEOfszRYfUXVaX8ZBWb2LDL8RE8VkL8ZGj1frZgvwFShuCeCD7BJRwGhDKaiSaeA j0g6QDA3uEsoTpXwSWr+Ogra805j7MKLx4EfvVIiK/4JnwzvbZbpzlSS4weh3czEEr7Hio IuvRhzLKmqz7wfG4sTkmD2ganafx+RA= 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-1-0ZOgwE7cO8CBZIUE03QRaw-1; Wed, 29 Apr 2026 11:08:37 -0400 X-MC-Unique: 0ZOgwE7cO8CBZIUE03QRaw-1 X-Mimecast-MFC-AGG-ID: 0ZOgwE7cO8CBZIUE03QRaw_1777475314 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 DDE25195606C; Wed, 29 Apr 2026 15:08:33 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.44.49.234]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 71C1A1955F42; Wed, 29 Apr 2026 15:08:26 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Andrew Lunn , Arkadiusz Kubalewski , "David S. Miller" , Donald Hunter , Eric Dumazet , Jakub Kicinski , Jiri Pirko , Jonathan Corbet , Leon Romanovsky , Mark Bloch , Michal Schmidt , Paolo Abeni , Pasi Vaananen , Petr Oros , Prathosh Satish , Saeed Mahameed , Shuah Khan , Simon Horman , Tariq Toukan , Vadim Fedorenko , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org Subject: [PATCH net-next 1/2] dpll: move fractional-frequency-offset-ppt under pin-parent-device Date: Wed, 29 Apr 2026 17:08:16 +0200 Message-ID: <20260429150817.3059763-2-ivecera@redhat.com> In-Reply-To: <20260429150817.3059763-1-ivecera@redhat.com> References: <20260429150817.3059763-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" Move the fractional-frequency-offset-ppt attribute from the top-level pin attributes into the pin-parent-device nested attribute set. This makes it consistent with phase-offset which is already per-parent and clarifies that FFO PPT represents the frequency difference between a pin and its parent DPLL device. The top-level fractional-frequency-offset attribute (in PPM) remains unchanged for backward compatibility. Distinguish the two contexts in the ffo_get callback by passing dpll=3DNULL for the top-level (rx vs tx symbol rate) call and a valid dpll pointer for the nested (pin vs parent DPLL) call. Update mlx5 and zl3073x drivers to return -ENODATA for the nested context they do not yet support. Add documentation for both FFO attributes to dpll.rst. Signed-off-by: Ivan Vecera --- Documentation/driver-api/dpll.rst | 16 +++++++++ Documentation/netlink/specs/dpll.yaml | 11 +++--- drivers/dpll/dpll_netlink.c | 34 ++++++++++++++----- drivers/dpll/dpll_nl.c | 1 + drivers/dpll/zl3073x/dpll.c | 4 +++ .../net/ethernet/mellanox/mlx5/core/dpll.c | 4 +++ 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/d= pll.rst index 93c191b2d0898..007e07ef3a840 100644 --- a/Documentation/driver-api/dpll.rst +++ b/Documentation/driver-api/dpll.rst @@ -250,6 +250,22 @@ in the ``DPLL_A_PIN_PHASE_OFFSET`` attribute. ``DPLL_A_PHASE_OFFSET_MONITOR`` attr state of a feature =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 +Fractional frequency offset +=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 + +The fractional frequency offset (FFO) represents the frequency difference +between a pin and its parent DPLL device. It is reported in the +``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT`` attribute nested under +the parent device, in parts per trillion (PPT, 10^-12). + +This is analogous to ``DPLL_A_PIN_PHASE_OFFSET`` but in the frequency +domain. It is typically reported only for the currently active input pin. + +The top-level ``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET`` attribute (in PPM) +represents the RX vs TX symbol rate offset on the media associated with +the pin (e.g. for SyncE ethernet ports) and is independent of the +per-parent FFO PPT attribute. + Frequency monitor =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/= specs/dpll.yaml index 40465a3d7fc20..bf13c0e27c749 100644 --- a/Documentation/netlink/specs/dpll.yaml +++ b/Documentation/netlink/specs/dpll.yaml @@ -471,12 +471,10 @@ attribute-sets: name: fractional-frequency-offset-ppt type: sint doc: | - The FFO (Fractional Frequency Offset) of the pin with respect to - the nominal frequency. - Value =3D (frequency_measured - frequency_nominal) / frequency_n= ominal + The FFO (Fractional Frequency Offset) between a pin and its + parent DPLL device, similar to phase-offset but in frequency + domain. Value is in PPT (parts per trillion, 10^-12). - Note: This attribute provides higher resolution than the standard - fractional-frequency-offset (which is in PPM). - name: measured-frequency type: u64 @@ -503,6 +501,8 @@ attribute-sets: name: state - name: phase-offset + - + name: fractional-frequency-offset-ppt - name: pin-parent-pin subset-of: pin @@ -672,7 +672,6 @@ operations: - phase-adjust-max - phase-adjust - fractional-frequency-offset - - fractional-frequency-offset-ppt - esync-frequency - esync-frequency-supported - esync-pulse diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index af7ce62ec55ca..89d657df66ee0 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -394,6 +394,27 @@ dpll_msg_add_phase_offset(struct sk_buff *msg, struct = dpll_pin *pin, static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin, struct dpll_pin_ref *ref, struct netlink_ext_ack *extack) +{ + const struct dpll_pin_ops *ops =3D dpll_pin_ops(ref); + s64 ffo; + int ret; + + if (!ops->ffo_get) + return 0; + ret =3D ops->ffo_get(pin, dpll_pin_on_dpll_priv(ref->dpll, pin), + NULL, NULL, &ffo, extack); + if (ret) { + if (ret =3D=3D -ENODATA) + return 0; + return ret; + } + return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET, + div_s64(ffo, 1000000)); +} + +static int dpll_msg_add_ffo_ppt(struct sk_buff *msg, struct dpll_pin *pin, + struct dpll_pin_ref *ref, + struct netlink_ext_ack *extack) { const struct dpll_pin_ops *ops =3D dpll_pin_ops(ref); struct dpll_device *dpll =3D ref->dpll; @@ -409,14 +430,8 @@ static int dpll_msg_add_ffo(struct sk_buff *msg, struc= t dpll_pin *pin, return 0; return ret; } - /* Put the FFO value in PPM to preserve compatibility with older - * programs. - */ - ret =3D nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET, - div_s64(ffo, 1000000)); - if (ret) - return -EMSGSIZE; - return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT, + return nla_put_sint(msg, + DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT, ffo); } =20 @@ -659,6 +674,9 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll= _pin *pin, if (ret) goto nest_cancel; ret =3D dpll_msg_add_phase_offset(msg, pin, ref, extack); + if (ret) + goto nest_cancel; + ret =3D dpll_msg_add_ffo_ppt(msg, pin, ref, extack); if (ret) goto nest_cancel; nla_nest_end(msg, attr); diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c index 1e652340a5d73..6e4535bac1580 100644 --- a/drivers/dpll/dpll_nl.c +++ b/drivers/dpll/dpll_nl.c @@ -18,6 +18,7 @@ const struct nla_policy dpll_pin_parent_device_nl_policy[= DPLL_A_PIN_PHASE_OFFSET [DPLL_A_PIN_PRIO] =3D { .type =3D NLA_U32, }, [DPLL_A_PIN_STATE] =3D NLA_POLICY_RANGE(NLA_U32, 1, 3), [DPLL_A_PIN_PHASE_OFFSET] =3D { .type =3D NLA_S64, }, + [DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT] =3D { .type =3D NLA_SINT, }, }; =20 const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1= ] =3D { diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c index c95e93ef3ab04..6e9dfaf7309f7 100644 --- a/drivers/dpll/zl3073x/dpll.c +++ b/drivers/dpll/zl3073x/dpll.c @@ -299,6 +299,10 @@ zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *= dpll_pin, void *pin_priv, { struct zl3073x_dpll_pin *pin =3D pin_priv; =20 + /* Only rx vs tx symbol rate FFO is supported */ + if (dpll) + return -ENODATA; + *ffo =3D pin->freq_offset; =20 return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c b/drivers/net/e= thernet/mellanox/mlx5/core/dpll.c index bce72e8d1bc31..ef2c58c390efa 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c @@ -306,6 +306,10 @@ static int mlx5_dpll_ffo_get(const struct dpll_pin *pi= n, void *pin_priv, struct mlx5_dpll *mdpll =3D pin_priv; int err; =20 + /* Only rx vs tx symbol rate FFO is supported */ + if (dpll) + return -ENODATA; + err =3D mlx5_dpll_synce_status_get(mdpll->mdev, &synce_status); if (err) return err; --=20 2.53.0 From nobody Tue Jun 16 19:41:10 2026 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 34CEA377577 for ; Wed, 29 Apr 2026 15:08:51 +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=1777475333; cv=none; b=pNi5ME/6fsJzuc6pyebBtpcQBzjPoaKInLMX+w6PGuYrzwPV99VMr0F1IzvO4zfF79E3p1ZSlEQT7SGXxclx80AkBKU7AMlqX2cgHLS+w9uNj+/BcPMMYOb3n7aystJl+Sp/onUhDIF5Jpi4KZyBtf3HpjEZKpOP1c3y+P4wYp0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777475333; c=relaxed/simple; bh=nSpDh5JAVcMnvJl6TvFSJ4oampsPYHyg3/ychU1qErg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N3aGnxMwM8YfuwwGQ+hCGxNi3Hoo0/YWQl99aEny95gcHXr3aTYNlO1xO+0h12DPzv7EkhzRAxE6q7LtWPnQGi0hC2IdfFi9etxwq1JFsSvQ8xzAxZj7wI44+uT2cV7msw4ulqAhDWzWomwywovKeEMxZqN6TGCtZelDaFuAMzo= 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=IwOyRfHC; 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="IwOyRfHC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777475330; 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=GNccpgI2xsz1sZwJ9hab0PdIysEcq8xFnw8tQlOiyts=; b=IwOyRfHCKaSK9xJVx6UcX/bvvkVAiUNuxBA5PsUOjEM+KvEdVWJQgpvBb/qRLeUHN+EKxR 2hRw8RGPPr4xasbigwHZwwE4J4DnEfQ93kTYOOnlpF31eYLefXuWJSCCtUwqe9p55wnQ4W itca7V9t5ZhE/DHT8rp9LmlFhL2F/b4= 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-199-WIWQZtjOMeSMWeqaOxmNQQ-1; Wed, 29 Apr 2026 11:08:47 -0400 X-MC-Unique: WIWQZtjOMeSMWeqaOxmNQQ-1 X-Mimecast-MFC-AGG-ID: WIWQZtjOMeSMWeqaOxmNQQ_1777475322 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 4FE811800378; Wed, 29 Apr 2026 15:08:41 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.44.49.234]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5E87119560B7; Wed, 29 Apr 2026 15:08:34 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Andrew Lunn , Arkadiusz Kubalewski , "David S. Miller" , Donald Hunter , Eric Dumazet , Jakub Kicinski , Jiri Pirko , Jonathan Corbet , Leon Romanovsky , Mark Bloch , Michal Schmidt , Paolo Abeni , Pasi Vaananen , Petr Oros , Prathosh Satish , Saeed Mahameed , Shuah Khan , Simon Horman , Tariq Toukan , Vadim Fedorenko , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org Subject: [PATCH net-next 2/2] dpll: zl3073x: report FFO as DPLL vs input reference offset Date: Wed, 29 Apr 2026 17:08:17 +0200 Message-ID: <20260429150817.3059763-3-ivecera@redhat.com> In-Reply-To: <20260429150817.3059763-1-ivecera@redhat.com> References: <20260429150817.3059763-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" Replace the per-reference frequency offset measurement (which was redundant with measured-frequency) with a direct read of the DPLL's delta frequency offset vs its tracked input reference. The new implementation uses the dpll_df_offset_x register with ref_ofst=3D1 via the dpll_df_read_x semaphore mechanism. This provides 2^-48 resolution (~3.5 fE) and reports the actual frequency difference between the DPLL and its active input. FFO is now reported only for the active input pin in the nested (pin vs parent DPLL) context. Top-level FFO returns -ENODATA. Rewrite ffo_check to compare the cached df_offset converted to PPT instead of using the old per-reference measurement. Remove the ref_ffo_update periodic measurement and the ref ffo field since they are no longer needed. Signed-off-by: Ivan Vecera --- drivers/dpll/zl3073x/chan.c | 31 +++++++++++++++++++++++-- drivers/dpll/zl3073x/chan.h | 14 ++++++++++++ drivers/dpll/zl3073x/core.c | 45 ------------------------------------- drivers/dpll/zl3073x/dpll.c | 34 ++++++++++++---------------- drivers/dpll/zl3073x/ref.h | 14 ------------ drivers/dpll/zl3073x/regs.h | 15 +++++++++++++ 6 files changed, 72 insertions(+), 81 deletions(-) diff --git a/drivers/dpll/zl3073x/chan.c b/drivers/dpll/zl3073x/chan.c index 2f48ca2391494..2fe3c3da84bb5 100644 --- a/drivers/dpll/zl3073x/chan.c +++ b/drivers/dpll/zl3073x/chan.c @@ -18,6 +18,7 @@ int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index) { struct zl3073x_chan *chan =3D &zldev->chan[index]; + u64 val; int rc; =20 rc =3D zl3073x_read_u8(zldev, ZL_REG_DPLL_MON_STATUS(index), @@ -25,8 +26,34 @@ int zl3073x_chan_state_update(struct zl3073x_dev *zldev,= u8 index) if (rc) return rc; =20 - return zl3073x_read_u8(zldev, ZL_REG_DPLL_REFSEL_STATUS(index), - &chan->refsel_status); + rc =3D zl3073x_read_u8(zldev, ZL_REG_DPLL_REFSEL_STATUS(index), + &chan->refsel_status); + if (rc) + return rc; + + /* Read df_offset vs tracked reference */ + rc =3D zl3073x_poll_zero_u8(zldev, ZL_REG_DPLL_DF_READ(index), + ZL_DPLL_DF_READ_SEM); + if (rc) + return rc; + + rc =3D zl3073x_write_u8(zldev, ZL_REG_DPLL_DF_READ(index), + ZL_DPLL_DF_READ_SEM | ZL_DPLL_DF_READ_REF_OFST); + if (rc) + return rc; + + rc =3D zl3073x_poll_zero_u8(zldev, ZL_REG_DPLL_DF_READ(index), + ZL_DPLL_DF_READ_SEM); + if (rc) + return rc; + + rc =3D zl3073x_read_u48(zldev, ZL_REG_DPLL_DF_OFFSET(index), &val); + if (rc) + return rc; + + chan->df_offset =3D sign_extend64(val, 47); + + return 0; } =20 /** diff --git a/drivers/dpll/zl3073x/chan.h b/drivers/dpll/zl3073x/chan.h index 481da2133202b..4353809c69122 100644 --- a/drivers/dpll/zl3073x/chan.h +++ b/drivers/dpll/zl3073x/chan.h @@ -17,6 +17,7 @@ struct zl3073x_dev; * @ref_prio: reference priority registers (4 bits per ref, P/N packed) * @mon_status: monitor status register value * @refsel_status: reference selection status register value + * @df_offset: frequency offset vs tracked reference in 2^-48 steps */ struct zl3073x_chan { struct_group(cfg, @@ -26,6 +27,7 @@ struct zl3073x_chan { struct_group(stat, u8 mon_status; u8 refsel_status; + s64 df_offset; ); }; =20 @@ -37,6 +39,18 @@ int zl3073x_chan_state_set(struct zl3073x_dev *zldev, u8= index, =20 int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index); =20 +/** + * zl3073x_chan_df_offset_get - get cached df_offset vs tracked reference + * @chan: pointer to channel state + * + * Return: frequency offset in 2^-48 steps + */ +static inline s64 +zl3073x_chan_df_offset_get(const struct zl3073x_chan *chan) +{ + return chan->df_offset; +} + /** * zl3073x_chan_mode_get - get DPLL channel operating mode * @chan: pointer to channel state diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c index 5f1e70f3e40a0..b3345060490db 100644 --- a/drivers/dpll/zl3073x/core.c +++ b/drivers/dpll/zl3073x/core.c @@ -704,44 +704,6 @@ zl3073x_ref_freq_meas_update(struct zl3073x_dev *zldev) return 0; } =20 -/** - * zl3073x_ref_ffo_update - update reference fractional frequency offsets - * @zldev: pointer to zl3073x_dev structure - * - * The function asks device to latch the latest measured fractional - * frequency offset values, reads and stores them into the ref state. - * - * Return: 0 on success, <0 on error - */ -static int -zl3073x_ref_ffo_update(struct zl3073x_dev *zldev) -{ - int i, rc; - - rc =3D zl3073x_ref_freq_meas_latch(zldev, - ZL_REF_FREQ_MEAS_CTRL_REF_FREQ_OFF); - if (rc) - return rc; - - /* Read DPLL-to-REFx frequency offset measurements */ - for (i =3D 0; i < ZL3073X_NUM_REFS; i++) { - s32 value; - - /* Read value stored in units of 2^-32 signed */ - rc =3D zl3073x_read_u32(zldev, ZL_REG_REF_FREQ(i), &value); - if (rc) - return rc; - - /* Convert to ppt - * ffo =3D (10^12 * value) / 2^32 - * ffo =3D ( 5^12 * value) / 2^20 - */ - zldev->ref[i].ffo =3D mul_s64_u64_shr(value, 244140625, 20); - } - - return 0; -} - static void zl3073x_dev_periodic_work(struct kthread_work *work) { @@ -776,13 +738,6 @@ zl3073x_dev_periodic_work(struct kthread_work *work) } } =20 - /* Update references' fractional frequency offsets */ - rc =3D zl3073x_ref_ffo_update(zldev); - if (rc) - dev_warn(zldev->dev, - "Failed to update fractional frequency offsets: %pe\n", - ERR_PTR(rc)); - list_for_each_entry(zldpll, &zldev->dplls, list) zl3073x_dpll_changes_check(zldpll); =20 diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c index 6e9dfaf7309f7..06dec77b2a516 100644 --- a/drivers/dpll/zl3073x/dpll.c +++ b/drivers/dpll/zl3073x/dpll.c @@ -299,8 +299,12 @@ zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *= dpll_pin, void *pin_priv, { struct zl3073x_dpll_pin *pin =3D pin_priv; =20 - /* Only rx vs tx symbol rate FFO is supported */ - if (dpll) + /* Only nested FFO (pin vs parent DPLL) is supported */ + if (!dpll) + return -ENODATA; + + /* Report FFO only for the active pin */ + if (pin->operstate !=3D DPLL_PIN_OPERSTATE_ACTIVE) return -ENODATA; =20 *ffo =3D pin->freq_offset; @@ -1699,37 +1703,27 @@ zl3073x_dpll_pin_phase_offset_check(struct zl3073x_= dpll_pin *pin) } =20 /** - * zl3073x_dpll_pin_ffo_check - check for pin fractional frequency offset = change + * zl3073x_dpll_pin_ffo_check - check for FFO change on active pin * @pin: pin to check * - * Check for the given pin's fractional frequency change. - * - * Return: true on fractional frequency offset change, false otherwise + * Return: true on change, false otherwise */ static bool zl3073x_dpll_pin_ffo_check(struct zl3073x_dpll_pin *pin) { struct zl3073x_dpll *zldpll =3D pin->dpll; - struct zl3073x_dev *zldev =3D zldpll->dev; - const struct zl3073x_ref *ref; - u8 ref_id; + const struct zl3073x_chan *chan; s64 ffo; =20 - /* Get reference monitor status */ - ref_id =3D zl3073x_input_pin_ref_get(pin->id); - ref =3D zl3073x_ref_state_get(zldev, ref_id); - - /* Do not report ffo changes if the reference monitor report errors */ - if (!zl3073x_ref_is_status_ok(ref)) + if (pin->operstate !=3D DPLL_PIN_OPERSTATE_ACTIVE) return false; =20 - /* Compare with previous value */ - ffo =3D zl3073x_ref_ffo_get(ref); + chan =3D zl3073x_chan_state_get(zldpll->dev, zldpll->id); + ffo =3D mul_s64_u64_shr(zl3073x_chan_df_offset_get(chan), + 244140625, 36); + if (pin->freq_offset !=3D ffo) { - dev_dbg(zldev->dev, "%s freq offset changed: %lld -> %lld\n", - pin->label, pin->freq_offset, ffo); pin->freq_offset =3D ffo; - return true; } =20 diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h index 55e80e4f08734..e140ca3ea17dc 100644 --- a/drivers/dpll/zl3073x/ref.h +++ b/drivers/dpll/zl3073x/ref.h @@ -22,7 +22,6 @@ struct zl3073x_dev; * @freq_ratio_n: FEC mode divisor * @sync_ctrl: reference sync control * @config: reference config - * @ffo: current fractional frequency offset * @meas_freq: measured input frequency in Hz * @mon_status: reference monitor status */ @@ -40,7 +39,6 @@ struct zl3073x_ref { u8 config; ); struct_group(stat, /* Status */ - s64 ffo; u32 meas_freq; u8 mon_status; ); @@ -58,18 +56,6 @@ int zl3073x_ref_state_update(struct zl3073x_dev *zldev, = u8 index); =20 int zl3073x_ref_freq_factorize(u32 freq, u16 *base, u16 *mult); =20 -/** - * zl3073x_ref_ffo_get - get current fractional frequency offset - * @ref: pointer to ref state - * - * Return: the latest measured fractional frequency offset - */ -static inline s64 -zl3073x_ref_ffo_get(const struct zl3073x_ref *ref) -{ - return ref->ffo; -} - /** * zl3073x_ref_meas_freq_get - get measured input frequency * @ref: pointer to ref state diff --git a/drivers/dpll/zl3073x/regs.h b/drivers/dpll/zl3073x/regs.h index d425dc67250fe..b8bbea31748f8 100644 --- a/drivers/dpll/zl3073x/regs.h +++ b/drivers/dpll/zl3073x/regs.h @@ -157,6 +157,11 @@ #define ZL_DPLL_MODE_REFSEL_MODE_NCO 4 #define ZL_DPLL_MODE_REFSEL_REF GENMASK(7, 4) =20 +#define ZL_REG_DPLL_DF_READ(_idx) \ + ZL_REG_IDX(_idx, 5, 0x28, 1, ZL3073X_MAX_CHANNELS, 1) +#define ZL_DPLL_DF_READ_SEM BIT(4) +#define ZL_DPLL_DF_READ_REF_OFST BIT(3) + #define ZL_REG_DPLL_MEAS_CTRL ZL_REG(5, 0x50, 1) #define ZL_DPLL_MEAS_CTRL_EN BIT(0) #define ZL_DPLL_MEAS_CTRL_AVG_FACTOR GENMASK(7, 4) @@ -169,6 +174,16 @@ #define ZL_REG_DPLL_PHASE_ERR_DATA(_idx) \ ZL_REG_IDX(_idx, 5, 0x55, 6, ZL3073X_MAX_CHANNELS, 6) =20 +/******************************* + * Register Pages 6-7, DPLL Data + *******************************/ + +#define ZL_REG_DPLL_DF_OFFSET_03(_idx) \ + ZL_REG_IDX(_idx, 6, 0x00, 6, 4, 0x20) +#define ZL_REG_DPLL_DF_OFFSET_4 ZL_REG(7, 0x00, 6) +#define ZL_REG_DPLL_DF_OFFSET(_idx) \ + ((_idx) < 4 ? ZL_REG_DPLL_DF_OFFSET_03(_idx) : ZL_REG_DPLL_DF_OFFSET_4) + /*********************************** * Register Page 9, Synth and Output ***********************************/ --=20 2.53.0