Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2216523/?format=api
{ "id": 2216523, "url": "http://patchwork.ozlabs.org/api/patches/2216523/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260326162832.3135857-6-grzegorz.nitka@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260326162832.3135857-6-grzegorz.nitka@intel.com>", "list_archive_url": null, "date": "2026-03-26T16:28:29", "name": "[v4,net-next,5/8] ice: add TX clock (TXC) DPLL interface for E825 devices", "commit_ref": null, "pull_url": null, "state": "handled-elsewhere", "archived": false, "hash": "6988f03fe415deed7c6b03f349f21779f514b87d", "submitter": { "id": 82711, "url": "http://patchwork.ozlabs.org/api/people/82711/?format=api", "name": "Nitka, Grzegorz", "email": "grzegorz.nitka@intel.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260326162832.3135857-6-grzegorz.nitka@intel.com/mbox/", "series": [ { "id": 497620, "url": "http://patchwork.ozlabs.org/api/series/497620/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=497620", "date": "2026-03-26T16:28:24", "name": "dpll/ice: Add TXC DPLL type and full TX reference clock control for E825", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/497620/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2216523/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2216523/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=osuosl.org header.i=@osuosl.org header.a=rsa-sha256\n header.s=default header.b=ZSYWajv+;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=osuosl.org\n (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org;\n envelope-from=intel-wired-lan-bounces@osuosl.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fhTpp1ZXXz1yGD\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 27 Mar 2026 03:33:06 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id D84426084C;\n\tThu, 26 Mar 2026 16:33:04 +0000 (UTC)", "from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id 8LtteRp02BjP; Thu, 26 Mar 2026 16:33:03 +0000 (UTC)", "from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id BD36A60853;\n\tThu, 26 Mar 2026 16:33:03 +0000 (UTC)", "from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n by lists1.osuosl.org (Postfix) with ESMTP id 21C631D3\n for <intel-wired-lan@lists.osuosl.org>; Thu, 26 Mar 2026 16:33:03 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp3.osuosl.org (Postfix) with ESMTP id 1F27E60853\n for <intel-wired-lan@lists.osuosl.org>; Thu, 26 Mar 2026 16:33:03 +0000 (UTC)", "from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id R7X2PQTMD207 for <intel-wired-lan@lists.osuosl.org>;\n Thu, 26 Mar 2026 16:33:02 +0000 (UTC)", "from mgamail.intel.com (mgamail.intel.com [192.198.163.19])\n by smtp3.osuosl.org (Postfix) with ESMTPS id F0D4E6084C\n for <intel-wired-lan@lists.osuosl.org>; Thu, 26 Mar 2026 16:33:01 +0000 (UTC)", "from orviesa007.jf.intel.com ([10.64.159.147])\n by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 26 Mar 2026 09:33:01 -0700", "from gklab-003-001.igk.intel.com ([10.91.173.48])\n by orviesa007.jf.intel.com with ESMTP; 26 Mar 2026 09:32:57 -0700" ], "X-Virus-Scanned": [ "amavis at osuosl.org", "amavis at osuosl.org" ], "X-Comment": "SPF check N/A for local connections - client-ip=140.211.166.142;\n helo=lists1.osuosl.org; envelope-from=intel-wired-lan-bounces@osuosl.org;\n receiver=<UNKNOWN> ", "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 smtp3.osuosl.org BD36A60853", "OpenDKIM Filter v2.11.0 smtp3.osuosl.org F0D4E6084C" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=osuosl.org;\n\ts=default; t=1774542783;\n\tbh=0/dhRr6VDluE3gW0xLlbaV2NpCjo8FpEUjH2j2oIg6s=;\n\th=From:To:Date:In-Reply-To:References:Subject:List-Id:\n\t List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe:\n\t Cc:From;\n\tb=ZSYWajv+fE+v5liaQ4sV8ztNyeS3PvPb7YdQNsED1vRs9cQEU7QVfhDGvEsy1qHm3\n\t TyarSBbrSpLtqFRQf9goTHSgCv82nNoC7RP1SadvCjDoa7I3CJKCy2D8ENLtqKqj2B\n\t 6IZKB7QRseOgtuC/l+Nuybe/zzPukiw7QEyLvd2ZqmFnwv+ZfldYqSfZj6rOuE/ETb\n\t hulYDgqQYTWn2N1aaENbpW6W6w1rOblPvRK7xHUytYk8CB1pbm8B4ER1kjDVh3PT8d\n\t gA/dQpq3XmTCOxSsaVnzEKqyvCB0lzmXo6stiZ9/XncgjHGFK0ZmvMJ7xXZWTOQsMD\n\t 3XEw3g7As3jiw==", "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=192.198.163.19;\n helo=mgamail.intel.com; envelope-from=grzegorz.nitka@intel.com;\n receiver=<UNKNOWN>", "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp3.osuosl.org F0D4E6084C", "X-CSE-ConnectionGUID": [ "b4nvPUY0RTCBdAgrgdTd6w==", "UEH2dNSlS32v7jmotODE2w==" ], "X-CSE-MsgGUID": [ "3MvUZpgzSbekHL3TP8Q1pA==", "2nDTOYt9Ql6QRFNCuuUcFA==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6800,10657,11741\"; a=\"74636682\"", "E=Sophos;i=\"6.23,142,1770624000\"; d=\"scan'208\";a=\"74636682\"", "E=Sophos;i=\"6.23,142,1770624000\"; d=\"scan'208\";a=\"225311144\"" ], "X-ExtLoop1": "1", "From": "Grzegorz Nitka <grzegorz.nitka@intel.com>", "To": "netdev@vger.kernel.org", "Date": "Thu, 26 Mar 2026 17:28:29 +0100", "Message-Id": "<20260326162832.3135857-6-grzegorz.nitka@intel.com>", "X-Mailer": "git-send-email 2.39.3", "In-Reply-To": "<20260326162832.3135857-1-grzegorz.nitka@intel.com>", "References": "<20260326162832.3135857-1-grzegorz.nitka@intel.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Mailman-Original-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1774542782; x=1806078782;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=8ceLVs2JsObasP3Lu+oXmghvt3ALk1HbwW5kHqK/T4Q=;\n b=IBClPsnwa98bsL/QsQwVTRDOTtd8G7CnYeJ1C4/rX8DT3mgvPcYmHaWQ\n SFCxdVYwmdaW1AjSFal2f84rHFuTtFcAJe0W4BQWpB40pjcEn66VC1b1m\n gsk9JPiYO1o9vBglZSZbpvjTWoDd+EF/v8VYFRr+bLM/zOD4MZlOSreM9\n mW8wwweKWIMz6YEFvEbRq7rY54e05d4gIkMzsZW4mVBOCA9htCbFtKW6m\n NyfnJSkl5bSSSCOiQWHpOaXfVQF4Tz8eZUOIMZkVZSZwH1RHubPklID9z\n DBWcRuP6rLSybuyAiI/AEoF4BaIylOnReEdyNNF6lkoGPWSCjZ1cuVeqH\n A==;", "X-Mailman-Original-Authentication-Results": [ "smtp3.osuosl.org;\n dmarc=pass (p=none dis=none)\n header.from=intel.com", "smtp3.osuosl.org;\n dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com\n header.a=rsa-sha256 header.s=Intel header.b=IBClPsnw" ], "Subject": "[Intel-wired-lan] [PATCH v4 net-next 5/8] ice: add TX clock (TXC)\n DPLL interface for E825 devices", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n <intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Cc": "ivecera@redhat.com, vadim.fedorenko@linux.dev, kuba@kernel.org,\n jiri@resnulli.us, edumazet@google.com, przemyslaw.kitszel@intel.com,\n richardcochran@gmail.com, donald.hunter@gmail.com,\n linux-kernel@vger.kernel.org, arkadiusz.kubalewski@intel.com,\n andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org, horms@kernel.org,\n Prathosh.Satish@microchip.com, anthony.l.nguyen@intel.com, pabeni@redhat.com,\n davem@davemloft.net", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "Introduce a TX clock DPLL instance and pins for E825-based devices.\nThe TXC domain exposes two reference pins:\n - EXT_EREF0 (board external electrical reference)\n - SYNCE (port-derived reference, described via fwnode)\n\nA new pin type (ICE_DPLL_PIN_TYPE_TXCLK) and pin ops are added. The\nSYNCE pin is registered when its fwnode becomes available, while\nEXT_EREF0 is registered directly. The notifier worker is updated to\nregister/unregister TXC pins and to ignore notifications that are a\nside effect of internal registration by checking the src_id.\n\nA new per-pin attribute tracks the TX reference source\n(enum ice_e825c_ref_clk). The TXC DPLL device is created and torn\ndown alongside existing PPS/EEC devices on E825, with specific init\nand deinit flows for the TXC pins.\n\nCurrent TXC pin state getters return DISCONNECTED as a placeholder;\nhardware-backed state reporting will be implemented in a follow-up.\n\nReviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>\nSigned-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>\n---\n drivers/net/ethernet/intel/ice/ice_dpll.c | 296 ++++++++++++++++++--\n drivers/net/ethernet/intel/ice/ice_dpll.h | 6 +\n drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 7 +\n 3 files changed, 286 insertions(+), 23 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c\nindex 62f75701d652..72518fd1398d 100644\n--- a/drivers/net/ethernet/intel/ice/ice_dpll.c\n+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c\n@@ -19,6 +19,11 @@\n #define ICE_DPLL_SW_PIN_INPUT_BASE_QSFP\t\t6\n #define ICE_DPLL_SW_PIN_OUTPUT_BASE\t\t0\n \n+#define E825_EXT_EREF_PIN_IDX\t\t\t0\n+#define E825_EXT_SYNCE_PIN_IDX\t\t\t1\n+#define E825_RCLK_PARENT_0_PIN_IDX\t\t0\n+#define E825_RCLK_PARENT_1_PIN_IDX\t\t1\n+\n #define ICE_DPLL_PIN_SW_INPUT_ABS(in_idx) \\\n \t(ICE_DPLL_SW_PIN_INPUT_BASE_SFP + (in_idx))\n \n@@ -57,6 +62,7 @@\n * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin\n * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin\n * @ICE_DPLL_PIN_TYPE_SOFTWARE: software controlled SMA/U.FL pins\n+ * @ICE_DPLL_PIN_TYPE_TXCLK: transmit clock reference input pin\n */\n enum ice_dpll_pin_type {\n \tICE_DPLL_PIN_INVALID,\n@@ -64,6 +70,7 @@ enum ice_dpll_pin_type {\n \tICE_DPLL_PIN_TYPE_OUTPUT,\n \tICE_DPLL_PIN_TYPE_RCLK_INPUT,\n \tICE_DPLL_PIN_TYPE_SOFTWARE,\n+\tICE_DPLL_PIN_TYPE_TXCLK,\n };\n \n static const char * const pin_type_name[] = {\n@@ -71,10 +78,13 @@ static const char * const pin_type_name[] = {\n \t[ICE_DPLL_PIN_TYPE_OUTPUT] = \"output\",\n \t[ICE_DPLL_PIN_TYPE_RCLK_INPUT] = \"rclk-input\",\n \t[ICE_DPLL_PIN_TYPE_SOFTWARE] = \"software\",\n+\t[ICE_DPLL_PIN_TYPE_TXCLK] = \"txclk-input\",\n };\n \n static const char * const ice_dpll_sw_pin_sma[] = { \"SMA1\", \"SMA2\" };\n static const char * const ice_dpll_sw_pin_ufl[] = { \"U.FL1\", \"U.FL2\" };\n+static const char * const ice_dpll_ext_eref_pin = \"EXT_EREF0\";\n+static const char * const ice_dpll_fwnode_ext_synce = \"clk_ref_synce\";\n \n static const struct dpll_pin_frequency ice_esync_range[] = {\n \tDPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),\n@@ -2517,12 +2527,75 @@ ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv,\n \treturn ret;\n }\n \n+/**\n+ * ice_dpll_txclk_state_on_dpll_set - set a state on TX clk pin\n+ * @pin: pointer to a pin\n+ * @pin_priv: private data pointer passed on pin registration\n+ * @dpll: registered dpll pointer\n+ * @dpll_priv: private data pointer passed on dpll registration\n+ * @state: state to be set on pin\n+ * @extack: error reporting\n+ *\n+ * Dpll subsystem callback, set a state of a Tx reference clock pin\n+ *\n+ * Return:\n+ * * negative - failure\n+ */\n+static int\n+ice_dpll_txclk_state_on_dpll_set(const struct dpll_pin *pin, void *pin_priv,\n+\t\t\t\t const struct dpll_device *dpll,\n+\t\t\t\t void *dpll_priv, enum dpll_pin_state state,\n+\t\t\t\t struct netlink_ext_ack *extack)\n+{\n+\t/*\n+\t * TODO: set HW accordingly to selected TX reference clock.\n+\t * To be added in the follow up patches.\n+\t */\n+\treturn -EOPNOTSUPP;\n+}\n+\n+/**\n+ * ice_dpll_txclk_state_on_dpll_get - get a state of Tx clk reference pin\n+ * @pin: pointer to a pin\n+ * @pin_priv: private data pointer passed on pin registration\n+ * @dpll: registered dpll pointer\n+ * @dpll_priv: private data pointer passed on dpll registration\n+ * @state: on success holds pin state on parent pin\n+ * @extack: error reporting\n+ *\n+ * dpll subsystem callback, get a state of a TX clock reference pin.\n+ *\n+ * Return:\n+ * * 0 - success\n+ */\n+static int\n+ice_dpll_txclk_state_on_dpll_get(const struct dpll_pin *pin, void *pin_priv,\n+\t\t\t\t const struct dpll_device *dpll,\n+\t\t\t\t void *dpll_priv,\n+\t\t\t\t enum dpll_pin_state *state,\n+\t\t\t\t struct netlink_ext_ack *extack)\n+{\n+\t/*\n+\t * TODO: query HW status to determine if the TX reference is selected.\n+\t * To be added in the follow up patches.\n+\t */\n+\t*state = DPLL_PIN_STATE_DISCONNECTED;\n+\n+\treturn 0;\n+}\n+\n static const struct dpll_pin_ops ice_dpll_rclk_ops = {\n \t.state_on_pin_set = ice_dpll_rclk_state_on_pin_set,\n \t.state_on_pin_get = ice_dpll_rclk_state_on_pin_get,\n \t.direction_get = ice_dpll_input_direction,\n };\n \n+static const struct dpll_pin_ops ice_dpll_txclk_ops = {\n+\t.state_on_dpll_set = ice_dpll_txclk_state_on_dpll_set,\n+\t.state_on_dpll_get = ice_dpll_txclk_state_on_dpll_get,\n+\t.direction_get = ice_dpll_input_direction,\n+};\n+\n static const struct dpll_pin_ops ice_dpll_pin_sma_ops = {\n \t.state_on_dpll_set = ice_dpll_sma_pin_state_set,\n \t.state_on_dpll_get = ice_dpll_sw_pin_state_get,\n@@ -3023,9 +3096,13 @@ ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,\n {\n \tint i;\n \n-\tfor (i = 0; i < count; i++)\n-\t\tif (!pins[i].hidden)\n-\t\t\tdpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);\n+\tfor (i = 0; i < count; i++) {\n+\t\tif (pins[i].hidden)\n+\t\t\tcontinue;\n+\t\tif (IS_ERR_OR_NULL(pins[i].pin))\n+\t\t\tcontinue;\n+\t\tdpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);\n+\t}\n }\n \n /**\n@@ -3199,19 +3276,40 @@ static bool ice_dpll_is_fwnode_pin(struct ice_dpll_pin *pin)\n \treturn !IS_ERR_OR_NULL(pin->fwnode);\n }\n \n+static bool ice_dpll_fwnode_eq(const struct fwnode_handle *a,\n+\t\t\t const struct fwnode_handle *b)\n+{\n+\treturn a && b && a == b;\n+}\n+\n static void ice_dpll_pin_notify_work(struct work_struct *work)\n {\n \tstruct ice_dpll_pin_work *w = container_of(work,\n \t\t\t\t\t\t struct ice_dpll_pin_work,\n \t\t\t\t\t\t work);\n \tstruct ice_dpll_pin *pin, *parent = w->pin;\n+\tbool is_tx_synce_parent = false;\n \tstruct ice_pf *pf = parent->pf;\n+\tbool is_rclk_parent = false;\n \tint ret;\n \n \twait_for_completion(&pf->dplls.dpll_init);\n \tif (!test_bit(ICE_FLAG_DPLL, pf->flags))\n \t\tgoto out; /* DPLL initialization failed */\n \n+\t/* Decide which parent we are handling, defensively checking FWNs */\n+\tis_rclk_parent =\n+\t\tice_dpll_fwnode_eq(parent->fwnode,\n+\t\t\t\t pf->dplls.inputs[E825_RCLK_PARENT_0_PIN_IDX].fwnode) ||\n+\t\tice_dpll_fwnode_eq(parent->fwnode,\n+\t\t\t\t pf->dplls.inputs[E825_RCLK_PARENT_1_PIN_IDX].fwnode);\n+\n+\tis_tx_synce_parent =\n+\t\tice_dpll_fwnode_eq(parent->fwnode,\n+\t\t\t\t pf->dplls.txclks[E825_EXT_SYNCE_PIN_IDX].fwnode);\n+\tif (!is_rclk_parent && !is_tx_synce_parent)\n+\t\tgoto out;\n+\n \tswitch (w->action) {\n \tcase DPLL_PIN_CREATED:\n \t\tif (!IS_ERR_OR_NULL(parent->pin)) {\n@@ -3228,16 +3326,28 @@ static void ice_dpll_pin_notify_work(struct work_struct *work)\n \t\t\tgoto out;\n \t\t}\n \n-\t\t/* Register rclk pin */\n-\t\tpin = &pf->dplls.rclk;\n-\t\tret = dpll_pin_on_pin_register(parent->pin, pin->pin,\n-\t\t\t\t\t &ice_dpll_rclk_ops, pin);\n-\t\tif (ret) {\n-\t\t\tdev_err(ice_pf_to_dev(pf),\n-\t\t\t\t\"Failed to register pin: %pe\\n\", ERR_PTR(ret));\n-\t\t\tdpll_pin_put(parent->pin, &parent->tracker);\n-\t\t\tparent->pin = NULL;\n-\t\t\tgoto out;\n+\t\tif (is_rclk_parent) {\n+\t\t\t/* Register rclk pin via on-pin relationship */\n+\t\t\tpin = &pf->dplls.rclk;\n+\t\t\tret = dpll_pin_on_pin_register(parent->pin, pin->pin,\n+\t\t\t\t\t\t &ice_dpll_rclk_ops, pin);\n+\t\t\tif (ret) {\n+\t\t\t\tdev_err(ice_pf_to_dev(pf),\n+\t\t\t\t\t\"RCLK pin register failed: %pe\\n\",\n+\t\t\t\t\tERR_PTR(ret));\n+\t\t\t\tgoto drop_parent_ref;\n+\t\t\t}\n+\t\t} else if (is_tx_synce_parent) {\n+\t\t\t/* Register TX-CLK SYNCE pin directly to TXC DPLL */\n+\t\t\tpin = &pf->dplls.txclks[E825_EXT_SYNCE_PIN_IDX];\n+\t\t\tret = dpll_pin_register(pf->dplls.txc.dpll, pin->pin,\n+\t\t\t\t\t\t&ice_dpll_txclk_ops, pin);\n+\t\t\tif (ret) {\n+\t\t\t\tdev_err(ice_pf_to_dev(pf),\n+\t\t\t\t\t\"TX SYNCE pin register failed: %pe\\n\",\n+\t\t\t\t\tERR_PTR(ret));\n+\t\t\t\tgoto drop_parent_ref;\n+\t\t\t}\n \t\t}\n \t\tbreak;\n \tcase DPLL_PIN_DELETED:\n@@ -3246,11 +3356,18 @@ static void ice_dpll_pin_notify_work(struct work_struct *work)\n \t\t\tgoto out;\n \t\t}\n \n-\t\t/* Unregister rclk pin */\n-\t\tpin = &pf->dplls.rclk;\n-\t\tdpll_pin_on_pin_unregister(parent->pin, pin->pin,\n-\t\t\t\t\t &ice_dpll_rclk_ops, pin);\n-\n+\t\tif (is_rclk_parent) {\n+\t\t\t/* Unregister rclk pin */\n+\t\t\tpin = &pf->dplls.rclk;\n+\t\t\tdpll_pin_on_pin_unregister(parent->pin, pin->pin,\n+\t\t\t\t\t\t &ice_dpll_rclk_ops, pin);\n+\t\t} else if (is_tx_synce_parent) {\n+\t\t\t/* Unregister TX-CLK SYNCE pin from TXC DPLL */\n+\t\t\tpin = &pf->dplls.txclks[E825_EXT_SYNCE_PIN_IDX];\n+\t\t\tdpll_pin_unregister(pf->dplls.txc.dpll, pin->pin,\n+\t\t\t\t\t &ice_dpll_txclk_ops, pin);\n+\t\t}\n+drop_parent_ref:\n \t\t/* Drop fwnode pin reference */\n \t\tdpll_pin_put(parent->pin, &parent->tracker);\n \t\tparent->pin = NULL;\n@@ -3276,6 +3393,12 @@ static int ice_dpll_pin_notify(struct notifier_block *nb, unsigned long action,\n \tif (pin->fwnode != info->fwnode)\n \t\treturn NOTIFY_DONE; /* Not this pin */\n \n+\t/* Ignore notification which are the outcome of internal pin\n+\t * registration/unregistration calls - synce pin case.\n+\t */\n+\tif (info->src_id == pin->pf->dplls.clock_id)\n+\t\treturn NOTIFY_DONE;\n+\n \twork = kzalloc_obj(*work);\n \tif (!work)\n \t\treturn NOTIFY_DONE;\n@@ -3401,6 +3524,19 @@ ice_dpll_deinit_fwnode_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,\n \tdestroy_workqueue(pf->dplls.wq);\n }\n \n+static int ice_dpll_deinit_txclk_pins(struct ice_pf *pf)\n+{\n+\tstruct ice_dpll_pin *synce_pin = &pf->dplls.txclks[E825_EXT_SYNCE_PIN_IDX];\n+\tstruct ice_dpll *dt = &pf->dplls.txc;\n+\n+\tice_dpll_unregister_pins(dt->dpll, pf->dplls.txclks,\n+\t\t\t\t &ice_dpll_txclk_ops,\n+\t\t\t\t ARRAY_SIZE(pf->dplls.txclks));\n+\tice_dpll_release_pins(&pf->dplls.txclks[E825_EXT_EREF_PIN_IDX], 1);\n+\tice_dpll_deinit_fwnode_pin(synce_pin);\n+\treturn 0;\n+}\n+\n /**\n * ice_dpll_deinit_pins - deinitialize direct pins\n * @pf: board private structure\n@@ -3420,8 +3556,10 @@ static void ice_dpll_deinit_pins(struct ice_pf *pf, bool cgu)\n \tstruct ice_dpll *dp = &d->pps;\n \n \tice_dpll_deinit_rclk_pin(pf);\n-\tif (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)\n+\tif (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {\n+\t\tice_dpll_deinit_txclk_pins(pf);\n \t\tice_dpll_deinit_fwnode_pins(pf, pf->dplls.inputs, 0);\n+\t}\n \tif (cgu) {\n \t\tice_dpll_unregister_pins(dp->dpll, inputs, &ice_dpll_input_ops,\n \t\t\t\t\t num_inputs);\n@@ -3552,6 +3690,58 @@ ice_dpll_init_fwnode_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,\n \treturn ret;\n }\n \n+static int ice_dpll_init_txclk_pins(struct ice_pf *pf, int start_idx)\n+{\n+\tstruct ice_dpll_pin *ref_pin = pf->dplls.txclks;\n+\tstruct ice_dpll *txc = &pf->dplls.txc;\n+\tint ret;\n+\n+\t/* Configure EXT_EREF0 pin */\n+\tret = ice_dpll_get_pins(pf, ref_pin, start_idx, 1, pf->dplls.clock_id);\n+\tif (ret)\n+\t\treturn ret;\n+\tret = dpll_pin_register(txc->dpll, ref_pin->pin, &ice_dpll_txclk_ops,\n+\t\t\t\tref_pin);\n+\tif (ret)\n+\t\tgoto err_release_ext_eref;\n+\n+\t/*\n+\t * Configure EXT_SYNCE pin (fwnode-backed).\n+\t * The pin may not yet be available; in that case registration\n+\t * will be deferred via the notifier path.\n+\t */\n+\tref_pin++;\n+\tret = ice_dpll_init_fwnode_pin(ref_pin, ice_dpll_fwnode_ext_synce);\n+\tif (ret)\n+\t\tgoto err_unregister_ext_eref;\n+\n+\tif (IS_ERR_OR_NULL(ref_pin->pin)) {\n+\t\tdev_dbg(ice_pf_to_dev(pf),\n+\t\t\t\"Tx-clk SYNCE pin not registered yet\\n\");\n+\t\treturn 0;\n+\t}\n+\n+\tret = dpll_pin_register(txc->dpll, ref_pin->pin, &ice_dpll_txclk_ops,\n+\t\t\t\tref_pin);\n+\tif (ret)\n+\t\tgoto err_deinit_synce;\n+\n+\treturn 0;\n+\n+err_deinit_synce:\n+\tice_dpll_deinit_fwnode_pin(ref_pin);\n+err_unregister_ext_eref:\n+\tdpll_pin_unregister(txc->dpll,\n+\t\t\t pf->dplls.txclks[E825_EXT_EREF_PIN_IDX].pin,\n+\t\t\t &ice_dpll_txclk_ops,\n+\t\t\t &pf->dplls.txclks[E825_EXT_EREF_PIN_IDX]);\n+\n+err_release_ext_eref:\n+\tice_dpll_release_pins(&pf->dplls.txclks[E825_EXT_EREF_PIN_IDX], 1);\n+\n+\treturn ret;\n+}\n+\n /**\n * ice_dpll_init_pins_e825 - init pins and register pins with a dplls\n * @pf: board private structure\n@@ -3574,6 +3764,15 @@ static int ice_dpll_init_pins_e825(struct ice_pf *pf)\n \n \tret = ice_dpll_init_rclk_pin(pf, DPLL_PIN_IDX_UNSPEC,\n \t\t\t\t &ice_dpll_rclk_ops);\n+\n+\tif (ret)\n+\t\tgoto unregister_pins;\n+\n+\tret = ice_dpll_init_txclk_pins(pf, 0);\n+\tif (ret)\n+\t\tice_dpll_deinit_rclk_pin(pf);\n+\n+unregister_pins:\n \tif (ret) {\n \t\t/* Inform DPLL notifier works that DPLL init was finished\n \t\t * unsuccessfully (ICE_DPLL_FLAG not set).\n@@ -3692,7 +3891,7 @@ static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu)\n static void\n ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)\n {\n-\tif (cgu)\n+\tif (cgu || pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)\n \t\tdpll_device_unregister(d->dpll, d->ops, d);\n \tdpll_device_put(d->dpll, &d->tracker);\n }\n@@ -3727,12 +3926,13 @@ ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,\n \t\treturn ret;\n \t}\n \td->pf = pf;\n-\tif (cgu) {\n+\tif (cgu || pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {\n \t\tconst struct dpll_device_ops *ops = &ice_dpll_ops;\n \n \t\tif (type == DPLL_TYPE_PPS && ice_dpll_is_pps_phase_monitor(pf))\n \t\t\tops = &ice_dpll_pom_ops;\n-\t\tice_dpll_update_state(pf, d, true);\n+\t\tif (cgu)\n+\t\t\tice_dpll_update_state(pf, d, true);\n \t\tret = dpll_device_register(d->dpll, type, ops, d);\n \t\tif (ret) {\n \t\t\tdpll_device_put(d->dpll, &d->tracker);\n@@ -4081,6 +4281,36 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)\n \treturn 0;\n }\n \n+/**\n+ * ice_dpll_init_info_txclk_pins_e825c - initializes tx-clk pins information\n+ * @pf: board private structure\n+ *\n+ * Init information for tx-clks pin, cache them in pf->dplls.txclks\n+ *\n+ * Return:\n+ * * 0 - success\n+ */\n+static int ice_dpll_init_info_txclk_pins_e825c(struct ice_pf *pf)\n+{\n+\tstruct ice_dpll_pin *tx_pin;\n+\n+\tfor (int i = 0; i < ICE_DPLL_TXCLK_NUM_MAX; i++) {\n+\t\ttx_pin = &pf->dplls.txclks[i];\n+\t\ttx_pin->prop.type = DPLL_PIN_TYPE_EXT;\n+\t\ttx_pin->prop.capabilities |=\n+\t\t\t\t DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;\n+\t\ttx_pin->pf = pf;\n+\t\tif (i == E825_EXT_EREF_PIN_IDX) {\n+\t\t\ttx_pin->prop.board_label = ice_dpll_ext_eref_pin;\n+\t\t\ttx_pin->tx_ref_src = ICE_REF_CLK_EREF0;\n+\t\t} else if (i == E825_EXT_SYNCE_PIN_IDX) {\n+\t\t\ttx_pin->tx_ref_src = ICE_REF_CLK_SYNCE;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n /**\n * ice_dpll_init_pins_info - init pins info wrapper\n * @pf: board private structure\n@@ -4106,6 +4336,9 @@ ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type)\n \t\t\treturn ice_dpll_init_info_rclk_pin(pf);\n \tcase ICE_DPLL_PIN_TYPE_SOFTWARE:\n \t\treturn ice_dpll_init_info_sw_pins(pf);\n+\n+\tcase ICE_DPLL_PIN_TYPE_TXCLK:\n+\t\treturn ice_dpll_init_info_txclk_pins_e825c(pf);\n \tdefault:\n \t\treturn -EINVAL;\n \t}\n@@ -4139,11 +4372,15 @@ static void ice_dpll_deinit_info(struct ice_pf *pf)\n static int ice_dpll_init_info_e825c(struct ice_pf *pf)\n {\n \tstruct ice_dplls *d = &pf->dplls;\n+\tstruct ice_dpll *dt = &d->txc;\n \tint ret = 0;\n \tint i;\n \n \td->clock_id = ice_generate_clock_id(pf);\n \td->num_inputs = ICE_SYNCE_CLK_NUM;\n+\tdt->dpll_state = DPLL_LOCK_STATUS_LOCKED;\n+\tdt->mode = DPLL_MODE_MANUAL;\n+\tdt->dpll_idx = pf->ptp.port.port_num;\n \n \td->inputs = kzalloc_objs(*d->inputs, d->num_inputs);\n \tif (!d->inputs)\n@@ -4160,6 +4397,11 @@ static int ice_dpll_init_info_e825c(struct ice_pf *pf)\n \tret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);\n \tif (ret)\n \t\tgoto deinit_info;\n+\n+\tret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_TXCLK);\n+\tif (ret)\n+\t\tgoto deinit_info;\n+\n \tdev_dbg(ice_pf_to_dev(pf),\n \t\t\"%s - success, inputs: %u, outputs: %u, rclk-parents: %u\\n\",\n \t\t __func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);\n@@ -4292,6 +4534,9 @@ void ice_dpll_deinit(struct ice_pf *pf)\n \t\tice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);\n \tif (!IS_ERR_OR_NULL(pf->dplls.eec.dpll))\n \t\tice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);\n+\tif (!IS_ERR_OR_NULL(pf->dplls.txc.dpll))\n+\t\tice_dpll_deinit_dpll(pf, &pf->dplls.txc, false);\n+\n \tice_dpll_deinit_info(pf);\n \tmutex_destroy(&pf->dplls.lock);\n }\n@@ -4317,14 +4562,19 @@ static void ice_dpll_init_e825(struct ice_pf *pf)\n \terr = ice_dpll_init_info_e825c(pf);\n \tif (err)\n \t\tgoto err_exit;\n-\terr = ice_dpll_init_pins_e825(pf);\n+\terr = ice_dpll_init_dpll(pf, &pf->dplls.txc, false, DPLL_TYPE_TXC);\n \tif (err)\n \t\tgoto deinit_info;\n+\terr = ice_dpll_init_pins_e825(pf);\n+\tif (err)\n+\t\tgoto deinit_txclk;\n \tset_bit(ICE_FLAG_DPLL, pf->flags);\n \tcomplete_all(&d->dpll_init);\n \n \treturn;\n \n+deinit_txclk:\n+\tice_dpll_deinit_dpll(pf, &pf->dplls.txc, false);\n deinit_info:\n \tice_dpll_deinit_info(pf);\n err_exit:\ndiff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h\nindex ae42cdea0ee1..23f9d4da73c5 100644\n--- a/drivers/net/ethernet/intel/ice/ice_dpll.h\n+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h\n@@ -7,6 +7,7 @@\n #include \"ice.h\"\n \n #define ICE_DPLL_RCLK_NUM_MAX\t4\n+#define ICE_DPLL_TXCLK_NUM_MAX\t2\n \n /**\n * enum ice_dpll_pin_sw - enumerate ice software pin indices:\n@@ -63,6 +64,7 @@ struct ice_dpll_pin {\n \tu8 ref_sync;\n \tbool active;\n \tbool hidden;\n+\tenum ice_e825c_ref_clk tx_ref_src;\n };\n \n /** ice_dpll - store info required for DPLL control\n@@ -111,9 +113,11 @@ struct ice_dpll {\n * @lock: locks access to configuration of a dpll\n * @eec: pointer to EEC dpll dev\n * @pps: pointer to PPS dpll dev\n+ * @txc: pointer to TXC dpll dev\n * @inputs: input pins pointer\n * @outputs: output pins pointer\n * @rclk: recovered pins pointer\n+ * @txclks: TX clock reference pins pointer\n * @num_inputs: number of input pins available on dpll\n * @num_outputs: number of output pins available on dpll\n * @cgu_state_acq_err_num: number of errors returned during periodic work\n@@ -131,11 +135,13 @@ struct ice_dplls {\n \tstruct completion dpll_init;\n \tstruct ice_dpll eec;\n \tstruct ice_dpll pps;\n+\tstruct ice_dpll txc;\n \tstruct ice_dpll_pin *inputs;\n \tstruct ice_dpll_pin *outputs;\n \tstruct ice_dpll_pin sma[ICE_DPLL_PIN_SW_NUM];\n \tstruct ice_dpll_pin ufl[ICE_DPLL_PIN_SW_NUM];\n \tstruct ice_dpll_pin rclk;\n+\tstruct ice_dpll_pin txclks[ICE_DPLL_TXCLK_NUM_MAX];\n \tu8 num_inputs;\n \tu8 num_outputs;\n \tu8 sma_data;\ndiff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h\nindex 9bfd3e79c580..cbc9693179a1 100644\n--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h\n+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h\n@@ -265,6 +265,13 @@ struct ice_cgu_pin_desc {\n \tstruct dpll_pin_frequency *freq_supp;\n };\n \n+enum ice_e825c_ref_clk {\n+\tICE_REF_CLK_ENET,\n+\tICE_REF_CLK_SYNCE,\n+\tICE_REF_CLK_EREF0,\n+\tICE_REF_CLK_MAX,\n+};\n+\n #define E810C_QSFP_C827_0_HANDLE 2\n #define E810C_QSFP_C827_1_HANDLE 3\n \n", "prefixes": [ "v4", "net-next", "5/8" ] }