From patchwork Fri Nov 1 10:32:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lei Wei X-Patchwork-Id: 13859170 X-Patchwork-Delegate: kuba@kernel.org Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 943F319340F; Fri, 1 Nov 2024 10:35:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457318; cv=none; b=nvp2se3E9mGJyVyEYiNq9DrqYMQSPiu/t+bVNm0nk9WvPeEe4ZWJFsKkPb+wXtr6FKI0SXZ/1/A/EbiZxED12z9SuamLoF81QQqCMbRAy69nNg6XJ2cvcMC973ZE9jTONeFJFj2QQSj2JJQVspNS86R8lDspDUrV7SqnspkWqF0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457318; c=relaxed/simple; bh=ez6Oz15e7tFtEnPxUJUUBU8yvslLppWCnlwtyGMKK9g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=NyZsJT3KalkCp+zbGOHsR2hYQbyWiHXySv1w7qccGxyCR4lWxAj45VYA8rk/vT7o82vezgoB5GlTqHJVx1JMbtULZRZkiWen/o44QqxKBIqSCEDzun8Q/6NmGqFZUO14jp0Sw4lLwtHnvtjqS+CH6vJst7ByLfMIQVQ+nE1QY08= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=ilR6ykCQ; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="ilR6ykCQ" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4A15H3pL004044; Fri, 1 Nov 2024 10:34:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= U7OwHXkhaFAS6wHJUJWydfCSFr/5ZuJeSDfsL+eq3j8=; b=ilR6ykCQfItdqz+Q 0viRMlPHKHES0UJo51Qt08iNFJK7cqQKQkfJaEznPC+kGIP8xaVXLWq1VdK/TK/H WjEoUDBwbxSeIVgU2alZO3eX1zvTQ6JAgdBmX1WHj2FkEI3wl2A/znRTQcKu+phE rf2VaGznG+zSSRLdk4R/AUtdI3Q5H/0TAdv1OzyiIJtUQ9YZ7x9DMEYESwAG2Zfp 5m3TjZK8bR4a1zuC2rZmhDxjNeQvsMoC/8HNe1KrwJLp+NnebFjdw232hvcnMBD3 4h/a1fmT5UNF4yJsW4HqVfYhzTMYPUUJfXkEytbK0IjWIAx98PPFgfnpjQQVjpbH 2vkTbw== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 42kns3pp8v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 01 Nov 2024 10:34:49 +0000 (GMT) Received: from nasanex01a.na.qualcomm.com (nasanex01a.na.qualcomm.com [10.52.223.231]) by NASANPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 4A1AYm8T022328 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 1 Nov 2024 10:34:48 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01a.na.qualcomm.com (10.52.223.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Fri, 1 Nov 2024 03:34:43 -0700 From: Lei Wei Date: Fri, 1 Nov 2024 18:32:49 +0800 Subject: [PATCH net-next 1/5] dt-bindings: net: pcs: Add Ethernet PCS for Qualcomm IPQ9574 SoC Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20241101-ipq_pcs_rc1-v1-1-fdef575620cf@quicinc.com> References: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> In-Reply-To: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andrew Lunn , Heiner Kallweit , Russell King CC: , , , , , , , , , , , , X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1730457277; l=9926; i=quic_leiwei@quicinc.com; s=20240829; h=from:subject:message-id; bh=ez6Oz15e7tFtEnPxUJUUBU8yvslLppWCnlwtyGMKK9g=; b=aYmGYaeDinTCGwb554ZAlrnuvyJioK8lqorBpYiz4RD9jNVxuYMXQY75voC9q0lVpQO52GvjA kkv6Bg3kpCTBG+twmzJCBqYuSr8D2Eaa9wYWgbcSmh6jUdBm2YH5fmi X-Developer-Key: i=quic_leiwei@quicinc.com; a=ed25519; pk=uFXBHtxtDjtIrTKpDEZlMLSn1i/sonZepYO8yioKACM= X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01a.na.qualcomm.com (10.52.223.231) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: YhtbEzaJUn-nt__9weaCOPKCU1zNqrWF X-Proofpoint-ORIG-GUID: YhtbEzaJUn-nt__9weaCOPKCU1zNqrWF X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 suspectscore=0 adultscore=0 spamscore=0 phishscore=0 mlxlogscore=999 malwarescore=0 bulkscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2411010076 X-Patchwork-Delegate: kuba@kernel.org The 'UNIPHY' PCS block in the IPQ9574 SoC includes PCS and SerDes functions. It supports different interface modes to enable Ethernet MAC connections to different types of external PHYs/switch. It includes PCS functions for 1Gbps and 2.5Gbps interface modes and XPCS functions for 10Gbps interface modes. There are three UNIPHY (PCS) instances in IPQ9574 SoC which provide PCS/XPCS functions to the six Ethernet ports. Signed-off-by: Lei Wei --- .../bindings/net/pcs/qcom,ipq9574-pcs.yaml | 230 +++++++++++++++++++++ include/dt-bindings/net/pcs-qcom-ipq.h | 15 ++ 2 files changed, 245 insertions(+) diff --git a/Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml b/Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml new file mode 100644 index 000000000000..a33873c7ad73 --- /dev/null +++ b/Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml @@ -0,0 +1,230 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/pcs/qcom,ipq9574-pcs.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ethernet PCS for Qualcomm IPQ SoC + +maintainers: + - Lei Wei + +description: + The UNIPHY hardware blocks in the Qualcomm IPQ SoC include PCS and SerDes + functions. They enable connectivity between the Ethernet MAC inside the + PPE (packet processing engine) and external Ethernet PHY/switch. There are + three UNIPHY instances in IPQ9574 SoC which provide PCS functions to the + six Ethernet ports. + + For SGMII (1Gbps PHY) or 2500BASE-X (2.5Gbps PHY) interface modes, the PCS + function is enabled by using the PCS block inside UNIPHY. For USXGMII (10Gbps + PHY), the XPCS block in UNIPHY is used. + + The SerDes provides 125M (1Gbps mode) or 312.5M (2.5Gbps and 10Gbps modes) + RX and TX clocks to the NSSCC (Networking Sub System Clock Controller). The + NSSCC divides these clocks and generates the MII RX and TX clocks to each + of the MII interfaces between the PCS and MAC, as per the link speeds and + interface modes. + + Different IPQ SoC may support different number of UNIPHYs (PCSes) since the + number of ports and their capabilities can be different between these SoCs + + Below diagram depicts the UNIPHY (PCS) connections for an IPQ9574 SoC based + board. In this example, the first PCS0 has four GMIIs/XGMIIs, which can connect + with four MACs to support QSGMII (4 x 1Gbps) or 10G_QXGMII (4 x 2.5Gbps) + interface modes. + + - +-------+ +---------+ +-------------------------+ + +---------+CMN PLL| | GCC | | NSSCC (Divider) | + | +----+--+ +----+----+ +--+-------+--------------+ + | | | ^ | + | 31.25M | SYS/AHB|clk RX/TX|clk +------------+ + | ref clk| | | | | + | | v | MII RX|TX clk MAC| RX/TX clk + |25/50M +--+---------+----------+-------+---+ +-+---------+ + |ref clk | | +----------------+ | | | | PPE | + v | | | UNIPHY0 V | | V | + +-------+ | v | +-----------+ (X)GMII| | | + | | | +---+---+ | |--------|------|-- MAC0 | + | | | | | | | (X)GMII| | | + | Quad | | |SerDes | | PCS/XPCS |--------|------|-- MAC1 | + | +<----+ | | | | (X)GMII| | | + |(X)GPHY| | | | | |--------|------|-- MAC2 | + | | | | | | | (X)GMII| | | + | | | +-------+ | |--------|------|-- MAC3 | + +-------+ | | | | | | + | +-----------+ | | | + +-----------------------------------+ | | + +--+---------+----------+-------+---+ | | + +-------+ | UNIPHY1 | | | + | | | +-----------+ | | | + |(X)GPHY| | +-------+ | | (X)GMII| | | + | +<----+ |SerDes | | PCS/XPCS |--------|------|- MAC4 | + | | | | | | | | | | + +-------+ | +-------+ | | | | | + | +-----------+ | | | + +-----------------------------------+ | | + +--+---------+----------+-------+---+ | | + +-------+ | UNIPHY2 | | | + | | | +-----------+ | | | + |(X)GPHY| | +-------+ | | (X)GMII| | | + | +<----+ |SerDes | | PCS/XPCS |--------|------|- MAC5 | + | | | | | | | | | | + +-------+ | +-------+ | | | | | + | +-----------+ | | | + +-----------------------------------+ +-----------+ + +properties: + compatible: + enum: + - qcom,ipq9574-pcs + + reg: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + clocks: + items: + - description: system clock + - description: AHB clock needed for register interface access + + clock-names: + items: + - const: sys + - const: ahb + + '#clock-cells': + const: 1 + description: See include/dt-bindings/net/pcs-qcom-ipq.h for constants + +patternProperties: + "^pcs-mii@[0-4]$": + type: object + description: PCS MII interface. + + properties: + reg: + minimum: 0 + maximum: 4 + description: MII index + + clocks: + items: + - description: PCS MII RX clock + - description: PCS MII TX clock + + clock-names: + items: + - const: mii_rx + - const: mii_tx + + required: + - reg + - clocks + - clock-names + + additionalProperties: false + +required: + - compatible + - reg + - '#address-cells' + - '#size-cells' + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | + #include + + pcs0: ethernet-pcs@7a00000 { + compatible = "qcom,ipq9574-pcs"; + reg = <0x7a00000 0x10000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcc GCC_UNIPHY0_SYS_CLK>, + <&gcc GCC_UNIPHY0_AHB_CLK>; + clock-names = "sys", + "ahb"; + #clock-cells = <1>; + + pcs0_mii0: pcs-mii@0 { + reg = <0>; + clocks = <&nsscc 116>, + <&nsscc 117>; + clock-names = "mii_rx", + "mii_tx"; + }; + + pcs0_mii1: pcs-mii@1 { + reg = <1>; + clocks = <&nsscc 118>, + <&nsscc 119>; + clock-names = "mii_rx", + "mii_tx"; + }; + + pcs0_mii2: pcs-mii@2 { + reg = <2>; + clocks = <&nsscc 120>, + <&nsscc 121>; + clock-names = "mii_rx", + "mii_tx"; + }; + + pcs0_mii3: pcs-mii@3 { + reg = <3>; + clocks = <&nsscc 122>, + <&nsscc 123>; + clock-names = "mii_rx", + "mii_tx"; + }; + }; + + pcs1: ethernet-pcs@7a10000 { + compatible = "qcom,ipq9574-pcs"; + reg = <0x7a10000 0x10000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcc GCC_UNIPHY1_SYS_CLK>, + <&gcc GCC_UNIPHY1_AHB_CLK>; + clock-names = "sys", + "ahb"; + #clock-cells = <1>; + + pcs1_mii0: pcs-mii@0 { + reg = <0>; + clocks = <&nsscc 124>, + <&nsscc 125>; + clock-names = "mii_rx", + "mii_tx"; + }; + }; + + pcs2: ethernet-pcs@7a20000 { + compatible = "qcom,ipq9574-pcs"; + reg = <0x7a20000 0x10000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcc GCC_UNIPHY2_SYS_CLK>, + <&gcc GCC_UNIPHY2_AHB_CLK>; + clock-names = "sys", + "ahb"; + #clock-cells = <1>; + + pcs2_mii0: pcs-mii@0 { + reg = <0>; + clocks = <&nsscc 126>, + <&nsscc 127>; + clock-names = "mii_rx", + "mii_tx"; + }; + }; diff --git a/include/dt-bindings/net/pcs-qcom-ipq.h b/include/dt-bindings/net/pcs-qcom-ipq.h new file mode 100644 index 000000000000..8d9124ffd75d --- /dev/null +++ b/include/dt-bindings/net/pcs-qcom-ipq.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Device Tree constants for the Qualcomm IPQ PCS + */ + +#ifndef _DT_BINDINGS_PCS_QCOM_IPQ_H +#define _DT_BINDINGS_PCS_QCOM_IPQ_H + +/* The RX and TX clocks which are provided from the SerDes to NSSCC. */ +#define PCS_RX_CLK 0 +#define PCS_TX_CLK 1 + +#endif /* _DT_BINDINGS_PCS_QCOM_IPQ_H */ From patchwork Fri Nov 1 10:32:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lei Wei X-Patchwork-Id: 13859172 X-Patchwork-Delegate: kuba@kernel.org Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 741A4198A1B; Fri, 1 Nov 2024 10:35:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457319; cv=none; b=pSChrWpQtwntDoGsarzJ5RFAcAIjizOV/DRPP9l0pX5nfZxfghx5M/avDMYHJ27afCV3Dm01cYDOoSlXKmSXIPxS1T7qXikaYPJUEW0I/El/kOR6fVwreKirmqMAGVITnWqXiKdrsOTGR/RYvH1mLds02rh2LbWaFEN6JPZIrdc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457319; c=relaxed/simple; bh=PolE0UNqyAne3Dg4F8+n/5QUpLvNiQjGKwrF8SRbKxw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=Dy54gs3BuXOVjh12O5N/M+S9MD1FApV5BZoWDnn6+wM3SiVIvgTWQGia+unf51+9O4RZf5/k0Q1ny8N4AIHgjoKiyB6Ft+kZxJAwef+UvdMlyevcLxUGFpWdubdJwmR9QM7F4Y+LKZdo4X8M7gCcamZ/5hAKFRt6v+YkjE/rWJI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=pPvN0pES; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="pPvN0pES" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4A13wNhh002463; Fri, 1 Nov 2024 10:35:02 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 4NCjRcPHKsYgrv+5+SeIpj1+zNFY/YM6QzlS3mQ0YSA=; b=pPvN0pES/Y5J0MrX RFKU+ZvRq8S/tEPIoYj/4AkBAplGgGpOiCsSJyY2g5Deyyuh8pBUkdLmgA4N9Pdi zBJ9jPnxIGumlkhsm0LUtpoz9OzjhOp7kZL7ltUd7m24abbJ7esIjn8QBBqCNshI a0KnITaXvxVSgLIA07LE6kE5oSxRv19CzsU+mrpjivl0DZv3DPizgwsH1gSxc4U0 j2LXaQJPtvW7/Fg+758wjF5e1aNkrIhy/hNoez5iLbEz2ypyeuIx14stZJsWGZ7f 72iVwYo6gkD7kq7ba5ay8e/1Kb6TAyGax5NH0altswXTbbkpPf9c7lBTwOfrPHYV rssJ6A== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 42kmn5esbv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 01 Nov 2024 10:35:02 +0000 (GMT) Received: from nasanex01a.na.qualcomm.com (nasanex01a.na.qualcomm.com [10.52.223.231]) by NASANPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 4A1AYsAg005054 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 1 Nov 2024 10:34:54 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01a.na.qualcomm.com (10.52.223.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Fri, 1 Nov 2024 03:34:48 -0700 From: Lei Wei Date: Fri, 1 Nov 2024 18:32:50 +0800 Subject: [PATCH net-next 2/5] net: pcs: Add PCS driver for Qualcomm IPQ9574 SoC Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20241101-ipq_pcs_rc1-v1-2-fdef575620cf@quicinc.com> References: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> In-Reply-To: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andrew Lunn , Heiner Kallweit , Russell King CC: , , , , , , , , , , , , X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1730457277; l=9080; i=quic_leiwei@quicinc.com; s=20240829; h=from:subject:message-id; bh=PolE0UNqyAne3Dg4F8+n/5QUpLvNiQjGKwrF8SRbKxw=; b=6JfbSiZbrVVcQMeYOrG0cpx3f6uxRRwCqPDZBCSZIjflwskfWLS7UoSrn/vphDBbgK4V1xO6h 9zheuFUikKiASWgRE5myz3OJbHYGCkkmUe127nSrMyTVqMmKM2V3K8B X-Developer-Key: i=quic_leiwei@quicinc.com; a=ed25519; pk=uFXBHtxtDjtIrTKpDEZlMLSn1i/sonZepYO8yioKACM= X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01a.na.qualcomm.com (10.52.223.231) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: 51mb5ebkwCQKuHJZskoIp6yQbjf98Qob X-Proofpoint-GUID: 51mb5ebkwCQKuHJZskoIp6yQbjf98Qob X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 spamscore=0 lowpriorityscore=0 impostorscore=0 phishscore=0 mlxlogscore=999 priorityscore=1501 mlxscore=0 malwarescore=0 bulkscore=0 suspectscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2411010076 X-Patchwork-Delegate: kuba@kernel.org The 'UNIPHY' PCS hardware block in Qualcomm's IPQ SoC supports different interface modes to enable Ethernet MAC connections for different types of external PHYs/switch. Each UNIPHY block includes a SerDes and PCS/XPCS blocks, and can operate in either PCS or XPCS modes. It supports 1Gbps and 2.5Gbps interface modes (Ex: SGMII) using the PCS, and 10Gbps interface modes (Ex: USXGMII) using the XPCS. There are three UNIPHY (PCS) instances in IPQ9574 SoC which support the six Ethernet ports in the SoC. This patch adds support for the platform driver, probe and clock registrations for the PCS driver. The platform driver creates an 'ipq_pcs' instance for each of the UNIPHY used on the given board. Signed-off-by: Lei Wei --- drivers/net/pcs/Kconfig | 9 ++ drivers/net/pcs/Makefile | 1 + drivers/net/pcs/pcs-qcom-ipq.c | 244 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+) diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig index f6aa437473de..1053326958ee 100644 --- a/drivers/net/pcs/Kconfig +++ b/drivers/net/pcs/Kconfig @@ -25,6 +25,15 @@ config PCS_MTK_LYNXI This module provides helpers to phylink for managing the LynxI PCS which is part of MediaTek's SoC and Ethernet switch ICs. +config PCS_QCOM_IPQ + tristate "Qualcomm IPQ PCS" + depends on OF && (ARCH_QCOM || COMPILE_TEST) + depends on HAS_IOMEM + help + This module provides driver for UNIPHY PCS available on Qualcomm IPQ + SoC such as IPQ9574. The UNIPHY PCS supports both PCS and XPCS functions + to support different interface modes for MAC to PHY connections. + config PCS_RZN1_MIIC tristate "Renesas RZ/N1 MII converter" depends on OF && (ARCH_RZN1 || COMPILE_TEST) diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile index 4f7920618b90..399750c7c293 100644 --- a/drivers/net/pcs/Makefile +++ b/drivers/net/pcs/Makefile @@ -7,4 +7,5 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \ obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o +obj-$(CONFIG_PCS_QCOM_IPQ) += pcs-qcom-ipq.o obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o diff --git a/drivers/net/pcs/pcs-qcom-ipq.c b/drivers/net/pcs/pcs-qcom-ipq.c new file mode 100644 index 000000000000..e065bc61cd14 --- /dev/null +++ b/drivers/net/pcs/pcs-qcom-ipq.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define XPCS_INDIRECT_ADDR 0x8000 +#define XPCS_INDIRECT_AHB_ADDR 0x83fc +#define XPCS_INDIRECT_ADDR_H GENMASK(20, 8) +#define XPCS_INDIRECT_ADDR_L GENMASK(7, 0) +#define XPCS_INDIRECT_DATA_ADDR(reg) (FIELD_PREP(GENMASK(15, 10), 0x20) | \ + FIELD_PREP(GENMASK(9, 2), \ + FIELD_GET(XPCS_INDIRECT_ADDR_L, reg))) + +/* Private data for the PCS instance */ +struct ipq_pcs { + struct device *dev; + void __iomem *base; + struct regmap *regmap; + phy_interface_t interface; + + /* RX clock supplied to NSSCC */ + struct clk_hw rx_hw; + /* TX clock supplied to NSSCC */ + struct clk_hw tx_hw; +}; + +static unsigned long ipq_pcs_clk_rate_get(struct ipq_pcs *qpcs) +{ + switch (qpcs->interface) { + case PHY_INTERFACE_MODE_USXGMII: + return 312500000; + default: + return 125000000; + } +} + +/* Return clock rate for the RX clock supplied to NSSCC + * as per the interface mode. + */ +static unsigned long ipq_pcs_rx_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ipq_pcs *qpcs = container_of(hw, struct ipq_pcs, rx_hw); + + return ipq_pcs_clk_rate_get(qpcs); +} + +/* Return clock rate for the TX clock supplied to NSSCC + * as per the interface mode. + */ +static unsigned long ipq_pcs_tx_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ipq_pcs *qpcs = container_of(hw, struct ipq_pcs, tx_hw); + + return ipq_pcs_clk_rate_get(qpcs); +} + +static int ipq_pcs_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + switch (req->rate) { + case 125000000: + case 312500000: + return 0; + default: + return -EINVAL; + } +} + +/* Clock ops for the RX clock supplied to NSSCC */ +static const struct clk_ops qpcs_rx_clk_ops = { + .determine_rate = ipq_pcs_clk_determine_rate, + .recalc_rate = ipq_pcs_rx_clk_recalc_rate, +}; + +/* Clock ops for the TX clock supplied to NSSCC */ +static const struct clk_ops qpcs_tx_clk_ops = { + .determine_rate = ipq_pcs_clk_determine_rate, + .recalc_rate = ipq_pcs_tx_clk_recalc_rate, +}; + +static struct clk_hw *ipq_pcs_clk_hw_get(struct of_phandle_args *clkspec, + void *data) +{ + struct ipq_pcs *qpcs = data; + + switch (clkspec->args[0]) { + case PCS_RX_CLK: + return &qpcs->rx_hw; + case PCS_TX_CLK: + return &qpcs->tx_hw; + } + + return ERR_PTR(-EINVAL); +} + +/* Register the RX and TX clock which are output from SerDes to + * the NSSCC. The NSSCC driver assigns the RX and TX clock as + * parent, divides them to generate the MII RX and TX clock to + * each MII interface of the PCS as per the link speeds and + * interface modes. + */ +static int ipq_pcs_clk_register(struct ipq_pcs *qpcs) +{ + struct clk_init_data init = { }; + int ret; + + init.ops = &qpcs_rx_clk_ops; + init.name = devm_kasprintf(qpcs->dev, GFP_KERNEL, "%s::rx_clk", + dev_name(qpcs->dev)); + if (!init.name) + return -ENOMEM; + + qpcs->rx_hw.init = &init; + ret = devm_clk_hw_register(qpcs->dev, &qpcs->rx_hw); + if (ret) + return ret; + + init.ops = &qpcs_tx_clk_ops; + init.name = devm_kasprintf(qpcs->dev, GFP_KERNEL, "%s::tx_clk", + dev_name(qpcs->dev)); + if (!init.name) + return -ENOMEM; + + qpcs->tx_hw.init = &init; + ret = devm_clk_hw_register(qpcs->dev, &qpcs->tx_hw); + if (ret) + return ret; + + return devm_of_clk_add_hw_provider(qpcs->dev, ipq_pcs_clk_hw_get, qpcs); +} + +static int ipq_pcs_regmap_read(void *context, unsigned int reg, + unsigned int *val) +{ + struct ipq_pcs *qpcs = context; + + /* PCS uses direct AHB access while XPCS uses indirect AHB access */ + if (reg >= XPCS_INDIRECT_ADDR) { + writel(FIELD_GET(XPCS_INDIRECT_ADDR_H, reg), + qpcs->base + XPCS_INDIRECT_AHB_ADDR); + *val = readl(qpcs->base + XPCS_INDIRECT_DATA_ADDR(reg)); + } else { + *val = readl(qpcs->base + reg); + } + + return 0; +} + +static int ipq_pcs_regmap_write(void *context, unsigned int reg, + unsigned int val) +{ + struct ipq_pcs *qpcs = context; + + /* PCS uses direct AHB access while XPCS uses indirect AHB access */ + if (reg >= XPCS_INDIRECT_ADDR) { + writel(FIELD_GET(XPCS_INDIRECT_ADDR_H, reg), + qpcs->base + XPCS_INDIRECT_AHB_ADDR); + writel(val, qpcs->base + XPCS_INDIRECT_DATA_ADDR(reg)); + } else { + writel(val, qpcs->base + reg); + } + + return 0; +} + +static const struct regmap_config ipq_pcs_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_read = ipq_pcs_regmap_read, + .reg_write = ipq_pcs_regmap_write, + .fast_io = true, +}; + +static int ipq_pcs_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ipq_pcs *qpcs; + struct clk *clk; + int ret; + + qpcs = devm_kzalloc(dev, sizeof(*qpcs), GFP_KERNEL); + if (!qpcs) + return -ENOMEM; + + qpcs->dev = dev; + + qpcs->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(qpcs->base)) + return dev_err_probe(dev, PTR_ERR(qpcs->base), + "Failed to ioremap resource\n"); + + qpcs->regmap = devm_regmap_init(dev, NULL, qpcs, &ipq_pcs_regmap_cfg); + if (IS_ERR(qpcs->regmap)) + return dev_err_probe(dev, PTR_ERR(qpcs->regmap), + "Failed to allocate register map\n"); + + clk = devm_clk_get_enabled(dev, "sys"); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), + "Failed to enable SYS clock\n"); + + clk = devm_clk_get_enabled(dev, "ahb"); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), + "Failed to enable AHB clock\n"); + + ret = ipq_pcs_clk_register(qpcs); + if (ret) + return ret; + + platform_set_drvdata(pdev, qpcs); + + return 0; +} + +static const struct of_device_id ipq_pcs_of_mtable[] = { + { .compatible = "qcom,ipq9574-pcs" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ipq_pcs_of_mtable); + +static struct platform_driver ipq_pcs_driver = { + .driver = { + .name = "ipq_pcs", + .of_match_table = ipq_pcs_of_mtable, + }, + .probe = ipq_pcs_probe, +}; +module_platform_driver(ipq_pcs_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm IPQ PCS driver"); +MODULE_AUTHOR("Lei Wei "); From patchwork Fri Nov 1 10:32:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lei Wei X-Patchwork-Id: 13859171 X-Patchwork-Delegate: kuba@kernel.org Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 5CA8A18FC7F; Fri, 1 Nov 2024 10:35:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457318; cv=none; b=QaDx+AtC8lS9j+1wYTvr4KLhlQlXqPJzOhVFZ8APu7KQVObT7MumLfeeB06dEFxjaOvs+QShSjXnCCUtdecS6lyWekn6s2H4VFXANj6S1vny5OXIjWRLNdcgGYUgAFaCPXdbK+/+1f4Mexb9ElT/+wwamaXgAg8PafI8K4VMXjI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457318; c=relaxed/simple; bh=bebEFil+SSN5X457CqYRRNV8UXgv/s7PAdEWyzCe1Is=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=q1nbfFbBnp7GfWIgK25PztyIzS8VlkCsgWNsZz39Ke1PkBhLkkgTzbyNYr5i3I6ieQ4pYwv2j3dcPiM+G+brj5Uny7Io9y8Zm3FfDGScj9lL4JN0gxVFuMNA52W4p6NBxy0y0wpxkoTPNPlG/hfaoJ65BCch7J7RcYOJPuoyWJg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=K6Q434Zv; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="K6Q434Zv" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4A19qCdQ006410; Fri, 1 Nov 2024 10:35:02 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= Wu+efcj0Oo6l2pkStofY5kptl2ZkwZAabmJBbkdLYIE=; b=K6Q434Zv/fN1cKIR TW4nfcZMtwOqq2hFN6/aHtsU1d9ZG2ubKx/DsMEQxJ9H85L0eLqmjRl7Zyl8Oc2H 4z8kwCUmJQ7kHXa5ufXcQ0QpiOvITjx63JnIGeopGJqTHfrnrIYDnhx6pcK+yD9q DeMPXPGrJpluSQhAq+6CJeN5p7rz0qHD6sMAUmoiA5WJbKNIKby4donAALT30W8I gejRZOs1d1JYGWmHydRwQws+IuGa7h96Uk6dgXBDwmgocpzcjd3MhUa9vHM+mRej 5E3a/fXc3x3hZjvlSHF2GSWJ4BTydp1+8a+rOSMNGGm0V4D6LV0NL0Ff73PrdPF7 BeVF7A== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 42ku65dnm4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 01 Nov 2024 10:35:01 +0000 (GMT) Received: from nasanex01a.na.qualcomm.com (nasanex01a.na.qualcomm.com [10.52.223.231]) by NASANPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 4A1AZ016023524 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 1 Nov 2024 10:35:00 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01a.na.qualcomm.com (10.52.223.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Fri, 1 Nov 2024 03:34:53 -0700 From: Lei Wei Date: Fri, 1 Nov 2024 18:32:51 +0800 Subject: [PATCH net-next 3/5] net: pcs: qcom-ipq: Add PCS create and phylink operations for IPQ9574 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20241101-ipq_pcs_rc1-v1-3-fdef575620cf@quicinc.com> References: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> In-Reply-To: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andrew Lunn , Heiner Kallweit , Russell King CC: , , , , , , , , , , , , X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1730457277; l=14076; i=quic_leiwei@quicinc.com; s=20240829; h=from:subject:message-id; bh=bebEFil+SSN5X457CqYRRNV8UXgv/s7PAdEWyzCe1Is=; b=1ag6jWFW8v9efEggUVKXpRkMoOajDATO6EF5HXYDlFfRTcon79UOVT+8dWQWraQBaIaLXXq+/ QG1/zVQJo+xDFFn3E7xOfu9WIWx+IdMLAtzSh6adk7eU8fsJKxR49Dc X-Developer-Key: i=quic_leiwei@quicinc.com; a=ed25519; pk=uFXBHtxtDjtIrTKpDEZlMLSn1i/sonZepYO8yioKACM= X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01a.na.qualcomm.com (10.52.223.231) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: Yk-gTq8CMTJE2ZZvAWuCntUEfc6vBZJO X-Proofpoint-ORIG-GUID: Yk-gTq8CMTJE2ZZvAWuCntUEfc6vBZJO X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 suspectscore=0 bulkscore=0 lowpriorityscore=0 mlxscore=0 priorityscore=1501 impostorscore=0 phishscore=0 clxscore=1015 malwarescore=0 spamscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2411010076 X-Patchwork-Delegate: kuba@kernel.org This patch adds the following PCS functionality for the PCS driver for IPQ9574 SoC: a.) PCS instance create and destroy APIs. The network driver calls the PCS create API to create and associate the PCS instance with the port MAC. The PCS MII RX and TX clocks are also enabled in the PCS create API. b.) PCS phylink operations for SGMII/QSGMII interface modes. Signed-off-by: Lei Wei --- drivers/net/pcs/pcs-qcom-ipq.c | 455 +++++++++++++++++++++++++++++++++++++++ include/linux/pcs/pcs-qcom-ipq.h | 16 ++ 2 files changed, 471 insertions(+) diff --git a/drivers/net/pcs/pcs-qcom-ipq.c b/drivers/net/pcs/pcs-qcom-ipq.c index e065bc61cd14..dd432303b549 100644 --- a/drivers/net/pcs/pcs-qcom-ipq.c +++ b/drivers/net/pcs/pcs-qcom-ipq.c @@ -6,12 +6,49 @@ #include #include #include +#include +#include +#include #include +#include #include #include #include +/* Maximum number of MIIs per PCS instance. There are 5 MIIs for PSGMII. */ +#define PCS_MAX_MII_NRS 5 + +#define PCS_CALIBRATION 0x1e0 +#define PCS_CALIBRATION_DONE BIT(7) + +#define PCS_MODE_CTRL 0x46c +#define PCS_MODE_SEL_MASK GENMASK(12, 8) +#define PCS_MODE_SGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x4) +#define PCS_MODE_QSGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x1) +#define PCS_MODE_AN_MODE BIT(0) + +#define PCS_MII_CTRL(x) (0x480 + 0x18 * (x)) +#define PCS_MII_ADPT_RESET BIT(11) +#define PCS_MII_FORCE_MODE BIT(3) +#define PCS_MII_SPEED_MASK GENMASK(2, 1) +#define PCS_MII_SPEED_1000 FIELD_PREP(PCS_MII_SPEED_MASK, 0x2) +#define PCS_MII_SPEED_100 FIELD_PREP(PCS_MII_SPEED_MASK, 0x1) +#define PCS_MII_SPEED_10 FIELD_PREP(PCS_MII_SPEED_MASK, 0x0) + +#define PCS_MII_STS(x) (0x488 + 0x18 * (x)) +#define PCS_MII_LINK_STS BIT(7) +#define PCS_MII_STS_DUPLEX_FULL BIT(6) +#define PCS_MII_STS_SPEED_MASK GENMASK(5, 4) +#define PCS_MII_STS_SPEED_10 0 +#define PCS_MII_STS_SPEED_100 1 +#define PCS_MII_STS_SPEED_1000 2 +#define PCS_MII_STS_PAUSE_TX_EN BIT(1) +#define PCS_MII_STS_PAUSE_RX_EN BIT(0) + +#define PCS_PLL_RESET 0x780 +#define PCS_ANA_SW_RESET BIT(6) + #define XPCS_INDIRECT_ADDR 0x8000 #define XPCS_INDIRECT_AHB_ADDR 0x83fc #define XPCS_INDIRECT_ADDR_H GENMASK(20, 8) @@ -27,12 +64,428 @@ struct ipq_pcs { struct regmap *regmap; phy_interface_t interface; + /* Lock to protect PCS configurations shared by multiple MII ports */ + struct mutex config_lock; + /* RX clock supplied to NSSCC */ struct clk_hw rx_hw; /* TX clock supplied to NSSCC */ struct clk_hw tx_hw; }; +/* PCS MII clock ID */ +enum { + PCS_MII_RX_CLK, + PCS_MII_TX_CLK, + PCS_MII_CLK_MAX +}; + +/* PCS MII clock name */ +static const char *const pcs_mii_clk_name[PCS_MII_CLK_MAX] = { + "mii_rx", + "mii_tx", +}; + +/* Per PCS MII private data */ +struct ipq_pcs_mii { + struct ipq_pcs *qpcs; + struct phylink_pcs pcs; + int index; + + /* Rx/Tx clocks from NSSCC to PCS MII */ + struct clk *clk[PCS_MII_CLK_MAX]; +}; + +#define phylink_pcs_to_qpcs_mii(_pcs) \ + container_of(_pcs, struct ipq_pcs_mii, pcs) + +static void ipq_pcs_get_state_sgmii(struct ipq_pcs *qpcs, + int index, + struct phylink_link_state *state) +{ + unsigned int val; + int ret; + + ret = regmap_read(qpcs->regmap, PCS_MII_STS(index), &val); + if (ret) { + state->link = 0; + return; + } + + state->link = !!(val & PCS_MII_LINK_STS); + + if (!state->link) + return; + + switch (FIELD_GET(PCS_MII_STS_SPEED_MASK, val)) { + case PCS_MII_STS_SPEED_1000: + state->speed = SPEED_1000; + break; + case PCS_MII_STS_SPEED_100: + state->speed = SPEED_100; + break; + case PCS_MII_STS_SPEED_10: + state->speed = SPEED_10; + break; + default: + state->link = false; + return; + } + + if (val & PCS_MII_STS_DUPLEX_FULL) + state->duplex = DUPLEX_FULL; + else + state->duplex = DUPLEX_HALF; + + if (val & PCS_MII_STS_PAUSE_TX_EN) + state->pause |= MLO_PAUSE_TX; + + if (val & PCS_MII_STS_PAUSE_RX_EN) + state->pause |= MLO_PAUSE_RX; +} + +static int ipq_pcs_config_mode(struct ipq_pcs *qpcs, + phy_interface_t interface) +{ + unsigned int val; + int ret; + + /* Configure PCS interface mode */ + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + /* Select Qualcomm SGMII AN mode */ + ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL, + PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE, + PCS_MODE_SGMII); + if (ret) + return ret; + break; + case PHY_INTERFACE_MODE_QSGMII: + ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL, + PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE, + PCS_MODE_QSGMII); + if (ret) + return ret; + break; + default: + dev_err(qpcs->dev, + "Unsupported interface %s\n", phy_modes(interface)); + return -EOPNOTSUPP; + } + + /* PCS PLL reset */ + ret = regmap_update_bits(qpcs->regmap, PCS_PLL_RESET, + PCS_ANA_SW_RESET, 0); + if (ret) + return ret; + + fsleep(1000); + ret = regmap_update_bits(qpcs->regmap, PCS_PLL_RESET, + PCS_ANA_SW_RESET, PCS_ANA_SW_RESET); + if (ret) + return ret; + + /* Wait for calibration completion */ + ret = regmap_read_poll_timeout(qpcs->regmap, PCS_CALIBRATION, + val, val & PCS_CALIBRATION_DONE, + 1000, 100000); + if (ret) { + dev_err(qpcs->dev, "PCS calibration timed-out\n"); + return ret; + } + + qpcs->interface = interface; + + return 0; +} + +static int ipq_pcs_config_sgmii(struct ipq_pcs *qpcs, + int index, + unsigned int neg_mode, + phy_interface_t interface) +{ + int ret; + + /* Access to PCS registers such as PCS_MODE_CTRL which are + * common to all MIIs, is lock protected and configured + * only once. This is required only for interface modes + * such as QSGMII. + */ + if (interface == PHY_INTERFACE_MODE_QSGMII) + mutex_lock(&qpcs->config_lock); + + if (qpcs->interface != interface) { + ret = ipq_pcs_config_mode(qpcs, interface); + if (ret) + goto err; + } + + if (interface == PHY_INTERFACE_MODE_QSGMII) + mutex_unlock(&qpcs->config_lock); + + /* Nothing to do here as in-band autoneg mode is enabled + * by default for each PCS MII port. + */ + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) + return 0; + + /* Set force speed mode */ + return regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index), + PCS_MII_FORCE_MODE, PCS_MII_FORCE_MODE); + +err: + if (interface == PHY_INTERFACE_MODE_QSGMII) + mutex_unlock(&qpcs->config_lock); + + return ret; +} + +static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs, + int index, + unsigned int neg_mode, + int speed) +{ + int ret; + + /* PCS speed need not be configured if in-band autoneg is enabled */ + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) + goto pcs_adapter_reset; + + /* PCS speed set for force mode */ + switch (speed) { + case SPEED_1000: + ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index), + PCS_MII_SPEED_MASK, + PCS_MII_SPEED_1000); + if (ret) + return ret; + break; + case SPEED_100: + ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index), + PCS_MII_SPEED_MASK, PCS_MII_SPEED_100); + if (ret) + return ret; + break; + case SPEED_10: + ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index), + PCS_MII_SPEED_MASK, PCS_MII_SPEED_10); + if (ret) + return ret; + break; + default: + dev_err(qpcs->dev, "Invalid SGMII speed %d\n", speed); + return -EINVAL; + } + +pcs_adapter_reset: + /* PCS adapter reset */ + ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index), + PCS_MII_ADPT_RESET, 0); + if (ret) + return ret; + + return regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index), + PCS_MII_ADPT_RESET, PCS_MII_ADPT_RESET); +} + +static void ipq_pcs_get_state(struct phylink_pcs *pcs, + struct phylink_link_state *state) +{ + struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs); + struct ipq_pcs *qpcs = qpcs_mii->qpcs; + int index = qpcs_mii->index; + + switch (state->interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + ipq_pcs_get_state_sgmii(qpcs, index, state); + break; + default: + break; + } + + dev_dbg(qpcs->dev, + "mode=%s/%s/%s link=%u\n", + phy_modes(state->interface), + phy_speed_to_str(state->speed), + phy_duplex_to_str(state->duplex), + state->link); +} + +static int ipq_pcs_config(struct phylink_pcs *pcs, + unsigned int neg_mode, + phy_interface_t interface, + const unsigned long *advertising, + bool permit) +{ + struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs); + struct ipq_pcs *qpcs = qpcs_mii->qpcs; + int index = qpcs_mii->index; + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface); + default: + dev_err(qpcs->dev, + "Unsupported interface %s\n", phy_modes(interface)); + return -EOPNOTSUPP; + }; +} + +static void ipq_pcs_link_up(struct phylink_pcs *pcs, + unsigned int neg_mode, + phy_interface_t interface, + int speed, int duplex) +{ + struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs); + struct ipq_pcs *qpcs = qpcs_mii->qpcs; + int index = qpcs_mii->index; + int ret; + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + ret = ipq_pcs_link_up_config_sgmii(qpcs, index, + neg_mode, speed); + break; + default: + dev_err(qpcs->dev, + "Unsupported interface %s\n", phy_modes(interface)); + return; + } + + if (ret) + dev_err(qpcs->dev, "PCS link up fail for interface %s\n", + phy_modes(interface)); +} + +static const struct phylink_pcs_ops ipq_pcs_phylink_ops = { + .pcs_get_state = ipq_pcs_get_state, + .pcs_config = ipq_pcs_config, + .pcs_link_up = ipq_pcs_link_up, +}; + +/** + * ipq_pcs_create() - Create an IPQ PCS MII instance + * @np: Device tree node to the PCS MII + * + * Description: Create a phylink PCS instance for the given PCS MII node @np + * and enable the MII clocks. This instance is associated with the specific + * MII of the PCS and the corresponding Ethernet netdevice. + * + * Return: A pointer to the phylink PCS instance or an error-pointer value. + */ +struct phylink_pcs *ipq_pcs_create(struct device_node *np) +{ + struct platform_device *pdev; + struct ipq_pcs_mii *qpcs_mii; + struct device_node *pcs_np; + struct ipq_pcs *qpcs; + int i, ret; + u32 index; + + if (!of_device_is_available(np)) + return ERR_PTR(-ENODEV); + + if (of_property_read_u32(np, "reg", &index)) + return ERR_PTR(-EINVAL); + + if (index >= PCS_MAX_MII_NRS) + return ERR_PTR(-EINVAL); + + pcs_np = of_get_parent(np); + if (!pcs_np) + return ERR_PTR(-ENODEV); + + if (!of_device_is_available(pcs_np)) { + of_node_put(pcs_np); + return ERR_PTR(-ENODEV); + } + + pdev = of_find_device_by_node(pcs_np); + of_node_put(pcs_np); + if (!pdev) + return ERR_PTR(-ENODEV); + + qpcs = platform_get_drvdata(pdev); + put_device(&pdev->dev); + + /* If probe is not yet completed, return DEFER to + * the dependent driver. + */ + if (!qpcs) + return ERR_PTR(-EPROBE_DEFER); + + qpcs_mii = kzalloc(sizeof(*qpcs_mii), GFP_KERNEL); + if (!qpcs_mii) + return ERR_PTR(-ENOMEM); + + qpcs_mii->qpcs = qpcs; + qpcs_mii->index = index; + qpcs_mii->pcs.ops = &ipq_pcs_phylink_ops; + qpcs_mii->pcs.neg_mode = true; + qpcs_mii->pcs.poll = true; + + for (i = 0; i < PCS_MII_CLK_MAX; i++) { + qpcs_mii->clk[i] = of_clk_get_by_name(np, pcs_mii_clk_name[i]); + if (IS_ERR(qpcs_mii->clk[i])) { + dev_err(qpcs->dev, + "Failed to get MII %d interface clock %s\n", + index, pcs_mii_clk_name[i]); + goto err_clk_get; + } + + ret = clk_prepare_enable(qpcs_mii->clk[i]); + if (ret) { + dev_err(qpcs->dev, + "Failed to enable MII %d interface clock %s\n", + index, pcs_mii_clk_name[i]); + goto err_clk_en; + } + } + + return &qpcs_mii->pcs; + +err_clk_en: + clk_put(qpcs_mii->clk[i]); +err_clk_get: + while (i) { + i--; + clk_disable_unprepare(qpcs_mii->clk[i]); + clk_put(qpcs_mii->clk[i]); + } + + kfree(qpcs_mii); + return ERR_PTR(-ENODEV); +} +EXPORT_SYMBOL(ipq_pcs_create); + +/** + * ipq_pcs_destroy() - Destroy the IPQ PCS MII instance + * @pcs: PCS instance + * + * Description: Destroy a phylink PCS instance. + */ +void ipq_pcs_destroy(struct phylink_pcs *pcs) +{ + struct ipq_pcs_mii *qpcs_mii; + int i; + + if (!pcs) + return; + + qpcs_mii = phylink_pcs_to_qpcs_mii(pcs); + + for (i = 0; i < PCS_MII_CLK_MAX; i++) { + clk_disable_unprepare(qpcs_mii->clk[i]); + clk_put(qpcs_mii->clk[i]); + } + + kfree(qpcs_mii); +} +EXPORT_SYMBOL(ipq_pcs_destroy); + static unsigned long ipq_pcs_clk_rate_get(struct ipq_pcs *qpcs) { switch (qpcs->interface) { @@ -219,6 +672,8 @@ static int ipq_pcs_probe(struct platform_device *pdev) if (ret) return ret; + mutex_init(&qpcs->config_lock); + platform_set_drvdata(pdev, qpcs); return 0; diff --git a/include/linux/pcs/pcs-qcom-ipq.h b/include/linux/pcs/pcs-qcom-ipq.h new file mode 100644 index 000000000000..f72a895afaba --- /dev/null +++ b/include/linux/pcs/pcs-qcom-ipq.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * + */ + +#ifndef __LINUX_PCS_QCOM_IPQ_H +#define __LINUX_PCS_QCOM_IPQ_H + +struct device_node; +struct phylink_pcs; + +struct phylink_pcs *ipq_pcs_create(struct device_node *np); +void ipq_pcs_destroy(struct phylink_pcs *pcs); + +#endif /* __LINUX_PCS_QCOM_IPQ_H */ From patchwork Fri Nov 1 10:32:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lei Wei X-Patchwork-Id: 13859173 X-Patchwork-Delegate: kuba@kernel.org Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 AC3901A0AE1; Fri, 1 Nov 2024 10:35:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457326; cv=none; b=H5rCuP/TbmBIflXLpkfbcFFFIUDgj1muzHodvU3j9ux9TxxTJL92KnsO2AwW/KHzXRQl5ZPh3Y8DBMjEVPJ3E+tNMr7cnhRkTaDFPhAAERPShfc9L15HEvGb8A1VF0lMTkndgDVV6PZ9y5RkYQwog+4m0C0hcKiedvjP5pHuzOY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457326; c=relaxed/simple; bh=5BCkNeRcshI9KjANnXaqdtrejbfKFp3NeWF0f9umzBg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=PSFylbZ8qgNckdTiN3HNRTxqnncwxrMIU46z5Z8FqjcmOhnpYRm6alo+PWPvCm6ODPVAhCHLZnNMtdpZn8jRJ4ck+FTTXpRpitR3rYJkqqWYGAJk8Td65MD+44mSwxeWUQmOmGAeH0tBg4FufSVL9ljMUOuQzCl3HrcFfQmtDWQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=dEbeWQix; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="dEbeWQix" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4A13Jnk2019830; Fri, 1 Nov 2024 10:35:08 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= cJU8D/oiuhvdJzzr8DdcXs2hWijqPz683UrCaE/vrEk=; b=dEbeWQixWnhrmvwG v2pQZEwcu2l5PuvBGeOwtyRPOSS6NyXtJAwhB8Y4XHi5hv33tTh1F7y3DwITKHXn iv3NGDX20DWYfUoVwBFEEGJ0bf8O8K6Z4dV6w0S3RmgnJouDicmc438ZugeGMNgZ oEZt8YVFO/kjtGbW//aQleF+ISIp0zIVnmNiq1VUiZKCGKxxi463FDJOWmUY4k1P qI9tulvkNPHf6sUr1gY2ZpOPGu8xpd8QuuEm/ZhLbUw6HkuQBRIC5tjTFAdPJT8o tFGoaMtXQIO/vghL5/yDcZWdnwlQoQ8YQl5J4JZaSr4q9vNSf1SELUe1FlQUT/+E +3hNAw== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 42kmp0pupy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 01 Nov 2024 10:35:07 +0000 (GMT) Received: from nasanex01a.na.qualcomm.com (nasanex01a.na.qualcomm.com [10.52.223.231]) by NASANPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 4A1AZ7oI023884 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 1 Nov 2024 10:35:07 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01a.na.qualcomm.com (10.52.223.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Fri, 1 Nov 2024 03:35:00 -0700 From: Lei Wei Date: Fri, 1 Nov 2024 18:32:52 +0800 Subject: [PATCH net-next 4/5] net: pcs: qcom-ipq: Add USXGMII interface mode for IPQ9574 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20241101-ipq_pcs_rc1-v1-4-fdef575620cf@quicinc.com> References: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> In-Reply-To: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andrew Lunn , Heiner Kallweit , Russell King CC: , , , , , , , , , , , , X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1730457277; l=7406; i=quic_leiwei@quicinc.com; s=20240829; h=from:subject:message-id; bh=5BCkNeRcshI9KjANnXaqdtrejbfKFp3NeWF0f9umzBg=; b=EKC/Faohp4cixOpYExMX2fd++2qoCs2XW2LN+AiwZDCKBu1IcH/N0zkQcR2XUAXxqCOfKJzwD xLKWmLwXB+PAsG5Ufj6yrSCnolMkzAw5B1gX+I6tW0mpmZMv0zH0UJ9 X-Developer-Key: i=quic_leiwei@quicinc.com; a=ed25519; pk=uFXBHtxtDjtIrTKpDEZlMLSn1i/sonZepYO8yioKACM= X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01a.na.qualcomm.com (10.52.223.231) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 690z9GnxDjB4r-KgS961yNTXifzaispV X-Proofpoint-ORIG-GUID: 690z9GnxDjB4r-KgS961yNTXifzaispV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 impostorscore=0 mlxscore=0 suspectscore=0 adultscore=0 clxscore=1015 phishscore=0 spamscore=0 mlxlogscore=999 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2411010076 X-Patchwork-Delegate: kuba@kernel.org USXGMII mode is enabled by PCS when 10Gbps PHYs are connected, such as Aquantia 10Gbps PHY. Signed-off-by: Lei Wei --- drivers/net/pcs/pcs-qcom-ipq.c | 180 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) diff --git a/drivers/net/pcs/pcs-qcom-ipq.c b/drivers/net/pcs/pcs-qcom-ipq.c index dd432303b549..19cb995f7c87 100644 --- a/drivers/net/pcs/pcs-qcom-ipq.c +++ b/drivers/net/pcs/pcs-qcom-ipq.c @@ -26,6 +26,7 @@ #define PCS_MODE_SEL_MASK GENMASK(12, 8) #define PCS_MODE_SGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x4) #define PCS_MODE_QSGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x1) +#define PCS_MODE_XPCS FIELD_PREP(PCS_MODE_SEL_MASK, 0x10) #define PCS_MODE_AN_MODE BIT(0) #define PCS_MII_CTRL(x) (0x480 + 0x18 * (x)) @@ -57,6 +58,35 @@ FIELD_PREP(GENMASK(9, 2), \ FIELD_GET(XPCS_INDIRECT_ADDR_L, reg))) +#define XPCS_DIG_CTRL 0x38000 +#define XPCS_USXG_ADPT_RESET BIT(10) +#define XPCS_USXG_EN BIT(9) + +#define XPCS_MII_CTRL 0x1f0000 +#define XPCS_MII_AN_EN BIT(12) +#define XPCS_DUPLEX_FULL BIT(8) +#define XPCS_SPEED_MASK (BIT(13) | BIT(6) | BIT(5)) +#define XPCS_SPEED_10000 (BIT(13) | BIT(6)) +#define XPCS_SPEED_5000 (BIT(13) | BIT(5)) +#define XPCS_SPEED_2500 BIT(5) +#define XPCS_SPEED_1000 BIT(6) +#define XPCS_SPEED_100 BIT(13) +#define XPCS_SPEED_10 0 + +#define XPCS_MII_AN_CTRL 0x1f8001 +#define XPCS_MII_AN_8BIT BIT(8) + +#define XPCS_MII_AN_INTR_STS 0x1f8002 +#define XPCS_USXG_AN_LINK_STS BIT(14) +#define XPCS_USXG_AN_DUPLEX_FULL BIT(13) +#define XPCS_USXG_AN_SPEED_MASK GENMASK(12, 10) +#define XPCS_USXG_AN_SPEED_10 0 +#define XPCS_USXG_AN_SPEED_100 1 +#define XPCS_USXG_AN_SPEED_1000 2 +#define XPCS_USXG_AN_SPEED_2500 4 +#define XPCS_USXG_AN_SPEED_5000 5 +#define XPCS_USXG_AN_SPEED_10000 3 + /* Private data for the PCS instance */ struct ipq_pcs { struct device *dev; @@ -144,9 +174,57 @@ static void ipq_pcs_get_state_sgmii(struct ipq_pcs *qpcs, state->pause |= MLO_PAUSE_RX; } +static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs, + struct phylink_link_state *state) +{ + unsigned int val; + int ret; + + ret = regmap_read(qpcs->regmap, XPCS_MII_AN_INTR_STS, &val); + if (ret) { + state->link = 0; + return; + } + + state->link = !!(val & XPCS_USXG_AN_LINK_STS); + + if (!state->link) + return; + + switch (FIELD_GET(XPCS_USXG_AN_SPEED_MASK, val)) { + case XPCS_USXG_AN_SPEED_10000: + state->speed = SPEED_10000; + break; + case XPCS_USXG_AN_SPEED_5000: + state->speed = SPEED_5000; + break; + case XPCS_USXG_AN_SPEED_2500: + state->speed = SPEED_2500; + break; + case XPCS_USXG_AN_SPEED_1000: + state->speed = SPEED_1000; + break; + case XPCS_USXG_AN_SPEED_100: + state->speed = SPEED_100; + break; + case XPCS_USXG_AN_SPEED_10: + state->speed = SPEED_10; + break; + default: + state->link = false; + return; + } + + if (val & XPCS_USXG_AN_DUPLEX_FULL) + state->duplex = DUPLEX_FULL; + else + state->duplex = DUPLEX_HALF; +} + static int ipq_pcs_config_mode(struct ipq_pcs *qpcs, phy_interface_t interface) { + unsigned long rate = 125000000; unsigned int val; int ret; @@ -167,6 +245,13 @@ static int ipq_pcs_config_mode(struct ipq_pcs *qpcs, if (ret) return ret; break; + case PHY_INTERFACE_MODE_USXGMII: + rate = 312500000; + ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL, + PCS_MODE_SEL_MASK, PCS_MODE_XPCS); + if (ret) + return ret; + break; default: dev_err(qpcs->dev, "Unsupported interface %s\n", phy_modes(interface)); @@ -196,6 +281,21 @@ static int ipq_pcs_config_mode(struct ipq_pcs *qpcs, qpcs->interface = interface; + /* Configure the RX and TX clock to NSSCC as 125M or 312.5M based + * on current interface mode. + */ + ret = clk_set_rate(qpcs->rx_hw.clk, rate); + if (ret) { + dev_err(qpcs->dev, "Failed to set RX clock rate\n"); + return ret; + } + + ret = clk_set_rate(qpcs->tx_hw.clk, rate); + if (ret) { + dev_err(qpcs->dev, "Failed to set TX clock rate\n"); + return ret; + } + return 0; } @@ -240,6 +340,35 @@ static int ipq_pcs_config_sgmii(struct ipq_pcs *qpcs, return ret; } +static int ipq_pcs_config_usxgmii(struct ipq_pcs *qpcs) +{ + int ret; + + /* Configure the XPCS for USXGMII mode if required */ + if (qpcs->interface != PHY_INTERFACE_MODE_USXGMII) { + ret = ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_USXGMII); + if (ret) + return ret; + + ret = regmap_update_bits(qpcs->regmap, XPCS_DIG_CTRL, + XPCS_USXG_EN, XPCS_USXG_EN); + if (ret) + return ret; + + ret = regmap_update_bits(qpcs->regmap, XPCS_MII_AN_CTRL, + XPCS_MII_AN_8BIT, XPCS_MII_AN_8BIT); + if (ret) + return ret; + + ret = regmap_update_bits(qpcs->regmap, XPCS_MII_CTRL, + XPCS_MII_AN_EN, XPCS_MII_AN_EN); + if (ret) + return ret; + } + + return 0; +} + static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs, int index, unsigned int neg_mode, @@ -288,6 +417,49 @@ static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs, PCS_MII_ADPT_RESET, PCS_MII_ADPT_RESET); } +static int ipq_pcs_link_up_config_usxgmii(struct ipq_pcs *qpcs, int speed) +{ + unsigned int val; + int ret; + + switch (speed) { + case SPEED_10000: + val = XPCS_SPEED_10000; + break; + case SPEED_5000: + val = XPCS_SPEED_5000; + break; + case SPEED_2500: + val = XPCS_SPEED_2500; + break; + case SPEED_1000: + val = XPCS_SPEED_1000; + break; + case SPEED_100: + val = XPCS_SPEED_100; + break; + case SPEED_10: + val = XPCS_SPEED_10; + break; + default: + dev_err(qpcs->dev, "Invalid USXGMII speed %d\n", speed); + return -EINVAL; + } + + /* USXGMII only support full duplex mode */ + val |= XPCS_DUPLEX_FULL; + + /* Configure XPCS speed */ + ret = regmap_update_bits(qpcs->regmap, XPCS_MII_CTRL, + XPCS_SPEED_MASK | XPCS_DUPLEX_FULL, val); + if (ret) + return ret; + + /* XPCS adapter reset */ + return regmap_update_bits(qpcs->regmap, XPCS_DIG_CTRL, + XPCS_USXG_ADPT_RESET, XPCS_USXG_ADPT_RESET); +} + static void ipq_pcs_get_state(struct phylink_pcs *pcs, struct phylink_link_state *state) { @@ -300,6 +472,9 @@ static void ipq_pcs_get_state(struct phylink_pcs *pcs, case PHY_INTERFACE_MODE_QSGMII: ipq_pcs_get_state_sgmii(qpcs, index, state); break; + case PHY_INTERFACE_MODE_USXGMII: + ipq_pcs_get_state_usxgmii(qpcs, state); + break; default: break; } @@ -326,6 +501,8 @@ static int ipq_pcs_config(struct phylink_pcs *pcs, case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface); + case PHY_INTERFACE_MODE_USXGMII: + return ipq_pcs_config_usxgmii(qpcs); default: dev_err(qpcs->dev, "Unsupported interface %s\n", phy_modes(interface)); @@ -349,6 +526,9 @@ static void ipq_pcs_link_up(struct phylink_pcs *pcs, ret = ipq_pcs_link_up_config_sgmii(qpcs, index, neg_mode, speed); break; + case PHY_INTERFACE_MODE_USXGMII: + ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed); + break; default: dev_err(qpcs->dev, "Unsupported interface %s\n", phy_modes(interface)); From patchwork Fri Nov 1 10:32:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lei Wei X-Patchwork-Id: 13859174 X-Patchwork-Delegate: kuba@kernel.org Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 E4A271A256E; Fri, 1 Nov 2024 10:35:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457330; cv=none; b=Q8LGd0Sp3b8cvIBtwJTBYRfzRUn59+XS+pQKyY1xLt5N8O4M5v7gwMpMhvp6td8rZvSthXaL/I30bgRN+DiFAb0Y/t/Tz7T7ylB/83GpolWYRM6NqB5+J6vhy/ZK5tqRty7Oh0kzRpSBUn+sNhUtS/YNvw0gUXXbi3IbeLBjxqQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730457330; c=relaxed/simple; bh=cCTMz0n3TufOW/nzpqclVZkXSz9b3dTWlwVdZAF6w6c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=MMJAveUoNPj3pisACJEm3Eo9RikOGsDiWx6fblZ+beluuNCHh3A54ITI1I2JJ7B08h86Nfn5qsthYVh0Vol4A3s3AEBVoUyx6u0cRd4zD32i8aHiKFZM9C8xZq8nr4XG7qaS3xj5sTqdGApwykTafcxq/L5wvljjrlqkZS/IN3Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=aAdkv6/s; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="aAdkv6/s" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4A13Jnk5019830; Fri, 1 Nov 2024 10:35:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= MG6QcRdCDOsIB7rtc2QzNR/9cTeI6HRt5XW82nF1E0w=; b=aAdkv6/s5kIve4bY hh8tfG4tJ0Mw5YD4L5n58OzUvk/W0RACpPKNDK092uHNz2zuEvblsKwPhF9mTnKk kouQANESLF8hHGsj48gB/uhSI7G5EV11iof2gnTSFCR61cEDVSNjfX+zT0o/E9zV uxDUjKrfliuTZTrBTQYT79uwcPilYRqcc/ivl7KFLpYXfD74fqk6p9yQ+PCn2Dju MrZeeBlL2ByfgL7u0iNr7O/sy5FCVGOc37aHbE+nNrtI3wmpp9YTNyu175NFERLP Y3ERFwVt7om3yoE45SQDHfUHYWaZGAVYdBuVvif0pl82d4cJieuYOvvERDNkLeEo WZAYzg== Received: from nasanppmta02.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 42kmp0puqg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 01 Nov 2024 10:35:14 +0000 (GMT) Received: from nasanex01a.na.qualcomm.com (nasanex01a.na.qualcomm.com [10.52.223.231]) by NASANPPMTA02.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 4A1AZDch008294 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 1 Nov 2024 10:35:13 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01a.na.qualcomm.com (10.52.223.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Fri, 1 Nov 2024 03:35:07 -0700 From: Lei Wei Date: Fri, 1 Nov 2024 18:32:53 +0800 Subject: [PATCH net-next 5/5] MAINTAINERS: Add maintainer for Qualcomm IPQ PCS driver Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20241101-ipq_pcs_rc1-v1-5-fdef575620cf@quicinc.com> References: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> In-Reply-To: <20241101-ipq_pcs_rc1-v1-0-fdef575620cf@quicinc.com> To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andrew Lunn , Heiner Kallweit , Russell King CC: , , , , , , , , , , , , X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1730457277; l=942; i=quic_leiwei@quicinc.com; s=20240829; h=from:subject:message-id; bh=cCTMz0n3TufOW/nzpqclVZkXSz9b3dTWlwVdZAF6w6c=; b=7y4AbnidauEDXfLUXhW7SLPKDR/nM9ZviEmqdPJrsDVNGfwzyhMkLyEsottWDgQNrwCMep+KW JWX8W+C1PGVDlj7jNpMB1/s1bJFtniQAisFPMwMM7NwDOr+4NTD0gEB X-Developer-Key: i=quic_leiwei@quicinc.com; a=ed25519; pk=uFXBHtxtDjtIrTKpDEZlMLSn1i/sonZepYO8yioKACM= X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01a.na.qualcomm.com (10.52.223.231) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: z8NdR-kpGwNaqy4L5TQFo3xtu0JcAKBf X-Proofpoint-ORIG-GUID: z8NdR-kpGwNaqy4L5TQFo3xtu0JcAKBf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 impostorscore=0 mlxscore=0 suspectscore=0 adultscore=0 clxscore=1015 phishscore=0 spamscore=0 mlxlogscore=835 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2411010076 X-Patchwork-Delegate: kuba@kernel.org Add maintainer for the Ethernet PCS driver supported for Qualcomm IPQ SoC such as IPQ9574. Signed-off-by: Lei Wei --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c27f3190737f..6c5599c3834b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19148,6 +19148,15 @@ F: Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml F: drivers/mailbox/qcom-ipcc.c F: include/dt-bindings/mailbox/qcom-ipcc.h +QUALCOMM IPQ Ethernet PCS DRIVER +M: Lei Wei +L: netdev@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml +F: drivers/net/pcs/pcs-qcom-ipq.c +F: include/dt-bindings/net/pcs-qcom-ipq.h +F: include/linux/pcs/pcs-qcom-ipq.h + QUALCOMM IPQ4019 USB PHY DRIVER M: Robert Marko M: Luka Perkov