From patchwork Mon Feb 5 17:28:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 196955 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:168b:b0:106:860b:bbdd with SMTP id ma11csp1031309dyb; Mon, 5 Feb 2024 09:37:54 -0800 (PST) X-Google-Smtp-Source: AGHT+IGPnHGW2LOkuXg62NZ45PvoWR88PhJ+moFQQAF0mhCGvaojcLBp4gpKakPxM8twC3W8QmAL X-Received: by 2002:a17:90a:e392:b0:296:19b1:3d76 with SMTP id b18-20020a17090ae39200b0029619b13d76mr99393pjz.37.1707154674677; Mon, 05 Feb 2024 09:37:54 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707154674; cv=pass; d=google.com; s=arc-20160816; b=NlouKTq6QIv18C4FC4L6gORPdikWpBPUsUoRbsu1YDJCxxpaVLYnTdP5e1qLr+F/J+ A9iTwGzay+YuuxRGtUnDJII95TNtjeCGt5SuQdi8DphbY4oFcswC1nKwE5YBjz6BGcAT QkKk4JF3y6syIh9Ec/VUhvIzMVrZeGsuYmeeFyQqbCl/cmHdMPhwQ7TUlYeeBAuh2htU 3wi3uqlb4A00QShz+b/JIk9nRQonBso4qKuPvedZeSurTSW22G5p2JHWN+XDHFleAFTA Xf4KmG5xK0Xj+wuUsdsEcsE2et8lzhqfpevJJgkxeaI19WwxPOCvrsolYc7vEhSwjhlC AtPA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-disposition:mime-version:list-unsubscribe:list-subscribe :list-id:precedence:message-id:subject:to:from:date; bh=cJnc60gS+J7znT5nLyWKaMmA2nb4MeXbLJozAsUS+Oo=; fh=qdeikBFjwQkndx3IIzZoBohQvqRe7+jG1TLoV/iEK+k=; b=dvI7tpyZxmlUuUf2lAabKbpkZist7AZW6eEjZ3ZISbQRotSaD5z2Z2YzjQrBoT8LNQ etBOtO2vAlpnj0kJ1ZAz2H6RDgZgW++L/7PULC/ptOneNNjp/u29VshIh69FDRONYQr0 KjjxlQ5LNTvqFIbQtuzm68TPVWSR67FIhByDvoG5BWZUEZMRMnQGmr2HBpfKoLU5F+Vr 3A4PBaVc/g8c7MOz1n9bDAB/G2fwVqCl/PcLxiYk7yGz8F4TV/5Hl3Eak3N3DjGXpTRF U2M6FjF5wkDWuuaN3jlU9Vc6+DHeNbLEK0uT4nqudpLJDd4xfT+oHKue/yJNb0kLmIVW SdIw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=makrotopia.org); spf=pass (google.com: domain of linux-kernel+bounces-53103-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-53103-ouuuleilei=gmail.com@vger.kernel.org" X-Forwarded-Encrypted: i=1; AJvYcCV3SvDtyZVr+r2cLDmpYvxgkRhQCDgYJJNSKgb6bXefpaFoFAXYOItUx9y1fHzlhF3e9ZGyzhal43NQPjjj2wgFr7sN6A== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id ha2-20020a17090af3c200b00290da6bae15si4701018pjb.127.2024.02.05.09.37.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 09:37:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-53103-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=makrotopia.org); spf=pass (google.com: domain of linux-kernel+bounces-53103-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-53103-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id D9AFBB24C5E for ; Mon, 5 Feb 2024 17:29:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2DE514503E; Mon, 5 Feb 2024 17:28:45 +0000 (UTC) Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) (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 C3A2344C66; Mon, 5 Feb 2024 17:28:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.142.180.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707154123; cv=none; b=tgpnQJy07VmxnZscr0jp13G761I6M0jVBQhDm8xedOZzWFXEehGWPRYYOmxouF05mcx44e8zFxSpySok9dMjxHGBpepkqNvLe4s1aRkF8kifn29OwBK+bXPLt1DOK6xQzaTcKgmEcX73c/M/dmyN+KqPfBTx8kN4/9NiSny+fL8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707154123; c=relaxed/simple; bh=mlrjZuog6v94ZLezXrGvG5aQ50FyFFhxMe3KiPzrb6E=; h=Date:From:To:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=TkyceT6JVwJt52RUdRen0lujjKb6fwrgIvqg5suOke5gZ+crkiVqGDYRfjIckgVgYV8B42iXmaiMzYDOHsgv3g1HS1wJC9EHZ9egAlkWYnG/Zgotivr2LdzNwkOhCzUxhy1cLNdCM5kaEnIiB/iYFbUuPn25KZifF+KievzHgPg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org; spf=pass smtp.mailfrom=makrotopia.org; arc=none smtp.client-ip=185.142.180.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=makrotopia.org Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96.2) (envelope-from ) id 1rX2lZ-0000ND-05; Mon, 05 Feb 2024 17:28:21 +0000 Date: Mon, 5 Feb 2024 17:28:17 +0000 From: Daniel Golle To: Chunfeng Yun , Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Daniel Golle , Qingfang Deng , SkyLake Huang , Philipp Zabel , linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add new bindings Message-ID: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790081420059782627 X-GMAIL-MSGID: 1790081420059782627 Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in the MediaTek MT7988 SoC which can operate at various interfaces modes: via USXGMII PCS: * USXGMII * 10GBase-R * 5GBase-R via LynxI SGMII PCS: * 2500Base-X * 1000Base-X * Cisco SGMII (MAC side) Signed-off-by: Daniel Golle Reviewed-by: AngeloGioacchino Del Regno --- v2: unify filename and compatible as requested .../phy/mediatek,mt7988-xfi-tphy.yaml | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml diff --git a/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml new file mode 100644 index 0000000000000..e897118dcf7e6 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/mediatek,mt7988-xfi-tphy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek XFI T-PHY + +maintainers: + - Daniel Golle + +description: + The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes + used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in + MediaTek's 10G-capabale MT7988 SoC. + +properties: + compatible: + const: mediatek,mt7988-xfi-tphy + + reg: + maxItems: 1 + + clocks: + items: + - description: XFI PHY clock + - description: XFI register clock + + clock-names: + items: + - const: xfipll + - const: topxtal + + resets: + items: + - description: PEXTP reset + + mediatek,usxgmii-performance-errata: + $ref: /schemas/types.yaml#/definitions/flag + description: + One instance of the T-PHY on MT7988 suffers from a performance + problem in 10GBase-R mode which needs a work-around in the driver. + The work-around is enabled using this flag. + + "#phy-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - "#phy-cells" + +additionalProperties: false + +examples: + - | + #include + soc { + #address-cells = <2>; + #size-cells = <2>; + + phy@11f20000 { + compatible = "mediatek,mt7988-xfi-tphy"; + reg = <0 0x11f20000 0 0x10000>; + clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, + <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>; + clock-names = "xfipll", "topxtal"; + resets = <&watchdog 14>; + mediatek,usxgmii-performance-errata; + #phy-cells = <0>; + }; + }; + +... From patchwork Mon Feb 5 17:29:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 196944 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:168b:b0:106:860b:bbdd with SMTP id ma11csp1027014dyb; Mon, 5 Feb 2024 09:30:52 -0800 (PST) X-Google-Smtp-Source: AGHT+IGIIy0Jz3Rpjk/tJZmtfSceQW3ouU1Stm1LVecbSxqhX1NEK2r517owV/oBAU8LKbfsJmEl X-Received: by 2002:a05:6a21:a583:b0:19c:9df2:216 with SMTP id gd3-20020a056a21a58300b0019c9df20216mr234842pzc.17.1707154252398; Mon, 05 Feb 2024 09:30:52 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707154252; cv=pass; d=google.com; s=arc-20160816; b=f0lQWL2Xx/kh+8mvZoJNalHJfYCA90ZaZQwrjcrwsnDVuYG1DmZpxkS0qvc+rTccUy wefPYVRA8vwy1R0B5vk/NUARGC6uF8o7R6sUOetiAmw/lNHWC2YBV862ah+q6YR5H5aX 2TTcn4+IxFKa8oAOYjOmjHQnMnTrY0v8PW46cErUY8NOKgAqQeyCwAD45ymrosWhzcjN WvcgaObVccDwzuppCA9KSw3tmfB7OTZkcOBX89UJ5ysTUs2l4rvMx+0PAABwTPIaA+O+ yAKbjRl7VS2TCaptsoPCtDPVc7lHSPOEqZSTyWO18H26+bAQgDC3ZCyEKKDQL5ue/3QZ LO6A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:message-id:subject:cc :to:from:date; bh=4bTe1C99wT2LWO2pgHzenk66/YE0Y1TXqITljlgNi1I=; fh=WG/mhqJggrbqOMU8m17wX1J8jXHekxad6RDlq0U5SZQ=; b=A9Y3hCa7lqT7m9wFrIquTuD5nQmlP6Cg5547t/cuL9R7RCRQ9esnpq+G91iBhpbNpf EJS+p6fJX4hV7U8YahrWr3Gc6VePEPCb28mzVF5sdFu3IumLFxVirTfFicjS7YXoYDbj 8n+PzfOjGO6jttutfamtuh40SibKetJ7GFeRBSajsgXvl5aWI0wxMRS0gyWsTpcs4zK8 7ydm3HSAgsoVQCPOjWMmWoxJv0kHZsD3fzRxmxRXo+ZQ0+l9Relt9v9PMOVnUYOdWakt hZMUrQRE1huoDikUwm7z9FPEoNdRjLuTMQAwjHJc7JwAerS/FIjuAxOAwBbNc/V7SeQX 1JMA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=makrotopia.org); spf=pass (google.com: domain of linux-kernel+bounces-53108-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-53108-ouuuleilei=gmail.com@vger.kernel.org" X-Forwarded-Encrypted: i=1; AJvYcCVNciFrPpQi1pxhEuG2KD93A4Tx1+22lAxAZBmpwMUx1sc9tcnQB0UqfqVtKRWIEUDqZdA5f89JtuI1r0qHD4jYK+kRLg== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id g9-20020a636b09000000b005d66232593dsi172930pgc.868.2024.02.05.09.30.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 09:30:52 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-53108-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=makrotopia.org); spf=pass (google.com: domain of linux-kernel+bounces-53108-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-53108-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 2B349281FFD for ; Mon, 5 Feb 2024 17:30:52 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DD788481AE; Mon, 5 Feb 2024 17:29:55 +0000 (UTC) Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) (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 87CCC44C68; Mon, 5 Feb 2024 17:29:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.142.180.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707154191; cv=none; b=OIodUktvbpaZZXCiBXRLPG8f9RlL8d5RfV9fR6EG0H4hyMn6FQJZRkXdDZ8U7Mf2Ng0yfoMs8dYhbbtZu4o/L4/Jrrhpfgcw7TxNKtbS0R0ocE0Sds6QS+pEOB9g3wiAYi2xaTyf0I6wvDW3XsI/Nj12NMGhBSfC9tImcXqEIeA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707154191; c=relaxed/simple; bh=LpMt/C9jTwabPrHQKminLpDQh32Ily5U8qwI0l5o+Ls=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Vw6z2q/FaK79PA57dRYOYRh7pGvrCKAhaSRc1e60G/s3QRt3hGLUO87qEvR7bZz1KfRQF/HvhqTqsfDdOCAo3x3dma/b6/nFF5EQdHYgrf4kUkd1d4jMV1KqBJEf6GlYQON3YS5hiy4EO72aF/GrWfxeJTJ1YOXZ3GlGzwlObps= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org; spf=pass smtp.mailfrom=makrotopia.org; arc=none smtp.client-ip=185.142.180.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=makrotopia.org Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96.2) (envelope-from ) id 1rX2mp-0000Ob-2z; Mon, 05 Feb 2024 17:29:40 +0000 Date: Mon, 5 Feb 2024 17:29:36 +0000 From: Daniel Golle To: Chunfeng Yun , Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Daniel Golle , Qingfang Deng , SkyLake Huang , Philipp Zabel , linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Cc: Bc-bocun Chen , Steven Liu , John Crispin Subject: [PATCH v2 2/2] phy: add driver for MediaTek XFI T-PHY Message-ID: <2972dfd0b9ca48174fbf49b9d162bac1a12b2331.1707153425.git.daniel@makrotopia.org> References: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org> X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790080977724989207 X-GMAIL-MSGID: 1790080977724989207 Add driver for MediaTek's XFI T-PHY which can be found in the MT7988 SoC. The XFI T-PHY is a 10 Gigabit/s Ethernet SerDes PHY with muxes on the internal side to be used with either USXGMII PCS or LynxI PCS, depending on the selected PHY interface mode. The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of PHY_INTERFACE_MODE_* corresponding to the supported modes: * USXGMII \ * 10GBase-R }- USXGMII PCS - XGDM \ * 5GBase-R / \ }- Ethernet MAC * 2500Base-X \ / * 1000Base-X }- LynxI PCS - GDM / * Cisco SGMII (MAC side) / In order to work-around a performance issue present on the first of two XFI T-PHYs present in MT7988, special tuning is applied which can be selected by adding the 'mediatek,usxgmii-performance-errata' property to the device tree node. There is no documentation for most registers used for the analog/tuning part, however, most of the registers have been partially reverse-engineered from MediaTek's SDK implementation (an opaque sequence of 32-bit register writes) and descriptions for all relevant digital registers and bits such as resets and muxes have been supplied by MediaTek. Signed-off-by: Daniel Golle Reviewed-by: AngeloGioacchino Del Regno --- v2: * use IO helpers from mtk-io.h instead of rolling my own * use devm_clk_bulk_get() * yse devm_platform_ioremap_resource() * unify name and description everywhere * invert bool is_xgmii into bool use_lynxi_pcs and add comments describing the meaning of each of the stack variables * not much we can do about remaining magic values unless MTK provides definitions for them MAINTAINERS | 1 + drivers/phy/mediatek/Kconfig | 12 + drivers/phy/mediatek/Makefile | 1 + drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 360 ++++++++++++++++++++++++ 4 files changed, 374 insertions(+) create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c diff --git a/MAINTAINERS b/MAINTAINERS index ff059e870a444..72270296de2bd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13729,6 +13729,7 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/phy/mediatek-ge-soc.c F: drivers/net/phy/mediatek-ge.c +F: drivers/phy/mediatek/phy-mtk-xfi-tphy.c MEDIATEK I2C CONTROLLER DRIVER M: Qii Wang diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig index 3125ecb5d119f..be2abf642f2f3 100644 --- a/drivers/phy/mediatek/Kconfig +++ b/drivers/phy/mediatek/Kconfig @@ -13,6 +13,18 @@ config PHY_MTK_PCIE callback for PCIe GEN3 port, it supports software efuse initialization. +config PHY_MTK_XFI_TPHY + tristate "MediaTek 10GE SerDes XFI T-PHY driver" + depends on ARCH_MEDIATEK || COMPILE_TEST + depends on OF && OF_ADDRESS + depends on HAS_IOMEM + select GENERIC_PHY + help + Say 'Y' here to add support for MediaTek XFI T-PHY driver. + The driver provides access to the Ethernet SerDes T-PHY supporting + 1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes + via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet. + config PHY_MTK_TPHY tristate "MediaTek T-PHY Driver" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile index c9a50395533eb..fa7217178e7f4 100644 --- a/drivers/phy/mediatek/Makefile +++ b/drivers/phy/mediatek/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE) += phy-mtk-pcie.o obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o +obj-$(CONFIG_PHY_MTK_XFI_TPHY) += phy-mtk-xfi-tphy.o phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c new file mode 100644 index 0000000000000..551d6cee33f94 --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* MediaTek 10GE SerDes XFI T-PHY driver + * + * Copyright (c) 2024 Daniel Golle + * Bc-bocun Chen + * based on mtk_usxgmii.c and mtk_sgmii.c found in MediaTek's SDK (GPL-2.0) + * Copyright (c) 2022 MediaTek Inc. + * Author: Henry Yen + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-mtk-io.h" + +#define MTK_XFI_TPHY_NUM_CLOCKS 2 + +#define REG_DIG_GLB_70 0x0070 +#define XTP_PCS_RX_EQ_IN_PROGRESS(x) FIELD_PREP(GENMASK(25, 24), (x)) +#define XTP_PCS_MODE_MASK GENMASK(17, 16) +#define XTP_PCS_MODE(x) FIELD_PREP(GENMASK(17, 16), (x)) +#define XTP_PCS_RST_B BIT(15) +#define XTP_FRC_PCS_RST_B BIT(14) +#define XTP_PCS_PWD_SYNC_MASK GENMASK(13, 12) +#define XTP_PCS_PWD_SYNC(x) FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x)) +#define XTP_PCS_PWD_ASYNC_MASK GENMASK(11, 10) +#define XTP_PCS_PWD_ASYNC(x) FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x)) +#define XTP_FRC_PCS_PWD_ASYNC BIT(8) +#define XTP_PCS_UPDT BIT(4) +#define XTP_PCS_IN_FR_RG BIT(0) + +#define REG_DIG_GLB_F4 0x00f4 +#define XFI_DPHY_PCS_SEL BIT(0) +#define XFI_DPHY_PCS_SEL_SGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 1) +#define XFI_DPHY_PCS_SEL_USXGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 0) +#define XFI_DPHY_AD_SGDT_FRC_EN BIT(5) + +#define REG_DIG_LN_TRX_40 0x3040 +#define XTP_LN_FRC_TX_DATA_EN BIT(29) +#define XTP_LN_TX_DATA_EN BIT(28) + +#define REG_DIG_LN_TRX_B0 0x30b0 +#define XTP_LN_FRC_TX_MACCK_EN BIT(5) +#define XTP_LN_TX_MACCK_EN BIT(4) + +#define REG_ANA_GLB_D0 0x90d0 +#define XTP_GLB_USXGMII_SEL_MASK GENMASK(3, 1) +#define XTP_GLB_USXGMII_SEL(x) FIELD_PREP(GENMASK(3, 1), (x)) +#define XTP_GLB_USXGMII_EN BIT(0) + +struct mtk_xfi_tphy { + void __iomem *base; + struct device *dev; + struct reset_control *reset; + struct clk_bulk_data clocks[MTK_XFI_TPHY_NUM_CLOCKS]; + bool da_war; +}; + +static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy, + phy_interface_t interface) +{ + /* Override 10GBase-R tuning value if work-around is selected */ + bool da_war = (xfi_tphy->da_war && (interface == PHY_INTERFACE_MODE_10GBASER)); + /* Bools to make setting up values for specific PHY speeds easier */ + bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX); + bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX || + interface == PHY_INTERFACE_MODE_SGMII); + bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER || + interface == PHY_INTERFACE_MODE_USXGMII); + bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER); + /* Bool to configure input mux to either + * - USXGMII PCS (64b/66b coding) for 5G/10G + * - LynxI PCS (8b/10b coding) for 1G/2.5G + */ + bool use_lynxi_pcs = (is_1g || is_2p5g); + + dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface)); + + /* Setup PLL setting */ + mtk_phy_update_bits(xfi_tphy->base + 0x9024, 0x100000, is_10g ? 0x0 : 0x100000); + mtk_phy_update_bits(xfi_tphy->base + 0x2020, 0x202000, is_5g ? 0x202000 : 0x0); + mtk_phy_update_bits(xfi_tphy->base + 0x2030, 0x500, is_1g ? 0x0 : 0x500); + mtk_phy_update_bits(xfi_tphy->base + 0x2034, 0xa00, is_1g ? 0x0 : 0xa00); + mtk_phy_update_bits(xfi_tphy->base + 0x2040, 0x340000, is_1g ? 0x200000 : 0x140000); + + /* Setup RXFE BW setting */ + mtk_phy_update_bits(xfi_tphy->base + 0x50f0, 0xc10, is_1g ? 0x410 : is_5g ? 0x800 : 0x400); + mtk_phy_update_bits(xfi_tphy->base + 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000); + + /* Setup RX CDR setting */ + mtk_phy_update_bits(xfi_tphy->base + 0x506c, 0x30000, is_5g ? 0x0 : 0x30000); + mtk_phy_update_bits(xfi_tphy->base + 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000); + mtk_phy_update_bits(xfi_tphy->base + 0x5074, 0x180000, is_5g ? 0x180000 : 0x0); + mtk_phy_update_bits(xfi_tphy->base + 0x5078, 0xf000400, is_5g ? 0x8000000 : + 0x7000400); + mtk_phy_update_bits(xfi_tphy->base + 0x507c, 0x5000500, is_5g ? 0x4000400 : + 0x1000100); + mtk_phy_update_bits(xfi_tphy->base + 0x5080, 0x1410, is_1g ? 0x400 : is_5g ? 0x1010 : 0x0); + mtk_phy_update_bits(xfi_tphy->base + 0x5084, 0x30300, is_1g ? 0x30300 : + is_5g ? 0x30100 : + 0x100); + mtk_phy_update_bits(xfi_tphy->base + 0x5088, 0x60200, is_1g ? 0x20200 : + is_5g ? 0x40000 : + 0x20000); + + /* Setting RXFE adaptation range setting */ + mtk_phy_update_bits(xfi_tphy->base + 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000); + mtk_phy_update_bits(xfi_tphy->base + 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000); + mtk_phy_update_bits(xfi_tphy->base + 0x50ec, 0xa00, is_1g ? 0x200 : 0x800); + mtk_phy_update_bits(xfi_tphy->base + 0x50a8, 0xee0000, is_5g ? 0x800000 : + 0x6e0000); + mtk_phy_update_bits(xfi_tphy->base + 0x6004, 0x190000, is_5g ? 0x0 : 0x190000); + + if (is_10g) + writel(0x01423342, xfi_tphy->base + 0x00f8); + else if (is_5g) + writel(0x00a132a1, xfi_tphy->base + 0x00f8); + else if (is_2p5g) + writel(0x009c329c, xfi_tphy->base + 0x00f8); + else + writel(0x00fa32fa, xfi_tphy->base + 0x00f8); + + /* Force SGDT_OUT off and select PCS */ + mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_F4, + XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL, + XFI_DPHY_AD_SGDT_FRC_EN | + (use_lynxi_pcs ? XFI_DPHY_PCS_SEL_SGMII : + XFI_DPHY_PCS_SEL_USXGMII)); + + /* Force GLB_CKDET_OUT */ + mtk_phy_set_bits(xfi_tphy->base + 0x0030, 0xc00); + + /* Force AEQ on */ + writel(XTP_PCS_RX_EQ_IN_PROGRESS(2) | XTP_PCS_PWD_SYNC(2) | XTP_PCS_PWD_ASYNC(2), + xfi_tphy->base + REG_DIG_GLB_70); + + usleep_range(1, 5); + + /* Setup TX DA default value */ + mtk_phy_update_bits(xfi_tphy->base + 0x30b0, 0x30, 0x20); + writel(0x00008a01, xfi_tphy->base + 0x3028); + writel(0x0000a884, xfi_tphy->base + 0x302c); + writel(0x00083002, xfi_tphy->base + 0x3024); + + /* Setup RG default value */ + if (use_lynxi_pcs) { + writel(0x00011110, xfi_tphy->base + 0x3010); + writel(0x40704000, xfi_tphy->base + 0x3048); + } else { + writel(0x00022220, xfi_tphy->base + 0x3010); + writel(0x0f020a01, xfi_tphy->base + 0x5064); + writel(0x06100600, xfi_tphy->base + 0x50b4); + if (interface == PHY_INTERFACE_MODE_USXGMII) + writel(0x40704000, xfi_tphy->base + 0x3048); + else + writel(0x47684100, xfi_tphy->base + 0x3048); + } + + if (is_1g) + writel(0x0000c000, xfi_tphy->base + 0x3064); + + /* Setup RX EQ initial value */ + mtk_phy_update_bits(xfi_tphy->base + 0x3050, 0xa8000000, + (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xa8000000 : 0x0); + mtk_phy_update_bits(xfi_tphy->base + 0x3054, 0xaa, + (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xaa : 0x0); + + if (!use_lynxi_pcs) + writel(0x00000f00, xfi_tphy->base + 0x306c); + else if (is_2p5g) + writel(0x22000f00, xfi_tphy->base + 0x306c); + else + writel(0x20200f00, xfi_tphy->base + 0x306c); + + mtk_phy_update_bits(xfi_tphy->base + 0xa008, 0x10000, da_war ? 0x10000 : 0x0); + + mtk_phy_update_bits(xfi_tphy->base + 0xa060, 0x50000, use_lynxi_pcs ? 0x50000 : 0x40000); + + /* Setup PHYA speed */ + mtk_phy_update_bits(xfi_tphy->base + REG_ANA_GLB_D0, + XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN, + is_10g ? XTP_GLB_USXGMII_SEL(0) : + is_5g ? XTP_GLB_USXGMII_SEL(1) : + is_2p5g ? XTP_GLB_USXGMII_SEL(2) : + XTP_GLB_USXGMII_SEL(3)); + mtk_phy_set_bits(xfi_tphy->base + REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN); + + /* Release reset */ + mtk_phy_set_bits(xfi_tphy->base + REG_DIG_GLB_70, + XTP_PCS_RST_B | XTP_FRC_PCS_RST_B); + usleep_range(150, 500); + + /* Switch to P0 */ + mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70, + XTP_PCS_IN_FR_RG | + XTP_FRC_PCS_PWD_ASYNC | + XTP_PCS_PWD_ASYNC_MASK | + XTP_PCS_PWD_SYNC_MASK | + XTP_PCS_UPDT, + XTP_PCS_IN_FR_RG | + XTP_FRC_PCS_PWD_ASYNC | + XTP_PCS_UPDT); + usleep_range(1, 5); + + mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT); + usleep_range(15, 50); + + if (use_lynxi_pcs) { + /* Switch to Gen2 */ + mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70, + XTP_PCS_MODE_MASK | XTP_PCS_UPDT, + XTP_PCS_MODE(1) | XTP_PCS_UPDT); + } else { + /* Switch to Gen3 */ + mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70, + XTP_PCS_MODE_MASK | XTP_PCS_UPDT, + XTP_PCS_MODE(2) | XTP_PCS_UPDT); + } + usleep_range(1, 5); + + mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT); + + usleep_range(100, 500); + + /* Enable MAC CK */ + mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN); + mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN); + + /* Enable TX data */ + mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_40, + XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN); + usleep_range(400, 1000); +} + +static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int + submode) +{ + struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy); + + if (mode != PHY_MODE_ETHERNET) + return -EINVAL; + + switch (submode) { + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_5GBASER: + case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_USXGMII: + mtk_xfi_tphy_setup(xfi_tphy, submode); + return 0; + default: + return -EINVAL; + } +} + +static int mtk_xfi_tphy_reset(struct phy *phy) +{ + struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy); + + reset_control_assert(xfi_tphy->reset); + usleep_range(100, 500); + reset_control_deassert(xfi_tphy->reset); + usleep_range(1, 10); + + return 0; +} + +static int mtk_xfi_tphy_power_on(struct phy *phy) +{ + struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy); + + return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks); +} + +static int mtk_xfi_tphy_power_off(struct phy *phy) +{ + struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy); + + clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks); + + return 0; +} + +static const struct phy_ops mtk_xfi_tphy_ops = { + .power_on = mtk_xfi_tphy_power_on, + .power_off = mtk_xfi_tphy_power_off, + .set_mode = mtk_xfi_tphy_set_mode, + .reset = mtk_xfi_tphy_reset, + .owner = THIS_MODULE, +}; + +static int mtk_xfi_tphy_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct phy_provider *phy_provider; + struct mtk_xfi_tphy *xfi_tphy; + struct phy *phy; + int ret; + + if (!np) + return -ENODEV; + + xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL); + if (!xfi_tphy) + return -ENOMEM; + + xfi_tphy->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(xfi_tphy->base)) + return PTR_ERR(xfi_tphy->base); + + xfi_tphy->dev = &pdev->dev; + xfi_tphy->clocks[0].id = "topxtal"; + xfi_tphy->clocks[1].id = "xfipll"; + ret = devm_clk_bulk_get(&pdev->dev, MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks); + if (ret) + return ret; + + xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(xfi_tphy->reset)) + return PTR_ERR(xfi_tphy->reset); + + xfi_tphy->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata"); + + phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + phy_set_drvdata(phy, xfi_tphy); + phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id mtk_xfi_tphy_match[] = { + { .compatible = "mediatek,mt7988-xfi-tphy", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match); + +static struct platform_driver mtk_xfi_tphy_driver = { + .probe = mtk_xfi_tphy_probe, + .driver = { + .name = "mtk-xfi-tphy", + .of_match_table = mtk_xfi_tphy_match, + }, +}; +module_platform_driver(mtk_xfi_tphy_driver); + +MODULE_DESCRIPTION("MediaTek 10GE SerDes XFI T-PHY driver"); +MODULE_AUTHOR("Daniel Golle "); +MODULE_AUTHOR("Bc-bocun Chen "); +MODULE_LICENSE("GPL");