From nobody Tue Sep 29 02:34:10 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 87D003C2781; Thu, 13 Aug 2026 09:57:11 +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=1786615031; cv=none; b=eYcCiHGc34iIe7HoQZLud1cFUWLlTx4SdrM9bGFP+mRQHLFo+ZGasbTmIhs/1HKwCf3+ZqbFiXYw0t86uI8wDHlzcE+MAQNyFu47GHsxIkA79oJTuO0AWLhzEK5IncwpLqUtig3n3CTquGmL5lQw+Ly/J5m1lfAOG7OSota7TZw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786615031; c=relaxed/simple; bh=QoMXlPLzALhwByi+1x8x2yYmLLmFtvcOqO7OqLXmh3A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JA7Dyi4yHMm9PZqlMqzZekzc8AWinQqu1/8X9oY3Vdgq+PtcMz/uIczE4rFhRKdVH+Ssmq7uD1bFYtwqfFukATbhoLsvy0J6XPu3F1/z4t7OU+gzAf3BKep2F7XWL2g5eVtbosoYPXOu00SRoi6vm77UbAgtcmko8T2FuSXV240= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WtLOIRNe; 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="WtLOIRNe" Received: by smtp.kernel.org (Postfix) with ESMTPS id 1F1DCC2BCC7; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786615031; bh=QoMXlPLzALhwByi+1x8x2yYmLLmFtvcOqO7OqLXmh3A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=WtLOIRNeIk9GweSGMkZBCGV0mLKufRKJCcvPQ4umeCEE8mBcpAlS/g+pwGGrzOsGI RTNrgpSGGRa2c6JveuSbwymDjKC74v/MqFBc+O160kDb1+lQqwZNXn+xP3z+YPIUML 6L1+R7nHhmFNOz4BB+02mJ1KhA5OagVzOkeqI/bV4zsqYbgkHUtwwYyKtP1eZtlNJD BDjeC/bV+wlOK7XWY1FitJwY0cEvsZ4rBFUhsW0r5HVcxGJioBIPdOgc8m6YwJ8uIQ zLxuoVZZodwj2Ny5CCEqrKj/QsE1g9W63e9JPlSZr1XqqN/6OAABOYt2s2GHSgGE3e zeo32K1f6pwKA== 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 0267EC5CFDB; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) From: Long Zhao via B4 Relay Date: Thu, 13 Aug 2026 17:56:12 +0800 Subject: [PATCH v3 1/6] dt-bindings: arm: add Ambarella CV75 platforms 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: <20260813-cv75-v3-a-v3-1-cfdd20b1b4dd@ambarella.com> References: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> In-Reply-To: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Catalin Marinas , Will Deacon , Arnd Bergmann , Alexandre Belloni , Linus Walleij Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, soc@lists.linux.dev, Long Zhao , Krzysztof Kozlowski X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786615029; l=1828; i=longzhao@ambarella.com; s=20260730; h=from:subject:message-id; bh=afPd4fMvs6m5AADxb0oc6RJxPyKNG50c78xrv0izT2E=; b=FfzHBtNw5HlISmo6udQC4oEZ/SBB5ags05+u2NZV8P60KxB/xQ8mXQqJM1Z7p36HjyPdJEtYF wbyzA21+8RnClLWBe+i2Gfho8WsA5mzaCIRHya4PBYk1J5P6/k3Ld1n X-Developer-Key: i=longzhao@ambarella.com; a=ed25519; pk=/xGhPTOX0/eYsyTWzyjjgAIW1Z/YD+IlnOnvcdRozow= X-Endpoint-Received: by B4 Relay for longzhao@ambarella.com/20260730 with auth_id=903 X-Original-From: Long Zhao Reply-To: longzhao@ambarella.com From: Long Zhao Add the Ambarella vendor prefix and CV75 EVK board compatible for the initial SoC bring-up. Signed-off-by: Long Zhao Reviewed-by: Krzysztof Kozlowski --- .../devicetree/bindings/arm/ambarella.yaml | 24 ++++++++++++++++++= ++++ .../devicetree/bindings/vendor-prefixes.yaml | 2 ++ 2 files changed, 26 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/ambarella.yaml b/Documen= tation/devicetree/bindings/arm/ambarella.yaml new file mode 100644 index 000000000000..72946e94fa76 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/ambarella.yaml @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/ambarella.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ambarella SoC platforms + +maintainers: + - Long Zhao + +properties: + $nodename: + const: "/" + + compatible: + oneOf: + - description: Ambarella CV75 boards + items: + - enum: + - ambarella,cv75-evk + - const: ambarella,cv75 + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Docum= entation/devicetree/bindings/vendor-prefixes.yaml index 85a27937832e..f48aa6dabbe9 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -112,6 +112,8 @@ patternProperties: description: Amarula Solutions "^amazon,.*": description: Amazon.com, Inc. + "^ambarella,.*": + description: Ambarella, Inc. "^amcc,.*": description: Applied Micro Circuits Corporation (APM, formally AMCC) "^amd,.*": --=20 2.34.1 From nobody Tue Sep 29 02:34:10 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 87C663B5318; Thu, 13 Aug 2026 09:57:11 +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=1786615031; cv=none; b=MGr1f++bHOD3dOWKSyId2MIoHtyHYuGkvL2jfM0FRm3olUomLOFv9BZTEQKS4MDAhOm6aCfraoTyH/TmoUMqAi3Rbly3ONaKhdmNxcdjYeWAWD3zqZmTNQbAOxmE7odEXd+l4lhue4s5FXGj6ZSYWASvas9kOofo09NS2WlwPEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786615031; c=relaxed/simple; bh=ZRtgythNUWuTKkqjsOPQzdBTM5sRjHcbFE1i7TFqLZU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YOt2cQohEV7WhPbI9/jcEBrOTBPr+SqQwpFQMMBZ81U/ouWUkmW70Fx1drvSHT00/qyjm7MoM76leI6P5q43VvaWb+yFzSJFZyJcqu0dCaIoTw6Cvh4WxiHHDNE1SsA2re+gfzkAmFTDuWTo50/+mVNDTUxMkJfZFc3KbTD34sk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LqV1zZOh; 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="LqV1zZOh" Received: by smtp.kernel.org (Postfix) with ESMTPS id 35484C2BCF5; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786615031; bh=ZRtgythNUWuTKkqjsOPQzdBTM5sRjHcbFE1i7TFqLZU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=LqV1zZOhynyWbDZWJ4jcEe9Kk0eTXNf4DW5NBwuEGzjqFa2JEmr9tA5H1b/CBqGJO htIaAJ5PU3Q67iEb+XlqnCQdlfM6B4OGuPuXvcehqGTpSI9qrxMf/JMMiity5CjAqV uG8Xv6YT8B43D7yocFCVT3CMUH/ysLUA7ZI9iiSjLJvaI8CEq0l/75fj+hLZHDhQTN tA6om1ttnNLdXP6K2KFjhHAYZJbWw4MD6CyQO7zIQxSEdcoqMAvdDixNoo9nb4BX8r NEpscYnkfCw/zaUJ/rGOEOMX2hyPm6nobjrL63iPXZXeaNIMzdZNIn9zYXOrFKxXq6 3dMjlHEdJwTkw== 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 16597C5DF66; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) From: Long Zhao via B4 Relay Date: Thu, 13 Aug 2026 17:56:13 +0800 Subject: [PATCH v3 2/6] dt-bindings: mfd: syscon: add Ambarella CV75 secure scratchpad 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: <20260813-cv75-v3-a-v3-2-cfdd20b1b4dd@ambarella.com> References: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> In-Reply-To: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Catalin Marinas , Will Deacon , Arnd Bergmann , Alexandre Belloni , Linus Walleij Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, soc@lists.linux.dev, Long Zhao X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786615029; l=887; i=longzhao@ambarella.com; s=20260730; h=from:subject:message-id; bh=7UUWM+HfbNQWDCef0OWKCQrG2Or9h9Cimqi3CyH0cqU=; b=B423N+54XHdjRnfbecFiazdfTgyW8mpLgkE4sCs9bmJOzhzyjTV6tukI2rcgCtP2596aLXAn1 Ozas4RbMAmnBCZuLhbeJqO6PiEQgVC722bDWBGL8ViNJb8llFo0pDKp X-Developer-Key: i=longzhao@ambarella.com; a=ed25519; pk=/xGhPTOX0/eYsyTWzyjjgAIW1Z/YD+IlnOnvcdRozow= X-Endpoint-Received: by B4 Relay for longzhao@ambarella.com/20260730 with auth_id=903 X-Original-From: Long Zhao Reply-To: longzhao@ambarella.com From: Long Zhao Allow ambarella,cv75-sec-scratchpad with syscon for shared secure scratchpad registers used by pinctrl pull configuration. Signed-off-by: Long Zhao --- Documentation/devicetree/bindings/mfd/syscon.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentat= ion/devicetree/bindings/mfd/syscon.yaml index fe882d3f828b..9ebf702c06f1 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -32,6 +32,7 @@ properties: - allwinner,sun50i-a64-system-controller - altr,l3regs - altr,sdr-ctl + - ambarella,cv75-sec-scratchpad - amd,pensando-elba-syscon - amlogic,meson-mx-assist - amlogic,meson-mx-bootrom --=20 2.34.1 From nobody Tue Sep 29 02:34:10 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 87F1C43F4B3; Thu, 13 Aug 2026 09:57:11 +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=1786615031; cv=none; b=cBRAzmUhgwY3CwP2eKkAlWfVA97nw2arBCDvlWsEvkqldwgrFE4ZRbY9rPQIFN+nQ0YKOSzbZdYh5dZtnbuSrA+pZq3R7mKgTXytmgOpR3MniI4bznWT2SRafRwYiJoBlcBoQh8dbVFCz0TbOTbzo4cQudc+Dslu+iOaoWKRNiM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786615031; c=relaxed/simple; bh=aSJA2EFPPGSpWartqH3BCX1f9nWW1yxSp86dYBj9s5Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZVOo96YqZpg5IksBZzlyvXF7yNfFe5NGK9jJAuuFofns7o0mpOSW1egqBPKvhOnk/3vW2hBLOKOiFXNwgSNxVtcYULIHJimxmmzoIdIQcx4FzozI+lB+mqGfuvXOdyVdsrwwxV6tV4qV0Qut6G2V2B/dfyZpVs+OfK9qVmjNnso= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=V8JWG0Y0; 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="V8JWG0Y0" Received: by smtp.kernel.org (Postfix) with ESMTPS id 4401EC2BD00; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786615031; bh=aSJA2EFPPGSpWartqH3BCX1f9nWW1yxSp86dYBj9s5Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=V8JWG0Y0KojYzOxwRMG6MZ025QkxS735fGNL5QXosSI2xZ6R1y4Mdp2vsZWqTxQHk smclbAPj6LrDhkH0mKoEtADGne9yk0KR1x0P+kUe4bPfQp2PkmM6i98k9d6iqU6jEr LcoScTKEghnKXBxRibr5vJ8Z4n6YS2Fjo2dHNqC8qp9GdajINWahzn4Mub7b0PuyG5 WpfhCha0/w28MqVuF+dE5rwWJIUwtDJoJeB5/V6PelS6QmcO0avdfMRPHS6cKSgC9f b9c12QVgIPIFchodsVwCrV3XZ8PylcZjltauI4Ff082fDBzNHD+lunb1w7iAY8HFWs bRbw0/gbM3Gfw== 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 26980C5CFEB; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) From: Long Zhao via B4 Relay Date: Thu, 13 Aug 2026 17:56:14 +0800 Subject: [PATCH v3 3/6] dt-bindings: clock: add Ambarella CV75 RCT 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: <20260813-cv75-v3-a-v3-3-cfdd20b1b4dd@ambarella.com> References: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> In-Reply-To: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Catalin Marinas , Will Deacon , Arnd Bergmann , Alexandre Belloni , Linus Walleij Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, soc@lists.linux.dev, Long Zhao X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786615029; l=2647; i=longzhao@ambarella.com; s=20260730; h=from:subject:message-id; bh=10b0bj80z69iNUeJ6xkO89WqeEirl990xJjncrVar6c=; b=+GveRNOHVJLxmO9iIuPI3qFB0pTqkG5nwUdiEvMgndDcqyay0kVz+JdAUZ0qITu6saweL9DhR soPCPX6RkO5AELmdzD2aofvSI3Ngnrz+3gAG6/Fo93PjB/0J6jQfOb7 X-Developer-Key: i=longzhao@ambarella.com; a=ed25519; pk=/xGhPTOX0/eYsyTWzyjjgAIW1Z/YD+IlnOnvcdRozow= X-Endpoint-Received: by B4 Relay for longzhao@ambarella.com/20260730 with auth_id=903 X-Original-From: Long Zhao Reply-To: longzhao@ambarella.com From: Long Zhao Document the CV75 RCT clock controller and the clock ID header used by DT consumers. Signed-off-by: Long Zhao --- .../bindings/clock/ambarella,cv75-rct.yaml | 58 ++++++++++++++++++= ++++ include/dt-bindings/clock/ambarella,cv75-rct.h | 15 ++++++ 2 files changed, 73 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/ambarella,cv75-rct.yam= l b/Documentation/devicetree/bindings/clock/ambarella,cv75-rct.yaml new file mode 100644 index 000000000000..eb5956fc32bc --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ambarella,cv75-rct.yaml @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ambarella,cv75-rct.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ambarella CV75 RCT Clock Controller + +maintainers: + - Long Zhao + +description: | + The RCT (Reset and Clock Tree) block on the Ambarella CV75 SoC provides + PLLs, clock muxes and dividers for on-chip peripherals. + + The same register region is also exposed as a syscon for other SoC + blocks (e.g. pin drive-strength), hence the "syscon" compatible. + + Clock indices are defined in include/dt-bindings/clock/ambarella,cv75-rc= t.h. + +properties: + + compatible: + items: + - const: ambarella,cv75-rct + - const: syscon + + reg: + maxItems: 1 + + clocks: + description: Reference crystal oscillator (typically 24 MHz) + maxItems: 1 + + clock-names: + const: osc + + "#clock-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + +additionalProperties: false + +examples: + - | + clock-controller@ed080000 { + compatible =3D "ambarella,cv75-rct", "syscon"; + reg =3D <0xed080000 0x1000>; + clocks =3D <&osc>; + clock-names =3D "osc"; + #clock-cells =3D <1>; + }; diff --git a/include/dt-bindings/clock/ambarella,cv75-rct.h b/include/dt-bi= ndings/clock/ambarella,cv75-rct.h new file mode 100644 index 000000000000..0a6e946c9108 --- /dev/null +++ b/include/dt-bindings/clock/ambarella,cv75-rct.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (C) 2026 Ambarella, Inc. + */ + +#ifndef _DT_BINDINGS_CLOCK_AMBARELLA_CV75_RCT_H +#define _DT_BINDINGS_CLOCK_AMBARELLA_CV75_RCT_H + +/* Boot / bus clocks */ +#define CV75_GCLK_UART0 0 +#define CV75_GCLK_CORE 1 +#define CV75_GCLK_AHB 2 +#define CV75_GCLK_APB 3 + +#endif --=20 2.34.1 From nobody Tue Sep 29 02:34:10 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 87E6F43F0B5; Thu, 13 Aug 2026 09:57:11 +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=1786615031; cv=none; b=JJLJEWgrkZo13jFLv1SHByy61Ni5ScONZWaxEC6A9lXcpn3II+WF7lEv0swE8407EsIHCoiRoY0s7C28B/QHgT67/PXIsBJGmTGQt9MXajlwTn/AeYnxBLHHfW3gesFmRgLRMs2Tspz2X+H4eZ8vst0grIwsi245E2HcCS0YX30= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786615031; c=relaxed/simple; bh=kQtt5SQH0YJyBg/LIq+FOvq7CVX7RqIxiNejvdCbHdo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QR+NfdG372kyOoy+elG08MIMB2UTSS1817wcgDUiJ2WIUF8ZNTKQ/48NSPWA0hJnOLIR2fNywloZ5oJXYyor4SvDhE70ZK1TLklGqwva8k7zxupz5gnjn8lQXdu9Pf2siXrX9ANEW3KknI2sq+zm1aUm4x8SipfzBtHiMe6EWnk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k8cpaEC9; 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="k8cpaEC9" Received: by smtp.kernel.org (Postfix) with ESMTPS id 515AFC2BCFD; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786615031; bh=kQtt5SQH0YJyBg/LIq+FOvq7CVX7RqIxiNejvdCbHdo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=k8cpaEC9U6TvnNEct/gz3SNmLTdY9T8GLFTq6mv1tBYe8532MUU0P3mKcBqzSd0y/ QmifnxLHJO5yFj+bFYF1regHJF803NFEYtmiJ5r3C1StRrYV8pHXZhqQUweM+zCxUi EvfhegQU7Zs4hG44yGlzFBsLJ2fZBSU3fAgI82CPYaMWnOyQO2XUyFx4SRlYYVLOEh 70+Gn8+T3bwtCt2EJoet+WV1KIzfhIduS7vP4w7Mqe/22OzqzXbhd8RVXjkokyD8TQ kht0ciItrGRf0o5QLpCWOMK7T8GLXP2RIGnWMokvNHjqr6lTshqk7qrqXTAEjm6DnM Bq7t4SeiHcJjw== 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 3EAC0C5CFDB; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) From: Long Zhao via B4 Relay Date: Thu, 13 Aug 2026 17:56:15 +0800 Subject: [PATCH v3 4/6] clk: ambarella: add CV75 CCU driver 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: <20260813-cv75-v3-a-v3-4-cfdd20b1b4dd@ambarella.com> References: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> In-Reply-To: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Catalin Marinas , Will Deacon , Arnd Bergmann , Alexandre Belloni , Linus Walleij Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, soc@lists.linux.dev, Long Zhao X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786615029; l=33033; i=longzhao@ambarella.com; s=20260730; h=from:subject:message-id; bh=hzI0GLPbLYqWQvcqXxGjz2taapaBZprKFeDWf0zaNd4=; b=fBRzDKcmjeAseYC4vKr80GRBk5XaMtbDkNbBgs/9aKdsikDlDZx0XrQQp8wkyuRfvWxoCOjRD o5Qho+l7SSWCM6xxJQnLYuKUUwC73yeiy6iotcU564NwdPXAOh+ib2A X-Developer-Key: i=longzhao@ambarella.com; a=ed25519; pk=/xGhPTOX0/eYsyTWzyjjgAIW1Z/YD+IlnOnvcdRozow= X-Endpoint-Received: by B4 Relay for longzhao@ambarella.com/20260730 with auth_id=903 X-Original-From: Long Zhao Reply-To: longzhao@ambarella.com From: Long Zhao Add the Ambarella CV75 clock driver covering the core PLL and the UART0 / AHB / APB clocks needed for early console bring-up. Signed-off-by: Long Zhao --- drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/ambarella/Kconfig | 13 ++ drivers/clk/ambarella/Makefile | 6 + drivers/clk/ambarella/ccu-cv75.c | 296 ++++++++++++++++++++++++++++ drivers/clk/ambarella/ccu_common.c | 60 ++++++ drivers/clk/ambarella/ccu_common.h | 25 +++ drivers/clk/ambarella/ccu_mux_div.c | 231 ++++++++++++++++++++++ drivers/clk/ambarella/ccu_mux_div.h | 35 ++++ drivers/clk/ambarella/ccu_pll.c | 378 ++++++++++++++++++++++++++++++++= ++++ drivers/clk/ambarella/ccu_pll.h | 70 +++++++ 11 files changed, 1116 insertions(+) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 1717ce75a907..fbbf4963716c 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -506,6 +506,7 @@ config COMMON_CLK_RPMI the RISC-V platform management interface (RPMI) specification. =20 source "drivers/clk/actions/Kconfig" +source "drivers/clk/ambarella/Kconfig" source "drivers/clk/analogbits/Kconfig" source "drivers/clk/aspeed/Kconfig" source "drivers/clk/bcm/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index cc108a75a900..30d823ee606f 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -112,6 +112,7 @@ obj-$(CONFIG_COMMON_CLK_XGENE) +=3D clk-xgene.o =20 # please keep this section sorted lexicographically by directory path name obj-y +=3D actions/ +obj-y +=3D ambarella/ obj-y +=3D analogbits/ obj-y +=3D aspeed/ obj-$(CONFIG_COMMON_CLK_AT91) +=3D at91/ diff --git a/drivers/clk/ambarella/Kconfig b/drivers/clk/ambarella/Kconfig new file mode 100644 index 000000000000..d79bb4bd6df5 --- /dev/null +++ b/drivers/clk/ambarella/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config CLK_AMBARELLA_CV75 + bool "Ambarella CV75 RCT clock controller" + depends on ARCH_AMBARELLA || COMPILE_TEST + select CLK_AMBARELLA_CCU + default ARCH_AMBARELLA + help + Say Y to enable the Ambarella CV75 RCT clock controller. + +config CLK_AMBARELLA_CCU + bool + select REGMAP_MMIO diff --git a/drivers/clk/ambarella/Makefile b/drivers/clk/ambarella/Makefile new file mode 100644 index 000000000000..36e96326ea97 --- /dev/null +++ b/drivers/clk/ambarella/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for ambarella specific clk +# + +obj-$(CONFIG_CLK_AMBARELLA_CCU) +=3D ccu_common.o ccu_mux_div.o ccu_pll.o +obj-$(CONFIG_CLK_AMBARELLA_CV75) +=3D ccu-cv75.o diff --git a/drivers/clk/ambarella/ccu-cv75.c b/drivers/clk/ambarella/ccu-c= v75.c new file mode 100644 index 000000000000..d682da3cf28d --- /dev/null +++ b/drivers/clk/ambarella/ccu-cv75.c @@ -0,0 +1,296 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Ambarella, Inc. + * + * CV75 RCT clock controller for boot clocks. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "ccu_common.h" +#include "ccu_mux_div.h" +#include "ccu_pll.h" + +enum amb_cv75_clk_type { + AMB_CV75_CLK_FIXED_RATE, + AMB_CV75_CLK_FIXED_FACTOR, + AMB_CV75_CLK_PLL, + AMB_CV75_CLK_DIV, + AMB_CV75_CLK_MUX_DIV, +}; + +enum amb_cv75_clk_ref { + AMB_CV75_CLK_REF_OSC =3D -1, + AMB_CV75_CLK_REF_DUMMY =3D -2, +}; + +/* PLL version for CV75 (ambarella,clkpll-v1 in vendor DTS) */ +static const struct amb_pll_soc_data cv75_pll_soc_data =3D { + .pll_version =3D 1, + .fsout_mask =3D CTRL2_FSOUT_DIV2, + .fsout_val =3D CTRL2_FSOUT_DIV2, + .fsdiv_mask =3D CTRL2_FSDIV_DIV2, + .fsdiv_val =3D CTRL2_FSDIV_DIV2, + .vcodiv_mask =3D CTRL2_VCODIV_DIV2, + .vcodiv_val =3D CTRL2_VCODIV_DIV2, + .vco_max_mhz =3D 2600UL, + .vco_min_mhz =3D 850UL, + .vco_range =3D { 1800UL, 1400UL, 1100UL, 0UL }, +}; + +struct amb_cv75_clk_desc { + int id; + enum amb_cv75_clk_type type; + const char *name; + int parent; + + union { + struct { + unsigned long rate; + } fixed_rate; + struct { + unsigned long flags; + unsigned int mult; + unsigned int div; + } fixed_factor; + struct { + u32 reg_offset[REG_NUM]; + const struct amb_pll_soc_data *soc_data; + } pll; + struct { + u32 reg; + u32 shift; + u32 width; + u32 flags; + u32 fix_divider; + } div; + struct amb_mux_div_desc mux_div; + }; +}; + +static const struct amb_cv75_clk_desc cv75_clks[] =3D { + { + .id =3D AMB_CV75_CLK_REF_DUMMY, + .type =3D AMB_CV75_CLK_FIXED_RATE, + .name =3D "dummy", + .fixed_rate.rate =3D 0, + }, + { + .id =3D CV75_GCLK_CORE, + .type =3D AMB_CV75_CLK_PLL, + .name =3D "core", + .parent =3D AMB_CV75_CLK_REF_OSC, + .pll =3D { + .reg_offset =3D { + 0x000, 0x004, 0x100, + 0x104, 0x000, 0x000, + }, + .soc_data =3D &cv75_pll_soc_data, + }, + }, + { + .id =3D CV75_GCLK_AHB, + .type =3D AMB_CV75_CLK_FIXED_FACTOR, + .name =3D "ahb", + .parent =3D CV75_GCLK_CORE, + .fixed_factor =3D { + .flags =3D 0, + .mult =3D 1, + .div =3D 2, + }, + }, + { + .id =3D CV75_GCLK_APB, + .type =3D AMB_CV75_CLK_FIXED_FACTOR, + .name =3D "apb", + .parent =3D CV75_GCLK_CORE, + .fixed_factor =3D { + .flags =3D 0, + .mult =3D 1, + .div =3D 4, + }, + }, + { + .id =3D CV75_GCLK_UART0, + .type =3D AMB_CV75_CLK_MUX_DIV, + .name =3D "uart0", + .mux_div =3D { + .name =3D "uart0", + .parents =3D (const int[]) { + AMB_CV75_CLK_REF_OSC, CV75_GCLK_CORE, + AMB_CV75_CLK_REF_DUMMY, AMB_CV75_CLK_REF_DUMMY, + }, + .num_parents =3D 4, + .mux_reg =3D 0x1c8, + .mux_shift =3D 0, + .mux_mask =3D 0x3, + .div_reg =3D 0x038, + .div_shift =3D 0, + .div_width =3D 24, + .div_flags =3D CLK_DIVIDER_ONE_BASED, + .fix_divider =3D 1, + }, + }, +}; + +static struct clk_hw *amb_cv75_get_parent(struct amb_ccu *ccu, + struct clk_hw *osc, + struct clk_hw *dummy, + int parent) +{ + if (parent =3D=3D AMB_CV75_CLK_REF_OSC) + return osc; + if (parent =3D=3D AMB_CV75_CLK_REF_DUMMY) + return dummy; + + if (parent < 0 || parent >=3D ccu->data->num) + return ERR_PTR(-EINVAL); + + if (!ccu->data->hws[parent]) + return ERR_PTR(-EPROBE_DEFER); + + return ccu->data->hws[parent]; +} + +static struct clk_hw *amb_cv75_register_mux_div(struct device *dev, + struct amb_ccu *ccu, + const struct amb_cv75_clk_desc *desc, + struct clk_hw *osc, + struct clk_hw *dummy) +{ + const struct amb_mux_div_desc *md =3D &desc->mux_div; + struct clk_parent_data *pdata; + struct clk_hw *parent; + u8 i; + + pdata =3D devm_kcalloc(dev, md->num_parents, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + for (i =3D 0; i < md->num_parents; i++) { + if (md->parents[i] =3D=3D AMB_CV75_CLK_REF_OSC) { + pdata[i].fw_name =3D "osc"; + continue; + } + + parent =3D amb_cv75_get_parent(ccu, osc, dummy, md->parents[i]); + if (IS_ERR(parent)) + return parent; + + pdata[i].hw =3D parent; + } + + return amb_mux_div_register(dev, ccu->map, md, pdata); +} + +static struct clk_hw *amb_cv75_register_clk(struct device *dev, + struct amb_ccu *ccu, + const struct amb_cv75_clk_desc *desc, + struct clk_hw *osc, + struct clk_hw *dummy) +{ + struct amb_pll_desc pll_desc; + struct clk_hw *parent; + + switch (desc->type) { + case AMB_CV75_CLK_FIXED_RATE: + return devm_clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, + desc->fixed_rate.rate); + case AMB_CV75_CLK_FIXED_FACTOR: + parent =3D amb_cv75_get_parent(ccu, osc, dummy, desc->parent); + if (IS_ERR(parent)) + return parent; + + return devm_clk_hw_register_fixed_factor_parent_hw(dev, + desc->name, parent, + desc->fixed_factor.flags, + desc->fixed_factor.mult, + desc->fixed_factor.div); + case AMB_CV75_CLK_PLL: + parent =3D amb_cv75_get_parent(ccu, osc, dummy, desc->parent); + if (IS_ERR(parent)) + return parent; + + pll_desc.name =3D desc->name; + pll_desc.parent =3D parent; + memcpy((void *)pll_desc.reg_offset, desc->pll.reg_offset, + sizeof(pll_desc.reg_offset)); + pll_desc.soc_data =3D desc->pll.soc_data; + pll_desc.frac_mode =3D false; + + return amb_pll_register(dev, ccu->map, &pll_desc); + case AMB_CV75_CLK_DIV: + parent =3D amb_cv75_get_parent(ccu, osc, dummy, desc->parent); + if (IS_ERR(parent)) + return parent; + + return amb_div_register(dev, ccu->map, desc->name, parent, + desc->div.reg, desc->div.shift, + desc->div.width, desc->div.flags, + desc->div.fix_divider); + case AMB_CV75_CLK_MUX_DIV: + return amb_cv75_register_mux_div(dev, ccu, desc, osc, dummy); + default: + return ERR_PTR(-EINVAL); + } +} + +static int amb_cv75_rct_probe(struct platform_device *pdev) +{ + struct amb_ccu *ccu; + struct clk *osc_clk; + struct clk_hw *osc, *dummy =3D NULL, *hw; + int i; + + ccu =3D amb_ccu_init(pdev, ARRAY_SIZE(cv75_clks)); + if (IS_ERR(ccu)) + return PTR_ERR(ccu); + + osc_clk =3D devm_clk_get(&pdev->dev, "osc"); + if (IS_ERR(osc_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(osc_clk), + "missing osc clock\n"); + osc =3D __clk_get_hw(osc_clk); + + for (i =3D 0; i < ARRAY_SIZE(cv75_clks); i++) { + hw =3D amb_cv75_register_clk(&pdev->dev, ccu, &cv75_clks[i], + osc, dummy); + if (IS_ERR(hw)) + return dev_err_probe(&pdev->dev, PTR_ERR(hw), + "failed to register %s\n", + cv75_clks[i].name); + + if (cv75_clks[i].id =3D=3D AMB_CV75_CLK_REF_DUMMY) + dummy =3D hw; + else + ccu->data->hws[cv75_clks[i].id] =3D hw; + } + + return amb_ccu_register(ccu); +} + +static const struct of_device_id amb_cv75_rct_match[] =3D { + { .compatible =3D "ambarella,cv75-rct" }, + { } +}; +MODULE_DEVICE_TABLE(of, amb_cv75_rct_match); + +static struct platform_driver amb_cv75_rct_driver =3D { + .probe =3D amb_cv75_rct_probe, + .driver =3D { + .name =3D "ambarella-cv75-rct", + .of_match_table =3D amb_cv75_rct_match, + }, +}; +module_platform_driver(amb_cv75_rct_driver); + +MODULE_AUTHOR("Ambarella Inc."); +MODULE_DESCRIPTION("Ambarella CV75 RCT clock controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/ambarella/ccu_common.c b/drivers/clk/ambarella/ccu= _common.c new file mode 100644 index 000000000000..78587c5f2ce1 --- /dev/null +++ b/drivers/clk/ambarella/ccu_common.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Ambarella, Inc. + */ + +#include +#include +#include +#include +#include + +#include "ccu_common.h" + +static const struct regmap_config amb_rct_regmap_config =3D { + .reg_bits =3D 32, + .val_bits =3D 32, + .reg_stride =3D 4, + .max_register =3D AMB_RCT_REG_SIZE - 4, +}; + +struct amb_ccu *amb_ccu_init(struct platform_device *pdev, + unsigned int num_clks) +{ + struct amb_ccu *ccu; + void __iomem *base; + + if (!num_clks) + return ERR_PTR(-EINVAL); + + ccu =3D devm_kzalloc(&pdev->dev, sizeof(*ccu), GFP_KERNEL); + if (!ccu) + return ERR_PTR(-ENOMEM); + + ccu->dev =3D &pdev->dev; + + ccu->data =3D devm_kzalloc(&pdev->dev, + struct_size(ccu->data, hws, num_clks), + GFP_KERNEL); + if (!ccu->data) + return ERR_PTR(-ENOMEM); + + ccu->data->num =3D num_clks; + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return ERR_CAST(base); + + ccu->map =3D devm_regmap_init_mmio(&pdev->dev, base, + &amb_rct_regmap_config); + if (IS_ERR(ccu->map)) + return ERR_CAST(ccu->map); + + return ccu; +} + +int amb_ccu_register(struct amb_ccu *ccu) +{ + return devm_of_clk_add_hw_provider(ccu->dev, of_clk_hw_onecell_get, + ccu->data); +} diff --git a/drivers/clk/ambarella/ccu_common.h b/drivers/clk/ambarella/ccu= _common.h new file mode 100644 index 000000000000..f2bf9d1f06d7 --- /dev/null +++ b/drivers/clk/ambarella/ccu_common.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 Ambarella, Inc. + */ + +#ifndef __CCU_COMMON_H +#define __CCU_COMMON_H + +#include +#include +#include + +#define AMB_RCT_REG_SIZE 0x1000 + +struct amb_ccu { + struct device *dev; + struct regmap *map; + struct clk_hw_onecell_data *data; +}; + +struct amb_ccu *amb_ccu_init(struct platform_device *pdev, + unsigned int num_clks); +int amb_ccu_register(struct amb_ccu *ccu); + +#endif diff --git a/drivers/clk/ambarella/ccu_mux_div.c b/drivers/clk/ambarella/cc= u_mux_div.c new file mode 100644 index 000000000000..77368a988315 --- /dev/null +++ b/drivers/clk/ambarella/ccu_mux_div.c @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Ambarella, Inc. + * + * Regmap-backed mux + divider, derived from the vendor composite-clock dr= iver. + */ + +#include +#include +#include +#include + +#include "ccu_mux_div.h" + +struct amb_mux { + struct clk_hw hw; + struct regmap *map; + u32 offset; + u32 mask; + u32 shift; +}; + +struct amb_div { + struct clk_hw hw; + struct regmap *map; + u32 offset; + u32 shift; + u32 width; + u32 flags; + u32 fix_divider; +}; + +#define to_amb_mux(_hw) container_of(_hw, struct amb_mux, hw) +#define to_amb_div(_hw) container_of(_hw, struct amb_div, hw) + +static u8 amb_mux_get_parent(struct clk_hw *hw) +{ + struct amb_mux *mux =3D to_amb_mux(hw); + u32 val; + + regmap_read(mux->map, mux->offset, &val); + val >>=3D mux->shift; + val &=3D mux->mask; + + return val; +} + +static int amb_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct amb_mux *mux =3D to_amb_mux(hw); + + return regmap_update_bits(mux->map, mux->offset, + mux->mask << mux->shift, + index << mux->shift); +} + +static const struct clk_ops amb_mux_ops =3D { + .get_parent =3D amb_mux_get_parent, + .set_parent =3D amb_mux_set_parent, +}; + +static unsigned long amb_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct amb_div *div =3D to_amb_div(hw); + unsigned long rate; + u32 val; + + regmap_read(div->map, div->offset, &val); + + /* Divider reset/disable bit sits above the field at shift+width. */ + if (val & (BIT(div->width) << div->shift)) + return 0; + + val >>=3D div->shift; + val &=3D clk_div_mask(div->width); + + rate =3D divider_recalc_rate(hw, parent_rate, val, NULL, + div->flags, div->width); + if (div->fix_divider) + rate =3D div_u64(rate, div->fix_divider); + + return rate; +} + +static int amb_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct amb_div *div =3D to_amb_div(hw); + struct clk_rate_request scaled =3D *req; + int ret; + + if (!req->rate && (div->flags & CLK_DIVIDER_ONE_BASED)) + return 0; + + if (div->fix_divider) { + scaled.rate =3D min(req->rate, + ULONG_MAX / div->fix_divider) * + div->fix_divider; + scaled.min_rate =3D min(req->min_rate, + ULONG_MAX / div->fix_divider) * + div->fix_divider; + scaled.max_rate =3D min(req->max_rate, + ULONG_MAX / div->fix_divider) * + div->fix_divider; + } + + ret =3D divider_determine_rate(hw, &scaled, NULL, div->width, + div->flags); + if (ret) + return ret; + + req->rate =3D scaled.rate; + req->best_parent_rate =3D scaled.best_parent_rate; + req->best_parent_hw =3D scaled.best_parent_hw; + if (div->fix_divider) + req->rate =3D div_u64(req->rate, div->fix_divider); + + return 0; +} + +static int amb_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct amb_div *div =3D to_amb_div(hw); + int val, mask; + + if (div->fix_divider) + rate *=3D div->fix_divider; + + if (!rate) { + /* Assert the reset/disable bit above the divider field. */ + val =3D BIT(div->width); + mask =3D clk_div_mask(div->width + 1); + } else { + val =3D divider_get_val(rate, parent_rate, NULL, + div->width, div->flags); + if (val < 0) + return val; + + mask =3D (div->flags & CLK_DIVIDER_ONE_BASED) ? + clk_div_mask(div->width + 1) : clk_div_mask(div->width); + } + + regmap_update_bits(div->map, div->offset, mask << div->shift, + val << div->shift); + + /* + * Non-ONE_BASED dividers use bit 0 as a write-enable strobe. Skip the + * pulse when shift =3D=3D 0 so we do not corrupt the divider field itsel= f. + */ + if (!(div->flags & CLK_DIVIDER_ONE_BASED) && div->shift) { + regmap_update_bits(div->map, div->offset, BIT(0), BIT(0)); + regmap_update_bits(div->map, div->offset, BIT(0), 0); + } + + return 0; +} + +static const struct clk_ops amb_div_ops =3D { + .recalc_rate =3D amb_div_recalc_rate, + .determine_rate =3D amb_div_determine_rate, + .set_rate =3D amb_div_set_rate, +}; + +struct clk_hw *amb_div_register(struct device *dev, struct regmap *map, + const char *name, const struct clk_hw *parent, + u32 div_reg, u32 div_shift, u32 div_width, + u32 div_flags, u32 fix_divider) +{ + struct amb_div *div; + struct clk_init_data init =3D {}; + int ret; + + div =3D devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + div->map =3D map; + div->offset =3D div_reg; + div->shift =3D div_shift; + div->width =3D div_width; + div->flags =3D div_flags; + div->fix_divider =3D fix_divider; + + init.name =3D name; + init.ops =3D &amb_div_ops; + init.parent_hws =3D &parent; + init.num_parents =3D 1; + + div->hw.init =3D &init; + + ret =3D devm_clk_hw_register(dev, &div->hw); + if (ret) + return ERR_PTR(ret); + + return &div->hw; +} + +struct clk_hw *amb_mux_div_register(struct device *dev, struct regmap *map, + const struct amb_mux_div_desc *desc, + const struct clk_parent_data *parent_data) +{ + struct amb_mux *mux; + struct amb_div *div; + + mux =3D devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); + div =3D devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); + if (!mux || !div) + return ERR_PTR(-ENOMEM); + + mux->map =3D map; + mux->offset =3D desc->mux_reg; + mux->shift =3D desc->mux_shift; + mux->mask =3D desc->mux_mask; + + div->map =3D map; + div->offset =3D desc->div_reg; + div->shift =3D desc->div_shift; + div->width =3D desc->div_width; + div->flags =3D desc->div_flags; + div->fix_divider =3D desc->fix_divider; + + return devm_clk_hw_register_composite_pdata(dev, desc->name, + parent_data, + desc->num_parents, + &mux->hw, &amb_mux_ops, + &div->hw, &amb_div_ops, + NULL, NULL, + CLK_SET_RATE_NO_REPARENT); +} diff --git a/drivers/clk/ambarella/ccu_mux_div.h b/drivers/clk/ambarella/cc= u_mux_div.h new file mode 100644 index 000000000000..abaefff1201a --- /dev/null +++ b/drivers/clk/ambarella/ccu_mux_div.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 Ambarella, Inc. + */ + +#ifndef __CCU_MUX_DIV_H +#define __CCU_MUX_DIV_H + +#include +#include + +struct amb_mux_div_desc { + const char *name; + const int *parents; + u8 num_parents; + u32 mux_reg; + u32 mux_shift; + u32 mux_mask; + u32 div_reg; + u32 div_shift; + u32 div_width; + u32 div_flags; + u32 fix_divider; +}; + +struct clk_hw *amb_mux_div_register(struct device *dev, struct regmap *map, + const struct amb_mux_div_desc *desc, + const struct clk_parent_data *parent_data); + +struct clk_hw *amb_div_register(struct device *dev, struct regmap *map, + const char *name, const struct clk_hw *parent, + u32 div_reg, u32 div_shift, u32 div_width, + u32 div_flags, u32 fix_divider); + +#endif diff --git a/drivers/clk/ambarella/ccu_pll.c b/drivers/clk/ambarella/ccu_pl= l.c new file mode 100644 index 000000000000..f4a90b4d179a --- /dev/null +++ b/drivers/clk/ambarella/ccu_pll.c @@ -0,0 +1,378 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Ambarella, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ccu_pll.h" + +#define AMB_PLL_MAX_SOUT 16UL +#define AMB_PLL_MAX_SDIV 16UL + +struct amb_pll { + struct clk_hw hw; + struct regmap *map; + u32 reg_offset[REG_NUM]; + const struct amb_pll_soc_data *soc_data; + u32 fix_divider; + bool frac_mode; +}; + +#define to_amb_pll(_hw) container_of(_hw, struct amb_pll, hw) + +static void amb_pll_write_enable(struct regmap *map, u32 offset, u32 val) +{ + regmap_write(map, offset, val); + regmap_write(map, offset, val | CTRL_WRITE_ENABLE); + regmap_write(map, offset, val); +} + +static unsigned long amb_pll_calc_vco(struct amb_pll *pll, + unsigned long parent_rate) +{ + const struct amb_pll_soc_data *soc_data =3D pll->soc_data; + u32 *reg =3D pll->reg_offset; + u32 pre_scaler =3D 1; + u32 ctrl_val, ctrl2_val =3D 0, frac_val; + u32 intp, sdiv, vcodiv, fsdiv; + u64 frac =3D 0, vco; + + if (reg[PRES_OFFSET]) { + regmap_read(pll->map, reg[PRES_OFFSET], &pre_scaler); + pre_scaler =3D (pre_scaler >> 4) + 1; + } + + regmap_read(pll->map, reg[CTRL_OFFSET], &ctrl_val); + intp =3D ((ctrl_val >> 24) & 0x7f) + 1; + sdiv =3D ((ctrl_val >> 12) & 0xf) + 1; + + if (soc_data->pll_version >=3D 2) { + vcodiv =3D (ctrl_val & soc_data->vcodiv_mask) =3D=3D + soc_data->vcodiv_val ? 2 : 1; + fsdiv =3D (ctrl_val & soc_data->fsdiv_mask) =3D=3D + soc_data->fsdiv_val ? 2 : 1; + } else { + regmap_read(pll->map, reg[CTRL2_OFFSET], &ctrl2_val); + vcodiv =3D (ctrl2_val & soc_data->vcodiv_mask) =3D=3D + soc_data->vcodiv_val ? 2 : 1; + fsdiv =3D (ctrl2_val & soc_data->fsdiv_mask) =3D=3D + soc_data->fsdiv_val ? 2 : 1; + } + + vco =3D (u64)parent_rate * vcodiv * fsdiv * intp * sdiv; + vco =3D div_u64(vco, pre_scaler); + + if (ctrl_val & CTRL_FRAC_MODE) { + regmap_read(pll->map, reg[FRAC_OFFSET], &frac_val); + frac =3D (u64)parent_rate * vcodiv * fsdiv * sdiv * frac_val; + frac =3D div_u64(frac, pre_scaler) >> 32; + } + + return vco + frac; +} + +static unsigned long amb_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct amb_pll *pll =3D to_amb_pll(hw); + const struct amb_pll_soc_data *soc_data =3D pll->soc_data; + u32 *reg =3D pll->reg_offset; + u32 pre_scaler =3D 1, post_scaler =3D 1; + u32 ctrl_val, ctrl2_val =3D 0; + u32 vcodiv, fsout, sout; + u64 rate; + + regmap_read(pll->map, reg[CTRL_OFFSET], &ctrl_val); + if (ctrl_val & (CTRL_POWER_DOWN | CTRL_HALT_VCO | CTRL_FORCE_RESET)) + return 0; + + if (reg[PRES_OFFSET]) { + regmap_read(pll->map, reg[PRES_OFFSET], &pre_scaler); + pre_scaler =3D (pre_scaler >> 4) + 1; + } + + if (reg[POST_OFFSET]) { + regmap_read(pll->map, reg[POST_OFFSET], &post_scaler); + post_scaler =3D (post_scaler >> 4) + 1; + } + + if (ctrl_val & CTRL_BYPASS) + return parent_rate / pre_scaler / post_scaler; + + if (soc_data->pll_version >=3D 2) { + vcodiv =3D (ctrl_val & soc_data->vcodiv_mask) =3D=3D + soc_data->vcodiv_val ? 2 : 1; + fsout =3D (ctrl_val & soc_data->fsout_mask) =3D=3D + soc_data->fsout_val ? 2 : 1; + } else { + regmap_read(pll->map, reg[CTRL2_OFFSET], &ctrl2_val); + vcodiv =3D (ctrl2_val & soc_data->vcodiv_mask) =3D=3D + soc_data->vcodiv_val ? 2 : 1; + fsout =3D (ctrl2_val & soc_data->fsout_mask) =3D=3D + soc_data->fsout_val ? 2 : 1; + } + + sout =3D ((ctrl_val >> 16) & 0xf) + 1; + rate =3D amb_pll_calc_vco(pll, parent_rate); + + if (soc_data->pll_version >=3D 2) { + if (!(ctrl_val & CTRL_BYPASS_HSDIV)) + rate =3D div_u64(rate, vcodiv * fsout * sout); + } else { + if (!(ctrl2_val & CTRL2_BYPASS_HSDIV)) + rate =3D div_u64(rate, vcodiv * fsout * sout); + } + + rate =3D div_u64(rate, pll->fix_divider * post_scaler); + + return rate; +} + +static int amb_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct amb_pll *pll =3D to_amb_pll(hw); + unsigned long half_refclk =3D req->best_parent_rate / 2; + + if (pll->frac_mode) + return 0; + + if (!half_refclk) + return -EINVAL; + + req->rate =3D roundup(req->rate, half_refclk); + + return 0; +} + +static int amb_pll_calc_params(struct amb_pll *pll, unsigned long rate, + unsigned long parent_rate, u32 ctrl2_val, + u32 *intp, u32 *sdiv, u32 *sout, + u32 *vcodiv, u32 *fsdiv, u32 *fsout) +{ + const struct amb_pll_soc_data *soc_data =3D pll->soc_data; + unsigned long max_numerator, max_denominator; + unsigned long intp_ul, sout_ul, rate_tmp; + u32 ctrl_val; + + *sdiv =3D 1; + + if (soc_data->pll_version >=3D 2) { + ctrl_val =3D 0; + *vcodiv =3D (ctrl_val & soc_data->vcodiv_mask) =3D=3D + soc_data->vcodiv_val ? 2 : 1; + *fsdiv =3D (ctrl_val & soc_data->fsdiv_mask) =3D=3D + soc_data->fsdiv_val ? 2 : 1; + *fsout =3D (ctrl_val & soc_data->fsout_mask) =3D=3D + soc_data->fsout_val ? 2 : 1; + } else { + *vcodiv =3D (ctrl2_val & soc_data->vcodiv_mask) =3D=3D + soc_data->vcodiv_val ? 2 : 1; + *fsdiv =3D (ctrl2_val & soc_data->fsdiv_mask) =3D=3D + soc_data->fsdiv_val ? 2 : 1; + *fsout =3D (ctrl2_val & soc_data->fsout_mask) =3D=3D + soc_data->fsout_val ? 2 : 1; + } + + if (rate < parent_rate) + return -EINVAL; + + max_numerator =3D soc_data->vco_max_mhz; + max_numerator =3D div_u64(max_numerator * 1000000ULL, parent_rate); + max_numerator =3D div_u64(max_numerator, *vcodiv * *fsdiv); + max_numerator =3D min(128UL, max_numerator); + if (!max_numerator) + return -EINVAL; + + max_denominator =3D AMB_PLL_MAX_SOUT; + rate_tmp =3D rate; + rational_best_approximation(rate_tmp, parent_rate, max_numerator, + max_denominator, &intp_ul, &sout_ul); + + while (parent_rate * *fsdiv * intp_ul * *sdiv / *fsout / sout_ul > + rate) { + unsigned long resolution =3D parent_rate / AMB_PLL_MAX_SOUT; + + /* Avoid an infinite loop when parent_rate < AMB_PLL_MAX_SOUT. */ + if (!resolution) + resolution =3D 1; + + if (rate_tmp <=3D resolution) + return -EINVAL; + + rate_tmp -=3D resolution; + rational_best_approximation(rate_tmp, parent_rate, + max_numerator, max_denominator, + &intp_ul, &sout_ul); + } + + while (parent_rate / 1000000 * *vcodiv * *fsdiv * intp_ul * *sdiv < + soc_data->vco_min_mhz) { + if (sout_ul > 8 || intp_ul > 64) + break; + + intp_ul *=3D 2; + sout_ul *=3D 2; + } + + if (intp_ul > max_numerator || sout_ul > max_denominator || + *sdiv > AMB_PLL_MAX_SDIV) + return -EINVAL; + + *intp =3D intp_ul; + *sout =3D sout_ul; + + return 0; +} + +static int amb_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct amb_pll *pll =3D to_amb_pll(hw); + const struct amb_pll_soc_data *soc_data =3D pll->soc_data; + u32 *reg =3D pll->reg_offset; + u32 ctrl_val, ctrl2_val =3D 0, ctrl3_val, frac_val =3D 0; + u32 intp, sdiv, sout, vcodiv, fsdiv, fsout; + unsigned long old_rate, new_rate, rate_tmp; + int ret; + + if (!rate) { + regmap_read(pll->map, reg[CTRL_OFFSET], &ctrl_val); + ctrl_val |=3D CTRL_POWER_DOWN | CTRL_HALT_VCO; + amb_pll_write_enable(pll->map, reg[CTRL_OFFSET], ctrl_val); + return 0; + } + + rate *=3D pll->fix_divider; + + if (soc_data->ctrl2_val) + ctrl2_val =3D soc_data->ctrl2_val; + else + regmap_read(pll->map, reg[CTRL2_OFFSET], &ctrl2_val); + + ret =3D amb_pll_calc_params(pll, rate, parent_rate, ctrl2_val, + &intp, &sdiv, &sout, &vcodiv, &fsdiv, + &fsout); + if (ret) + return ret; + + if (soc_data->ctrl2_val) + regmap_write(pll->map, reg[CTRL2_OFFSET], soc_data->ctrl2_val); + + ctrl_val =3D ((intp - 1) & 0x7f) << 24; + ctrl_val |=3D ((sdiv - 1) & 0xf) << 12; + ctrl_val |=3D ((sout - 1) & 0xf) << 16; + if (soc_data->pll_version >=3D 2) { + ctrl_val |=3D vcodiv =3D=3D 2 ? soc_data->vcodiv_val : 0; + ctrl_val |=3D fsdiv =3D=3D 2 ? soc_data->fsdiv_val : 0; + ctrl_val |=3D fsout =3D=3D 2 ? soc_data->fsout_val : 0; + } + + regmap_write(pll->map, reg[CTRL_OFFSET], ctrl_val); + regmap_write(pll->map, reg[FRAC_OFFSET], 0); + + old_rate =3D amb_pll_recalc_rate(hw, parent_rate) * pll->fix_divider; + rate_tmp =3D old_rate > rate ? 0 : rate - old_rate; + if (rate_tmp && pll->frac_mode) { + u64 dividend, divider; + + dividend =3D (u64)rate_tmp * sout * fsout; + dividend <<=3D 32; + divider =3D (u64)sdiv * fsdiv * parent_rate; + frac_val =3D DIV_ROUND_CLOSEST_ULL(dividend, divider); + regmap_write(pll->map, reg[FRAC_OFFSET], frac_val); + ctrl_val |=3D CTRL_FRAC_MODE; + } + + if (soc_data->pll_version >=3D 2) { + ctrl3_val =3D soc_data->ctrl3_val; + regmap_write(pll->map, reg[CTRL3_OFFSET], + ctrl3_val | CTRL3_VCO_CLAMP); + regmap_write(pll->map, reg[CTRL_OFFSET], + ctrl_val | CTRL_FORCE_RESET); + ndelay(100); + regmap_write(pll->map, reg[CTRL_OFFSET], + ctrl_val & ~CTRL_FORCE_RESET); + ndelay(100); + regmap_write(pll->map, reg[CTRL3_OFFSET], + ctrl3_val & ~CTRL3_VCO_CLAMP); + } else { + u32 fvco_mhz, range; + + fvco_mhz =3D amb_pll_calc_vco(pll, parent_rate) / 1000000UL; + for (range =3D 0; range < ARRAY_SIZE(soc_data->vco_range); + range++) { + if (fvco_mhz > soc_data->vco_range[range]) + break; + } + range =3D ARRAY_SIZE(soc_data->vco_range) - range - 1; + + regmap_read(pll->map, reg[CTRL3_OFFSET], &ctrl3_val); + ctrl3_val &=3D ~CTRL3_VCO_RANGE_MASK; + ctrl3_val |=3D range << 1; + regmap_write(pll->map, reg[CTRL3_OFFSET], ctrl3_val); + + if (frac_val) { + ctrl_val |=3D CTRL_FORCE_RESET; + amb_pll_write_enable(pll->map, reg[CTRL_OFFSET], + ctrl_val); + } + + ctrl_val &=3D ~CTRL_FORCE_RESET; + amb_pll_write_enable(pll->map, reg[CTRL_OFFSET], ctrl_val); + } + + new_rate =3D amb_pll_recalc_rate(hw, parent_rate); + rate_tmp =3D rate / pll->fix_divider; + if (max(new_rate, rate_tmp) - min(new_rate, rate_tmp) > 10) + pr_warn("%s: requested %lu, got %lu\n", clk_hw_get_name(hw), + rate_tmp, new_rate); + + return 0; +} + +static const struct clk_ops amb_pll_ops =3D { + .recalc_rate =3D amb_pll_recalc_rate, + .determine_rate =3D amb_pll_determine_rate, + .set_rate =3D amb_pll_set_rate, +}; + +struct clk_hw *amb_pll_register(struct device *dev, struct regmap *map, + const struct amb_pll_desc *desc) +{ + struct amb_pll *pll; + struct clk_init_data init =3D {}; + const struct clk_hw *parent =3D desc->parent; + int ret; + + pll =3D devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + pll->map =3D map; + memcpy(pll->reg_offset, desc->reg_offset, sizeof(pll->reg_offset)); + pll->soc_data =3D desc->soc_data; + pll->fix_divider =3D 1; + pll->frac_mode =3D desc->frac_mode; + + init.name =3D desc->name; + init.ops =3D &amb_pll_ops; + init.flags =3D CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL; + init.parent_hws =3D &parent; + init.num_parents =3D 1; + + pll->hw.init =3D &init; + + ret =3D devm_clk_hw_register(dev, &pll->hw); + if (ret) + return ERR_PTR(ret); + + return &pll->hw; +} diff --git a/drivers/clk/ambarella/ccu_pll.h b/drivers/clk/ambarella/ccu_pl= l.h new file mode 100644 index 000000000000..b9e453e9debf --- /dev/null +++ b/drivers/clk/ambarella/ccu_pll.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 Ambarella, Inc. + */ + +#ifndef __CCU_PLL_H +#define __CCU_PLL_H + +#include +#include +#include +#include +#include + +enum { + CTRL_OFFSET =3D 0, + FRAC_OFFSET, + CTRL2_OFFSET, + CTRL3_OFFSET, + PRES_OFFSET, + POST_OFFSET, + REG_NUM, +}; + +#define CTRL_BYPASS BIT(2) +#define CTRL_WRITE_ENABLE BIT(0) +#define CTRL_FRAC_MODE BIT(3) +#define CTRL_FORCE_RESET BIT(4) +#define CTRL_POWER_DOWN BIT(5) +#define CTRL_HALT_VCO BIT(6) +#define CTRL_VCODIV_DIV2 BIT(8) +#define CTRL_FSDIV_DIV2 BIT(9) +#define CTRL_FSOUT_DIV2 BIT(10) +#define CTRL_BYPASS_HSDIV BIT(11) + +#define CTRL2_VCODIV_DIV2 BIT(8) +#define CTRL2_FSDIV_DIV2 BIT(9) +#define CTRL2_FSOUT_DIV2 BIT(11) +#define CTRL2_BYPASS_HSDIV BIT(12) + +#define CTRL3_VCO_RANGE_MASK 0x6 +#define CTRL3_VCO_CLAMP 0x8 + +struct amb_pll_soc_data { + u32 pll_version; + u32 fsout_mask; + u32 fsout_val; + u32 fsdiv_mask; + u32 fsdiv_val; + u32 vcodiv_mask; + u32 vcodiv_val; + u32 vco_max_mhz; + u32 vco_min_mhz; + u32 vco_range[4]; + u32 ctrl2_val; + u32 ctrl3_val; +}; + +struct amb_pll_desc { + const char *name; + const struct clk_hw *parent; + const u32 reg_offset[REG_NUM]; + const struct amb_pll_soc_data *soc_data; + bool frac_mode; +}; + +struct clk_hw *amb_pll_register(struct device *dev, struct regmap *map, + const struct amb_pll_desc *desc); + +#endif --=20 2.34.1 From nobody Tue Sep 29 02:34:10 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 B970B446067; Thu, 13 Aug 2026 09:57:11 +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=1786615031; cv=none; b=UAeKzHuX2WDwGaEzacrEIivUWHnjbcT5yIigdH5Atf+y7QFMBP/oxIPKoS2jLpROtffZzKsgM/WypxwmF3JmXrypQCJhxEdXxfOV+JHv3f8l5GNBVudSosller4qnqk/7M7LdvU+qQOYli24lLnC9+ZAxPT7a5tmd2R7XiQAlf8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786615031; c=relaxed/simple; bh=MGxW8mqYV5zxZ2nhKGBjrsUB+IauzQp8VHtemLsvom8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qMu1MyCccfKwvlSn8Iqhn944bkobTCNfH598P1hKctSfv1sG0tzBF1EF1Zth3NYPcA7kMSx2h4nVNrcPYPElCmzeSCEHUgk08+u9s8JsoQ8zxXaEc8YNOZC9jYuVqk3PYHMRIY1JjnXBh7jT2/2f6fPcWHurV3LwZ4kPmjB8LqI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BWrb0wHi; 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="BWrb0wHi" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5FA51C2BCFF; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786615031; bh=MGxW8mqYV5zxZ2nhKGBjrsUB+IauzQp8VHtemLsvom8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=BWrb0wHiEbAcCNJLBTLV+WkQmD4v3lQwr1M2Pyr1xpoSimS0OqPP7t6oN52LZtOrX k/gZAE04FpxwvKxfaH3FFK6PAH4JVRvjbaIUTlXJ6pXQ4uummWnjldCDiWcxzgcba6 Yf4mA5PxSa8p/sTQ820bhecKeTtYXoEr25Tyqn4kTTm2GMk3NuCF2UZTuxXjU4P6mP YC3LnBZ+I2HP5VX1ssm7K6rg3ttg2ZEz/QZ9pp4NiytZpQ+IInvxLr0LquPZzngrNH /TuXraeR8VyXoYVlZ+8hg67kVzw9wtXWnn5xTvDiHgTCYqWSWYz+h5Sejv6obbiSed EHadNVWmVbPvw== 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 4C9C9C5DF67; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) From: Long Zhao via B4 Relay Date: Thu, 13 Aug 2026 17:56:16 +0800 Subject: [PATCH v3 5/6] arm64: ambarella: add ARCH_AMBARELLA and CV75 EVK DT 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: <20260813-cv75-v3-a-v3-5-cfdd20b1b4dd@ambarella.com> References: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> In-Reply-To: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Catalin Marinas , Will Deacon , Arnd Bergmann , Alexandre Belloni , Linus Walleij Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, soc@lists.linux.dev, Long Zhao X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786615029; l=8142; i=longzhao@ambarella.com; s=20260730; h=from:subject:message-id; bh=y0qjOUV7DPDfe9Di6LtDKb/6xCPt3g9z1X5V+Ta6i/0=; b=R1bPvbBR9xTj/hGMduj897ST/rvX8BW1QXg6GPmmq+IiqeNHC+pHFvcIP4cf4Fwk7zIj+iwCE NtgKzoKXkCJAvOytP99FmbNw/sNZEWVIJfukbWm+AfzIGY0kWNLA5sB X-Developer-Key: i=longzhao@ambarella.com; a=ed25519; pk=/xGhPTOX0/eYsyTWzyjjgAIW1Z/YD+IlnOnvcdRozow= X-Endpoint-Received: by B4 Relay for longzhao@ambarella.com/20260730 with auth_id=903 X-Original-From: Long Zhao Reply-To: longzhao@ambarella.com From: Long Zhao Enable ARCH_AMBARELLA and add a minimal CV75 SoC / EVK device tree for console bring-up with the RCT clocks, UART, pinctrl and GPIO banks. Signed-off-by: Long Zhao --- arch/arm64/Kconfig.platforms | 9 ++ arch/arm64/boot/dts/Makefile | 1 + arch/arm64/boot/dts/ambarella/Makefile | 3 + arch/arm64/boot/dts/ambarella/cv75-evk.dts | 30 +++++ arch/arm64/boot/dts/ambarella/cv75.dtsi | 178 +++++++++++++++++++++++++= ++++ arch/arm64/configs/defconfig | 1 + 6 files changed, 222 insertions(+) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index d2acfac73003..166430ddb3c9 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -26,6 +26,15 @@ config ARCH_SUNXI help This enables support for Allwinner sunxi based SoCs like the A64. =20 +config ARCH_AMBARELLA + bool "Ambarella SoC family" + select ARM_PSCI + select HAVE_ARM_ARCH_TIMER + select PINCTRL + select PINCTRL_AMB + help + This enables support for the ARM64 based Ambarella SoCs like CV75. + config ARCH_ALPINE bool "Annapurna Labs Alpine platform" select ALPINE_MSI if PCI diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index fc726b215f12..f1709eb5d915 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -4,6 +4,7 @@ subdir-y +=3D airoha subdir-y +=3D allwinner subdir-y +=3D altera subdir-y +=3D amazon +subdir-y +=3D ambarella subdir-y +=3D amd subdir-y +=3D amlogic subdir-y +=3D apm diff --git a/arch/arm64/boot/dts/ambarella/Makefile b/arch/arm64/boot/dts/a= mbarella/Makefile new file mode 100644 index 000000000000..ddca3d7b18cc --- /dev/null +++ b/arch/arm64/boot/dts/ambarella/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +dtb-$(CONFIG_ARCH_AMBARELLA) +=3D cv75-evk.dtb diff --git a/arch/arm64/boot/dts/ambarella/cv75-evk.dts b/arch/arm64/boot/d= ts/ambarella/cv75-evk.dts new file mode 100644 index 000000000000..42a0fe24b83b --- /dev/null +++ b/arch/arm64/boot/dts/ambarella/cv75-evk.dts @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Ambarella CV75 EVK board + */ + +/dts-v1/; + +#include "cv75.dtsi" + +/ { + model =3D "Ambarella CV75 EVK Board"; + compatible =3D "ambarella,cv75-evk", "ambarella,cv75"; + + aliases { + serial0 =3D &uart0; + }; + + chosen { + stdout-path =3D &uart0; + }; + + memory@200000 { + device_type =3D "memory"; + reg =3D <0x0 0x00200000 0x0 0x07e00000>; + }; +}; + +&uart0 { + status =3D "okay"; +}; diff --git a/arch/arm64/boot/dts/ambarella/cv75.dtsi b/arch/arm64/boot/dts/= ambarella/cv75.dtsi new file mode 100644 index 000000000000..994eac6728ce --- /dev/null +++ b/arch/arm64/boot/dts/ambarella/cv75.dtsi @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Ambarella CV75 SoC + * + * Boot peripheral: UART0 console. + * Clocks: a single ambarella,cv75-rct provider. + */ + +#include +#include + +/ { + compatible =3D "ambarella,cv75"; + interrupt-parent =3D <&gic>; + #address-cells =3D <2>; + #size-cells =3D <2>; + + cpus { + #address-cells =3D <1>; + #size-cells =3D <0>; + + cpu@0 { + compatible =3D "arm,cortex-a76"; + device_type =3D "cpu"; + reg =3D <0x000>; + enable-method =3D "psci"; + }; + + cpu@1 { + compatible =3D "arm,cortex-a76"; + device_type =3D "cpu"; + reg =3D <0x100>; + enable-method =3D "psci"; + }; + }; + + osc: oscillator { + compatible =3D "fixed-clock"; + #clock-cells =3D <0>; + clock-frequency =3D <24000000>; + clock-output-names =3D "osc"; + }; + + psci { + compatible =3D "arm,psci-0.2"; + method =3D "smc"; + }; + + soc { + compatible =3D "simple-bus"; + #address-cells =3D <2>; + #size-cells =3D <2>; + ranges; + + ahb@ffe0000000 { + compatible =3D "simple-bus"; + reg =3D <0xff 0xe0000000 0x0 0x01000000>; + ranges =3D <0xe0000000 0xff 0xe0000000 0x01000000>; + #address-cells =3D <1>; + #size-cells =3D <1>; + + s_scratchpad_syscon: scratchpad@e002e000 { + compatible =3D "ambarella,cv75-sec-scratchpad", "syscon"; + reg =3D <0xe002e000 0x1000>; + }; + }; + + apb@ffe4000000 { + compatible =3D "simple-bus"; + reg =3D <0xff 0xe4000000 0x0 0x01000000>; + ranges =3D <0xe4000000 0xff 0xe4000000 0x01000000>; + #address-cells =3D <1>; + #size-cells =3D <1>; + + uart0: serial@e4000000 { + compatible =3D "ambarella,cv75-uart", + "snps,dw-apb-uart"; + reg =3D <0xe4000000 0x1000>; + clocks =3D <&rct CV75_GCLK_UART0>; + interrupts =3D ; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&uart0_pins>; + reg-io-width =3D <4>; + reg-shift =3D <2>; + + status =3D "disabled"; + }; + + pinctrl: pinctrl@e4010000 { + compatible =3D "ambarella,cv75-pinctrl"; + reg =3D <0xe4010000 0x1000>; + ambarella,drive-strength-syscon =3D <&rct>; + ambarella,pull-syscon =3D <&s_scratchpad_syscon>; + + uart0_pins: uart0-pins { + function =3D "uart0"; + groups =3D "uart0"; + }; + }; + + gpio0: gpio@e4013000 { + compatible =3D "ambarella,cv75-gpio", "arm,primecell"; + reg =3D <0xe4013000 0x1000>; + clocks =3D <&rct CV75_GCLK_APB>; + clock-names =3D "apb_pclk"; + interrupts =3D ; + gpio-controller; + #gpio-cells =3D <2>; + gpio-ranges =3D <&pinctrl 0 0 32>; + interrupt-controller; + #interrupt-cells =3D <2>; + arm,primecell-periphid =3D <0x00000061>; + }; + + gpio1: gpio@e4014000 { + compatible =3D "ambarella,cv75-gpio", "arm,primecell"; + reg =3D <0xe4014000 0x1000>; + clocks =3D <&rct CV75_GCLK_APB>; + clock-names =3D "apb_pclk"; + interrupts =3D ; + gpio-controller; + #gpio-cells =3D <2>; + gpio-ranges =3D <&pinctrl 0 32 32>; + interrupt-controller; + #interrupt-cells =3D <2>; + arm,primecell-periphid =3D <0x00000061>; + }; + + gpio2: gpio@e4015000 { + compatible =3D "ambarella,cv75-gpio", "arm,primecell"; + reg =3D <0xe4015000 0x1000>; + clocks =3D <&rct CV75_GCLK_APB>; + clock-names =3D "apb_pclk"; + interrupts =3D ; + gpio-controller; + #gpio-cells =3D <2>; + gpio-ranges =3D <&pinctrl 0 64 32>; + interrupt-controller; + #interrupt-cells =3D <2>; + arm,primecell-periphid =3D <0x00000061>; + }; + }; + + rct: clock-controller@ffed080000 { + compatible =3D "ambarella,cv75-rct", "syscon"; + reg =3D <0xff 0xed080000 0x0 0x1000>; + clocks =3D <&osc>; + clock-names =3D "osc"; + #clock-cells =3D <1>; + assigned-clocks =3D <&rct CV75_GCLK_UART0>; + assigned-clock-parents =3D <&osc>; + assigned-clock-rates =3D <24000000>; + }; + + gic: interrupt-controller@fff0101000 { + compatible =3D "arm,gic-400"; + reg =3D <0xff 0xf0101000 0x0 0x1000>, + <0xff 0xf0102000 0x0 0x2000>, + <0xff 0xf0104000 0x0 0x2000>, + <0xff 0xf0106000 0x0 0x2000>; + interrupt-controller; + #interrupt-cells =3D <3>; + #address-cells =3D <0>; + #size-cells =3D <1>; + interrupts =3D ; + }; + }; + + timer { + compatible =3D "arm,armv8-timer"; + interrupts =3D , + , + , + , + ; + }; +}; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index ad3bd3d9507b..454f07a6a6a6 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -36,6 +36,7 @@ CONFIG_CRASH_DUMP=3Dy CONFIG_ARCH_ACTIONS=3Dy CONFIG_ARCH_AIROHA=3Dy CONFIG_ARCH_SUNXI=3Dy +CONFIG_ARCH_AMBARELLA=3Dy CONFIG_ARCH_ALPINE=3Dy CONFIG_ARCH_APPLE=3Dy CONFIG_ARCH_ARTPEC=3Dy --=20 2.34.1 From nobody Tue Sep 29 02:34:10 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 B97DF44606A; Thu, 13 Aug 2026 09:57:11 +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=1786615031; cv=none; b=Qm3zXCYfitj23NkK+wF36kCS09I9z81K9MXzTZqozUbmV54h06M8LAC6pDX9Q/FFxlvHKfn4QAqwlvnxTKxc6D1KYzTKPAUeq7FVLMvtf9TOle5Ubnqj3wZV70l15E0QSeDtrOwIzB8Hg4YU9KBBIDzbkAJNBKWSuRdm6cOss7o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786615031; c=relaxed/simple; bh=u1O2yyg4IFgXvWdBWEfBf7DSbFAtEAmAyY6MwVpsw88=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TuSc3sfcVPqUelLUKFi2+FbnhsdnPoUFyPb5X5sjqrspOrFjaoEUwJ44AQlLfKemswL+E9ML+uYFwePpZFK5XUVDNMRm4YI6XZ/QXGecnT37vKMF4eVjKFXH7CQesYHEY7p1/U/LV3vNd6udynusYLJriFsTjzehzm41SPe/F38= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rBSuYI8P; 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="rBSuYI8P" Received: by smtp.kernel.org (Postfix) with ESMTPS id 712CFC2BD05; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786615031; bh=u1O2yyg4IFgXvWdBWEfBf7DSbFAtEAmAyY6MwVpsw88=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=rBSuYI8PDxgBrevDwj5Va/zkiTPCOCJSYDpXxDYqy7D6z3qOSW+N3MtWqy4GcGsUJ Fg8S/Fh3jG4oLSCk87gwvXQtZSRpk/xCp2Rk+bQwiVMJFCfq9dz5/HPNkOSrvdCHUo m4X4xwyx7Th4+d6RBto8WSncZHnozJ+BCyNiqRSb/ewvYF5tfT76QdDHNaCFLmSa7X wNExHkXwteFYTcR6zKHbXijuU7xW5PuSL59IbE9yDbT2HBtKmeZzb2Qu86x3GBJeOn inPgO5Agc3qTGuhJk0WKzLVJQnuYu8gbLW/SxmrGe664WrIopAU6xTbsdKZ1gbQnJo qRTGKDRsHEFHQ== 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 5D8D1C5DF66; Thu, 13 Aug 2026 09:57:11 +0000 (UTC) From: Long Zhao via B4 Relay Date: Thu, 13 Aug 2026 17:56:17 +0800 Subject: [PATCH v3 6/6] MAINTAINERS: add ARM/AMBARELLA SoC 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: <20260813-cv75-v3-a-v3-6-cfdd20b1b4dd@ambarella.com> References: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> In-Reply-To: <20260813-cv75-v3-a-v3-0-cfdd20b1b4dd@ambarella.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michael Turquette , Stephen Boyd , Catalin Marinas , Will Deacon , Arnd Bergmann , Alexandre Belloni , Linus Walleij Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, soc@lists.linux.dev, Long Zhao X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786615029; l=1193; i=longzhao@ambarella.com; s=20260730; h=from:subject:message-id; bh=FMdxZub31R7avQT3Ojw4RWRGTKHK7OVLHXgrDSDBBvo=; b=/IQi7jn1+JWAK5SDTA0CYa9LQ8IsAgoKCWXSJ1vjrygfa08jTqnQYQK7RoBkFPXbPUzRStR44 Tt0+6EgTg3iC0Wg4BUURRCOrjGJpk7Jik3Csir8PaPEUJignncdS9I2 X-Developer-Key: i=longzhao@ambarella.com; a=ed25519; pk=/xGhPTOX0/eYsyTWzyjjgAIW1Z/YD+IlnOnvcdRozow= X-Endpoint-Received: by B4 Relay for longzhao@ambarella.com/20260730 with auth_id=903 X-Original-From: Long Zhao Reply-To: longzhao@ambarella.com From: Long Zhao Add a maintainer entry covering Ambarella CV75 bindings, DTS and related drivers. Signed-off-by: Long Zhao --- MAINTAINERS | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 803b60ad628f..59e5b32d7a02 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2502,6 +2502,20 @@ F: drivers/clocksource/asm9260_timer.c F: drivers/rtc/rtc-asm9260.c F: drivers/watchdog/asm9260_wdt.c =20 +ARM/AMBARELLA SOC SUPPORT +M: Long Zhao +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: devicetree@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/arm/ambarella.yaml +F: Documentation/devicetree/bindings/clock/ambarella,cv75-rct.yaml +F: Documentation/devicetree/bindings/pinctrl/ambarella,cv75-pinctrl.yaml +F: arch/arm64/boot/dts/ambarella/ +F: drivers/clk/ambarella/ +F: drivers/pinctrl/pinctrl-ambarella* +F: include/dt-bindings/clock/ambarella,cv75-rct.h +N: ambarella + ARM/AMD PENSANDO ARM64 ARCHITECTURE M: Brad Larson L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) --=20 2.34.1