From nobody Sun May 24 23:29:00 2026 Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C57B35200B for ; Wed, 20 May 2026 15:09:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289774; cv=none; b=Xrw0Jwz6JGHjHv5r6cytFMFpO7/J9CgviPbLovXX1ktXE0DsGiltJufFppWjd3XBFN2924qhyjKSo0W+LEmLcCv2pUGDWbUW8z5544O0XjuUFdeJQk3iOggk/kGYflR2bUBLeZ4EzqNShBfN0WmBryDD56WSz0wqFjHWPdavqVM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289774; c=relaxed/simple; bh=ZFCPxnBsn7l/q5muCwmNmTDcY6bBCEJ2vd6Wy7/pDdM=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MRQVwF2tZ5zUanFLAiVNpSzNHGmBOEvVvrFTf3Q+oGKa3LNCl6PBvLkXZc54PuBff3NQmjQeCFa7JVPQFmQ5NWYIIkSoFCjED1FP0kDzmIcE2UnhaM1runqLZ4b0NEpaebMlEa8DKadDpRVgA7M7p/0S+PvOVNsNVADa9QIBORE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LWbRuiOg; arc=none smtp.client-ip=209.85.221.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LWbRuiOg" Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-449d6c68ed8so2184484f8f.0 for ; Wed, 20 May 2026 08:09:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779289771; x=1779894571; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=jNa4hPs6+EpEb0GIRuEgBVkSu+eNRa7QDRsXvqoVr38=; b=LWbRuiOg4Orvt8OGvEjCgKYJ+SN9IvVWMPzxtX1pomrFyMN8IoC2OairjswLJJWDkq bhfjT+87OT0PYMGm7MKjfZFR9aGu5JyJ7IZO5wgQyh8PaBhE/Mqlf6Y7dg1bePFkqF6P AJK4yAkEC2qPaKhl8pQoheAQEDkkVUuCmTosZfBjpkdMXTr350JNFRlHcUZEBEBQEkkn pct6t0EL6JBh/8y8t7qRDU+kCXqCSoPMxVsDIP3BAwJW1YaawwtUVI1HFNUqVIGyC6G4 BPidk/QCDW4n7lMCvq4Bqv2dzICBDZCR9lDFkqjLwcYoQnIBnTlpZaXdZxLsFrN8Eb+t HSIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779289771; x=1779894571; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=jNa4hPs6+EpEb0GIRuEgBVkSu+eNRa7QDRsXvqoVr38=; b=cAgdkkK3W/t7oj4FG17ntQLayNlBTWE+l3lSGd5nO/6f6ccicuXLjQxqLMvTe5fd5O 86S97zGHjv8dQdqzlwgzFbrjDVMoiMkko2YDK++1luTOvvWBZg07BlGd4APjItiYDY9P hzF644UzFMVfpUp5RIqIeRLpebaMfwjM5urMJizkHkFG4zW2i2eKLuyVRSy0IFxh83oN 3AUbhsihnhGtYxuB6mcUOsrdk1m/7KCc77kdjpebHg59t3a2I5o8dqrYO4xk1rQQ6suZ 39/t9EwYjHmUOfIbJObfstJUi6hczLMtgH8C4wY/Edu95mBLiwWRq5wEUSwfu4YhfFb3 O2/A== X-Forwarded-Encrypted: i=1; AFNElJ/AHSzEQzTCPv7xRFLXOi4KHUG+fEOTHClrWfWvK22aT4LvV8MfJCeRogX1vpjlkJGcI0Ruutzd0xzMqcM=@vger.kernel.org X-Gm-Message-State: AOJu0Yyfj/BMiMGJpsjjJf32nH/29gvryO7gZqxdt9S9fKlOCsienrvx aTKanjuiItQ5TkVNOwbe71MVvGf5BEeYODgVTZOaY8c+ZpjMbe4R4veUMavXkQ== X-Gm-Gg: Acq92OEMo4oEFLnjqGv9fH7mcgjXgqTneJDDvLVsqIeodWzhYpuzG9UIFZj2pvuqMJA +WJ78pGEdNirahrLNgCf+BRonuxiTvJVPDuUgo8NWr+sKQ6dWwje++mfH+BgvVANj37X0CZ0TMt xxaZpW7CACSLWZVCRPexCt6tMpybxtNBcM2VC4QvZkkGmXwiodlZA5F59FZ6HeDl6U4eclBNC7M iy/2jPTpyZBl4OO3wN4cZ+cJF7aOkO44lrU2xEeAApv9UsegxLYgVpYjZ+eI4h2/9K3Pp2CJFQq AcR8554xRYRBAEPR7hFfm9vmf/FczvPK6Zy0k4izsA6xQEb+6nZQoImgBOIXZ81YMv2/W9cfNEp LLMz15PsoHyHq7UeUfClhWeoR1NdjvkR/nYi5owVZBHMmE6p+O62rSKdFE3iuo2cVcWGub4vggO ZvooZj4pis0mcgTY0aG+mrbULuK1qLwC12qOoiFpRTdb0nlGa5PbZYKBVw0BJFM8JP22GXEyV9m A== X-Received: by 2002:a05:6000:2503:b0:43f:e43a:f4a6 with SMTP id ffacd0b85a97d-45e5c35e7bdmr39357421f8f.6.1779289770707; Wed, 20 May 2026 08:09:30 -0700 (PDT) Received: from Ansuel-XPS24 (host-79-22-5-99.retail.telecomitalia.it. [79.22.5.99]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-45d9ec39806sm53639804f8f.9.2026.05.20.08.09.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2026 08:09:30 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Brian Masney , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Neil Armstrong , Lorenzo Bianconi , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v8 1/5] dt-bindings: clock: airoha: Add PHY binding for Serdes port Date: Wed, 20 May 2026 17:09:06 +0200 Message-ID: <20260520150912.11614-2-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520150912.11614-1-ansuelsmth@gmail.com> References: <20260520150912.11614-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add PHY cell property for Serdes port selection. Currently supported only for Airoha AN7581 SoC, that support up to 4 Serdes port. The Serdes port can support both PCIe, USB3 or Ethernet mode. - PCIe1 Serdes can support PCIe or Ethernet mode. - PCIe2 Serdes can support PCIe or Ethernet mode. - USB1 Serdes can support USB3 or HSGMII mode. - USB2 Serdes can support USB3 or PCIe mode. Add bindings to permit correct reference of the Serdes ports in DT. Values are just symbolic and enumerates the Serdes port with a specific number for precise reference. The available Serdes port can be selected following the dt-binding header in [2]. [2] Signed-off-by: Christian Marangi Reviewed-by: Krzysztof Kozlowski --- .../devicetree/bindings/clock/airoha,en7523-scu.yaml | 9 +++++++++ include/dt-bindings/soc/airoha,scu-ssr.h | 11 +++++++++++ 2 files changed, 20 insertions(+) create mode 100644 include/dt-bindings/soc/airoha,scu-ssr.h diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml= b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml index eb24a5687639..913ddc16182b 100644 --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml @@ -23,6 +23,7 @@ description: | =20 All these identifiers can be found in: [1]: . + [2]: . =20 The clocks are provided inside a system controller node. =20 @@ -50,6 +51,12 @@ properties: description: ID of the controller reset line const: 1 =20 + '#phy-cells': + description: + The first cell indicates the serdes phy number, see [2] for the + available serdes port. + const: 1 + required: - compatible - reg @@ -65,6 +72,8 @@ allOf: reg: minItems: 2 =20 + '#phy-cells': false + - if: properties: compatible: diff --git a/include/dt-bindings/soc/airoha,scu-ssr.h b/include/dt-bindings= /soc/airoha,scu-ssr.h new file mode 100644 index 000000000000..33c64844ada3 --- /dev/null +++ b/include/dt-bindings/soc/airoha,scu-ssr.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef __DT_BINDINGS_AIROHA_SCU_SSR_H +#define __DT_BINDINGS_AIROHA_SCU_SSR_H + +#define AIROHA_SCU_SERDES_PCIE1 0 +#define AIROHA_SCU_SERDES_PCIE2 1 +#define AIROHA_SCU_SERDES_USB1 2 +#define AIROHA_SCU_SERDES_USB2 3 + +#endif /* __DT_BINDINGS_AIROHA_SCU_SSR_H */ --=20 2.53.0 From nobody Sun May 24 23:29:00 2026 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D4D93EFD09 for ; Wed, 20 May 2026 15:09:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289775; cv=none; b=f/Q1pLOTMScn6qRThaErdhzuKfeFHtkMWhkM4EoJhMNsIzjH0+r/0lTCEZWAVmxgY4CWUa5m+fWpUmaWeho5ClSrLec6uJf3nEaNi33PC7jzgy208sN+1NO0mdkR9Up0FkT/j/gP8j65LQULKkm65glN1AhCysxXxGARRUcMwV0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289775; c=relaxed/simple; bh=/cWkT/5cDwRr+Z/YzDvHLC9i7Z75yeCUvsJcM9mi1FE=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uAwMHLsJYE4lqI6cd7lVCqmGsYAwlAgIKgpyCPl5urm0gNCRXz05gY1E+7ml296mPC+P9OrM5ue/GYxD40xTRC8GAbNzIPHNMIOw8IYhqgoNpwmPABKy85xk/EMl1NUKGsiWCmOjaQBfAxBbYUXUuZlmQcYR03PnZEmU0lW4CLA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fLhbP1uu; arc=none smtp.client-ip=209.85.221.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fLhbP1uu" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-45e7c636e74so2569083f8f.0 for ; Wed, 20 May 2026 08:09:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779289773; x=1779894573; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=lV7W1ei2FqWvKC5DxEE00R5KzZQXh+DIYHlxBEzj0kw=; b=fLhbP1uuHTWyzWj6Ds1mvrVg0NMVd9GnjbPwngQpFLtEeUf2T6hB210hHYNFF5nuVk e7PNbw7Lfmy6EbK0zWIl5zFX1A4irIsU1UiD6SvyHKNxkVzvIK70xqrg9PS/yNHJDqoL uZ1w/HisP3e6PKex/VXXUNraNRp7OWisidTGWRFqsqRA65zxIkZkPfhW7DwdDsi0tnQw MLs47n9uiFDPVBfr1x/w8JVPe1l/gQS4Xyaybsx2hWweVKyPMGbb6xR4B52+nT33+Fyo sy2BG9Rfi2WW+mUXqrWz/GdfcD+pJrBOcfp/gFDudKd9NsB8pY0V87FuaheOIBvt4MaF q29w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779289773; x=1779894573; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=lV7W1ei2FqWvKC5DxEE00R5KzZQXh+DIYHlxBEzj0kw=; b=qheJd5o5qTKdBYEmqubBSmpoPC/5t4toi5ITp+p2iRg9QLVR/zs/Bx6dP326GUM8UG 5MPAPQLlv7lg9FdeD0DRdYEQVnQieai2kHtjKSq58moFRpY80nNy2AfHedwiaBahWtJu uU6Jqgsvfhxp+oAY1JobzMCRu4k2+Nd7LHM1ZRLl/jSi77GuN9IyoTbjVzkRhzJQCidk sXr/ZOq1x1fHDoPYkW7ApRlJNF6lWV62DtbkwaZEBLkoPqytetpFrAP7AAT/0w1xUbDO zO8jxrT56sLbHdkyUHfRDb4/dljqgeMsG/4KVYrR6gLGlJXWrqX50zQHB+oqLMIT21cJ MdjA== X-Forwarded-Encrypted: i=1; AFNElJ+BT/jf871SEW/VKxUGVOzPINudeNWbM+U5Gj3/6ovUxO2ujUilo6bqa19VrP/ZCws46zKzpYseRw85mMA=@vger.kernel.org X-Gm-Message-State: AOJu0Yy3A9zc2EaiqQ7Wg6WRh0p4bGVRCf8bkxrkoeJAUHBN3cFUKW43 0Dd6HUftN0Ub+EHz8Ni1SlKME3kgK5jDTXwaUDw8sTviJncnsA6ntMi1 X-Gm-Gg: Acq92OH7l5UnQk34af5p/s1KoR2Esvaxug0ZwbciEWKuVYMWRw6bsvpCKvlQVvtNtwv P3bisau4cgoF8x2hIATdksdCWBNmmFLjuQQPRONxQJRqVwtlvNv3fQ26Il1G1Ioeb3KzLxY1HsC 6LIbli67mJSuGfprTDXi2VIRPo43vqILw3cUIDaeIDauirFI/m6TMLftFW/xBNSejSMYTZf0KjN nMNnSMJVl7u1D7PObNKEMBLknNUzbxT/0B3OiAw8kJklHtINbYKASp2Bm2eAuDpBofQka4JZ8nO 43eAp/0/XVhZ1q+b9c4E6DcIecJ71JZiQFf+LEA9X/Ggt3V1wWxcLnqt4zhH0P+wJOuMABI9OfO Yeupl9wS/X7iVzHwBJODO6dsYjtaisqPJW+IEnbH6C/ZD/nvREGi/VxmFKmNTzGxz6rgoM89WbM WsbzTKupxYkTNz3ikHgQi1R349r9KJI8hwQjAyeO0h6wBBCho8XUsNrZZCi8f03TuAOcKoSkhYj A== X-Received: by 2002:a05:6000:25c1:b0:43c:fb48:6856 with SMTP id ffacd0b85a97d-45e5c5af3c9mr45932958f8f.13.1779289772363; Wed, 20 May 2026 08:09:32 -0700 (PDT) Received: from Ansuel-XPS24 (host-79-22-5-99.retail.telecomitalia.it. [79.22.5.99]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-45d9ec39806sm53639804f8f.9.2026.05.20.08.09.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2026 08:09:31 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Brian Masney , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Neil Armstrong , Lorenzo Bianconi , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v8 2/5] dt-bindings: phy: Add documentation for Airoha AN7581 USB PHY Date: Wed, 20 May 2026 17:09:07 +0200 Message-ID: <20260520150912.11614-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520150912.11614-1-ansuelsmth@gmail.com> References: <20260520150912.11614-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add documentation for Airoha AN7581 USB PHY that describe the USB PHY for the USB controller. Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is always supported. The USB 3.0 mode is optional and depends on the Serdes mode currently configured on the system for the relevant USB port. To correctly calibrate, the USB 2.0 port require correct value in "airoha,usb2-monitor-clk-sel" property. Both the 2 USB 2.0 port permit selecting one of the 4 monitor clock for calibration (internal clock not exposed to the system) but each port have only one of the 4 actually connected in HW hence the correct value needs to be specified in DT based on board and the physical port. Normally it's monitor clock 1 for USB1 and monitor clock 2 for USB2. To correctly setup the Serdes mode attached to the USB 3.0 mode, a phys property is required with the phandle pointing to the correct Serdes port provided by the SCU node. Signed-off-by: Christian Marangi --- .../bindings/phy/airoha,an7581-usb-phy.yaml | 62 +++++++++++++++++++ MAINTAINERS | 6 ++ 2 files changed, 68 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/airoha,an7581-usb= -phy.yaml diff --git a/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.ya= ml b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml new file mode 100644 index 000000000000..f561cf2a8103 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/airoha,an7581-usb-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Airoha AN7581 SoC USB PHY + +maintainers: + - Christian Marangi + +description: > + The Airoha AN7581 SoC USB PHY describes the USB PHY for the USB controll= er. + + Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is + always supported. The USB 3.0 mode is optional and depends on the Serdes + mode currently configured on the system for the relevant USB port. + +properties: + compatible: + const: airoha,an7581-usb-phy + + reg: + maxItems: 1 + + airoha,usb2-monitor-clk-sel: + description: Describe what oscillator across the available 4 + should be selected for USB 2.0 Slew Rate calibration. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + phys: + items: + - description: phandle to Serdes PHY + + '#phy-cells': + description: The cell contains the mode, PHY_TYPE_USB2 or PHY_TYPE_USB= 3, + as defined in dt-bindings/phy/phy.h. + const: 1 + +required: + - compatible + - reg + - airoha,usb2-monitor-clk-sel + - '#phy-cells' + +additionalProperties: false + +examples: + - | + #include + + phy@1fac0000 { + compatible =3D "airoha,an7581-usb-phy"; + reg =3D <0x1fac0000 0x10000>; + + airoha,usb2-monitor-clk-sel =3D <1>; + phys =3D <&scu AIROHA_SCU_SERDES_USB1>; + + #phy-cells =3D <1>; + }; + diff --git a/MAINTAINERS b/MAINTAINERS index 21c0ef0b9ce5..932044785a39 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -771,6 +771,12 @@ S: Maintained F: Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml F: drivers/spi/spi-airoha-snfi.c =20 +AIROHA USB PHY DRIVER +M: Christian Marangi +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml + AIRSPY MEDIA DRIVER L: linux-media@vger.kernel.org S: Orphan --=20 2.53.0 From nobody Sun May 24 23:29:00 2026 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D07573F1AA3 for ; Wed, 20 May 2026 15:09:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289779; cv=none; b=BcgIR5z1uMCDalyt6GmlMaTDOcJvxNEquFsG4BPJZlkIcup6NilfAYQjplUJQ+m69CXBzjI1oPMgulGiUISUp5g03lIgP05xInEXOyHK3T+eJ5L9j5CYntuxf1WvXnFC2W1KLeWaAuGVZhTyWmLS23NIpxYfQ0DIieOOaSaKLKM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289779; c=relaxed/simple; bh=Lb10nTQ+Y2EDvWM3iNhPzMKLtTjEpE4NhIvlNz51DcQ=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Rv7hQ2utRtpL514JMIq+oTmyNivUK2Uq5YyipfreBwyUYysmCrwArWq1IvZtSU9fWtfL6q0Y0IUfY2DEV6G1ads/0KjQpDhGCl3dm++UcrOYpUU4rpHyYiHqCSqpKZ74IoQOQHVVILatsHnhoWAWgKMJjeHF5OQo7W6clOynfgw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=rt2Dk4Vq; arc=none smtp.client-ip=209.85.221.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rt2Dk4Vq" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-4585a116a4aso4169357f8f.3 for ; Wed, 20 May 2026 08:09:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779289774; x=1779894574; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=OcqxyJy9+iSxN3v0eKucih1v5mXSuhXWeT3NG1ofCfU=; b=rt2Dk4VqZa+w/k7BASm7M4pp/LlIQdXT3txWpafe/Jy6zJsg4NX+1XLhnS36ClME1A /x3bwC9wZlXh0kY6vDyWJgnchFHox3+IapAuLU7Q3GNrOy7gzoxpyg6pjGdYREUKW+GG skom0BgKvjekgKFXBEsCqXBUA/uQXCOxx7KG7vJgSUvzojh+CGjNBD8IaOmJRz7IkCoM L7uhvutKTS5aKZwZgNzg777pZ5GsBUbc8zJAUTn6Rw8w5ep+thjPFk1zFJZIcS9rmoo2 Tt6jC8Y8wECap6htuV0rin9sL7VOzIoZWeGUcn7vqytzbZayu3R2qdgRm/Mjya1XVgPr W25A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779289774; x=1779894574; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=OcqxyJy9+iSxN3v0eKucih1v5mXSuhXWeT3NG1ofCfU=; b=j8HOLo/nCuYCUtDxEPrtwoMs3W7m36e4toDLlsOWlO5D08RQx2qdnouVegMY/CkBW/ vZTPVXKCJekeaVaWsRgXGVNx7vgTNGUuOZYZrVifQ9sVIdKkuiXvCZMIuWtyRJE5DT+7 gvLdT/LgRVDYoZ8E1J7H9aaIzDtZFQGrWS8LxIIbP6cf92oEcNFccDTmCDMxjvpjrF1P utY16i5EsBXb5G4X5Sn3uEmcS5G+SX5Zu1SQuVF0q4Uij7u3pyYxv5HoN9/Q5m8J6aW8 iuPzNolebqd6P8XUbLq0804VGXjNyw0RutY2n11Iqw/ym5ZPRZrkaeXSF8bslQDT3TIo MmRQ== X-Forwarded-Encrypted: i=1; AFNElJ/RmMZqtFZ9duKo+p+baPogd05YWCQj+HFyARcb4hyqeMG+iToe4NO6hUN3ANXOcrYkrEJtxH5hOiO5WiY=@vger.kernel.org X-Gm-Message-State: AOJu0YwO1jBDwBuOuG1V2s7JNA1noXyKUMboW5X3dF3YRjyZtDollUXv 3MlIweOz35sLVVVvo9nLGcJAqvMLT6mjaOEstCZsE+wqNa2B1/FvSjQv X-Gm-Gg: Acq92OHMNNmaSrGsk6cLKzKROhRgUhE/AYXYu74a40+dwogKWuSy0bTteO1PVCuhybp CK1/TvH2FP0f/e/CReJbGzlIjjPdzyCEWBVKbKHICuDCjm3kU5mWonygkdDO1oYYxhu8xRiM5sI aSieSICE/z0IwGPl2/wW18TMZRBqcTKHtiaYAFEdupmdQdJnJIiruEfbTzLoU1w9zlCCf6pps9u DKtrAszXMnPlZOFkAgQ2kwyU8qTCLbogRUwQpynzyCYHSrmvyHRdARbWBbWf5TPE0BtfjFYO/D8 Ri4x1PnabW8xDurNqigvWBmxE2XODACA1h49WJu5q8zTlg85wwucyfzA7KB4d9StnTDbUD5XVI8 nc7AKhgU42H3sQuTUq7c5IKPQ5sD9ZK9SMhKuodNDnCtAvuVRAMiL4O4SjkS/xJpoEteGzX4MEM 6VoaxOxWAT9ITVtOJTpJZvK8YiW4Alm/L8IAoqxu0rip4osPV/Wa34hc3U5OjlsTk= X-Received: by 2002:a05:6000:200c:b0:45e:9421:4ca8 with SMTP id ffacd0b85a97d-45e94215044mr5889094f8f.28.1779289774192; Wed, 20 May 2026 08:09:34 -0700 (PDT) Received: from Ansuel-XPS24 (host-79-22-5-99.retail.telecomitalia.it. [79.22.5.99]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-45d9ec39806sm53639804f8f.9.2026.05.20.08.09.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2026 08:09:33 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Brian Masney , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Neil Armstrong , Lorenzo Bianconi , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v8 3/5] clk: en7523: Add support for selecting the Serdes port in SCU Date: Wed, 20 May 2026 17:09:08 +0200 Message-ID: <20260520150912.11614-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520150912.11614-1-ansuelsmth@gmail.com> References: <20260520150912.11614-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the SCU register for clock and reset, there are also some register to select the Serdes port mode. The Airoha AN7581 SoC have 4 different Serdes that can switch between PCIe, USB or Ethernet mode. Add a simple PHY provider that expose the .set_mode OP to toggle the requested mode for the Serdes port. Signed-off-by: Christian Marangi Reviewed-by: Brian Masney --- drivers/clk/Kconfig | 1 + drivers/clk/clk-en7523.c | 216 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 214 insertions(+), 3 deletions(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index b2efbe9f6acb..e60a824b5117 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -221,6 +221,7 @@ config COMMON_CLK_EN7523 bool "Clock driver for Airoha/EcoNet SoC system clocks" depends on OF depends on ARCH_AIROHA || ECONET || COMPILE_TEST + select GENERIC_PHY default ARCH_AIROHA help This driver provides the fixed clocks and gates present on Airoha diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 1ab0e2eca5d3..d4b73c5f15b9 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -6,14 +6,18 @@ #include #include #include +#include +#include #include #include #include +#include #include #include #include #include #include +#include =20 #define RST_NR_PER_BANK 32 =20 @@ -40,9 +44,22 @@ #define REG_HIR_MASK GENMASK(31, 16) /* EN7581 */ #define REG_NP_SCU_PCIC 0x88 +#define REG_NP_SCU_SSR3 0x94 +#define REG_SSUSB_HSGMII_SEL_MASK BIT(29) +#define REG_SSUSB_HSGMII_SEL_HSGMII FIELD_PREP_CONST(REG_SSUSB_HSGMII_SEL_= MASK, 0x0) +#define REG_SSUSB_HSGMII_SEL_USB FIELD_PREP_CONST(REG_SSUSB_HSGMII_SEL_MAS= K, 0x1) #define REG_NP_SCU_SSTR 0x9c #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) +#define REG_PCIE_XSI0_SEL_PCIE FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0= x0) +#define REG_PCIE_XSI0_SEL_XFI FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x= 1) +#define REG_PCIE_XSI0_SEL_HSGMII FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, = 0x2) #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) +#define REG_PCIE_XSI1_SEL_PCIE FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0= x0) +#define REG_PCIE_XSI1_SEL_XFI FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x= 1) +#define REG_PCIE_XSI1_SEL_HSGMII FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, = 0x2) +#define REG_USB_PCIE_SEL_MASK BIT(3) +#define REG_USB_PCIE_SEL_PCIE FIELD_PREP_CONST(REG_USB_PCIE_SEL_MASK, 0x0) +#define REG_USB_PCIE_SEL_USB FIELD_PREP_CONST(REG_USB_PCIE_SEL_MASK, 0x1) #define REG_CRYPTO_CLKSRC2 0x20c /* EN751221 */ #define EN751221_REG_SPI_DIV 0x0cc @@ -81,6 +98,8 @@ enum en_hir { HIR_MAX =3D 14, }; =20 +#define EN_SERDES_PHY_NUM 4 + struct en_clk_desc { int id; const char *name; @@ -113,6 +132,18 @@ struct en_rst_data { struct reset_controller_dev rcdev; }; =20 +struct en_serdes_phy_instance { + struct phy *phy; + unsigned int serdes_port; +}; + +struct en_clk_priv { + void __iomem *base; + /* protect SCU register */ + spinlock_t lock; + struct en_serdes_phy_instance *serdes_phys[EN_SERDES_PHY_NUM]; +}; + struct en_clk_soc_data { u32 num_clocks; const struct clk_ops pcie_ops; @@ -830,12 +861,179 @@ static int en7581_reset_register(struct device *dev,= void __iomem *base, return devm_reset_controller_register(dev, &rst_data->rcdev); } =20 +static int en7581_serdes_phy_set_mode(struct phy *phy, enum phy_mode mode, + int submode) +{ + struct en_serdes_phy_instance *instance =3D phy_get_drvdata(phy); + struct en_clk_priv *priv =3D dev_get_drvdata(phy->dev.parent); + u32 reg, mask, sel, val; + unsigned long flags; + + switch (instance->serdes_port) { + case AIROHA_SCU_SERDES_PCIE1: + reg =3D REG_NP_SCU_SSTR; + mask =3D REG_PCIE_XSI0_SEL_MASK; + + if (mode !=3D PHY_MODE_ETHERNET && mode !=3D PHY_MODE_PCIE) + return -EINVAL; + + if (mode =3D=3D PHY_MODE_ETHERNET) { + switch (submode) { + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + sel =3D REG_PCIE_XSI0_SEL_XFI; + break; + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + sel =3D REG_PCIE_XSI0_SEL_HSGMII; + break; + default: + return -EINVAL; + } + } else { + sel =3D REG_PCIE_XSI0_SEL_PCIE; + } + + break; + case AIROHA_SCU_SERDES_PCIE2: + reg =3D REG_NP_SCU_SSTR; + mask =3D REG_PCIE_XSI1_SEL_MASK; + + if (mode !=3D PHY_MODE_ETHERNET && mode !=3D PHY_MODE_PCIE) + return -EINVAL; + + if (mode =3D=3D PHY_MODE_ETHERNET) { + switch (submode) { + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + sel =3D REG_PCIE_XSI1_SEL_XFI; + break; + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + sel =3D REG_PCIE_XSI1_SEL_HSGMII; + break; + default: + return -EINVAL; + } + } else { + sel =3D REG_PCIE_XSI1_SEL_PCIE; + } + + break; + case AIROHA_SCU_SERDES_USB1: + reg =3D REG_NP_SCU_SSR3; + mask =3D REG_SSUSB_HSGMII_SEL_MASK; + + if (mode !=3D PHY_MODE_ETHERNET && mode !=3D PHY_MODE_USB_DEVICE && + mode !=3D PHY_MODE_USB_DEVICE_SS) + return -EINVAL; + + if (mode =3D=3D PHY_MODE_ETHERNET) + sel =3D REG_SSUSB_HSGMII_SEL_HSGMII; + else + sel =3D REG_SSUSB_HSGMII_SEL_USB; + + break; + case AIROHA_SCU_SERDES_USB2: + reg =3D REG_NP_SCU_SSTR; + mask =3D REG_USB_PCIE_SEL_MASK; + + if (mode !=3D PHY_MODE_PCIE && mode !=3D PHY_MODE_USB_DEVICE && + mode !=3D PHY_MODE_USB_DEVICE_SS) + return -EINVAL; + + if (mode =3D=3D PHY_MODE_PCIE) + sel =3D REG_USB_PCIE_SEL_PCIE; + else + sel =3D REG_USB_PCIE_SEL_USB; + + break; + default: + return -EINVAL; + } + + spin_lock_irqsave(&priv->lock, flags); + val =3D readl(priv->base + reg); + val &=3D ~mask; + val |=3D sel; + writel(val, priv->base + reg); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static const struct phy_ops en7581_serdes_phy_ops =3D { + .set_mode =3D en7581_serdes_phy_set_mode, + .owner =3D THIS_MODULE, +}; + +static struct phy *en7581_serdes_phy_xlate(struct device *dev, + const struct of_phandle_args *args) +{ + struct en_clk_priv *priv =3D dev_get_drvdata(dev); + struct en_serdes_phy_instance *instance; + unsigned int serdes_port; + + if (args->args_count !=3D 1) { + dev_err(dev, "invalid number of cells in 'phy' property\n"); + return ERR_PTR(-EINVAL); + } + + serdes_port =3D args->args[0]; + if (serdes_port >=3D EN_SERDES_PHY_NUM) { + dev_err(dev, "invalid serdes port: %d\n", serdes_port); + return ERR_PTR(-EINVAL); + } + + instance =3D priv->serdes_phys[serdes_port]; + if (!instance) { + dev_err(dev, "failed to find appropriate serdes phy\n"); + return ERR_PTR(-EINVAL); + } + + return instance->phy; +} + +static int en7581_serdes_phy_register(struct device *dev) +{ + struct en_clk_priv *priv =3D dev_get_drvdata(dev); + struct phy_provider *phy_provider; + int i; + + for (i =3D 0; i < EN_SERDES_PHY_NUM; i++) { + struct en_serdes_phy_instance *instance; + + instance =3D devm_kzalloc(dev, sizeof(*instance), + GFP_KERNEL); + if (!instance) + return -ENOMEM; + + instance->phy =3D devm_phy_create(dev, NULL, + &en7581_serdes_phy_ops); + if (IS_ERR(instance->phy)) + return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy= \n"); + + instance->serdes_port =3D i; + priv->serdes_phys[i] =3D instance; + + phy_set_drvdata(instance->phy, instance); + } + + phy_provider =3D devm_of_phy_provider_register(dev, en7581_serdes_phy_xla= te); + + return PTR_ERR_OR_ZERO(phy_provider); +} + static int en7581_clk_hw_init(struct platform_device *pdev, struct clk_hw_onecell_data *clk_data) { + struct en_clk_priv *priv =3D platform_get_drvdata(pdev); struct regmap *map; void __iomem *base; u32 val; + int ret; =20 map =3D syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); if (IS_ERR(map)) @@ -845,6 +1043,8 @@ static int en7581_clk_hw_init(struct platform_device *= pdev, if (IS_ERR(base)) return PTR_ERR(base); =20 + priv->base =3D base; + en7581_register_clocks(&pdev->dev, clk_data, map, base); =20 val =3D readl(base + REG_NP_SCU_SSTR); @@ -853,9 +1053,12 @@ static int en7581_clk_hw_init(struct platform_device = *pdev, val =3D readl(base + REG_NP_SCU_PCIC); writel(val | 3, base + REG_NP_SCU_PCIC); =20 - return en7581_reset_register(&pdev->dev, base, en7581_rst_map, - ARRAY_SIZE(en7581_rst_map), - en7581_rst_ofs); + ret =3D en7581_reset_register(&pdev->dev, base, en7581_rst_map, + ARRAY_SIZE(en7581_rst_map), en7581_rst_ofs); + if (ret) + return ret; + + return en7581_serdes_phy_register(&pdev->dev); } =20 static enum en_hir get_hw_id(void __iomem *np_base) @@ -962,16 +1165,23 @@ static int en7523_clk_probe(struct platform_device *= pdev) struct device_node *node =3D pdev->dev.of_node; const struct en_clk_soc_data *soc_data; struct clk_hw_onecell_data *clk_data; + struct en_clk_priv *priv; int r; =20 soc_data =3D device_get_match_data(&pdev->dev); =20 + priv =3D devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + clk_data =3D devm_kzalloc(&pdev->dev, struct_size(clk_data, hws, soc_data->num_clocks), GFP_KERNEL); if (!clk_data) return -ENOMEM; =20 + platform_set_drvdata(pdev, priv); + clk_data->num =3D soc_data->num_clocks; r =3D soc_data->hw_init(pdev, clk_data); if (r) --=20 2.53.0 From nobody Sun May 24 23:29:00 2026 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D19B23F39D1 for ; Wed, 20 May 2026 15:09:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289780; cv=none; b=oWX4fZPGd7EBkxQ7d9PvD7cH+DfF42dl2nOgtJbjZvduUOn4sOy1FDndFSAVc8agnCAAsHwZ7IeE/v9i9miv3VVV1yZKB031PzZS3oDqQJRlcTWVKa4qcUY1Zg65ghVJ3kw+vDGl813iqgczuvnuI9ROUH9zODp/wl3XW3T8uGM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289780; c=relaxed/simple; bh=vlR3puWHieza9MOKOJJmGwiDMzuP1TFxVd7G1KyNRhE=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p2YftXOAPVqbRaknmCLW9d11bm9xi5lLNpOtumcyj9jRwGO+kdvoa24kCbBulT/KM/f6XS57j9nT4GW7SyVp3WZqsFAesNjh6k3y4HTreWl4ixbP2pLOOPUwD7wj/vARsZ5xjZjvYAAJgFHSnTHIQslmNtJ1ufQEAKL+3jrb8o0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=S5x73lQB; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="S5x73lQB" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-4896c22fcbaso41994935e9.0 for ; Wed, 20 May 2026 08:09:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779289776; x=1779894576; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=+2MTlGdLnnx84SeHTRkSWUbFZVMSjGe7LyFztDYyPJA=; b=S5x73lQBCf9UybaDWvvjcXmxHXgiEzbnTdBwUVli19zUHvDqwqkE3plYGdpffl0ukA 2BQawt5rEpnXcVCikBNQzzr/ZkgEWVKDQ/tgwKYWwz2zDvL9mrR35gcmJ/NEGafTar5N iqreCi1sQmG/iihGDtzCFPRrOMk+GtYHtizdnhK9rqLfu3zuDY9Dqcnj6t3zWUnppvNm Z5EywHBskfYaxR2tlEE9BdJncw5bOC8H1PUscB7nQI8TjNJWMjsuV7lZm3aZ8TSemIx7 T82g557EO9fFueYIr2Ok5dZCmeEaGdRGyJpzN/yEF+j3k0nB46fEdn7RHKcYjlVRwXvq JjQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779289776; x=1779894576; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=+2MTlGdLnnx84SeHTRkSWUbFZVMSjGe7LyFztDYyPJA=; b=S3ndCrU9JYVx/qaow+4ht6qoMyQLuBXWf/kOLNqWWPnnzkCWR1JauduELKkvhM12Zd d7S68Qu3n5Jz8S/J72K5SJEwKIo+uqGozkTMqjMkPo0Gs0ZWqs6SNfAyhPeWW6DQCk9t eESKFCoOLNjpBs+izDQcyV7LfpzkvAJIlJl2y67JqKbk7bEP4/WLiiS19E90lkqKcuq1 j/XLgtMCpSYOfFPcvdaXtrEYzRitSkIFws1WGpHHbClA7ZbubnbvfUUVHbO2ItHD124W qMftVO1IsusY/wimLwuNkicsUHlBdjI1MWPRmhVvnVWBNQ/6WwAMtb7YJf4a01aio37E Pj+A== X-Forwarded-Encrypted: i=1; AFNElJ8C5ocvzxTdwiXFbf2CGp6LHg4wOYMrzl1HdqirFCHXngiFN4c7M7/ZK8oEKXiEfhMefVtkI0YUSlE07J4=@vger.kernel.org X-Gm-Message-State: AOJu0YyFqYB+GUgHFqlqVwZ7lyEFazVGY1ICg7GDBP1gBaEsd7AIUtxG H1fa/eD0Loq9naJ/TBX0rilnAXqH0UtbLZkbTpNAv5xDmiOK89uMepjW X-Gm-Gg: Acq92OGXTimmUNK7bhRVAj1Z2sS8GYqxn2canQYGQIxm5EERkGzTY9fAfALp3fhofw2 pzThgxPlY/xqn86xz2vAQ9cVPU7h5lt0q453vLRTcd3hxLQJjWE07wtfdR+yvk9ScQo6zyI+eK8 iEcj3rgSP7mMINuZRupHx9vZmbUeMsmatiMVAxfEi2i0tt4TeZTJElUkHzHgv62nwNfjOtoJaei 9tDE/sTiLvice47NbrZsv4jVfaJ7UYU5uQljiEfdWkVPTifPE8jzEzQgrHol58fHxHkYDrGfISh VNwW63hfsZX5FuvWXR4Irllj8jGBrCZYPqD1hyNyC50v6MsJRi/r/xltfF3Hr6Hn+L0Y7/eEj8e giZ0DZw1E72a5mRqTVdGW8mDfgJeh4QSXjo+lupr3jUvRG3ZQ1HPq3ZbEpqhTgSMcCwE0xspiRY LGXQfTpUk9h+u526KGscieeSGGoh+6vDnLfLDEN2NMgjieBi3CMglwI/HynbFhwpo= X-Received: by 2002:a05:600d:8496:10b0:48f:eb8b:9980 with SMTP id 5b1f17b1804b1-48feb8b9ademr241288455e9.30.1779289776052; Wed, 20 May 2026 08:09:36 -0700 (PDT) Received: from Ansuel-XPS24 (host-79-22-5-99.retail.telecomitalia.it. [79.22.5.99]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-45d9ec39806sm53639804f8f.9.2026.05.20.08.09.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2026 08:09:35 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Brian Masney , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Neil Armstrong , Lorenzo Bianconi , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v8 4/5] phy: move and rename Airoha PCIe PHY driver to dedicated directory Date: Wed, 20 May 2026 17:09:09 +0200 Message-ID: <20260520150912.11614-5-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520150912.11614-1-ansuelsmth@gmail.com> References: <20260520150912.11614-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To keep the generic PHY directory tidy, move the PCIe PHY driver for Airoha AN7581 SoC to a dedicated directory. Also rename the driver and add the relevant SoC name to the .c and .h file in preparation for support of PCIe and USB PHY driver for Airoha AN7583 SoC that use a completely different implementation and calibration for PHYs and will have their own dedicated drivers. The rename permits to better identify the specific usage of the driver in the future once the airoha PHY directory will have multiple driver for multiple SoC. The config is changed from PHY_AIROHA_PCIE to PHY_AIROHA_AN7581_PCIE. Signed-off-by: Christian Marangi Acked-by: Lorenzo Bianconi --- MAINTAINERS | 4 ++-- drivers/phy/Kconfig | 11 +---------- drivers/phy/Makefile | 4 ++-- drivers/phy/airoha/Kconfig | 13 +++++++++++++ drivers/phy/airoha/Makefile | 3 +++ .../phy-an7581-pcie-regs.h} | 2 +- .../{phy-airoha-pcie.c =3D> airoha/phy-an7581-pcie.c} | 6 +++--- 7 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 drivers/phy/airoha/Kconfig create mode 100644 drivers/phy/airoha/Makefile rename drivers/phy/{phy-airoha-pcie-regs.h =3D> airoha/phy-an7581-pcie-reg= s.h} (99%) rename drivers/phy/{phy-airoha-pcie.c =3D> airoha/phy-an7581-pcie.c} (99%) diff --git a/MAINTAINERS b/MAINTAINERS index 932044785a39..7bea8c620da8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -759,8 +759,8 @@ M: Lorenzo Bianconi L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml -F: drivers/phy/phy-airoha-pcie-regs.h -F: drivers/phy/phy-airoha-pcie.c +F: drivers/phy/airoha/phy-an7581-pcie-regs.h +F: drivers/phy/airoha/phy-an7581-pcie.c =20 AIROHA SPI SNFI DRIVER M: Lorenzo Bianconi diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 227b9a4c612e..f9cd765a3ccc 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -46,16 +46,6 @@ config GENERIC_PHY_MIPI_DPHY Provides a number of helpers a core functions for MIPI D-PHY drivers to us. =20 -config PHY_AIROHA_PCIE - tristate "Airoha PCIe-PHY Driver" - depends on ARCH_AIROHA || COMPILE_TEST - depends on OF - select GENERIC_PHY - help - Say Y here to add support for Airoha PCIe PHY driver. - This driver create the basic PHY instance and provides initialize - callback for PCIe GEN3 port. - config PHY_CAN_TRANSCEIVER tristate "CAN transceiver PHY" select GENERIC_PHY @@ -133,6 +123,7 @@ config PHY_XGENE help This option enables support for APM X-Gene SoC multi-purpose PHY. =20 +source "drivers/phy/airoha/Kconfig" source "drivers/phy/allwinner/Kconfig" source "drivers/phy/amlogic/Kconfig" source "drivers/phy/apple/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index f49d83f00a3d..84062279fa63 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_PHY_COMMON_PROPS) +=3D phy-common-props.o obj-$(CONFIG_PHY_COMMON_PROPS_TEST) +=3D phy-common-props-test.o obj-$(CONFIG_GENERIC_PHY) +=3D phy-core.o obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) +=3D phy-core-mipi-dphy.o -obj-$(CONFIG_PHY_AIROHA_PCIE) +=3D phy-airoha-pcie.o obj-$(CONFIG_PHY_CAN_TRANSCEIVER) +=3D phy-can-transceiver.o obj-$(CONFIG_PHY_GOOGLE_USB) +=3D phy-google-usb.o obj-$(CONFIG_USB_LGM_PHY) +=3D phy-lgm-usb.o @@ -17,7 +16,8 @@ obj-$(CONFIG_PHY_PISTACHIO_USB) +=3D phy-pistachio-usb.o obj-$(CONFIG_PHY_SNPS_EUSB2) +=3D phy-snps-eusb2.o obj-$(CONFIG_PHY_XGENE) +=3D phy-xgene.o =20 -obj-$(CONFIG_GENERIC_PHY) +=3D allwinner/ \ +obj-$(CONFIG_GENERIC_PHY) +=3D airoha/ \ + allwinner/ \ amlogic/ \ apple/ \ broadcom/ \ diff --git a/drivers/phy/airoha/Kconfig b/drivers/phy/airoha/Kconfig new file mode 100644 index 000000000000..9a1b625a7701 --- /dev/null +++ b/drivers/phy/airoha/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Phy drivers for Airoha devices +# +config PHY_AIROHA_AN7581_PCIE + tristate "Airoha AN7581 PCIe-PHY Driver" + depends on ARCH_AIROHA || COMPILE_TEST + depends on OF + select GENERIC_PHY + help + Say Y here to add support for Airoha AN7581 PCIe PHY driver. + This driver create the basic PHY instance and provides initialize + callback for PCIe GEN3 port. diff --git a/drivers/phy/airoha/Makefile b/drivers/phy/airoha/Makefile new file mode 100644 index 000000000000..912f3e11a061 --- /dev/null +++ b/drivers/phy/airoha/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_PHY_AIROHA_AN7581_PCIE) +=3D phy-an7581-pcie.o diff --git a/drivers/phy/phy-airoha-pcie-regs.h b/drivers/phy/airoha/phy-an= 7581-pcie-regs.h similarity index 99% rename from drivers/phy/phy-airoha-pcie-regs.h rename to drivers/phy/airoha/phy-an7581-pcie-regs.h index 58572c793722..b938a7b468fe 100644 --- a/drivers/phy/phy-airoha-pcie-regs.h +++ b/drivers/phy/airoha/phy-an7581-pcie-regs.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2024 AIROHA Inc * Author: Lorenzo Bianconi diff --git a/drivers/phy/phy-airoha-pcie.c b/drivers/phy/airoha/phy-an7581-= pcie.c similarity index 99% rename from drivers/phy/phy-airoha-pcie.c rename to drivers/phy/airoha/phy-an7581-pcie.c index 56e9ade8a9fd..81ddf0e7638b 100644 --- a/drivers/phy/phy-airoha-pcie.c +++ b/drivers/phy/airoha/phy-an7581-pcie.c @@ -13,7 +13,7 @@ #include #include =20 -#include "phy-airoha-pcie-regs.h" +#include "phy-an7581-pcie-regs.h" =20 #define LEQ_LEN_CTRL_MAX_VAL 7 #define FREQ_LOCK_MAX_ATTEMPT 10 @@ -1279,12 +1279,12 @@ MODULE_DEVICE_TABLE(of, airoha_pcie_phy_of_match); static struct platform_driver airoha_pcie_phy_driver =3D { .probe =3D airoha_pcie_phy_probe, .driver =3D { - .name =3D "airoha-pcie-phy", + .name =3D "airoha-an7581-pcie-phy", .of_match_table =3D airoha_pcie_phy_of_match, }, }; module_platform_driver(airoha_pcie_phy_driver); =20 -MODULE_DESCRIPTION("Airoha PCIe PHY driver"); +MODULE_DESCRIPTION("Airoha AN7581 PCIe PHY driver"); MODULE_AUTHOR("Lorenzo Bianconi "); MODULE_LICENSE("GPL"); --=20 2.53.0 From nobody Sun May 24 23:29:00 2026 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA7E63F4124 for ; Wed, 20 May 2026 15:09:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289782; cv=none; b=gyUlvOnJubCvq+3dV3nMznf4JndxmdomRRM9w4f4nUaOrFuKQ3yeQkFSD3nH5rh4m79CVuEEyYB8rLAKfsbE1bMu5W1mgYip1ldzjooB1O5WJvovEExHyY7cUVPYh6CO3Sf2DBc9sJc4BOmWOr6iCc98RA6/fE5ujnFXrGNcbME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779289782; c=relaxed/simple; bh=NYexyj5Gf2QeNQ7e/Won9RAQdu8QySVaBrFvAYuyO+A=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rCH0hYBXtTYR4iSGB0pulbG0PnOguvDw0GDIlU8awapzdO1jFqSAF2rh+aL5U23gOGmtpDf9ajUsJYJzEOu4l0MtRpTyJuDwwoye99SxDg0wrQVtCteIzVpG8ccKkDgklX2vRdpDUkS6l07iwvccUjy0ruHU868nUQvPdoWIIp8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LRKFqXo6; arc=none smtp.client-ip=209.85.221.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LRKFqXo6" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-44a5174670eso2917086f8f.1 for ; Wed, 20 May 2026 08:09:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779289778; x=1779894578; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=JWS1OAAP+b6jwf7on2TcOnkNACLqdJFBfR6vTM3JGm4=; b=LRKFqXo6d/7wqCJUJuc4nZK7L6v8YggX+movgz4GxeGOkODWfxP18h8ZsiIGF8sxcN e+wdDGsL8SM8LeXY+LTq95amR5FMHSwM46I6Y9FBrMCRfgNQzRFghz2kg/lQQn6RiT/7 x6HqWhImBGsMffYa6vN0qCe5kwjBIApt1Dknj6Kow2LIxSh/j9hXOjr4Si9BmFlr29f+ tGW3wFhNZeqPJ9AAmCB5G/aD8tpEguz+ivjIhlgFmQnOVz6mE2ztWsomJCFDTUbZux6q IBEoUR469zaPck8bxqO3fg2sfadw4nsghPntzBk9GQ3ZMr7tZTNru2+9tHgHb14uUsvE /Rhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779289778; x=1779894578; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=JWS1OAAP+b6jwf7on2TcOnkNACLqdJFBfR6vTM3JGm4=; b=AKZ/Tyoo1WpMJv59bN/t433Qy3ns9qa+kpS64DzYOK6GJolgVHI7QjJZeVGJcxHxig myj0cs0Lz38S2ysJHtx4KYrAPsBUryW0vWlxnI25ScmzU6v3IjwU3aSmoY49/49KHTIE 6hN/18XWFOsy+CxSVF+vN5tKhHwNT3c8mnrmyv/4h4hY0EjtTA65vEaQ/qk37CcYt66J cSy6N3Q9AqJChc3F3YIUKF8cxir928r6T2j9fmjZ+NzTxiAYlGvMYVgduRKxNsUABiZd rMWk3l5R2A3Z4n4W6nEmL35atXWP2UaakrJ5zop/I/Eh/D7flpqTePW6QmRNPGJnhOjf xXCg== X-Forwarded-Encrypted: i=1; AFNElJ/PFpYTF3Wd/bTnx+qzmsNh6sTLmqLfGHVyZoMx4cY1sSQW0aw9DT1lbkIDHDYWnpYWEU2S3HdkW4XWUq4=@vger.kernel.org X-Gm-Message-State: AOJu0Yzk8N2/JMvMu5zcamzxfuMWL2qESp2A8DVx6NLfWcrjzgddINzu HupV5BPo8UTixrLn6kKc+rlFMn+DbuDSttl/tVwZ+QjEJTrdsT9bfrNW X-Gm-Gg: Acq92OGXZwHjHlAfxFL0xsE9NxHPQ18v1KrE2LIJg4JFU9EwU6mbAo2VBBBx+21+tjF vPN1+H+OASt241Lsk1TCmPv7v0qI/LwbU0L6PM+dSLFgKa2+eyoFAc/j6OMpyFzZoaDTsoWyRZV OHWs8OlauwGI9IS+fi8NY5+XgPtjMOg1mSaRwg2+ewmSDOJpCOsuDzQRM9FhoeI/ahDOe3ysM3m rkO8TrptC9FtEOtc41hAP6VCFKDWmxfb2ZwdF5RZ8amiVg+y0jysfewYw5GFc1vUzy0CRviQQOz MbfNZupJyPF5D5py9HSyv2zi+wqb+G5VIUJZutohke6grGQ8hlpipYE/zC5V4owWMHXmsm2Gugd 7BMKFGgbozUV8pXhpPQZ4e/65WMEaOJ//lxHhTVF0/rDnlmVKTP9EWqgvr1DEGu12sFD6WZRdr3 AIqmiyKdzzwTu7RbPixGnQLkTzaU5uKDvMXRRxmeNcytKZKflrcFZs6fBmxWtm7DZBPUf+5yfXe A== X-Received: by 2002:a5d:5d0d:0:b0:43c:f583:126a with SMTP id ffacd0b85a97d-45e5c5a0cf8mr40664221f8f.14.1779289777753; Wed, 20 May 2026 08:09:37 -0700 (PDT) Received: from Ansuel-XPS24 (host-79-22-5-99.retail.telecomitalia.it. [79.22.5.99]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-45d9ec39806sm53639804f8f.9.2026.05.20.08.09.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2026 08:09:37 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Brian Masney , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Neil Armstrong , Lorenzo Bianconi , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v8 5/5] phy: airoha: Add support for Airoha AN7581 USB PHY Date: Wed, 20 May 2026 17:09:10 +0200 Message-ID: <20260520150912.11614-6-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520150912.11614-1-ansuelsmth@gmail.com> References: <20260520150912.11614-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for Airoha AN7581 USB PHY driver. AN7581 supports up to 2 USB port with USB 2.0 mode always supported and USB 3.0 mode available only if the Serdes port is correctly configured for USB 3.0. If the USB 3.0 mode is not configured, the modes needs to be also disabled in the xHCI node or the driver will report unsable clock and fail probe. For USB 2.0 Slew Rate calibration, airoha,usb2-monitor-clk-sel is mandatory and is used to select the monitor clock for calibration. Normally it's 1 for USB port 1 and 2 for USB port 2. Signed-off-by: Christian Marangi --- MAINTAINERS | 1 + drivers/phy/airoha/Kconfig | 11 + drivers/phy/airoha/Makefile | 1 + drivers/phy/airoha/phy-an7581-usb.c | 554 ++++++++++++++++++++++++++++ 4 files changed, 567 insertions(+) create mode 100644 drivers/phy/airoha/phy-an7581-usb.c diff --git a/MAINTAINERS b/MAINTAINERS index 7bea8c620da8..2f05faa44503 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -776,6 +776,7 @@ M: Christian Marangi L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml +F: drivers/phy/airoha/phy-an7581-usb.c =20 AIRSPY MEDIA DRIVER L: linux-media@vger.kernel.org diff --git a/drivers/phy/airoha/Kconfig b/drivers/phy/airoha/Kconfig index 9a1b625a7701..634448ee39b5 100644 --- a/drivers/phy/airoha/Kconfig +++ b/drivers/phy/airoha/Kconfig @@ -11,3 +11,14 @@ config PHY_AIROHA_AN7581_PCIE Say Y here to add support for Airoha AN7581 PCIe PHY driver. This driver create the basic PHY instance and provides initialize callback for PCIe GEN3 port. + +config PHY_AIROHA_AN7581_USB + tristate "Airoha AN7581 USB PHY Driver" + depends on ARCH_AIROHA || COMPILE_TEST + depends on OF + select GENERIC_PHY + select REGMAP_MMIO + help + Say 'Y' here to add support for Airoha AN7581 USB PHY driver. + This driver create the basic PHY instance and provides initialize + callback for USB port. diff --git a/drivers/phy/airoha/Makefile b/drivers/phy/airoha/Makefile index 912f3e11a061..944bf842deba 100644 --- a/drivers/phy/airoha/Makefile +++ b/drivers/phy/airoha/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 =20 obj-$(CONFIG_PHY_AIROHA_AN7581_PCIE) +=3D phy-an7581-pcie.o +obj-$(CONFIG_PHY_AIROHA_AN7581_USB) +=3D phy-an7581-usb.o diff --git a/drivers/phy/airoha/phy-an7581-usb.c b/drivers/phy/airoha/phy-a= n7581-usb.c new file mode 100644 index 000000000000..af20f5cb4ed1 --- /dev/null +++ b/drivers/phy/airoha/phy-an7581-usb.c @@ -0,0 +1,554 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: Christian Marangi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* U2PHY */ +#define AIROHA_USB_PHY_FMCR0 0x100 +#define AIROHA_USB_PHY_MONCLK_SEL GENMASK(27, 26) +#define AIROHA_USB_PHY_MONCLK_SEL0 FIELD_PREP_CONST(AIROHA_USB_PHY_MONC= LK_SEL, 0x0) +#define AIROHA_USB_PHY_MONCLK_SEL1 FIELD_PREP_CONST(AIROHA_USB_PHY_MONC= LK_SEL, 0x1) +#define AIROHA_USB_PHY_MONCLK_SEL2 FIELD_PREP_CONST(AIROHA_USB_PHY_MONC= LK_SEL, 0x2) +#define AIROHA_USB_PHY_MONCLK_SEL3 FIELD_PREP_CONST(AIROHA_USB_PHY_MONC= LK_SEL, 0x3) +#define AIROHA_USB_PHY_FREQDET_EN BIT(24) +#define AIROHA_USB_PHY_CYCLECNT GENMASK(23, 0) +#define AIROHA_USB_PHY_FMMONR0 0x10c +#define AIROHA_USB_PHY_USB_FM_OUT GENMASK(31, 0) +#define AIROHA_USB_PHY_FMMONR1 0x110 +#define AIROHA_USB_PHY_FRCK_EN BIT(8) + +#define AIROHA_USB_PHY_USBPHYACR4 0x310 +#define AIROHA_USB_PHY_USB20_FS_CR GENMASK(10, 8) +#define AIROHA_USB_PHY_USB20_FS_CR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_FS_CR, 0x0) +#define AIROHA_USB_PHY_USB20_FS_CR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PH= Y_USB20_FS_CR, 0x2) +#define AIROHA_USB_PHY_USB20_FS_CR_SMALLER FIELD_PREP_CONST(AIROHA_USB_P= HY_USB20_FS_CR, 0x4) +#define AIROHA_USB_PHY_USB20_FS_CR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_FS_CR, 0x6) +#define AIROHA_USB_PHY_USB20_FS_SR GENMASK(2, 0) +#define AIROHA_USB_PHY_USB20_FS_SR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_FS_SR, 0x0) +#define AIROHA_USB_PHY_USB20_FS_SR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PH= Y_USB20_FS_SR, 0x2) +#define AIROHA_USB_PHY_USB20_FS_SR_SMALLER FIELD_PREP_CONST(AIROHA_USB_P= HY_USB20_FS_SR, 0x4) +#define AIROHA_USB_PHY_USB20_FS_SR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_FS_SR, 0x6) +#define AIROHA_USB_PHY_USBPHYACR5 0x314 +#define AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN BIT(15) +#define AIROHA_USB_PHY_USB20_HSTX_SRCTRL GENMASK(14, 12) +#define AIROHA_USB_PHY_USBPHYACR6 0x318 +#define AIROHA_USB_PHY_USB20_BC11_SW_EN BIT(23) +#define AIROHA_USB_PHY_USB20_DISCTH GENMASK(7, 4) +#define AIROHA_USB_PHY_USB20_DISCTH_400 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x0) +#define AIROHA_USB_PHY_USB20_DISCTH_420 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x1) +#define AIROHA_USB_PHY_USB20_DISCTH_440 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x2) +#define AIROHA_USB_PHY_USB20_DISCTH_460 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x3) +#define AIROHA_USB_PHY_USB20_DISCTH_480 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x4) +#define AIROHA_USB_PHY_USB20_DISCTH_500 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x5) +#define AIROHA_USB_PHY_USB20_DISCTH_520 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x6) +#define AIROHA_USB_PHY_USB20_DISCTH_540 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x7) +#define AIROHA_USB_PHY_USB20_DISCTH_560 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x8) +#define AIROHA_USB_PHY_USB20_DISCTH_580 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0x9) +#define AIROHA_USB_PHY_USB20_DISCTH_600 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0xa) +#define AIROHA_USB_PHY_USB20_DISCTH_620 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0xb) +#define AIROHA_USB_PHY_USB20_DISCTH_640 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0xc) +#define AIROHA_USB_PHY_USB20_DISCTH_660 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0xd) +#define AIROHA_USB_PHY_USB20_DISCTH_680 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0xe) +#define AIROHA_USB_PHY_USB20_DISCTH_700 FIELD_PREP_CONST(AIROHA_USB_PHY_= USB20_DISCTH, 0xf) +#define AIROHA_USB_PHY_USB20_SQTH GENMASK(3, 0) +#define AIROHA_USB_PHY_USB20_SQTH_85 FIELD_PREP_CONST(AIROHA_USB_PHY_US= B20_SQTH, 0x0) +#define AIROHA_USB_PHY_USB20_SQTH_90 FIELD_PREP_CONST(AIROHA_USB_PHY_US= B20_SQTH, 0x1) +#define AIROHA_USB_PHY_USB20_SQTH_95 FIELD_PREP_CONST(AIROHA_USB_PHY_US= B20_SQTH, 0x2) +#define AIROHA_USB_PHY_USB20_SQTH_100 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0x3) +#define AIROHA_USB_PHY_USB20_SQTH_105 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0x4) +#define AIROHA_USB_PHY_USB20_SQTH_110 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0x5) +#define AIROHA_USB_PHY_USB20_SQTH_115 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0x6) +#define AIROHA_USB_PHY_USB20_SQTH_120 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0x7) +#define AIROHA_USB_PHY_USB20_SQTH_125 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0x8) +#define AIROHA_USB_PHY_USB20_SQTH_130 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0x9) +#define AIROHA_USB_PHY_USB20_SQTH_135 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0xa) +#define AIROHA_USB_PHY_USB20_SQTH_140 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0xb) +#define AIROHA_USB_PHY_USB20_SQTH_145 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0xc) +#define AIROHA_USB_PHY_USB20_SQTH_150 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0xd) +#define AIROHA_USB_PHY_USB20_SQTH_155 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0xe) +#define AIROHA_USB_PHY_USB20_SQTH_160 FIELD_PREP_CONST(AIROHA_USB_PHY_U= SB20_SQTH, 0xf) + +#define AIROHA_USB_PHY_U2PHYDTM1 0x36c +#define AIROHA_USB_PHY_FORCE_IDDIG BIT(9) +#define AIROHA_USB_PHY_IDDIG BIT(1) + +#define AIROHA_USB_PHY_GPIO_CTLD 0x80c +#define AIROHA_USB_PHY_C60802_GPIO_CTLD GENMASK(31, 0) +#define AIROHA_USB_PHY_SSUSB_IP_SW_RST BIT(31) +#define AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN BIT(30) +#define AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST BIT(29) +#define AIROHA_USB_PHY_SSUSB_SW_RST BIT(28) + +#define AIROHA_USB_PHY_U3_PHYA_REG0 0xb00 +#define AIROHA_USB_PHY_SSUSB_BG_DIV GENMASK(29, 28) +#define AIROHA_USB_PHY_SSUSB_BG_DIV_2 FIELD_PREP_CONST(AIROHA_USB_PHY_S= SUSB_BG_DIV, 0x0) +#define AIROHA_USB_PHY_SSUSB_BG_DIV_4 FIELD_PREP_CONST(AIROHA_USB_PHY_S= SUSB_BG_DIV, 0x1) +#define AIROHA_USB_PHY_SSUSB_BG_DIV_8 FIELD_PREP_CONST(AIROHA_USB_PHY_S= SUSB_BG_DIV, 0x2) +#define AIROHA_USB_PHY_SSUSB_BG_DIV_16 FIELD_PREP_CONST(AIROHA_USB_PHY_S= SUSB_BG_DIV, 0x3) +#define AIROHA_USB_PHY_U3_PHYA_REG1 0xb04 +#define AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE GENMASK(25, 10) +#define AIROHA_USB_PHY_U3_PHYA_REG6 0xb18 +#define AIROHA_USB_PHY_SSUSB_CDR_RESERVE GENMASK(31, 24) +#define AIROHA_USB_PHY_U3_PHYA_REG8 0xb20 +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY GENMASK(7, 6) +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32 FIELD_PREP_CONST(AIROHA_USB_= PHY_SSUSB_CDR_RST_DLY, 0x0) +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_64 FIELD_PREP_CONST(AIROHA_USB_= PHY_SSUSB_CDR_RST_DLY, 0x1) +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_128 FIELD_PREP_CONST(AIROHA_USB= _PHY_SSUSB_CDR_RST_DLY, 0x2) +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_216 FIELD_PREP_CONST(AIROHA_USB= _PHY_SSUSB_CDR_RST_DLY, 0x3) + +#define AIROHA_USB_PHY_U3_PHYA_DA_REG19 0xc38 +#define AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3 GENMASK(15, 0) + +#define AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT 1024 +#define AIROHA_USB_PHY_REF_CK 20 +#define AIROHA_USB_PHY_U2_SR_COEF 28 +#define AIROHA_USB_PHY_U2_SR_COEF_DIVISOR 1000 + +#define AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION 0x5 +#define AIROHA_USB_PHY_FREQDET_SLEEP 1000 /* 1ms */ +#define AIROHA_USB_PHY_FREQDET_TIMEOUT (AIROHA_USB_PHY_FREQDET_SLEEP * 10) + +struct an7581_usb_phy_instance { + struct phy *phy; + u32 type; +}; + +enum an7581_usb_phy_instance_type { + AIROHA_PHY_USB2, + AIROHA_PHY_USB3, + + AIROHA_PHY_USB_MAX, +}; + +struct an7581_usb_phy_priv { + struct device *dev; + struct regmap *regmap; + + unsigned int monclk_sel; + + struct phy *serdes_phy; + struct an7581_usb_phy_instance *phys[AIROHA_PHY_USB_MAX]; +}; + +static void an7581_usb_phy_u2_slew_rate_calibration(struct an7581_usb_phy_= priv *priv) +{ + u32 fm_out =3D 0; + u32 srctrl; + + /* Enable HS TX SR calibration */ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, + AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); + + usleep_range(1000, 1500); + + /* Enable Free run clock */ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, + AIROHA_USB_PHY_FRCK_EN); + + /* Select Monitor Clock */ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, + AIROHA_USB_PHY_MONCLK_SEL, + FIELD_PREP(AIROHA_USB_PHY_MONCLK_SEL, + priv->monclk_sel)); + + /* Set cyclecnt */ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, + AIROHA_USB_PHY_CYCLECNT, + FIELD_PREP(AIROHA_USB_PHY_CYCLECNT, + AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT)); + + /* Enable Frequency meter */ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, + AIROHA_USB_PHY_FREQDET_EN); + + /* Timeout can happen and we will apply workaround at the end */ + regmap_read_poll_timeout(priv->regmap, AIROHA_USB_PHY_FMMONR0, fm_out, + fm_out, AIROHA_USB_PHY_FREQDET_SLEEP, + AIROHA_USB_PHY_FREQDET_TIMEOUT); + + /* Disable Frequency meter */ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, + AIROHA_USB_PHY_FREQDET_EN); + + /* Disable Free run clock */ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, + AIROHA_USB_PHY_FRCK_EN); + + /* Disable HS TX SR calibration */ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, + AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); + + usleep_range(1000, 1500); + + /* Frequency was not detected, use default SR calibration value */ + if (!fm_out) { + srctrl =3D AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION; + dev_err(priv->dev, "Frequency not detected, using default SR calibration= .\n"); + } else { + /* (1024 / FM_OUT) * REF_CK * U2_SR_COEF (round to the nearest digits) */ + srctrl =3D AIROHA_USB_PHY_REF_CK * AIROHA_USB_PHY_U2_SR_COEF; + srctrl =3D (srctrl * AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT) / fm_out; + srctrl =3D DIV_ROUND_CLOSEST(srctrl, AIROHA_USB_PHY_U2_SR_COEF_DIVISOR); + dev_dbg(priv->dev, "SR calibration applied: %x\n", srctrl); + } + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, + AIROHA_USB_PHY_USB20_HSTX_SRCTRL, + FIELD_PREP(AIROHA_USB_PHY_USB20_HSTX_SRCTRL, srctrl)); +} + +static void an7581_usb_phy_u2_init(struct an7581_usb_phy_priv *priv) +{ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, + AIROHA_USB_PHY_USB20_FS_CR, + AIROHA_USB_PHY_USB20_FS_CR_MIN); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, + AIROHA_USB_PHY_USB20_FS_SR, + AIROHA_USB_PHY_USB20_FS_SR_NORMAL); + + /* FIXME: evaluate if needed */ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_SQTH, + AIROHA_USB_PHY_USB20_SQTH_130); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_DISCTH, + AIROHA_USB_PHY_USB20_DISCTH_600); + + /* Enable the USB port and then disable after calibration */ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_BC11_SW_EN); + + an7581_usb_phy_u2_slew_rate_calibration(priv); + + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_BC11_SW_EN); + + usleep_range(1000, 1500); +} + +/* + * USB 3.0 mode can only work if USB serdes is correctly set. + * This is validated in xLate function. + */ +static void an7581_usb_phy_u3_init(struct an7581_usb_phy_priv *priv) +{ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG8, + AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, + AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG6, + AIROHA_USB_PHY_SSUSB_CDR_RESERVE, + FIELD_PREP(AIROHA_USB_PHY_SSUSB_CDR_RESERVE, 0xe)); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG0, + AIROHA_USB_PHY_SSUSB_BG_DIV, + AIROHA_USB_PHY_SSUSB_BG_DIV_4); + + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG1, + FIELD_PREP(AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE, 0x600)); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_DA_REG19, + AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, + FIELD_PREP(AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, 0x43)); +} + +static int an7581_usb_phy_init(struct phy *phy) +{ + struct an7581_usb_phy_instance *instance =3D phy_get_drvdata(phy); + struct an7581_usb_phy_priv *priv =3D dev_get_drvdata(phy->dev.parent); + int ret; + + switch (instance->type) { + case PHY_TYPE_USB2: + an7581_usb_phy_u2_init(priv); + break; + case PHY_TYPE_USB3: + ret =3D phy_set_mode(priv->serdes_phy, PHY_MODE_USB_DEVICE_SS); + if (ret) + return ret; + + an7581_usb_phy_u3_init(priv); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int an7581_usb_phy_u2_power_on(struct an7581_usb_phy_priv *priv) +{ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_BC11_SW_EN); + + usleep_range(1000, 1500); + + return 0; +} + +static int an7581_usb_phy_u3_power_on(struct an7581_usb_phy_priv *priv) +{ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, + AIROHA_USB_PHY_SSUSB_IP_SW_RST | + AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN | + AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST | + AIROHA_USB_PHY_SSUSB_SW_RST); + + usleep_range(1000, 1500); + + return 0; +} + +static int an7581_usb_phy_power_on(struct phy *phy) +{ + struct an7581_usb_phy_instance *instance =3D phy_get_drvdata(phy); + struct an7581_usb_phy_priv *priv =3D dev_get_drvdata(phy->dev.parent); + + switch (instance->type) { + case PHY_TYPE_USB2: + an7581_usb_phy_u2_power_on(priv); + break; + case PHY_TYPE_USB3: + an7581_usb_phy_u3_power_on(priv); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int an7581_usb_phy_u2_power_off(struct an7581_usb_phy_priv *priv) +{ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_BC11_SW_EN); + + usleep_range(1000, 1500); + + return 0; +} + +static int an7581_usb_phy_u3_power_off(struct an7581_usb_phy_priv *priv) +{ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, + AIROHA_USB_PHY_SSUSB_IP_SW_RST | + AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST); + + usleep_range(1000, 1500); + + return 0; +} + +static int an7581_usb_phy_power_off(struct phy *phy) +{ + struct an7581_usb_phy_instance *instance =3D phy_get_drvdata(phy); + struct an7581_usb_phy_priv *priv =3D dev_get_drvdata(phy->dev.parent); + + switch (instance->type) { + case PHY_TYPE_USB2: + an7581_usb_phy_u2_power_off(priv); + break; + case PHY_TYPE_USB3: + an7581_usb_phy_u3_power_off(priv); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int an7581_usb_phy_u2_set_mode(struct an7581_usb_phy_priv *priv, + enum phy_mode mode) +{ + u32 val; + + /* + * For Device and Host mode, enable force IDDIG. + * For Device set IDDIG, for Host clear IDDIG. + * For OTG disable force and clear IDDIG bit while at it. + */ + switch (mode) { + case PHY_MODE_USB_DEVICE: + val =3D AIROHA_USB_PHY_FORCE_IDDIG | + AIROHA_USB_PHY_IDDIG; + break; + case PHY_MODE_USB_HOST: + val =3D AIROHA_USB_PHY_FORCE_IDDIG; + break; + case PHY_MODE_USB_OTG: + val =3D 0; + break; + default: + return 0; + } + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U2PHYDTM1, + AIROHA_USB_PHY_FORCE_IDDIG | + AIROHA_USB_PHY_IDDIG, val); + + return 0; +} + +static int an7581_usb_phy_set_mode(struct phy *phy, enum phy_mode mode, in= t submode) +{ + struct an7581_usb_phy_instance *instance =3D phy_get_drvdata(phy); + struct an7581_usb_phy_priv *priv =3D dev_get_drvdata(phy->dev.parent); + + switch (instance->type) { + case PHY_TYPE_USB2: + return an7581_usb_phy_u2_set_mode(priv, mode); + default: + return 0; + } +} + +static struct phy *an7581_usb_phy_xlate(struct device *dev, + const struct of_phandle_args *args) +{ + struct an7581_usb_phy_priv *priv =3D dev_get_drvdata(dev); + struct an7581_usb_phy_instance *instance =3D NULL; + unsigned int index, phy_type; + + if (args->args_count !=3D 1) { + dev_err(dev, "invalid number of cells in 'phy' property\n"); + return ERR_PTR(-EINVAL); + } + + phy_type =3D args->args[0]; + if (!(phy_type =3D=3D PHY_TYPE_USB2 || phy_type =3D=3D PHY_TYPE_USB3)) { + dev_err(dev, "unsupported device type: %d\n", phy_type); + return ERR_PTR(-EINVAL); + } + + for (index =3D 0; index < AIROHA_PHY_USB_MAX; index++) + if (priv->phys[index] && + phy_type =3D=3D priv->phys[index]->type) { + instance =3D priv->phys[index]; + break; + } + + if (!instance) { + dev_err(dev, "failed to find appropriate phy\n"); + return ERR_PTR(-EINVAL); + } + + return instance->phy; +} + +static const struct phy_ops airoha_phy =3D { + .init =3D an7581_usb_phy_init, + .power_on =3D an7581_usb_phy_power_on, + .power_off =3D an7581_usb_phy_power_off, + .set_mode =3D an7581_usb_phy_set_mode, + .owner =3D THIS_MODULE, +}; + +static const struct regmap_config an7581_usb_phy_regmap_config =3D { + .reg_bits =3D 32, + .val_bits =3D 32, + .reg_stride =3D 4, +}; + +static int an7581_usb_phy_probe(struct platform_device *pdev) +{ + struct phy_provider *phy_provider; + struct an7581_usb_phy_priv *priv; + struct device *dev =3D &pdev->dev; + unsigned int index; + void __iomem *base; + int ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev =3D dev; + + ret =3D of_property_read_u32(dev->of_node, "airoha,usb2-monitor-clk-sel", + &priv->monclk_sel); + if (ret) + return dev_err_probe(dev, ret, "Monitor clock selection is mandatory for= USB PHY calibration\n"); + + if (priv->monclk_sel > 3) + return dev_err_probe(dev, -EINVAL, "only 4 Monitor clock are selectable = on the SoC\n"); + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->regmap =3D devm_regmap_init_mmio(dev, base, &an7581_usb_phy_regmap_= config); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + platform_set_drvdata(pdev, priv); + + for (index =3D 0; index < AIROHA_PHY_USB_MAX; index++) { + struct an7581_usb_phy_instance *instance; + u32 phy_type; + + switch (index) { + case AIROHA_PHY_USB2: + phy_type =3D PHY_TYPE_USB2; + break; + case AIROHA_PHY_USB3: + phy_type =3D PHY_TYPE_USB3; + break; + } + + if (phy_type =3D=3D PHY_TYPE_USB3) { + priv->serdes_phy =3D devm_phy_get(dev, NULL); + if (IS_ERR(priv->serdes_phy)) + return dev_err_probe(dev, PTR_ERR(priv->serdes_phy), "missing serdes p= hy for USB 3.0\n"); + } + + instance =3D devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); + if (!instance) + return -ENOMEM; + + instance->type =3D phy_type; + priv->phys[index] =3D instance; + + instance->phy =3D devm_phy_create(dev, NULL, &airoha_phy); + if (IS_ERR(instance->phy)) + return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy= \n"); + + phy_set_drvdata(instance->phy, instance); + } + + phy_provider =3D devm_of_phy_provider_register(&pdev->dev, an7581_usb_phy= _xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id airoha_phy_id_table[] =3D { + { .compatible =3D "airoha,an7581-usb-phy" }, + { }, +}; +MODULE_DEVICE_TABLE(of, airoha_phy_id_table); + +static struct platform_driver an7581_usb_driver =3D { + .probe =3D an7581_usb_phy_probe, + .driver =3D { + .name =3D "airoha-an7581-usb-phy", + .of_match_table =3D airoha_phy_id_table, + }, +}; + +module_platform_driver(an7581_usb_driver); + +MODULE_DESCRIPTION("Airoha AN7581 USB PHY driver"); +MODULE_AUTHOR("Christian Marangi "); +MODULE_LICENSE("GPL"); --=20 2.53.0