From nobody Mon Sep 28 12:33:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 AE1783C1D6C; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313755; cv=none; b=B9kiT1jrehZe9rFF5HYDGtlyZSwO94jkvjGLl5lVqVWuewgzJ8r48L8qfI0hj2Vuwvhlqd3u8MdVDvmNss3KPSJSl4QovzmC3Gkepgfm9S3Sb/RYwCVOV4MsJO9Why25LjQlAj9HyF4g2KQJf3HK2EZfkWzqjQTKBR2rwC8W5Zk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313755; c=relaxed/simple; bh=DWRhVzxI1C3wXkqKVNxNuGCTQI6vLn5Bk41TAuSUgsE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I7v/AU8Zjgvb+9M1KoarNEs0OGiAZhuzdle2jevUz6JfhH83Wib539SB+kTuOhImjtx9S1WKG92jGXE7ylkjHGBnO/ui9eVwb36asPmzbRvgLaVSDNh5UDrzF/9BM/CzYMt9NaDza8XgVTVX0hSErUzx+FXU9QARu1GCFpZ2G4w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OaFpnvMi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OaFpnvMi" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5736BC2BCF7; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787313755; bh=DWRhVzxI1C3wXkqKVNxNuGCTQI6vLn5Bk41TAuSUgsE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=OaFpnvMirgQyd1SxUFyhFisLd4c2TdFX2XbF1+VmPfuOvyunqD6bk+sRJ/q4eqWfw PAcT97OvrRXAE0qcvYZnNCllELb0RVL/6JqXbM4t4AimuL58aJBOLqbd3Z05vxDwJJ Sqc4holO2Cy7zZaqUwLFQ7nrRPdWG8FSILrKnwpU0KfG5ynKEgvQg3ROc+RMrwvKuM DqJKtwpzb8MzJ1S6maLZQZQbFEIeWetL26iLQNOMuIM66MWCktT8JZjYkIlGyBicsT 325PUCo++k/qEUyGLtHWAnK6t/T/DkHbii7qiS4Je4qPwcOMsOPDiac2P7hkN1hquT CQU2XbRGxoyJQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3E2B7C5DF87; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) From: Jason Yang via B4 Relay Date: Fri, 21 Aug 2026 20:02:29 +0800 Subject: [PATCH v4 1/7] dt-bindings: phy: Add PHY_TYPE_DSI and PHY_TYPE_CSI definitions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-dcphy-rx-v1-v4-1-f1797634233d@gmail.com> References: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> In-Reply-To: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Guochun Huang , Philipp Zabel Cc: Michael Riesch , Sebastian Reichel , Bryan O'Donoghue , linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Jason Yang X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787313753; l=1230; i=jason98166@gmail.com; s=20260721; h=from:subject:message-id; bh=QW75aipJ7r+1l1HjnUlKV1E5sUZRB/BcBCVtuuiQvtA=; b=bz+eOdVuKzA1nXEkvtCyvOk8VSkT+16IY2otvOlUYef0QPyiVMe96H9WbD/KJDy79VrmZVK/z DDmmxdPuGQiDWSGcCqly3/fUJ/0N7C73PqqhpJQwbhtO+Kb5DaGPaRK X-Developer-Key: i=jason98166@gmail.com; a=ed25519; pk=xQmD001Q/ooHl39PxyQtusbUQmgbOsSfpFryRVWZ/k4= X-Endpoint-Received: by B4 Relay for jason98166@gmail.com/20260721 with auth_id=887 X-Original-From: Jason Yang Reply-To: jason98166@gmail.com From: Jason Yang A MIPI D-PHY or C-PHY can be a transmitter (DSI) or a receiver (CSI), and in some PHY blocks both work at the same time. The existing PHY_TYPE_DPHY and PHY_TYPE_CPHY cannot tell whether a consumer wants the transmitter or the receiver. Add PHY_TYPE_DSI and PHY_TYPE_CSI, so that a binding can select both D-PHY or C-PHY and transmitter or receiver. They do not replace PHY_TYPE_DPHY/PHY_TYPE_CPHY, which remain the right choice where a cell selects the mode. The first user is the Rockchip RK3588 MIPI DC-PHY binding. Suggested-by: Michael Riesch Link: https://lore.kernel.org/r/82da3622-9c3a-454c-87bc-fb4ec7adb68d@collab= ora.com Signed-off-by: Jason Yang --- include/dt-bindings/phy/phy.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h index 979b5dfd8353..8ee3f88e6d80 100644 --- a/include/dt-bindings/phy/phy.h +++ b/include/dt-bindings/phy/phy.h @@ -24,6 +24,8 @@ #define PHY_TYPE_CPHY 11 #define PHY_TYPE_USXGMII 12 #define PHY_TYPE_XAUI 13 +#define PHY_TYPE_DSI 14 +#define PHY_TYPE_CSI 15 =20 #define PHY_POL_NORMAL 0 #define PHY_POL_INVERT 1 --=20 2.43.0 From nobody Mon Sep 28 12:33:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 C4EB4486648; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313755; cv=none; b=k0s/GWTlSmp9RP4JxG0LUWZmYCgbqYZA28Tsk1tm8Kr2uISl1ffbWcgIAVJvePLuphaJ/eCQNz6n1WgeYKITyNJxoaHQGommNrvY+2e0wCiOFhmRV1vmNyLd5mtdfVipB+AxXBpMf5ton0RpYFNlmOCLROnyv1pRpC9BAvkfWok= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313755; c=relaxed/simple; bh=7wJCJfN4pMWX9++KJykYlazzN3vmq3alpryAcGcQgv8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NH8s61pd0T5/Dud5E5vcrYCS6/Al1WvTE13GrhldM53XZyaRupGnsIO99hdLw5EpSDwom2QJpx3A7d99MGLor0T8yyZu8OUxaulgMlfkuKt6gl72d5Wyxz7F3BmXvpDBIlp0hiS/MBCNDLwutSEVNCW/5p65vYgMvr+LGpT0ETw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r6F2DXKV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="r6F2DXKV" Received: by smtp.kernel.org (Postfix) with ESMTPS id 6F9A6C2BCB3; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787313755; bh=7wJCJfN4pMWX9++KJykYlazzN3vmq3alpryAcGcQgv8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=r6F2DXKVZHScJMmdTC3oEPfRertr+qgZlEzikRXkEDoIomjcbKPvasQjziwl+tGBQ Mlz151reb0G3CdzxYBgccWYDGv/9WpnSAsWWHYkVK9mnMsROC4ukTPfz0H3FoCwb6f 2r7bNf9Hmhbju7PxJlpDKUuWQwKemNTFSdmfWvC8wRD/K3W/C6Mkd0o0U+FchTYL1y pbSP4q3I8x/Y1kH0By1PgqhLU020k7xZtotC9xTmgGoCoYjPep13OisO/3CqI7AY9v uSRMFrMspPWiVelxxv4oXEzKTzEUiuFnJ0q1UF/Fo1FHqXGdN1c5HWxpXyz4s0/ubD 5QK7VpAHtpqiQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5CD24C5DF7D; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) From: Jason Yang via B4 Relay Date: Fri, 21 Aug 2026 20:02:30 +0800 Subject: [PATCH v4 2/7] dt-bindings: phy: rockchip,rk3588-mipi-dcphy: Allow DSI and CSI consumers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-dcphy-rx-v1-v4-2-f1797634233d@gmail.com> References: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> In-Reply-To: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Guochun Huang , Philipp Zabel Cc: Michael Riesch , Sebastian Reichel , Bryan O'Donoghue , linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Jason Yang X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787313753; l=2834; i=jason98166@gmail.com; s=20260721; h=from:subject:message-id; bh=0WXE/NlokgeSzl3fI3FkObkaA99tQXSoViMQEwXn3Mg=; b=3fWLRGuGuybNGBytIyM/G6LIROaQhrm/OnU6jbpr61L/vqpD0BxsqQjQbLKj7ESlidWA1ofMj WHjKv6jee5gBN9kUaAFSAyTOjjemDaF2a8QehcS5jjweyzVlkUv3vrs X-Developer-Key: i=jason98166@gmail.com; a=ed25519; pk=xQmD001Q/ooHl39PxyQtusbUQmgbOsSfpFryRVWZ/k4= X-Endpoint-Received: by B4 Relay for jason98166@gmail.com/20260721 with auth_id=887 X-Original-From: Jason Yang Reply-To: jason98166@gmail.com From: Jason Yang The Samsung MIPI D-/C-PHY block on RK3588 and RK3576 has a transmitter (DSI) and a receiver (CSI) on the same PHY, and two drivers can use them at the same time. The single cell this binding has selects the mode, so it cannot tell whether a consumer wants the transmitter or the receiver. Allow a second cell that selects the transmitter or the receiver. With D-PHY: /* the MIPI DSI host, driving the transmitter */ phys =3D <&mipidcphy0 PHY_TYPE_DPHY PHY_TYPE_DSI>; /* the MIPI CSI-2 host, driving the receiver */ phys =3D <&mipidcphy0 PHY_TYPE_DPHY PHY_TYPE_CSI>; and with C-PHY: phys =3D <&mipidcphy0 PHY_TYPE_CPHY PHY_TYPE_DSI>; phys =3D <&mipidcphy0 PHY_TYPE_CPHY PHY_TYPE_CSI>; The transmitter and the receiver cannot operate in different modes [1], so the first cell must match in both consumers. A board that wires up both sets '#phy-cells =3D <2>'. A board that only wires up the transmitter keeps '#phy-cells =3D <1>', so existing device trees are unaffected. [1] RK3588 TRM: section 22.1 (overview): "The TX and RX only support operate in the same PHY mode." Signed-off-by: Jason Yang --- .../bindings/phy/rockchip,rk3588-mipi-dcphy.yaml | 20 ++++++++++++++++= +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcp= hy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.= yaml index c8ff5ba22a86..595a71a51ee6 100644 --- a/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml +++ b/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml @@ -20,11 +20,25 @@ properties: maxItems: 1 =20 "#phy-cells": - const: 1 + enum: [1, 2] description: | - Argument is mode to operate in. Supported modes are: + A single cell selects the mode to operate in and refers to the + transmitter: - PHY_TYPE_DPHY - PHY_TYPE_CPHY + + Two cells select the mode and then the transmitter (DSI) or the + receiver (CSI), so that both can be described as independent + consumers of the same PHY: + - PHY_TYPE_DPHY PHY_TYPE_DSI + - PHY_TYPE_DPHY PHY_TYPE_CSI + - PHY_TYPE_CPHY PHY_TYPE_DSI + - PHY_TYPE_CPHY PHY_TYPE_CSI + + The transmitter (DSI) and the receiver (CSI) cannot operate in + different modes, so when both are described, the first cell must + match in both consumers. + See include/dt-bindings/phy/phy.h for constants. =20 clocks: @@ -82,6 +96,6 @@ examples: <&cru SRST_S_MIPI_DCPHY0>; reset-names =3D "m_phy", "apb", "grf", "s_phy"; rockchip,grf =3D <&mipidcphy0_grf>; - #phy-cells =3D <1>; + #phy-cells =3D <2>; }; }; --=20 2.43.0 From nobody Mon Sep 28 12:33:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 BB71047DF8D; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313755; cv=none; b=mrkB6C0CtbdDgqJvdGGXrel9LAoIL0UFdk7YINj+X6usTSXqcSQl12t/HXxPJ1GRBHQwQKNWHjqUpsQM/jXTDOQIcdDwuXK3vz4xbNeutzdbcWw3Xjgv7+GoHQnAJFqUR4vYg7q4s8IlXUyD/QdjwwhjBnqNseib+ORLdR72CBI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313755; c=relaxed/simple; bh=sj0ZvaEZhMU9545+yicP7xkr66CGRWMMJviaJQecDuY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=D5wmSYwWHr793ArdblnOx2zcVEmcR8X+W8irIg6gURevPyyEyK1jQqaTj0pk0HC8cfYb0LQAVZc8ItexXC/dk8lcJVml435R5iR7YKgVv8lyylDqiv6+K/mwtiAJ2sZx4O6HrrErkCimYA7fy27AIVtkjcrICvEWukjBGcsldxs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=htObtN4D; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="htObtN4D" Received: by smtp.kernel.org (Postfix) with ESMTPS id 88BB8C2BD00; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787313755; bh=sj0ZvaEZhMU9545+yicP7xkr66CGRWMMJviaJQecDuY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=htObtN4Dah7rhqLxSKBJrFdR9i4bMFdbG1vAxDy47P8JbmFgZwG5BkzgP4ONMwiHc CFxy3FBBfbiaSiH58ipyHvZxwnxQg5OH4+ntu1+Nvycxb5dvoDPVbDbVMVBmT4ggdE qPoUlLpUXb62SqK/WrWDyRIC5WKPrdSlzQ+g2dfWQvKK8He3AmR6Zu+r/VodhUJjre B24mgPc6NerukEQXIo3siIw1physZ+IINznaFYeVUQrUT87UsJZH1sM1dzzH5BtpKQ 31GeCJKU2e7ZW3aF1eLDvVb0g9pokiOmy0IH9lRjnEQSSfI88Rl/CeJ1wJ/hm8eYPl qmJ5s7rQSw+yQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70973C5DF89; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) From: Jason Yang via B4 Relay Date: Fri, 21 Aug 2026 20:02:31 +0800 Subject: [PATCH v4 3/7] phy: rockchip-samsung-dcphy: Move block-level setup to runtime resume Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-dcphy-rx-v1-v4-3-f1797634233d@gmail.com> References: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> In-Reply-To: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Guochun Huang , Philipp Zabel Cc: Michael Riesch , Sebastian Reichel , Bryan O'Donoghue , linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Jason Yang X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787313753; l=3359; i=jason98166@gmail.com; s=20260721; h=from:subject:message-id; bh=9cE+hPPqnU1uNwu7u1p4tFRsUnlEvTN31ifREdpQhEw=; b=pRJsM6dhNU4gu7l7zH2IQd0AoIZwurcXFWhoqiNKF4pLdt1ohsazT6fp0n15sPeWciqx+WLeX S7iw+OFEnZpAk8N51/As+Fu3mz5Pq3EeEqj/6i/9enPUMu4mxkH+sFY X-Developer-Key: i=jason98166@gmail.com; a=ed25519; pk=xQmD001Q/ooHl39PxyQtusbUQmgbOsSfpFryRVWZ/k4= X-Endpoint-Received: by B4 Relay for jason98166@gmail.com/20260721 with auth_id=887 X-Original-From: Jason Yang Reply-To: jason98166@gmail.com From: Jason Yang The APB reset and the BIAS references have to be treated as block-level [1]: both the transmitter and the receiver need them, and they only have to be programmed once. They are programmed from the transmitter's power-on path today. A later change registers one struct phy for each of them, and a second consumer coming up would then reset the block underneath a PHY that is already running. Program them from runtime resume instead, where whichever of the two comes up first brings the block up and a second one no longer resets it. This puts the BIAS writes ahead of the per-PHY reset assert, where the TRM's worked example has them after [1]. That is safe: neither M_RESETN nor S_RESETN covers the BIAS registers, and the values written are those registers' reset defaults. The output level select in BIAS_CON4 stays on the power-on path: it selects 400mV for D-PHY and 530mV for C-PHY, and the driver core resumes a runtime-PM supplier before the consumer's probe runs, so runtime resume cannot yet know which of the two applies. [1] RK3588 TRM: sections 22.4.1 (address map), 22.4.2 (reset values), 22.6.1.2 (reset) and 22.6.4.1 (D-PHY transmitter start-up) Signed-off-by: Jason Yang --- drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c | 25 ++++++++++++-------= ---- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/ph= y/rockchip/phy-rockchip-samsung-dcphy.c index 11e872cc6611..459ce882b369 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c @@ -980,13 +980,6 @@ static void samsung_mipi_dcphy_bias_block_enable(struc= t samsung_mipi_dcphy *sams I_LADDER_1_00V); regmap_write(samsung->regmap, BIAS_CON2, REG_325M_325MV | REG_LP_400M_400= MV | REG_400M_400MV | REG_645M_645MV); - - /* default output voltage select: - * dphy: 400mv - * cphy: 530mv - */ - regmap_update_bits(samsung->regmap, BIAS_CON4, - I_MUX_SEL_MASK, I_MUX_400MV); } =20 static void samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy *samsu= ng) @@ -1338,7 +1331,13 @@ static int samsung_mipi_dphy_power_on(struct samsung= _mipi_dcphy *samsung) =20 reset_control_assert(samsung->m_phy_rst); =20 - samsung_mipi_dcphy_bias_block_enable(samsung); + /* default output voltage select: + * dphy: 400mv + * cphy: 530mv + */ + regmap_update_bits(samsung->regmap, BIAS_CON4, + I_MUX_SEL_MASK, I_MUX_400MV); + samsung_mipi_dcphy_pll_configure(samsung); samsung_mipi_dphy_clk_lane_timing_init(samsung); samsung_mipi_dphy_data_lane_timing_init(samsung); @@ -1362,10 +1361,6 @@ static int samsung_mipi_dcphy_power_on(struct phy *p= hy) { struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); =20 - reset_control_assert(samsung->apb_rst); - udelay(1); - reset_control_deassert(samsung->apb_rst); - switch (samsung->type) { case PHY_TYPE_DPHY: return samsung_mipi_dphy_power_on(samsung); @@ -1656,6 +1651,12 @@ static __maybe_unused int samsung_mipi_dcphy_runtime= _resume(struct device *dev) return ret; } =20 + reset_control_assert(samsung->apb_rst); + udelay(1); + reset_control_deassert(samsung->apb_rst); + + samsung_mipi_dcphy_bias_block_enable(samsung); + return 0; } =20 --=20 2.43.0 From nobody Mon Sep 28 12:33:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 7DAC548F828; Fri, 21 Aug 2026 12:02:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313756; cv=none; b=FeULoXGtMkgPXs+iUDLm2454v7mkDAhDJ34Am1XMn/EAzPrD1nmq/Wi5DjAq5CxRPk3GfFBqoa677gNAE+tPS1iSSQutv3VHZeKU3Ygbt6uqB/HUp60wNQRiPJdQd58PMSKDrMd6oYH2mDfBOTFL05RBGs5iA0TyPY+yXW/FPA4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313756; c=relaxed/simple; bh=/DclBTmkrW/aLpo0XJOngtSwVpq+M7i3SUUpfDiAObE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qcf60OkuOXjPiaZgsU5odwbdgrPsTy10yFj6h+GzFGmoJzVtzK3BAF54xNC0uYZdVkuIqnnZ4mm6v8JV8K5H6KnAKsA1oA20pvRFfnrNrMsElrSoER1fHG7LXQR1L6XqyoQFKZHApVQfy7lLmqAS8WE9+0lKGyjlqANSPAoZzwI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=m8c4uS9p; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="m8c4uS9p" Received: by smtp.kernel.org (Postfix) with ESMTPS id 9E8DFC2BCFB; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787313755; bh=/DclBTmkrW/aLpo0XJOngtSwVpq+M7i3SUUpfDiAObE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=m8c4uS9pn5bUWdP6PkbMLZSBkO6frIcLDu1Ga2MeMcES/v3HYjMdSgOiN3tl/CIps bZuIZG3yEfXoHKM3d24FY89sG/SxcTDgyhHg/NZJMBrAQ03WQyoCCFPgx8plY4g0Nt zVvRYGnk5Nom9AuZhlwpJxDANfBYP7qNWfbaYPTA4nBiOk9pPfnCaxljWdFacp6uRY Tubzrq1ust6UxbcfRJwth4EXAfj1ra05fK9lJc4OEOQelc0s/D4x9yG3XT+NrchKAS pA86RNrmGAOtz91AgOIyPpP1G5JmYqbNQa/KMMmw0OqpNUUQGDU+LzVtYAK3n6Rn1T PCyrKappOAt2A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89783C5DF93; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) From: Jason Yang via B4 Relay Date: Fri, 21 Aug 2026 20:02:32 +0800 Subject: [PATCH v4 4/7] phy: rockchip-samsung-dcphy: Name the transmitter helpers and ops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-dcphy-rx-v1-v4-4-f1797634233d@gmail.com> References: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> In-Reply-To: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Guochun Huang , Philipp Zabel Cc: Michael Riesch , Sebastian Reichel , Bryan O'Donoghue , linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Jason Yang X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787313753; l=8931; i=jason98166@gmail.com; s=20260721; h=from:subject:message-id; bh=RI8y3y55VDx9txeJYIUShGvw08OtC0J/pJvHmCgrXF8=; b=L8poF0YKjkiUHo/iVz4H0fQsJIPrNoYlXPJAR8CftKkvy7FDQhm4Ibs+fU0DWHmRMUYyMViyQ k/5TXvbf/T9AhXhl6db8VfCIwzXmeGtjq750dAnFZr6uj/bbPY49Hc1 X-Developer-Key: i=jason98166@gmail.com; a=ed25519; pk=xQmD001Q/ooHl39PxyQtusbUQmgbOsSfpFryRVWZ/k4= X-Endpoint-Received: by B4 Relay for jason98166@gmail.com/20260721 with auth_id=887 X-Original-From: Jason Yang Reply-To: jason98166@gmail.com From: Jason Yang The block is a combo PHY: it exposes a transmitter and a receiver, and a later change registers one struct phy for each. Prepare for that. Give every helper that programs the master lanes a tx_ prefix, and move the phy pointer and the lane count, which only the transmitter uses, into a struct samsung_mipi_phy that the receiver can have one of too. Name the phy_ops and its callbacks after the transmitter as well, so that the receiver can bring its own rather than share these. The BIAS block and the PLL keep their names: the TRM puts both in the part common to the whole block [1], so neither belongs to one PHY even though only the transmitter drives the PLL. No functional change intended. [1] RK3588 TRM: sections 22.3.1 (bias generator), 22.3.2 (PLL) and 22.4.1 (address map) Assisted-by: Claude:claude-fable-5 Signed-off-by: Jason Yang --- drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c | 67 ++++++++++++-------= ---- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/ph= y/rockchip/phy-rockchip-samsung-dcphy.c index 459ce882b369..f58907dec733 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c @@ -280,6 +280,11 @@ struct samsung_mipi_dcphy_plat_data { u32 dphy_tx_max_lane_kbps; }; =20 +struct samsung_mipi_phy { + struct phy *phy; + unsigned int lanes; +}; + struct samsung_mipi_dcphy { struct device *dev; struct clk *ref_clk; @@ -290,8 +295,7 @@ struct samsung_mipi_dcphy { struct reset_control *s_phy_rst; struct reset_control *apb_rst; struct reset_control *grf_apb_rst; - unsigned int lanes; - struct phy *phy; + struct samsung_mipi_phy tx; u8 type; =20 const struct samsung_mipi_dcphy_plat_data *pdata; @@ -982,13 +986,13 @@ static void samsung_mipi_dcphy_bias_block_enable(stru= ct samsung_mipi_dcphy *sams REG_400M_400MV | REG_645M_645MV); } =20 -static void samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy *samsu= ng) +static void samsung_mipi_dphy_tx_lane_enable(struct samsung_mipi_dcphy *sa= msung) { regmap_write(samsung->regmap, DPHY_MC_GNR_CON1, T_PHY_READY(0x2000)); regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0, PHY_ENABLE, PHY_ENABLE); =20 - switch (samsung->lanes) { + switch (samsung->tx.lanes) { case 4: regmap_write(samsung->regmap, DPHY_MD3_GNR_CON1, T_PHY_READY(0x2000)); @@ -1017,9 +1021,9 @@ static void samsung_mipi_dphy_lane_enable(struct sams= ung_mipi_dcphy *samsung) } } =20 -static void samsung_mipi_dphy_lane_disable(struct samsung_mipi_dcphy *sams= ung) +static void samsung_mipi_dphy_tx_lane_disable(struct samsung_mipi_dcphy *s= amsung) { - switch (samsung->lanes) { + switch (samsung->tx.lanes) { case 4: regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0, PHY_ENABLE, 0); @@ -1094,7 +1098,7 @@ static void samsung_mipi_dcphy_pll_disable(struct sam= sung_mipi_dcphy *samsung) } =20 static const struct samsung_mipi_dphy_timing * -samsung_mipi_dphy_get_timing(struct samsung_mipi_dcphy *samsung) +samsung_mipi_dphy_tx_get_timing(struct samsung_mipi_dcphy *samsung) { const struct samsung_mipi_dphy_timing *timings; unsigned int num_timings; @@ -1201,13 +1205,13 @@ samsung_mipi_dcphy_pll_round_rate(struct samsung_mi= pi_dcphy *samsung, } =20 static void -samsung_mipi_dphy_clk_lane_timing_init(struct samsung_mipi_dcphy *samsung) +samsung_mipi_dphy_tx_clk_lane_timing_init(struct samsung_mipi_dcphy *samsu= ng) { const struct samsung_mipi_dphy_timing *timing; unsigned int lane_hs_rate =3D div64_ul(samsung->pll.rate, USEC_PER_SEC); u32 val, res_up, res_down; =20 - timing =3D samsung_mipi_dphy_get_timing(samsung); + timing =3D samsung_mipi_dphy_tx_get_timing(samsung); regmap_write(samsung->regmap, DPHY_MC_GNR_CON0, 0xf000); =20 /* @@ -1256,13 +1260,13 @@ samsung_mipi_dphy_clk_lane_timing_init(struct samsu= ng_mipi_dcphy *samsung) } =20 static void -samsung_mipi_dphy_data_lane_timing_init(struct samsung_mipi_dcphy *samsung) +samsung_mipi_dphy_tx_data_lane_timing_init(struct samsung_mipi_dcphy *sams= ung) { const struct samsung_mipi_dphy_timing *timing; unsigned int lane_hs_rate =3D div64_ul(samsung->pll.rate, USEC_PER_SEC); u32 val, res_up, res_down; =20 - timing =3D samsung_mipi_dphy_get_timing(samsung); + timing =3D samsung_mipi_dphy_tx_get_timing(samsung); =20 /* * The Drive-Strength / Voltage-Amplitude is adjusted by adjusting the @@ -1325,7 +1329,7 @@ samsung_mipi_dphy_data_lane_timing_init(struct samsun= g_mipi_dcphy *samsung) regmap_write(samsung->regmap, DPHY_MD3_TIME_CON4, 0x1f4); } =20 -static int samsung_mipi_dphy_power_on(struct samsung_mipi_dcphy *samsung) +static int samsung_mipi_dphy_tx_power_on(struct samsung_mipi_dcphy *samsun= g) { int ret; =20 @@ -1339,13 +1343,13 @@ static int samsung_mipi_dphy_power_on(struct samsun= g_mipi_dcphy *samsung) I_MUX_SEL_MASK, I_MUX_400MV); =20 samsung_mipi_dcphy_pll_configure(samsung); - samsung_mipi_dphy_clk_lane_timing_init(samsung); - samsung_mipi_dphy_data_lane_timing_init(samsung); + samsung_mipi_dphy_tx_clk_lane_timing_init(samsung); + samsung_mipi_dphy_tx_data_lane_timing_init(samsung); ret =3D samsung_mipi_dcphy_pll_enable(samsung); if (ret < 0) return ret; =20 - samsung_mipi_dphy_lane_enable(samsung); + samsung_mipi_dphy_tx_lane_enable(samsung); =20 reset_control_deassert(samsung->m_phy_rst); =20 @@ -1357,13 +1361,13 @@ static int samsung_mipi_dphy_power_on(struct samsun= g_mipi_dcphy *samsung) return 0; } =20 -static int samsung_mipi_dcphy_power_on(struct phy *phy) +static int samsung_mipi_dcphy_tx_power_on(struct phy *phy) { struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); =20 switch (samsung->type) { case PHY_TYPE_DPHY: - return samsung_mipi_dphy_power_on(samsung); + return samsung_mipi_dphy_tx_power_on(samsung); default: /* CPHY part to be implemented later */ return -EOPNOTSUPP; @@ -1372,13 +1376,13 @@ static int samsung_mipi_dcphy_power_on(struct phy *= phy) return 0; } =20 -static int samsung_mipi_dcphy_power_off(struct phy *phy) +static int samsung_mipi_dcphy_tx_power_off(struct phy *phy) { struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); =20 switch (samsung->type) { case PHY_TYPE_DPHY: - samsung_mipi_dphy_lane_disable(samsung); + samsung_mipi_dphy_tx_lane_disable(samsung); break; default: /* CPHY part to be implemented later */ @@ -1477,13 +1481,13 @@ samsung_mipi_dcphy_pll_calc_rate(struct samsung_mip= i_dcphy *samsung, } } =20 -static int samsung_mipi_dcphy_configure(struct phy *phy, - union phy_configure_opts *opts) +static int samsung_mipi_dcphy_tx_configure(struct phy *phy, + union phy_configure_opts *opts) { struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); unsigned long long target_rate =3D opts->mipi_dphy.hs_clk_rate; =20 - samsung->lanes =3D opts->mipi_dphy.lanes > 4 ? 4 : opts->mipi_dphy.lanes; + samsung->tx.lanes =3D opts->mipi_dphy.lanes > 4 ? 4 : opts->mipi_dphy.lan= es; =20 samsung_mipi_dcphy_pll_calc_rate(samsung, target_rate); opts->mipi_dphy.hs_clk_rate =3D samsung->pll.rate; @@ -1507,10 +1511,10 @@ static int samsung_mipi_dcphy_exit(struct phy *phy) return 0; } =20 -static const struct phy_ops samsung_mipi_dcphy_ops =3D { - .configure =3D samsung_mipi_dcphy_configure, - .power_on =3D samsung_mipi_dcphy_power_on, - .power_off =3D samsung_mipi_dcphy_power_off, +static const struct phy_ops samsung_mipi_dcphy_tx_ops =3D { + .configure =3D samsung_mipi_dcphy_tx_configure, + .power_on =3D samsung_mipi_dcphy_tx_power_on, + .power_off =3D samsung_mipi_dcphy_tx_power_off, .init =3D samsung_mipi_dcphy_init, .exit =3D samsung_mipi_dcphy_exit, .owner =3D THIS_MODULE, @@ -1540,7 +1544,7 @@ static struct phy *samsung_mipi_dcphy_xlate(struct de= vice *dev, =20 samsung->type =3D args->args[0]; =20 - return samsung->phy; + return samsung->tx.phy; } =20 static int samsung_mipi_dcphy_probe(struct platform_device *pdev) @@ -1609,11 +1613,12 @@ static int samsung_mipi_dcphy_probe(struct platform= _device *pdev) if (ret) return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); =20 - samsung->phy =3D devm_phy_create(dev, NULL, &samsung_mipi_dcphy_ops); - if (IS_ERR(samsung->phy)) - return dev_err_probe(dev, PTR_ERR(samsung->phy), "Failed to create MIPI = DC-PHY\n"); + samsung->tx.phy =3D devm_phy_create(dev, NULL, &samsung_mipi_dcphy_tx_ops= ); + if (IS_ERR(samsung->tx.phy)) + return dev_err_probe(dev, PTR_ERR(samsung->tx.phy), + "Failed to create MIPI DC-PHY transmitter\n"); =20 - phy_set_drvdata(samsung->phy, samsung); + phy_set_drvdata(samsung->tx.phy, samsung); =20 phy_provider =3D devm_of_phy_provider_register(dev, samsung_mipi_dcphy_xl= ate); if (IS_ERR(phy_provider)) --=20 2.43.0 From nobody Mon Sep 28 12:33:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 7522248EBF3; Fri, 21 Aug 2026 12:02:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313756; cv=none; b=K2vK1BWltGOtjoRqX5CJzRUvMCPYaWbSvQxH3wC6wFEOHBgSguqRHOHOOxotubcKpOOjaNwHUq3dMycEZdwzuLyA9h2DggSXWAmfq4orL8b1Px5QLKMjcjjdkIOPxqJwljpgDcyjW1fA7wPy6rXVrGmIyebuznZNLJxJSVUrYIA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313756; c=relaxed/simple; bh=TnI1p+P/50A7HWM9Y8HyRkngg4ldec9pgu0d66QJY5Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IxHB8Z8etT8omw+KqE/mFBCQmQCGsMWimnj7SEWlpGBT1+23xGABwXaXvhAJ/bkmU/CtztM/NpTig7fJP2+bLSD+xvzHZzc8kyKhcviCVxr8GmHdT5dhvzqyaq2Ojfy1VWPA1p+DUAKaMKmict6nG4DIdlpFiOwWspCHVzRcQZo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TroQY1et; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TroQY1et" Received: by smtp.kernel.org (Postfix) with ESMTPS id B5A0AC2BCFF; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787313755; bh=TnI1p+P/50A7HWM9Y8HyRkngg4ldec9pgu0d66QJY5Q=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=TroQY1etFEyAwtSBl2bnHKcPIyWCaSr94DsOSVADzv9hdB1dFykOsP7dpp1oSgljr /41jAxzMxhQav2Pp7GF93hS+bK8Ys59TOPfnVQb/s8cjQV33X3YtrE808HV3QaA8ZV 6i6rgrQCg/4A6RpOLBix2Hhq60uGjDloZvPvpvBzTpczayO6MGN8oCUKN3Q23EAh1a kvkF+JryigXrpFKxQz9PKlcIsCRLZ10nSinBNv59hQ4iMKRRIwtwbTpfKZdP0pfENr zGOuP1MyCXkBoYMGwDBgvSabq5A5EfUlMM09ofX/WwjRHE0/sbxvf22Ef/hdUj90qw LGoGUbQRUgZBQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1AA8C5DF87; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) From: Jason Yang via B4 Relay Date: Fri, 21 Aug 2026 20:02:33 +0800 Subject: [PATCH v4 5/7] phy: rockchip-samsung-dcphy: Factor the transmitter teardown into a helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-dcphy-rx-v1-v4-5-f1797634233d@gmail.com> References: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> In-Reply-To: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Guochun Huang , Philipp Zabel Cc: Michael Riesch , Sebastian Reichel , Bryan O'Donoghue , linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Jason Yang X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787313753; l=2267; i=jason98166@gmail.com; s=20260721; h=from:subject:message-id; bh=H9C3dBUKHCEqAqQXc3SD6EcAQzNiujpzdtKGk2VKgQE=; b=8OIV6ztcFUOG7ZAoX7MY1eISvfkc4VkrqMa6/7vGpV8pyY1fPXRP+0w9sUvq3clP/0n8GrXdG gtvDeMyM04IBjhrl25Y471zayq7Zy61zpJBQZYAB+Si2HHJHvA6nygk X-Developer-Key: i=jason98166@gmail.com; a=ed25519; pk=xQmD001Q/ooHl39PxyQtusbUQmgbOsSfpFryRVWZ/k4= X-Endpoint-Received: by B4 Relay for jason98166@gmail.com/20260721 with auth_id=887 X-Original-From: Jason Yang Reply-To: jason98166@gmail.com From: Jason Yang The transmitter's power-on path is in samsung_mipi_dphy_tx_power_on(), but the power_off callback still does the teardown itself. Move the teardown into samsung_mipi_dphy_tx_power_off(), so that power-on and power-off are a matching pair. Both callbacks then have a type switch whose arms are plain returns. Turn each into an early guard for the not yet supported C-PHY and drop the unreachable trailing return. No functional change intended. Signed-off-by: Jason Yang --- drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c | 31 ++++++++++---------= ---- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/ph= y/rockchip/phy-rockchip-samsung-dcphy.c index f58907dec733..5d9d44a1d6a2 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c @@ -1361,37 +1361,34 @@ static int samsung_mipi_dphy_tx_power_on(struct sam= sung_mipi_dcphy *samsung) return 0; } =20 +static int samsung_mipi_dphy_tx_power_off(struct samsung_mipi_dcphy *samsu= ng) +{ + samsung_mipi_dphy_tx_lane_disable(samsung); + samsung_mipi_dcphy_pll_disable(samsung); + + return 0; +} + static int samsung_mipi_dcphy_tx_power_on(struct phy *phy) { struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); =20 - switch (samsung->type) { - case PHY_TYPE_DPHY: - return samsung_mipi_dphy_tx_power_on(samsung); - default: - /* CPHY part to be implemented later */ + /* CPHY part to be implemented later */ + if (samsung->type !=3D PHY_TYPE_DPHY) return -EOPNOTSUPP; - } =20 - return 0; + return samsung_mipi_dphy_tx_power_on(samsung); } =20 static int samsung_mipi_dcphy_tx_power_off(struct phy *phy) { struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); =20 - switch (samsung->type) { - case PHY_TYPE_DPHY: - samsung_mipi_dphy_tx_lane_disable(samsung); - break; - default: - /* CPHY part to be implemented later */ + /* CPHY part to be implemented later */ + if (samsung->type !=3D PHY_TYPE_DPHY) return -EOPNOTSUPP; - } =20 - samsung_mipi_dcphy_pll_disable(samsung); - - return 0; + return samsung_mipi_dphy_tx_power_off(samsung); } =20 static int --=20 2.43.0 From nobody Mon Sep 28 12:33:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 4935248EBD0; Fri, 21 Aug 2026 12:02:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313756; cv=none; b=O28T+JqN4FLx8Y/H+n538ES9NAsbWxQN+Uzb2MTOkPF73uF6qpgGgvtPREGugfuvcf8AD0Tnq015VJFdhumx5zazeYMwobW4A02aUEMJ3M0ol/6KA6RxmiLQRFCBIyLv3L2sStS+YjscxgVlnYig57YR3IVEO29adKXw6+v7MV8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313756; c=relaxed/simple; bh=1YWU9CaZpCJLqtsjR0F+p6T2Me/cuaHMCTUFje7w4FY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QYARg9IcLwCJ7IE4Mw+i1w6bzx1nerM5cmvYfo2prN8dsuSW5mEpAUJl2wcngh7oUYav8fXd2TB2NDph1ldVXGwfMlL3X8QKrwReeGTjkKH/zJ8GRGQG4m0C1mh5vnkfIcarDydAXHvkae/2PDWFXu/raOwWW2DBIB3n1IX3HW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TUj7xkHh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TUj7xkHh" Received: by smtp.kernel.org (Postfix) with ESMTPS id C746CC19425; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787313755; bh=1YWU9CaZpCJLqtsjR0F+p6T2Me/cuaHMCTUFje7w4FY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=TUj7xkHhOpHb1lmJRcyBM75SlfrtGOsr5jpb6N9bov6ZMJV5zaqikJhAkeOYD0w5q Zysfc4GVcLFePBHBWK7F/blFUL1OG/ezEj9Lm1qD9Q0QwsnVIGN9jgH+YXjhQLsLZb 7EbBrn8wAg/Br1IIW3AMF3C8tG/YapRJBs55KLPvgMHM8Swi425s7G9QnbaqTA84sZ ryOsqAdlwXjX5ZssN8l3nnFS0zeJTIf3zRwNtWtiHIsVWLaRZLOJ47C8912grFbUPt K92gCSts90RQ+33m2yacztYtVtYbPGmQ4pgT2K9vEbiJZF3iOj5QYy+p73Q1egG6R5 IKzGZh3OHn2CQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4CA6C5DF7D; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) From: Jason Yang via B4 Relay Date: Fri, 21 Aug 2026 20:02:34 +0800 Subject: [PATCH v4 6/7] phy: rockchip-samsung-dcphy: Add a second PHY for the receiver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-dcphy-rx-v1-v4-6-f1797634233d@gmail.com> References: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> In-Reply-To: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Guochun Huang , Philipp Zabel Cc: Michael Riesch , Sebastian Reichel , Bryan O'Donoghue , linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Jason Yang X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787313753; l=4769; i=jason98166@gmail.com; s=20260721; h=from:subject:message-id; bh=Tpo2aJZByzL9nN+hv+FBEOMzziNDSj5dFxgoQfw6WoE=; b=DtlVLAqZAPRh42okYQIYhYZh/DDPpEAGH5EoRKvqs7GDAbe3CI85tDMs3bus5ETqQq9Z2KvHe l1323U8UXUMDyMD7SCEwuN7iWKLYdcAOUHq8mGn2G3qcoXYOaRrB+8x X-Developer-Key: i=jason98166@gmail.com; a=ed25519; pk=xQmD001Q/ooHl39PxyQtusbUQmgbOsSfpFryRVWZ/k4= X-Endpoint-Received: by B4 Relay for jason98166@gmail.com/20260721 with auth_id=887 X-Original-From: Jason Yang Reply-To: jason98166@gmail.com From: Jason Yang Give the receiver a struct phy of its own, with its own phy_ops and its own samsung_mipi_phy for the state the two do not share. of_xlate() takes the second cell, PHY_TYPE_DSI selecting the transmitter and PHY_TYPE_CSI the receiver, and falls back to the transmitter for a single-cell provider, so existing device trees keep working. It now rejects an unknown value in either cell, and a mix of D-PHY and C-PHY consumers, which the TRM does not support [1]. The receiver's callbacks return -EOPNOTSUPP until its bring-up is added in the next change. [1] RK3588 TRM: section 22.1 (overview) Assisted-by: Claude:claude-fable-5 Signed-off-by: Jason Yang --- drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c | 69 +++++++++++++++++++= ++-- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/ph= y/rockchip/phy-rockchip-samsung-dcphy.c index 5d9d44a1d6a2..d27a5916bd40 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c @@ -296,6 +296,8 @@ struct samsung_mipi_dcphy { struct reset_control *apb_rst; struct reset_control *grf_apb_rst; struct samsung_mipi_phy tx; + struct samsung_mipi_phy rx; + /* PHY mode, PHY_TYPE_DPHY or PHY_TYPE_CPHY. */ u8 type; =20 const struct samsung_mipi_dcphy_plat_data *pdata; @@ -1508,6 +1510,22 @@ static int samsung_mipi_dcphy_exit(struct phy *phy) return 0; } =20 +static int samsung_mipi_dcphy_rx_configure(struct phy *phy, + union phy_configure_opts *opts) +{ + return -EOPNOTSUPP; +} + +static int samsung_mipi_dcphy_rx_power_on(struct phy *phy) +{ + return -EOPNOTSUPP; +} + +static int samsung_mipi_dcphy_rx_power_off(struct phy *phy) +{ + return -EOPNOTSUPP; +} + static const struct phy_ops samsung_mipi_dcphy_tx_ops =3D { .configure =3D samsung_mipi_dcphy_tx_configure, .power_on =3D samsung_mipi_dcphy_tx_power_on, @@ -1517,6 +1535,15 @@ static const struct phy_ops samsung_mipi_dcphy_tx_op= s =3D { .owner =3D THIS_MODULE, }; =20 +static const struct phy_ops samsung_mipi_dcphy_rx_ops =3D { + .configure =3D samsung_mipi_dcphy_rx_configure, + .power_on =3D samsung_mipi_dcphy_rx_power_on, + .power_off =3D samsung_mipi_dcphy_rx_power_off, + .init =3D samsung_mipi_dcphy_init, + .exit =3D samsung_mipi_dcphy_exit, + .owner =3D THIS_MODULE, +}; + static const struct regmap_config samsung_mipi_dcphy_regmap_config =3D { .name =3D "dcphy", .reg_bits =3D 32, @@ -1529,19 +1556,42 @@ static struct phy *samsung_mipi_dcphy_xlate(struct = device *dev, const struct of_phandle_args *args) { struct samsung_mipi_dcphy *samsung =3D dev_get_drvdata(dev); + /* Device trees without the second cell describe the transmitter. */ + u32 protocol =3D PHY_TYPE_DSI; + u32 type; =20 - if (args->args_count !=3D 1) { + if (args->args_count < 1 || args->args_count > 2) { dev_err(dev, "invalid number of arguments\n"); return ERR_PTR(-EINVAL); } =20 - if (samsung->type !=3D PHY_NONE && samsung->type !=3D args->args[0]) - dev_warn(dev, "phy type select %d overwriting type %d\n", - args->args[0], samsung->type); + type =3D args->args[0]; + if (type !=3D PHY_TYPE_DPHY && type !=3D PHY_TYPE_CPHY) { + dev_err(dev, "invalid phy type %u\n", type); + return ERR_PTR(-EINVAL); + } =20 - samsung->type =3D args->args[0]; + if (args->args_count =3D=3D 2) + protocol =3D args->args[1]; =20 - return samsung->tx.phy; + if (protocol !=3D PHY_TYPE_DSI && protocol !=3D PHY_TYPE_CSI) { + dev_err(dev, "invalid protocol %u\n", protocol); + return ERR_PTR(-EINVAL); + } + + /* + * The TRM (section 22.1) does not support the transmitter and the + * receiver running in different modes, so the mode belongs to the + * block. + */ + if (samsung->type !=3D PHY_NONE && samsung->type !=3D type) { + dev_err(dev, "phy type %u conflicts with type %u already selected\n", + type, samsung->type); + return ERR_PTR(-EINVAL); + } + samsung->type =3D type; + + return protocol =3D=3D PHY_TYPE_CSI ? samsung->rx.phy : samsung->tx.phy; } =20 static int samsung_mipi_dcphy_probe(struct platform_device *pdev) @@ -1617,6 +1667,13 @@ static int samsung_mipi_dcphy_probe(struct platform_= device *pdev) =20 phy_set_drvdata(samsung->tx.phy, samsung); =20 + samsung->rx.phy =3D devm_phy_create(dev, NULL, &samsung_mipi_dcphy_rx_ops= ); + if (IS_ERR(samsung->rx.phy)) + return dev_err_probe(dev, PTR_ERR(samsung->rx.phy), + "Failed to create MIPI DC-PHY receiver\n"); + + phy_set_drvdata(samsung->rx.phy, samsung); + phy_provider =3D devm_of_phy_provider_register(dev, samsung_mipi_dcphy_xl= ate); if (IS_ERR(phy_provider)) return dev_err_probe(dev, PTR_ERR(phy_provider), --=20 2.43.0 From nobody Mon Sep 28 12:33:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 7D9AD48F827; Fri, 21 Aug 2026 12:02:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313756; cv=none; b=tuY1pqA5BIinEY+tq7lSVWX5FkLL5IvZKuJNeVxeqD5e5I2T7fW2/N8sTyFFvCCRnRTHE5k+sjwTVXHvW6Vl+fZgRT4lam8Igf0FEUFkygNXmaPeuBXJZ53Ms0qjZclHZBFRiaoKkZJNMVSvrvMwggptBGZ1OHctIkLghmuM1DE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787313756; c=relaxed/simple; bh=2UdzR7Mnrg71FEMEb2N22cxnvddOVC1L0Kj5QL7nZl0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Wo9JRx04luhqnS5NxOXiETzbbILLaMg1J8nScgcsxo6dwTlz2nxWCj9UY24dUt7CEsTURP3Vs3dQe4fRWA/B3qwVPlreVR03sfR4mopLFyoJ3CoasTRLNHr9TysT2zp9fu8YIzs61HvjZOUZbwg8/muGqOXbq0HUy+a16xHRNw4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bRSTOYsw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bRSTOYsw" Received: by smtp.kernel.org (Postfix) with ESMTPS id DD5C5C2BCF7; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787313755; bh=2UdzR7Mnrg71FEMEb2N22cxnvddOVC1L0Kj5QL7nZl0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=bRSTOYswRtu7r0vuINgbBJhwPPb1bpcea4g68DFU4MbJ5MREH7BK9Rclwn+KXkhku i7JDC4RmurkSkEjvrlKa0JikWuNPl7Rn1geEzKudH2uAc8JH0yXXo8HcKWsVwc55PK hj6dBHoGS1n8jr4b/pPrdvXOmVZER/vNtQWnvssdeXGarHGa5GLAGRUwboLwlsu9+0 PcDIrtu1OEPxGWfGGxfSNxNyWt9cJHfDX+5P+XxzV6UBrUie8YIIPIT4M0N/E4A3fS pOBcheIvDEa2ka/xMtg8rYFvl3IdctkQfLkGmrC6BfQ8KQ7i7V2fiHx0ydoZ7pmHiz zZ5TgefoiJxuA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA433C5DF89; Fri, 21 Aug 2026 12:02:35 +0000 (UTC) From: Jason Yang via B4 Relay Date: Fri, 21 Aug 2026 20:02:35 +0800 Subject: [PATCH v4 7/7] phy: rockchip-samsung-dcphy: Add MIPI D-PHY receiver support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-dcphy-rx-v1-v4-7-f1797634233d@gmail.com> References: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> In-Reply-To: <20260821-dcphy-rx-v1-v4-0-f1797634233d@gmail.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Guochun Huang , Philipp Zabel Cc: Michael Riesch , Sebastian Reichel , Bryan O'Donoghue , linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Jason Yang X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787313753; l=16417; i=jason98166@gmail.com; s=20260721; h=from:subject:message-id; bh=6dBCw8OahdISBi/SPeu4nYYJMh77hTufrIaviVdmQhc=; b=N6yyDSgsjtz2zqcRW3s5HFAJk08oMaoUiW7UP/oRR5iqBpznWe8korJ7zAjmWO9XxSF426FzU kH5ildPV/cQAw/buwT1si3jxufYUh+fJwN7VB58XBn9nIKm+kGTSXo2 X-Developer-Key: i=jason98166@gmail.com; a=ed25519; pk=xQmD001Q/ooHl39PxyQtusbUQmgbOsSfpFryRVWZ/k4= X-Endpoint-Received: by B4 Relay for jason98166@gmail.com/20260721 with auth_id=887 X-Original-From: Jason Yang Reply-To: jason98166@gmail.com From: Jason Yang Add the receiver (CSI) half of the block, so a MIPI CSI-2 camera can use the same PHY that already drives a MIPI DSI output on RK3588. It follows the receiver start-up sequence in the RK3588 TRM [1]. The HS-RX settle values come from the RK3588 vendor kernel. The initial deskew calibration that the D-PHY specification asks for above 1.5 Gbps is not implemented; the vendor kernel programs it from RK3576 onwards only. Tested on RK3588 with an IMX219 on the receiver and a DSI panel on the transmitter of the same PHY. [1] RK3588 TRM: sections 22.6.3 (receiver start-up) and 22.6.4.3 (worked receiver example) Assisted-by: Claude:claude-fable-5 Signed-off-by: Jason Yang --- drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c | 386 ++++++++++++++++++= +++- 1 file changed, 383 insertions(+), 3 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/ph= y/rockchip/phy-rockchip-samsung-dcphy.c index d27a5916bd40..947ce7a09c7c 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c @@ -244,6 +244,63 @@ #define T_TA_GET(x) FIELD_PREP(GENMASK(7, 4), x) #define T_TA_GO(x) FIELD_PREP(GENMASK(3, 0), x) =20 +/* D-PHY receiver registers (clock lane + four data lanes) */ +#define DPHY_SC_GNR_CON0 0x0b00 +#define DPHY_SC_GNR_CON1 0x0b04 +#define DPHY_SC_ANA_CON1 0x0b0c +#define HS_RX_BIAS_CON(x) FIELD_PREP(GENMASK(15, 11), x) +#define DPHY_SC_ANA_CON2 0x0b10 +#define HS_TERM_SW(x) FIELD_PREP(GENMASK(2, 0), x) +#define DPHY_SC_ANA_CON3 0x0b14 +#define ULPS_HYS_SW_DPHY(x) FIELD_PREP(GENMASK(10, 8), x) +#define DPHY_SC_TIME_CON0 0x0b30 +#define T_CLK_SETTLE(x) FIELD_PREP(GENMASK(7, 0), x) +#define T_CLK_MISS(x) FIELD_PREP(GENMASK(11, 8), x) +#define COMBO_SD0_GNR_CON0 0x0c00 +#define COMBO_SD0_GNR_CON1 0x0c04 +#define COMBO_SD0_ANA_CON1 0x0c0c +#define COMBO_SD0_ANA_CON2 0x0c10 +#define SKEW_DLYSEL(x) FIELD_PREP(GENMASK(9, 8), x) +#define RX_TERM_SW(x) FIELD_PREP(GENMASK(2, 0), x) +#define COMBO_SD0_ANA_CON3 0x0c14 +#define SEL_ESCPOL BIT(11) +#define LP_HYS_SW(x) FIELD_PREP(GENMASK(5, 4), x) +#define COMBO_SD0_ANA_CON7 0x0c24 +#define CLK_DBL_CTRL(x) FIELD_PREP(GENMASK(7, 6), x) +#define COMBO_SD0_TIME_CON0 0x0c30 +#define T_HS_SETTLE(x) FIELD_PREP(GENMASK(7, 0), x) +#define SETTLE_CLK_SEL BIT(8) +#define COMBO_SD0_TIME_CON1 0x0c34 +#define T_ERR_SOT_SYNC(x) FIELD_PREP(GENMASK(7, 0), x) +#define COMBO_SD0_DESKEW_CON2 0x0c48 +#define SKEW_CAL_CLK_COARSE_SET(x) FIELD_PREP(GENMASK(4, 0), x) +#define COMBO_SD1_GNR_CON0 0x0d00 +#define COMBO_SD1_GNR_CON1 0x0d04 +#define COMBO_SD1_ANA_CON1 0x0d0c +#define COMBO_SD1_ANA_CON2 0x0d10 +#define COMBO_SD1_ANA_CON3 0x0d14 +#define COMBO_SD1_ANA_CON7 0x0d24 +#define COMBO_SD1_TIME_CON0 0x0d30 +#define COMBO_SD1_TIME_CON1 0x0d34 +#define COMBO_SD1_DESKEW_CON2 0x0d48 +#define COMBO_SD2_GNR_CON0 0x0e00 +#define COMBO_SD2_GNR_CON1 0x0e04 +#define COMBO_SD2_ANA_CON1 0x0e0c +#define COMBO_SD2_ANA_CON2 0x0e10 +#define COMBO_SD2_ANA_CON3 0x0e14 +#define COMBO_SD2_ANA_CON7 0x0e24 +#define COMBO_SD2_TIME_CON0 0x0e30 +#define COMBO_SD2_TIME_CON1 0x0e34 +#define COMBO_SD2_DESKEW_CON2 0x0e48 +#define DPHY_SD3_GNR_CON0 0x0f00 +#define DPHY_SD3_GNR_CON1 0x0f04 +#define DPHY_SD3_ANA_CON1 0x0f0c +#define DPHY_SD3_ANA_CON2 0x0f10 +#define DPHY_SD3_ANA_CON3 0x0f14 +#define DPHY_SD3_TIME_CON0 0x0f30 +#define DPHY_SD3_TIME_CON1 0x0f34 +#define DPHY_SD3_DESKEW_CON2 0x0f48 + /* MIPI_CDPHY_GRF registers */ #define MIPI_DCPHY_GRF_CON0 0x0000 #define S_CPHY_MODE FIELD_PREP_WM16(BIT(3), 1) @@ -283,6 +340,7 @@ struct samsung_mipi_dcphy_plat_data { struct samsung_mipi_phy { struct phy *phy; unsigned int lanes; + unsigned long long hs_clk_rate; }; =20 struct samsung_mipi_dcphy { @@ -979,6 +1037,260 @@ struct samsung_mipi_dphy_timing samsung_mipi_dphy_ti= ming_table[] =3D { { 80, 2, 0, 0, 28, 5, 0, 22, 2, 0, 5}, }; =20 +/* D-PHY receiver HS-RX configuration lookup */ +struct samsung_mipi_dphy_rx_hsfreq_range { + u32 range_h_mbps; + u16 cfg_bit; +}; + +/* + * HS RX settle values taken verbatim from the rk3588 vendor kernel. + * The TRM defines these fields but defers the per-data-rate table to a + * timing supplement. Each cfg_bit is a pre-combined SETTLE_CLK_SEL | + * T_HS_SETTLE value for the data-lane TIME_CON0: bit 8 selects the + * divide-by-2 settle clock below 1500 Mbps per the TRM (the vendor + * table switches one bucket early, at 1490 Mbps, and is kept + * unchanged). The TRM marks bit 8 read-only, but the vendor kernel has + * always programmed it. Sorted by .range_h_mbps ascending. + */ +static const struct samsung_mipi_dphy_rx_hsfreq_range samsung_mipi_dphy_rx= _hsfreq_ranges[] =3D { + { 80, 0x105 }, { 100, 0x106 }, { 120, 0x107 }, { 140, 0x108 }, + { 160, 0x109 }, { 180, 0x10a }, { 200, 0x10b }, { 220, 0x10c }, + { 240, 0x10d }, { 270, 0x10e }, { 290, 0x10f }, { 310, 0x110 }, + { 330, 0x111 }, { 350, 0x112 }, { 370, 0x113 }, { 390, 0x114 }, + { 410, 0x115 }, { 430, 0x116 }, { 450, 0x117 }, { 470, 0x118 }, + { 490, 0x119 }, { 510, 0x11a }, { 540, 0x11b }, { 560, 0x11c }, + { 580, 0x11d }, { 600, 0x11e }, { 620, 0x11f }, { 640, 0x120 }, + { 660, 0x121 }, { 680, 0x122 }, { 700, 0x123 }, { 720, 0x124 }, + { 740, 0x125 }, { 760, 0x126 }, { 790, 0x127 }, { 810, 0x128 }, + { 830, 0x129 }, { 850, 0x12a }, { 870, 0x12b }, { 890, 0x12c }, + { 910, 0x12d }, { 930, 0x12e }, { 950, 0x12f }, { 970, 0x130 }, + { 990, 0x131 }, { 1010, 0x132 }, { 1030, 0x133 }, { 1060, 0x134 }, + { 1080, 0x135 }, { 1100, 0x136 }, { 1120, 0x137 }, { 1140, 0x138 }, + { 1160, 0x139 }, { 1180, 0x13a }, { 1200, 0x13b }, { 1220, 0x13c }, + { 1240, 0x13d }, { 1260, 0x13e }, { 1280, 0x13f }, { 1310, 0x140 }, + { 1330, 0x141 }, { 1350, 0x142 }, { 1370, 0x143 }, { 1390, 0x144 }, + { 1410, 0x145 }, { 1430, 0x146 }, { 1450, 0x147 }, { 1470, 0x148 }, + { 1490, 0x149 }, { 1580, 0x007 }, { 1740, 0x008 }, { 1910, 0x009 }, + { 2070, 0x00a }, { 2240, 0x00b }, { 2410, 0x00c }, { 2570, 0x00d }, + { 2740, 0x00e }, { 2910, 0x00f }, { 3070, 0x010 }, { 3240, 0x011 }, + { 3410, 0x012 }, { 3570, 0x013 }, { 3740, 0x014 }, { 3890, 0x015 }, + { 4070, 0x016 }, { 4240, 0x017 }, { 4400, 0x018 }, { 4500, 0x019 }, +}; + +static int samsung_mipi_dphy_rx_lookup_hsfreq(u32 lane_mbps, u16 *cfg_bit) +{ + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(samsung_mipi_dphy_rx_hsfreq_ranges); i++) { + if (lane_mbps <=3D samsung_mipi_dphy_rx_hsfreq_ranges[i].range_h_mbps) { + *cfg_bit =3D samsung_mipi_dphy_rx_hsfreq_ranges[i].cfg_bit; + return 0; + } + } + + return -ERANGE; +} + +/* SKEW_DLYSEL per data rate, from the RK3588 TRM ANA_CON2 description */ +static u32 samsung_mipi_dphy_rx_data_lane_dlysel(u32 lane_mbps) +{ + if (lane_mbps < 1500) + return 0; + if (lane_mbps < 2000) + return SKEW_DLYSEL(3); + if (lane_mbps < 3000) + return SKEW_DLYSEL(2); + if (lane_mbps < 4000) + return SKEW_DLYSEL(1); + return 0; +} + +/* + * Per-data-lane register bases, indexed by lane number. The clock lane + * shares the same block spacing but is programmed separately: its + * TIME_CON0 holds T_CLK_SETTLE/T_CLK_MISS rather than the per-rate + * T_HS_SETTLE/SETTLE_CLK_SEL, and it has no deskew configuration. + */ +static const u32 rx_data_lane_gnr_con0[] =3D { + COMBO_SD0_GNR_CON0, COMBO_SD1_GNR_CON0, + COMBO_SD2_GNR_CON0, DPHY_SD3_GNR_CON0, +}; + +static const u32 rx_data_lane_gnr_con1[] =3D { + COMBO_SD0_GNR_CON1, COMBO_SD1_GNR_CON1, + COMBO_SD2_GNR_CON1, DPHY_SD3_GNR_CON1, +}; + +static const u32 rx_lane_time_con0[] =3D { + COMBO_SD0_TIME_CON0, COMBO_SD1_TIME_CON0, + COMBO_SD2_TIME_CON0, DPHY_SD3_TIME_CON0, +}; + +static const u32 rx_lane_time_con1[] =3D { + COMBO_SD0_TIME_CON1, COMBO_SD1_TIME_CON1, + COMBO_SD2_TIME_CON1, DPHY_SD3_TIME_CON1, +}; + +/* + * These RX analog tuning values come from the vendor kernel. The + * termination (RX_TERM_SW/HS_TERM_SW =3D 2) is the 96.6 ohm setting the + * TRM ANA_CON2 value list annotates as the default, although the + * register itself resets to 102 ohm. Data lane 0 differs on purpose: + * the vendor's default receive profile applies the LP hysteresis and + * the swapped escape clock polarity to lane 0 only, and no manual + * skew-calibration delay there against three 30 ps steps on the other + * lanes. Data lane 3 is a plain D-PHY lane with no ANA_CON7, so it + * gets no CLK_DBL_CTRL write. + */ +static void samsung_mipi_dphy_rx_config_common(struct samsung_mipi_dcphy *= samsung) +{ + struct samsung_mipi_phy *rx =3D &samsung->rx; + u32 dlysel =3D samsung_mipi_dphy_rx_data_lane_dlysel(div_u64(rx->hs_clk_r= ate, + 1000000)); + u32 ana_con2_common =3D dlysel | RX_TERM_SW(2); + + /* Clock lane */ + regmap_write(samsung->regmap, DPHY_SC_ANA_CON1, HS_RX_BIAS_CON(0x10)); + regmap_write(samsung->regmap, DPHY_SC_ANA_CON2, HS_TERM_SW(2)); + regmap_write(samsung->regmap, DPHY_SC_ANA_CON3, ULPS_HYS_SW_DPHY(6)); + + /* Data lane 0; a zero lane count is rejected at power-on */ + regmap_write(samsung->regmap, COMBO_SD0_ANA_CON1, HS_RX_BIAS_CON(0x10)); + regmap_write(samsung->regmap, COMBO_SD0_ANA_CON2, ana_con2_common); + regmap_write(samsung->regmap, COMBO_SD0_ANA_CON3, + ULPS_HYS_SW_DPHY(6) | LP_HYS_SW(3) | SEL_ESCPOL); + regmap_write(samsung->regmap, COMBO_SD0_ANA_CON7, CLK_DBL_CTRL(1)); + regmap_write(samsung->regmap, COMBO_SD0_DESKEW_CON2, + SKEW_CAL_CLK_COARSE_SET(0)); + + /* Data lane 1 */ + if (rx->lanes > 1) { + regmap_write(samsung->regmap, COMBO_SD1_ANA_CON1, + HS_RX_BIAS_CON(0x10)); + regmap_write(samsung->regmap, COMBO_SD1_ANA_CON2, + ana_con2_common); + regmap_write(samsung->regmap, COMBO_SD1_ANA_CON3, + ULPS_HYS_SW_DPHY(6)); + regmap_write(samsung->regmap, COMBO_SD1_ANA_CON7, + CLK_DBL_CTRL(1)); + regmap_write(samsung->regmap, COMBO_SD1_DESKEW_CON2, + SKEW_CAL_CLK_COARSE_SET(3)); + } + + /* Data lane 2 */ + if (rx->lanes > 2) { + regmap_write(samsung->regmap, COMBO_SD2_ANA_CON1, + HS_RX_BIAS_CON(0x10)); + regmap_write(samsung->regmap, COMBO_SD2_ANA_CON2, + ana_con2_common); + regmap_write(samsung->regmap, COMBO_SD2_ANA_CON3, + ULPS_HYS_SW_DPHY(6)); + regmap_write(samsung->regmap, COMBO_SD2_ANA_CON7, + CLK_DBL_CTRL(1)); + regmap_write(samsung->regmap, COMBO_SD2_DESKEW_CON2, + SKEW_CAL_CLK_COARSE_SET(3)); + } + + /* Data lane 3 */ + if (rx->lanes > 3) { + regmap_write(samsung->regmap, DPHY_SD3_ANA_CON1, + HS_RX_BIAS_CON(0x10)); + regmap_write(samsung->regmap, DPHY_SD3_ANA_CON2, + ana_con2_common); + regmap_write(samsung->regmap, DPHY_SD3_ANA_CON3, + ULPS_HYS_SW_DPHY(6)); + regmap_write(samsung->regmap, DPHY_SD3_DESKEW_CON2, + SKEW_CAL_CLK_COARSE_SET(3)); + } +} + +static int samsung_mipi_dphy_rx_config_settle(struct samsung_mipi_dcphy *s= amsung) +{ + struct samsung_mipi_phy *rx =3D &samsung->rx; + u32 lane_mbps =3D div_u64(rx->hs_clk_rate, 1000000); + unsigned int i; + u16 cfg_bit; + int ret; + + ret =3D samsung_mipi_dphy_rx_lookup_hsfreq(lane_mbps, &cfg_bit); + if (ret) { + dev_err(samsung->dev, "no RX hsfreq cfg for %u Mbps\n", + lane_mbps); + return ret; + } + + /* + * Clock-lane settle uses the fixed value from the TRM RX bring-up + * example, unlike the per-rate data-lane settle below. + */ + regmap_write(samsung->regmap, DPHY_SC_TIME_CON0, + T_CLK_SETTLE(0x01) | T_CLK_MISS(0x03)); + + for (i =3D 0; i < rx->lanes; i++) { + regmap_update_bits(samsung->regmap, rx_lane_time_con0[i], + T_HS_SETTLE(0xff) | SETTLE_CLK_SEL, cfg_bit); + regmap_update_bits(samsung->regmap, rx_lane_time_con1[i], + T_ERR_SOT_SYNC(0xff), T_ERR_SOT_SYNC(0x03)); + } + + return 0; +} + +static void samsung_mipi_dphy_rx_lane_disable(struct samsung_mipi_dcphy *s= amsung) +{ + struct samsung_mipi_phy *rx =3D &samsung->rx; + unsigned int i; + + regmap_update_bits(samsung->regmap, DPHY_SC_GNR_CON0, PHY_ENABLE, 0); + for (i =3D 0; i < rx->lanes; i++) + regmap_update_bits(samsung->regmap, rx_data_lane_gnr_con0[i], + PHY_ENABLE, 0); +} + +static int samsung_mipi_dphy_rx_lane_enable(struct samsung_mipi_dcphy *sam= sung) +{ + struct samsung_mipi_phy *rx =3D &samsung->rx; + unsigned int i; + u32 sts; + int ret; + + regmap_write(samsung->regmap, DPHY_SC_GNR_CON1, T_PHY_READY(0x1450)); + regmap_update_bits(samsung->regmap, DPHY_SC_GNR_CON0, + PHY_ENABLE, PHY_ENABLE); + + for (i =3D 0; i < rx->lanes; i++) { + regmap_write(samsung->regmap, rx_data_lane_gnr_con1[i], + T_PHY_READY(0x1450)); + regmap_update_bits(samsung->regmap, rx_data_lane_gnr_con0[i], + PHY_ENABLE, PHY_ENABLE); + } + + ret =3D regmap_read_poll_timeout(samsung->regmap, DPHY_SC_GNR_CON0, + sts, sts & PHY_READY, 200, 4000); + if (ret) { + dev_err(samsung->dev, "RX clock lane not ready\n"); + goto err_lane_disable; + } + + for (i =3D 0; i < rx->lanes; i++) { + ret =3D regmap_read_poll_timeout(samsung->regmap, + rx_data_lane_gnr_con0[i], + sts, sts & PHY_READY, + 200, 2000); + if (ret) { + dev_err(samsung->dev, "RX data lane %u not ready\n", i); + goto err_lane_disable; + } + } + + return 0; + +err_lane_disable: + samsung_mipi_dphy_rx_lane_disable(samsung); + return ret; +} + static void samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy= *samsung) { regmap_write(samsung->regmap, BIAS_CON0, I_DEV_DIV_6 | I_RES_100_2UA); @@ -988,6 +1300,55 @@ static void samsung_mipi_dcphy_bias_block_enable(stru= ct samsung_mipi_dcphy *sams REG_400M_400MV | REG_645M_645MV); } =20 +static int samsung_mipi_dphy_rx_power_on(struct samsung_mipi_dcphy *samsun= g) +{ + struct samsung_mipi_phy *rx =3D &samsung->rx; + int ret; + + if (!rx->hs_clk_rate || !rx->lanes) + return -EINVAL; + + reset_control_assert(samsung->s_phy_rst); + + /* default output voltage select: + * dphy: 400mv + * cphy: 530mv + */ + regmap_update_bits(samsung->regmap, BIAS_CON4, + I_MUX_SEL_MASK, I_MUX_400MV); + + samsung_mipi_dphy_rx_config_common(samsung); + + ret =3D samsung_mipi_dphy_rx_config_settle(samsung); + if (ret) + goto out_deassert; + + ret =3D samsung_mipi_dphy_rx_lane_enable(samsung); + +out_deassert: + reset_control_deassert(samsung->s_phy_rst); + + return ret; +} + +static int samsung_mipi_dphy_rx_power_off(struct samsung_mipi_dcphy *samsu= ng) +{ + reset_control_assert(samsung->s_phy_rst); + + samsung_mipi_dphy_rx_lane_disable(samsung); + + reset_control_deassert(samsung->s_phy_rst); + + /* + * Let the lanes settle out of reset before the receiver may be + * brought up again. The delay follows the vendor driver; the TRM + * does not document a teardown sequence. + */ + usleep_range(500, 1000); + + return 0; +} + static void samsung_mipi_dphy_tx_lane_enable(struct samsung_mipi_dcphy *sa= msung) { regmap_write(samsung->regmap, DPHY_MC_GNR_CON1, T_PHY_READY(0x2000)); @@ -1513,17 +1874,36 @@ static int samsung_mipi_dcphy_exit(struct phy *phy) static int samsung_mipi_dcphy_rx_configure(struct phy *phy, union phy_configure_opts *opts) { - return -EOPNOTSUPP; + struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); + + samsung->rx.lanes =3D opts->mipi_dphy.lanes > 4 ? 4 : opts->mipi_dphy.lan= es; + + /* The sensor supplies the link clock, so the PLL stays off. */ + samsung->rx.hs_clk_rate =3D opts->mipi_dphy.hs_clk_rate; + + return 0; } =20 static int samsung_mipi_dcphy_rx_power_on(struct phy *phy) { - return -EOPNOTSUPP; + struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); + + /* CPHY part to be implemented later */ + if (samsung->type !=3D PHY_TYPE_DPHY) + return -EOPNOTSUPP; + + return samsung_mipi_dphy_rx_power_on(samsung); } =20 static int samsung_mipi_dcphy_rx_power_off(struct phy *phy) { - return -EOPNOTSUPP; + struct samsung_mipi_dcphy *samsung =3D phy_get_drvdata(phy); + + /* CPHY part to be implemented later */ + if (samsung->type !=3D PHY_TYPE_DPHY) + return -EOPNOTSUPP; + + return samsung_mipi_dphy_rx_power_off(samsung); } =20 static const struct phy_ops samsung_mipi_dcphy_tx_ops =3D { --=20 2.43.0