From patchwork Sat Sep 14 05:25:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianwei Zhao via B4 Relay X-Patchwork-Id: 13804199 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 CBFB449649; Sat, 14 Sep 2024 05:25:32 +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=1726291532; cv=none; b=YmB0yJ4H4bPS3hoxHpf9RFPWt6FdrxVnp0PzDigf2HsflKHTwGVRz3R1lxe2T3ay7UagAEtzAH8uZeTVDSyxBD0R479LRPk2MV6y1WNzxoHFWyVZ0EZtAUxaD1lkadP7GAeLMNmwXD3FZshrMNp9LzesAzTdtbsmJNsrnAJUMRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726291532; c=relaxed/simple; bh=XxOwoFH80Bhk5qESbi1I1pviMO4Ixnnb+WUrAi02KNk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ixz9zKq/bvOC38mQ7z0o4KeYBuHYfiz9KWdcWz4j1dH3txe2GtTiJe68IvWIjmfY0Rlt6oXNiBbUESQlXTmn14otAzNr+xJ7TDZJbcW3xdRsiOZI+byommG4dZ81ZqvSNqMv1MHYJtlBY8bhBD/+UQ3CcUt3VBmlMpDouIx3xQs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EVoJ8qtR; 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="EVoJ8qtR" Received: by smtp.kernel.org (Postfix) with ESMTPS id 698BCC4CEC6; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1726291532; bh=XxOwoFH80Bhk5qESbi1I1pviMO4Ixnnb+WUrAi02KNk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=EVoJ8qtRaS2sV7hcYyvvwwk6rXga7bS2sH7cy7Q0+1RgFgAoilX0oHnaYM4zNpbmy lMe0wIf6DMAWOtr8SE+CNWnnMyPESAqc6XL4E80RhVtgq7kKd4m9rcoZ+bh2SxI2xK jse4DcplsIx7ESdnA9KpShWDum9ib2ZRMvd5CN+WpEhd5Glh+sLmt38bbe0BDdfCr1 DPcKCICjoEbO2KujWaXbj/86zIkx2KhBxVF2SWb08rToxLt0UnBVCTzSi2tuveYpfj vvZtg73TN1JHWKELvoe2tfPbvzdo6v0pFloezMoqOFb+PpEVOGOReVb693NMe+V9HX 0gg0xOC7eS+vA== 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 563C6FC618E; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) From: Xianwei Zhao via B4 Relay Date: Sat, 14 Sep 2024 13:25:23 +0800 Subject: [PATCH 1/5] dt-bindings: clock: add Amlogic A5 PLL clock controller Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240914-a5-clk-v1-1-5ee2c4f1b08c@amlogic.com> References: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> In-Reply-To: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> To: Neil Armstrong , Jerome Brunet , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chuan Liu , Kevin Hilman , Martin Blumenstingl Cc: linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Xianwei Zhao X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1726291530; l=3134; i=xianwei.zhao@amlogic.com; s=20231208; h=from:subject:message-id; bh=lsom9knZP0lHkNe6jVzPiJ0BTgKhyMmo+ZKlPTInwcA=; b=yS6oZdIBel/t0WlOzbHPs8yDp55NT8uCAIH90lPpC1SKuLiNj9Pbfo9I1AFRulbMfX01vw5oT F2ERa6kW2UIBRQaj8an7TTI67sJqClsKT+CDUPc4/aV8C/Ae9DqH1FQ X-Developer-Key: i=xianwei.zhao@amlogic.com; a=ed25519; pk=o4fDH8ZXL6xQg5h17eNzRljf6pwZHWWjqcOSsj3dW24= X-Endpoint-Received: by B4 Relay for xianwei.zhao@amlogic.com/20231208 with auth_id=107 X-Original-From: Xianwei Zhao Reply-To: xianwei.zhao@amlogic.com From: Chuan Liu Add the PLL clock controller dt-bindings for Amlogic A5 SoC family. Signed-off-by: Chuan Liu Signed-off-by: Xianwei Zhao Reviewed-by: Rob Herring (Arm) --- .../bindings/clock/amlogic,a5-pll-clkc.yaml | 62 ++++++++++++++++++++++ include/dt-bindings/clock/amlogic,a5-pll-clkc.h | 24 +++++++++ 2 files changed, 86 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/amlogic,a5-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a5-pll-clkc.yaml new file mode 100644 index 000000000000..ef9e40193a1c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,a5-pll-clkc.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2024 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,a5-pll-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic A5 series PLL Clock Controller + +maintainers: + - Chuan Liu + - Xianwei Zhao + +properties: + compatible: + const: amlogic,a5-pll-clkc + + reg: + maxItems: 1 + + clocks: + items: + - description: input oscillator (usually at 24MHz) + - description: input fix pll dco + - description: input fix pll + + clock-names: + items: + - const: xtal_24m + - const: fix_dco + - const: fix + + "#clock-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + +additionalProperties: false + +examples: + - | + apb { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@8000 { + compatible = "amlogic,a5-pll-clkc"; + reg = <0x0 0x8000 0x0 0x1a4>; + clocks = <&xtal_24m>, + <&scmi_clk 6>, + <&scmi_clk 7>; + clock-names = "xtal_24m", + "fix_dco", + "fix"; + #clock-cells = <1>; + }; + }; diff --git a/include/dt-bindings/clock/amlogic,a5-pll-clkc.h b/include/dt-bindings/clock/amlogic,a5-pll-clkc.h new file mode 100644 index 000000000000..a74c448a8d8a --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a5-pll-clkc.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2024 Amlogic, Inc. All rights reserved. + * Author: Chuan Liu + */ + +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_A5_PLL_CLKC_H +#define _DT_BINDINGS_CLOCK_AMLOGIC_A5_PLL_CLKC_H + +#define CLKID_MPLL_PREDIV 0 +#define CLKID_MPLL0_DIV 1 +#define CLKID_MPLL0 2 +#define CLKID_MPLL1_DIV 3 +#define CLKID_MPLL1 4 +#define CLKID_MPLL2_DIV 5 +#define CLKID_MPLL2 6 +#define CLKID_MPLL3_DIV 7 +#define CLKID_MPLL3 8 +#define CLKID_GP0_PLL_DCO 9 +#define CLKID_GP0_PLL 10 +#define CLKID_HIFI_PLL_DCO 11 +#define CLKID_HIFI_PLL 12 + +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_A5_PLL_CLKC_H */ From patchwork Sat Sep 14 05:25:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianwei Zhao via B4 Relay X-Patchwork-Id: 13804200 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 CBF3225570; Sat, 14 Sep 2024 05:25:32 +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=1726291532; cv=none; b=f+nvQqgwhymYL/pryj4lONZgcW7JjU02y+/Ed6nD1wsAt8/91k4v+zk4Hb6zHU6aVjn0WxLvkLSb+/CTSFQpxbK/FcRCs0BQXqy6uRGqAc0E+8NT+hLvP2ASmG0qiEsNlZX6Thv7/zOwsYJGGZwNNxSedQtb1iQYRR7kt3iKjqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726291532; c=relaxed/simple; bh=JFXL0kBIFjySYpsf7icuA3X2ZFh5pKvYLb8OeVi+vM4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NcTLbfWftmmqbCX7skGyTLkIXnQD6DQ0X+61ejLV52RFDH5zIAIovSwpLLPQwc1GG0kz9pBeZpeT1rL2u4Cvjqh8r0z6WNlZ1hbzjjLDUCY53YZsBOvdC/9UM513OUCWLmHE0hyqZB8ZVzvpu2BenSqJiBQ0Xc4VV9phqmVGIpo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r695Jcj9; 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="r695Jcj9" Received: by smtp.kernel.org (Postfix) with ESMTPS id 78A9DC4CECE; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1726291532; bh=JFXL0kBIFjySYpsf7icuA3X2ZFh5pKvYLb8OeVi+vM4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=r695Jcj9zH6a9UXm0MJjXmP0PrcHPBoYA0R06h8hnrD8VLMRKmHA5CaCq3HV+ixpO 1pYVw6djM4guJ90RBZSaNckypcFa9hmAYa9krPQbc2sXmxIhH7VG1AZthzQ+jmaRSn dIClF3PH8klnyhaYbVBQJldmvFLGtVhaE+sIOGNcyrnsH4+wAAkhfO4HCwuzwstjlQ fpm0C5mgFFKfoCDk6esDLvkiud8FN+pX/Dyx6W5E8ytW0Ao0hJa1GCx0P3GZiuLXA5 0KG/BLxwyv71U3e6Uv+bCu72H0tSgp7Fi6e4lPz7ZBuC7WsDcBIjFpFO0CLhy3SXEc 6bEM0kdH1Zh3g== 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 67BB9FC6190; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) From: Xianwei Zhao via B4 Relay Date: Sat, 14 Sep 2024 13:25:24 +0800 Subject: [PATCH 2/5] dt-bindings: clock: add Amlogic A5 SCMI clock controller support Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240914-a5-clk-v1-2-5ee2c4f1b08c@amlogic.com> References: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> In-Reply-To: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> To: Neil Armstrong , Jerome Brunet , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chuan Liu , Kevin Hilman , Martin Blumenstingl Cc: linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Xianwei Zhao X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1726291530; l=1704; i=xianwei.zhao@amlogic.com; s=20231208; h=from:subject:message-id; bh=0VCFX2M/yMc0qFVf2pmxfgH7H6Hn/BYk4VGTASRH4GA=; b=px+kiFx0mdhXES0XOipO96yHeklV9a3/lQKjlLMzizKg/LpwjHRjuxA6w5hmuihPkXCK0Io+t oqr9LBja/8nDeYrshGL6w+md5QIH/yPRJTym02nPg5ceoWGs6sL+TtR X-Developer-Key: i=xianwei.zhao@amlogic.com; a=ed25519; pk=o4fDH8ZXL6xQg5h17eNzRljf6pwZHWWjqcOSsj3dW24= X-Endpoint-Received: by B4 Relay for xianwei.zhao@amlogic.com/20231208 with auth_id=107 X-Original-From: Xianwei Zhao Reply-To: xianwei.zhao@amlogic.com From: Chuan Liu Add the SCMI clock controller dt-bindings for Amlogic A5 SoC family. Signed-off-by: Chuan Liu Signed-off-by: Xianwei Zhao Reviewed-by: Rob Herring (Arm) --- include/dt-bindings/clock/amlogic,a5-scmi-clkc.h | 37 ++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h b/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h new file mode 100644 index 000000000000..d35d1ff6bab3 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2024 Amlogic, Inc. All rights reserved. + * Author: Chuan Liu + */ + +#ifndef __AMLOGIC_A5_SCMI_CLKC_H +#define __AMLOGIC_A5_SCMI_CLKC_H + +#define CLKID_OSC 0 +#define CLKID_SYS_CLK 1 +#define CLKID_AXI_CLK 2 +#define CLKID_CPU_CLK 3 +#define CLKID_DSU_CLK 4 +#define CLKID_GP1_PLL 5 +#define CLKID_FIXED_PLL_DCO 6 +#define CLKID_FIXED_PLL 7 +#define CLKID_ACLKM 8 +#define CLKID_SYS_PLL_DIV16 9 +#define CLKID_CPU_CLK_DIV16 10 +#define CLKID_FCLK_50M_PREDIV 11 +#define CLKID_FCLK_50M_DIV 12 +#define CLKID_FCLK_50M 13 +#define CLKID_FCLK_DIV2_DIV 14 +#define CLKID_FCLK_DIV2 15 +#define CLKID_FCLK_DIV2P5_DIV 16 +#define CLKID_FCLK_DIV2P5 17 +#define CLKID_FCLK_DIV3_DIV 18 +#define CLKID_FCLK_DIV3 19 +#define CLKID_FCLK_DIV4_DIV 20 +#define CLKID_FCLK_DIV4 21 +#define CLKID_FCLK_DIV5_DIV 22 +#define CLKID_FCLK_DIV5 23 +#define CLKID_FCLK_DIV7_DIV 24 +#define CLKID_FCLK_DIV7 25 + +#endif /* __AMLOGIC_A5_SCMI_CLKC_H */ From patchwork Sat Sep 14 05:25:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianwei Zhao via B4 Relay X-Patchwork-Id: 13804203 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 E94364AEF5; Sat, 14 Sep 2024 05:25:32 +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=1726291533; cv=none; b=emTENZ3oxnJWBSjOzKRn7IKIw1xUZgI7Hi0D7mJrB/K02BxXnh5Dkf1qiu94LB+E10TLy2rNtX0UIMzvnfVq+8AjDn5qWn+lFBwEd5WKUCz+uDdrOEgBod3wpcVbgPOLnY1oIK4HCbRBvcII6YptVQNTpD7LSeMPffMQaqsFNiE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726291533; c=relaxed/simple; bh=s5bKtB8PUeJW1Zs1aoJO0tNInKu9PxTfGSkPxQuxw+w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=W6iuDpR6ncK2dUXK79DGdWQk1F2n+kuPGXkPgj4+ZrMpER9+ULsBORY5yJW1hjY0h1myqFi/Wl6QcO0JiuKN5tjnVV7ZP1NavOymi09mb4pg72SbovsMSnLbPvK/x1z1WlBDlYnHIffwNgNElLXHOTs54/qI5XYcraUU/7IUCy4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PHUq/obB; 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="PHUq/obB" Received: by smtp.kernel.org (Postfix) with ESMTPS id 86D80C4CED0; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1726291532; bh=s5bKtB8PUeJW1Zs1aoJO0tNInKu9PxTfGSkPxQuxw+w=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=PHUq/obBRe0zda2Vth6qO0LH1GqRBE/68K/r+L8hmx1Lef7YY+cR4ksDNAh0hRy6s ctqbigjyAWIsi0gdBI2r1DGGnVv1I7mwDBR0vMvt8SBpTE5z7jw0zD6CRRG1S5X71q zO2FxmCK+wtiUYX0/JXghOCv2QB5zxJs9PJBo3PtKq1QolFBDll4MMeM2pGvCOU25z vzfadO5MONncTxqSYP/heACHaWQp1eTrqmCN2+s0d3nRQx8jhz4PwJtml1igDe5rA0 2YLpBPn7YZnXgpLgerWXWoAU6nazsxU0z8kg0yAzBojD/AU1JOCrueHmiprts/C25e 4+8b/oAIvyjaQ== 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 77D64FC6194; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) From: Xianwei Zhao via B4 Relay Date: Sat, 14 Sep 2024 13:25:25 +0800 Subject: [PATCH 3/5] dt-bindings: clock: add Amlogic A5 peripherals clock controller Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240914-a5-clk-v1-3-5ee2c4f1b08c@amlogic.com> References: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> In-Reply-To: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> To: Neil Armstrong , Jerome Brunet , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chuan Liu , Kevin Hilman , Martin Blumenstingl Cc: linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Xianwei Zhao X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1726291530; l=9179; i=xianwei.zhao@amlogic.com; s=20231208; h=from:subject:message-id; bh=uBo/4Nz74pi8prQxzPPRE4M3f5ApLdEU+mDCOCPA40o=; b=4QUBdvlEBLROw/h9SZTuJCpsTOG0TATYpf7ThOOmtnof51aL4qSMY+/t+bPAwHgpK3JdMBpDX AZG9MEOabCOD38InhNQZ3mJleSu28xtwgjjlCdM90Z9HUtIn2kqKjBf X-Developer-Key: i=xianwei.zhao@amlogic.com; a=ed25519; pk=o4fDH8ZXL6xQg5h17eNzRljf6pwZHWWjqcOSsj3dW24= X-Endpoint-Received: by B4 Relay for xianwei.zhao@amlogic.com/20231208 with auth_id=107 X-Original-From: Xianwei Zhao Reply-To: xianwei.zhao@amlogic.com From: Chuan Liu Add the peripherals clock controller dt-bindings for Amlogic A5 SoC family. Signed-off-by: Chuan Liu Signed-off-by: Xianwei Zhao Reviewed-by: Rob Herring (Arm) --- .../clock/amlogic,a5-peripherals-clkc.yaml | 126 +++++++++++++++++++ .../clock/amlogic,a5-peripherals-clkc.h | 139 +++++++++++++++++++++ 2 files changed, 265 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml new file mode 100644 index 000000000000..6529b7c79768 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml @@ -0,0 +1,126 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2024 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,a5-peripherals-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic A5 series Peripheral Clock Controller + +maintainers: + - Xianwei Zhao + - Chuan Liu + +properties: + compatible: + const: amlogic,a5-peripherals-clkc + + reg: + maxItems: 1 + + clocks: + minItems: 18 + items: + - description: input oscillator (usually at 24MHz) + - description: input oscillators multiplexer + - description: input fix pll + - description: input fclk div 2 + - description: input fclk div 2p5 + - description: input fclk div 3 + - description: input fclk div 4 + - description: input fclk div 5 + - description: input fclk div 7 + - description: input mpll2 + - description: input mpll3 + - description: input gp0 pll + - description: input gp1 pll + - description: input hifi pll + - description: input sys clk + - description: input axi clk + - description: input sys pll div 16 + - description: input cpu clk div 16 + - description: input pad clock for rtc clk (optional) + + clock-names: + minItems: 18 + items: + - const: xtal_24m + - const: oscin + - const: fix + - const: fdiv2 + - const: fdiv2p5 + - const: fdiv3 + - const: fdiv4 + - const: fdiv5 + - const: fdiv7 + - const: mpll2 + - const: mpll3 + - const: gp0 + - const: gp1 + - const: hifi + - const: sysclk + - const: axiclk + - const: sysplldiv16 + - const: cpudiv16 + - const: pad_osc + + "#clock-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + +additionalProperties: false + +examples: + - | + apb { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@0 { + compatible = "amlogic,a5-peripherals-clkc"; + reg = <0x0 0x0 0x0 0x224>; + #clock-cells = <1>; + clocks = <&xtal_24m>, + <&scmi_clk 0>, + <&scmi_clk 7>, + <&scmi_clk 15>, + <&scmi_clk 17>, + <&scmi_clk 19>, + <&scmi_clk 21>, + <&scmi_clk 23>, + <&scmi_clk 25>, + <&clkc_pll 6>, + <&clkc_pll 8>, + <&clkc_pll 10>, + <&scmi_clk 5>, + <&clkc_pll 12>, + <&scmi_clk 1>, + <&scmi_clk 2>, + <&scmi_clk 9>, + <&scmi_clk 10>; + clock-names = "xtal_24m", + "oscin", + "fix", + "fdiv2", + "fdiv2p5", + "fdiv3", + "fdiv4", + "fdiv5", + "fdiv7", + "mpll2", + "mpll3", + "gp0", + "gp1", + "hifi", + "sysclk", + "axiclk", + "sysplldiv16", + "cpudiv16"; + }; + }; diff --git a/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h new file mode 100644 index 000000000000..0ba61520e2c1 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2024 Amlogic, Inc. All rights reserved. + * Author: Chuan Liu + */ + +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H +#define _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H + +#define CLKID_RTC_XTAL_CLKIN 0 +#define CLKID_RTC_32K_DIV 1 +#define CLKID_RTC_32K_MUX 2 +#define CLKID_RTC_32K 3 +#define CLKID_RTC_CLK 4 +#define CLKID_SYS_RESET_CTRL 5 +#define CLKID_SYS_PWR_CTRL 6 +#define CLKID_SYS_PAD_CTRL 7 +#define CLKID_SYS_CTRL 8 +#define CLKID_SYS_TS_PLL 9 +#define CLKID_SYS_DEV_ARB 10 +#define CLKID_SYS_MMC_PCLK 11 +#define CLKID_SYS_MAILBOX 12 +#define CLKID_SYS_CPU_CTRL 13 +#define CLKID_SYS_JTAG_CTRL 14 +#define CLKID_SYS_IR_CTRL 15 +#define CLKID_SYS_IRQ_CTRL 16 +#define CLKID_SYS_MSR_CLK 17 +#define CLKID_SYS_ROM 18 +#define CLKID_SYS_CPU_ARB 19 +#define CLKID_SYS_RSA 20 +#define CLKID_SYS_SAR_ADC 21 +#define CLKID_SYS_STARTUP 22 +#define CLKID_SYS_SECURE 23 +#define CLKID_SYS_SPIFC 24 +#define CLKID_SYS_DSPA 25 +#define CLKID_SYS_NNA 26 +#define CLKID_SYS_ETH_MAC 27 +#define CLKID_SYS_GIC 28 +#define CLKID_SYS_RAMA 29 +#define CLKID_SYS_BIG_NIC 30 +#define CLKID_SYS_RAMB 31 +#define CLKID_SYS_AUDIO_TOP 32 +#define CLKID_SYS_AUDIO_VAD 33 +#define CLKID_SYS_USB 34 +#define CLKID_SYS_SD_EMMC_A 35 +#define CLKID_SYS_SD_EMMC_C 36 +#define CLKID_SYS_PWM_AB 37 +#define CLKID_SYS_PWM_CD 38 +#define CLKID_SYS_PWM_EF 39 +#define CLKID_SYS_PWM_GH 40 +#define CLKID_SYS_SPICC_1 41 +#define CLKID_SYS_SPICC_0 42 +#define CLKID_SYS_UART_A 43 +#define CLKID_SYS_UART_B 44 +#define CLKID_SYS_UART_C 45 +#define CLKID_SYS_UART_D 46 +#define CLKID_SYS_UART_E 47 +#define CLKID_SYS_I2C_M_A 48 +#define CLKID_SYS_I2C_M_B 49 +#define CLKID_SYS_I2C_M_C 50 +#define CLKID_SYS_I2C_M_D 51 +#define CLKID_SYS_RTC 52 +#define CLKID_AXI_AUDIO_VAD 53 +#define CLKID_AXI_AUDIO_TOP 54 +#define CLKID_AXI_SYS_NIC 55 +#define CLKID_AXI_RAMB 56 +#define CLKID_AXI_RAMA 57 +#define CLKID_AXI_CPU_DMC 58 +#define CLKID_AXI_NNA 59 +#define CLKID_AXI_DEV1_DMC 60 +#define CLKID_AXI_DEV0_DMC 61 +#define CLKID_AXI_DSP_DMC 62 +#define CLKID_12_24M_IN 63 +#define CLKID_12M_24M 64 +#define CLKID_FCLK_25M_DIV 65 +#define CLKID_FCLK_25M 66 +#define CLKID_GEN_SEL 67 +#define CLKID_GEN_DIV 68 +#define CLKID_GEN 69 +#define CLKID_SARADC_SEL 70 +#define CLKID_SARADC_DIV 71 +#define CLKID_SARADC 72 +#define CLKID_PWM_A_SEL 73 +#define CLKID_PWM_A_DIV 74 +#define CLKID_PWM_A 75 +#define CLKID_PWM_B_SEL 76 +#define CLKID_PWM_B_DIV 77 +#define CLKID_PWM_B 78 +#define CLKID_PWM_C_SEL 79 +#define CLKID_PWM_C_DIV 80 +#define CLKID_PWM_C 81 +#define CLKID_PWM_D_SEL 82 +#define CLKID_PWM_D_DIV 83 +#define CLKID_PWM_D 84 +#define CLKID_PWM_E_SEL 85 +#define CLKID_PWM_E_DIV 86 +#define CLKID_PWM_E 87 +#define CLKID_PWM_F_SEL 88 +#define CLKID_PWM_F_DIV 89 +#define CLKID_PWM_F 90 +#define CLKID_PWM_G_SEL 91 +#define CLKID_PWM_G_DIV 92 +#define CLKID_PWM_G 93 +#define CLKID_PWM_H_SEL 94 +#define CLKID_PWM_H_DIV 95 +#define CLKID_PWM_H 96 +#define CLKID_SPICC_0_SEL 97 +#define CLKID_SPICC_0_DIV 98 +#define CLKID_SPICC_0 99 +#define CLKID_SPICC_1_SEL 100 +#define CLKID_SPICC_1_DIV 101 +#define CLKID_SPICC_1 102 +#define CLKID_SD_EMMC_A_SEL 103 +#define CLKID_SD_EMMC_A_DIV 104 +#define CLKID_SD_EMMC_A 105 +#define CLKID_SD_EMMC_C_SEL 106 +#define CLKID_SD_EMMC_C_DIV 107 +#define CLKID_SD_EMMC_C 108 +#define CLKID_TS_DIV 109 +#define CLKID_TS 110 +#define CLKID_ETH_125M_DIV 111 +#define CLKID_ETH_125M 112 +#define CLKID_ETH_RMII_DIV 113 +#define CLKID_ETH_RMII 114 +#define CLKID_DSPA_0_SEL 115 +#define CLKID_DSPA_0_DIV 116 +#define CLKID_DSPA_0 117 +#define CLKID_DSPA_1_SEL 118 +#define CLKID_DSPA_1_DIV 119 +#define CLKID_DSPA_1 120 +#define CLKID_DSPA 121 +#define CLKID_NNA_CORE_SEL 122 +#define CLKID_NNA_CORE_DIV 123 +#define CLKID_NNA_CORE 124 +#define CLKID_NNA_AXI_SEL 125 +#define CLKID_NNA_AXI_DIV 126 +#define CLKID_NNA_AXI 127 + +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H */ From patchwork Sat Sep 14 05:25:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianwei Zhao via B4 Relay X-Patchwork-Id: 13804202 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 E7B5B4AEDA; Sat, 14 Sep 2024 05:25:32 +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=1726291533; cv=none; b=H34Lt2gs0vp6RU4rfOumDKJZf6z+bnB7jsEhcuZ4aGDDWssIViiuhBh/4+gpB3rb6gU9lOqPQsrYRZvKbIW+OA+9yNHzelov3fhBhihd+KndjLGaKkysPWsu6fF4Bx61AxD0cm9wIKN2so8ajPFVlmk3jRBmT9R3Ca3wg8wrm44= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726291533; c=relaxed/simple; bh=o1POVG/EavNF1IdurHF2om1aQENslANxZ3CmwpQDJ8U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=K8ptekYPLlzV5YQ8BVlUnm2RTxCJEYJxdg6ftjhkbECq67AfGcQoomDlJR4yuq6JfIPB02siDijKqD3pNdPHwtgOB33ygBhVS1GqlsoNS7x1INzcCxJ2IsvVqQfpT78sxJXMgCvb/WLC/sY+fR6GcpHmeoE1LxDW7IAc1EljsQ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PAnEzA8K; 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="PAnEzA8K" Received: by smtp.kernel.org (Postfix) with ESMTPS id 94079C4CED4; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1726291532; bh=o1POVG/EavNF1IdurHF2om1aQENslANxZ3CmwpQDJ8U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=PAnEzA8KBwag29/fhFb/5Camr2vKEMlhQjQjzgk+oO+4bOCYNtZWHZTVBPI+8K9BY UojVZ4l+aegj/Xy7mp+WBsLqlTcHTlXtwyFT2yaq2mHHuJSrTnpVeWt9YVbIEg5Cu5 Ajk6V0h7DS/wkybso0/i/xYjmT2xr+niQ1yFmj7y1W6aeH7ZVCGhrJv8kfFii3AtbQ R33UeNv7O1DUM3BBwgqDe4pYvVJMrtYicBTARVJSUsUd1cxEDBGVF1frpPqG6jThCF 3MaDupre/9f/9K6BQW82tpC5zIzD11R/ZUmbDBEf9WR0yLM6WjFmOVXMj2M+BuISit xR16DZSSRRgsw== 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 8798EFC6195; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) From: Xianwei Zhao via B4 Relay Date: Sat, 14 Sep 2024 13:25:26 +0800 Subject: [PATCH 4/5] clk: meson: add support for the A5 SoC PLL clock Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240914-a5-clk-v1-4-5ee2c4f1b08c@amlogic.com> References: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> In-Reply-To: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> To: Neil Armstrong , Jerome Brunet , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chuan Liu , Kevin Hilman , Martin Blumenstingl Cc: linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Xianwei Zhao X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1726291530; l=15971; i=xianwei.zhao@amlogic.com; s=20231208; h=from:subject:message-id; bh=wOTB/Z70w0swkdOKnz9DJj6G6E5++RaslIxM68oIK50=; b=fPkGc2UcckO8viYO4FEolEGwZMNHa/nlUmlJ3p7dD37ipRWMJKoNKl46bsOITgtzJVRYx0OHG lfT4GCgGa12CLXrjwApHBACf378ufGLNWC8VjaMn7RYjLJMzRkaK4u1 X-Developer-Key: i=xianwei.zhao@amlogic.com; a=ed25519; pk=o4fDH8ZXL6xQg5h17eNzRljf6pwZHWWjqcOSsj3dW24= X-Endpoint-Received: by B4 Relay for xianwei.zhao@amlogic.com/20231208 with auth_id=107 X-Original-From: Xianwei Zhao Reply-To: xianwei.zhao@amlogic.com From: Chuan Liu Add the PLL clock controller driver for the Amlogic A5 SoC family. Signed-off-by: Chuan Liu Signed-off-by: Xianwei Zhao --- drivers/clk/meson/Kconfig | 14 ++ drivers/clk/meson/Makefile | 1 + drivers/clk/meson/a5-pll.c | 553 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 568 insertions(+) diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 78f648c9c97d..2a713276e46c 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -132,6 +132,20 @@ config COMMON_CLK_A1_PERIPHERALS device, A1 SoC Family. Say Y if you want A1 Peripherals clock controller to work. +config COMMON_CLK_A5_PLL + tristate "Amlogic A5 PLL clock controller" + depends on ARM64 + default y + imply ARM_SCMI_PROTOCOL + imply COMMON_CLK_SCMI + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_PLL + select COMMON_CLK_MESON_CLKC_UTILS + help + Support for the PLL clock controller on Amlogic AV40x device, AKA A5. + Say Y if you want the board to work, because PLLs are the parent + of most peripherals. + config COMMON_CLK_C3_PLL tristate "Amlogic C3 PLL clock controller" depends on ARM64 diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index bc56a47931c1..fc4b8a723145 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o +obj-$(CONFIG_COMMON_CLK_A5_PLL) += a5-pll.o obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o diff --git a/drivers/clk/meson/a5-pll.c b/drivers/clk/meson/a5-pll.c new file mode 100644 index 000000000000..d96ed72ef8d4 --- /dev/null +++ b/drivers/clk/meson/a5-pll.c @@ -0,0 +1,553 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Amlogic A5 PLL Controller Driver + * + * Copyright (c) 2024 Amlogic, inc. + * Author: Chuan Liu + */ + +#include +#include +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-mpll.h" +#include "meson-clkc-utils.h" +#include + +#define ANACTRL_FIXPLL_CTRL1 0x44 +#define ANACTRL_GP0PLL_CTRL0 0x80 +#define ANACTRL_GP0PLL_CTRL1 0x84 +#define ANACTRL_GP0PLL_CTRL2 0x88 +#define ANACTRL_GP0PLL_CTRL3 0x8c +#define ANACTRL_GP0PLL_CTRL4 0x90 +#define ANACTRL_GP0PLL_CTRL5 0x94 +#define ANACTRL_GP0PLL_CTRL6 0x98 +#define ANACTRL_HIFIPLL_CTRL0 0x100 +#define ANACTRL_HIFIPLL_CTRL1 0x104 +#define ANACTRL_HIFIPLL_CTRL2 0x108 +#define ANACTRL_HIFIPLL_CTRL3 0x10c +#define ANACTRL_HIFIPLL_CTRL4 0x110 +#define ANACTRL_HIFIPLL_CTRL5 0x114 +#define ANACTRL_HIFIPLL_CTRL6 0x118 +#define ANACTRL_MPLL_CTRL0 0x180 +#define ANACTRL_MPLL_CTRL1 0x184 +#define ANACTRL_MPLL_CTRL2 0x188 +#define ANACTRL_MPLL_CTRL3 0x18c +#define ANACTRL_MPLL_CTRL4 0x190 +#define ANACTRL_MPLL_CTRL5 0x194 +#define ANACTRL_MPLL_CTRL6 0x198 +#define ANACTRL_MPLL_CTRL7 0x19c +#define ANACTRL_MPLL_CTRL8 0x1a0 + +static DEFINE_SPINLOCK(aml_clk_lock); + +static struct clk_fixed_factor mpll_prediv = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mpll_prediv", + .ops = &clk_fixed_factor_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fix_dco" + }, + .num_parents = 1, + }, +}; + +static const struct reg_sequence mpll0_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL2, .def = 0x40000033 }, +}; + +static struct clk_regmap mpll0_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = ANACTRL_MPLL_CTRL1, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = ANACTRL_MPLL_CTRL1, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = ANACTRL_MPLL_CTRL1, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = ANACTRL_MPLL_CTRL1, + .shift = 29, + .width = 1, + }, + .lock = &aml_clk_lock, + .init_regs = mpll0_init_regs, + .init_count = ARRAY_SIZE(mpll0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap mpll0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_MPLL_CTRL1, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &mpll0_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence mpll1_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL4, .def = 0x40000033 }, +}; + +static struct clk_regmap mpll1_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = ANACTRL_MPLL_CTRL3, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = ANACTRL_MPLL_CTRL3, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = ANACTRL_MPLL_CTRL3, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = ANACTRL_MPLL_CTRL3, + .shift = 29, + .width = 1, + }, + .lock = &aml_clk_lock, + .init_regs = mpll1_init_regs, + .init_count = ARRAY_SIZE(mpll1_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap mpll1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_MPLL_CTRL3, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &mpll1_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence mpll2_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL6, .def = 0x40000033 }, +}; + +static struct clk_regmap mpll2_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = ANACTRL_MPLL_CTRL5, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = ANACTRL_MPLL_CTRL5, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = ANACTRL_MPLL_CTRL5, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = ANACTRL_MPLL_CTRL5, + .shift = 29, + .width = 1, + }, + .lock = &aml_clk_lock, + .init_regs = mpll2_init_regs, + .init_count = ARRAY_SIZE(mpll2_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap mpll2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_MPLL_CTRL5, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &mpll2_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence mpll3_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL8, .def = 0x40000033 }, +}; + +static struct clk_regmap mpll3_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = ANACTRL_MPLL_CTRL7, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = ANACTRL_MPLL_CTRL7, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = ANACTRL_MPLL_CTRL7, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = ANACTRL_MPLL_CTRL7, + .shift = 29, + .width = 1, + }, + .lock = &aml_clk_lock, + .init_regs = mpll3_init_regs, + .init_count = ARRAY_SIZE(mpll3_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap mpll3 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_MPLL_CTRL7, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &mpll3_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence gp0_init_regs[] = { + { .reg = ANACTRL_GP0PLL_CTRL0, .def = 0X08000000 }, + { .reg = ANACTRL_GP0PLL_CTRL1, .def = 0x00000000 }, + { .reg = ANACTRL_GP0PLL_CTRL2, .def = 0x00000000 }, + { .reg = ANACTRL_GP0PLL_CTRL3, .def = 0x6a295c00 }, + { .reg = ANACTRL_GP0PLL_CTRL4, .def = 0x65771290 }, + { .reg = ANACTRL_GP0PLL_CTRL5, .def = 0x3927200a }, + { .reg = ANACTRL_GP0PLL_CTRL6, .def = 0x54540000 } +}; + +static const struct pll_mult_range gp0_pll_mult_range = { + .min = 125, + .max = 250, +}; + +static struct clk_regmap gp0_pll_dco = { + .data = &(struct meson_clk_pll_data) { + .en = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 0, + .width = 8, + }, + .frac = { + .reg_off = ANACTRL_GP0PLL_CTRL1, + .shift = 0, + .width = 17, + }, + .n = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &gp0_pll_mult_range, + .init_regs = gp0_init_regs, + .init_count = ARRAY_SIZE(gp0_init_regs), + .frac_max = 100000, + }, + .hw.init = &(struct clk_init_data) { + .name = "gp0_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal_24m", + }, + .num_parents = 1, + }, +}; + +/* The maximum frequency divider supports is 16, not 128(2^7) */ +static const struct clk_div_table gp0_pll_od_table[] = { + { 0, 1 }, + { 1, 2 }, + { 2, 4 }, + { 3, 8 }, + { 4, 16 }, + { 5, 32 }, + { /* sentinel */ } +}; + +static struct clk_regmap gp0_pll = { + .data = &(struct clk_regmap_div_data) { + .offset = ANACTRL_GP0PLL_CTRL0, + .shift = 16, + .width = 3, + .table = gp0_pll_od_table, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data) { + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &gp0_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence hifi_init_regs[] = { + { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0X08000000 }, + { .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x00000000 }, + { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00000000 }, + { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a295c00 }, + { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 }, + { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a }, + { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x54540000 } +}; + +static const struct pll_mult_range hifi_pll_mult_range = { + .min = 125, + .max = 250, +}; + +static struct clk_regmap hifi_pll_dco = { + .data = &(struct meson_clk_pll_data) { + .en = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .frac = { + .reg_off = ANACTRL_HIFIPLL_CTRL1, + .shift = 0, + .width = 17, + }, + .n = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &hifi_pll_mult_range, + .init_regs = hifi_init_regs, + .init_count = ARRAY_SIZE(hifi_init_regs), + .frac_max = 100000, + }, + .hw.init = &(struct clk_init_data) { + .name = "hifi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal_24m", + }, + .num_parents = 1, + }, +}; + +/* The maximum frequency divider supports is 16, not 128(2^7) */ +static const struct clk_div_table hifi_pll_od_table[] = { + { 0, 1 }, + { 1, 2 }, + { 2, 4 }, + { 3, 8 }, + { /* sentinel */ } +}; + +static struct clk_regmap hifi_pll = { + .data = &(struct clk_regmap_div_data) { + .offset = ANACTRL_HIFIPLL_CTRL0, + .shift = 16, + .width = 3, + .table = hifi_pll_od_table, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data) { + .name = "hifi_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &hifi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_hw *a5_pll_hw_clks[] = { + [CLKID_MPLL_PREDIV] = &mpll_prediv.hw, + [CLKID_MPLL0_DIV] = &mpll0_div.hw, + [CLKID_MPLL0] = &mpll0.hw, + [CLKID_MPLL1_DIV] = &mpll1_div.hw, + [CLKID_MPLL1] = &mpll1.hw, + [CLKID_MPLL2_DIV] = &mpll2_div.hw, + [CLKID_MPLL2] = &mpll2.hw, + [CLKID_MPLL3_DIV] = &mpll3_div.hw, + [CLKID_MPLL3] = &mpll3.hw, + [CLKID_GP0_PLL_DCO] = &gp0_pll_dco.hw, + [CLKID_GP0_PLL] = &gp0_pll.hw, + [CLKID_HIFI_PLL_DCO] = &hifi_pll_dco.hw, + [CLKID_HIFI_PLL] = &hifi_pll.hw +}; + +/* Convenience table to populate regmap in .probe */ +static struct clk_regmap *const a5_pll_clk_regmaps[] = { + &mpll0_div, + &mpll0, + &mpll1_div, + &mpll1, + &mpll2_div, + &mpll2, + &mpll3_div, + &mpll3, + &gp0_pll_dco, + &gp0_pll, + &hifi_pll_dco, + &hifi_pll +}; + +static const struct regmap_config clkc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = ANACTRL_MPLL_CTRL8, +}; + +static struct meson_clk_hw_data a5_pll_clks = { + .hws = a5_pll_hw_clks, + .num = ARRAY_SIZE(a5_pll_hw_clks), +}; + +static int aml_a5_pll_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *regmap; + void __iomem *base; + int clkid, ret, i; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Populate regmap for the regmap backed clocks */ + for (i = 0; i < ARRAY_SIZE(a5_pll_clk_regmaps); i++) + a5_pll_clk_regmaps[i]->map = regmap; + + for (clkid = 0; clkid < a5_pll_clks.num; clkid++) { + /* array might be sparse */ + if (!a5_pll_clks.hws[clkid]) + continue; + + ret = devm_clk_hw_register(dev, a5_pll_clks.hws[clkid]); + if (ret) { + dev_err(dev, "Clock registration failed\n"); + return ret; + } + } + + return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, + &a5_pll_clks); +} + +static const struct of_device_id a5_pll_clkc_match_table[] = { + { + .compatible = "amlogic,a5-pll-clkc", + }, + {} +}; +MODULE_DEVICE_TABLE(of, a5_pll_clkc_match_table); + +static struct platform_driver a5_pll_driver = { + .probe = aml_a5_pll_probe, + .driver = { + .name = "a5-pll-clkc", + .of_match_table = a5_pll_clkc_match_table, + }, +}; +module_platform_driver(a5_pll_driver); + +MODULE_DESCRIPTION("Amlogic A5 PLL Clock Controller driver"); +MODULE_AUTHOR("Chuan Liu "); +MODULE_LICENSE("GPL"); From patchwork Sat Sep 14 05:25:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xianwei Zhao via B4 Relay X-Patchwork-Id: 13804204 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 69CAC8289C; Sat, 14 Sep 2024 05:25:33 +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=1726291533; cv=none; b=qddRWiOR71V8yV33WIOLSIINlT9oOz1huzAgrP6yfXHhyBg2OMW/eulY2C+jG2yvW2Va+Uo47LzW7RLVREtvs9hJHpdxLrO1FaTUQS0OiUgxBP6AqzCdCo/+WYubUCKbvty1qp/GUKT/r9TA2TleC6+2ECvbIdIKewsswM0e+yc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726291533; c=relaxed/simple; bh=czVl8Hk0Vvy9SV5nolPykcop/GQI0G4YNQxbfG/ZTr4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uWixm8xMDfA4h8MwYgiVGOXNh6zdwLx2meajnNts4ZbO1Sr0oNaFvZIKbo9UZBy9z8XlO8mcVcR8h3xFksPxbk3fi+UiYyZmhVLj63G1L1fQy+Np3yNZy3l23ypH6E8FF6qOnnXOpH5SLy/lZqZcn72EG+bzoPMapMq8n6tNl70= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=j6wRxLtC; 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="j6wRxLtC" Received: by smtp.kernel.org (Postfix) with ESMTPS id 9FD39C4CED7; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1726291532; bh=czVl8Hk0Vvy9SV5nolPykcop/GQI0G4YNQxbfG/ZTr4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=j6wRxLtCP3M8Gv3Cj5bwML9xuRnbjJkprmx3lP+FOibk4YeVDtxS33P+hJVjAOP5G yzYfkc7SUqqP43xQhGvO6Fgll3KcN35JLXg5Ga8K5xKLDN+VfvSeRdFNgZPJgciDgc ImyJG/c8yb/WSDcw8elgsKUkE5k/la/54pcyqN0bt7gkprVgzGR8fVta9pZ975SXMm OPiK8H2wKufWndAUMmuh2NX+ymMIpYuM2plnF/ynZstZfxxITjfscXu+58yWagE/b7 tBwWvANrg7ABuQXbhPVxYL/AjEObxKto5jxKa2CWMds56Iar38fmlcpHVnB1lzZR0u CCIxTjhBGmu5w== 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 98B8FFC6190; Sat, 14 Sep 2024 05:25:32 +0000 (UTC) From: Xianwei Zhao via B4 Relay Date: Sat, 14 Sep 2024 13:25:27 +0800 Subject: [PATCH 5/5] clk: meson: add A5 clock peripherals controller driver Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240914-a5-clk-v1-5-5ee2c4f1b08c@amlogic.com> References: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> In-Reply-To: <20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com> To: Neil Armstrong , Jerome Brunet , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chuan Liu , Kevin Hilman , Martin Blumenstingl Cc: linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Xianwei Zhao X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1726291530; l=44579; i=xianwei.zhao@amlogic.com; s=20231208; h=from:subject:message-id; bh=Kve/Gn0UwoXQmUJZd0owhVCEANqSb5b0EGitN/vOiXY=; b=CSlSdmmXjUN96Gl/W/Ed8/MzhG2iJH9QS5gW9QBwuKSeNlTSLiUqsZwo+MmFC380j+2WqJI9V dooY5nd7r9wBCyFiZzxWJ/+R1cvD4ym5bpYoa+gUkPs+emsk00LsDNj X-Developer-Key: i=xianwei.zhao@amlogic.com; a=ed25519; pk=o4fDH8ZXL6xQg5h17eNzRljf6pwZHWWjqcOSsj3dW24= X-Endpoint-Received: by B4 Relay for xianwei.zhao@amlogic.com/20231208 with auth_id=107 X-Original-From: Xianwei Zhao Reply-To: xianwei.zhao@amlogic.com From: Chuan Liu Add the peripherals clock controller driver in the A5 SoC family. Signed-off-by: Chuan Liu Signed-off-by: Xianwei Zhao --- drivers/clk/meson/Kconfig | 14 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/a5-peripherals.c | 1471 ++++++++++++++++++++++++++++++++++++ 3 files changed, 1486 insertions(+) diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 2a713276e46c..21845edcd8ef 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -146,6 +146,20 @@ config COMMON_CLK_A5_PLL Say Y if you want the board to work, because PLLs are the parent of most peripherals. +config COMMON_CLK_A5_PERIPHERALS + tristate "Amlogic A5 peripherals clock controller" + depends on ARM64 + default y + imply ARM_SCMI_PROTOCOL + imply COMMON_CLK_SCMI + imply COMMON_CLK_A5_PLL + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_DUALDIV + select COMMON_CLK_MESON_CLKC_UTILS + help + Support for the Peripherals clock controller on Amlogic AV40x device, + AKA A5. Say Y if you want the peripherals clock to work. + config COMMON_CLK_C3_PLL tristate "Amlogic C3 PLL clock controller" depends on ARM64 diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index fc4b8a723145..58236c6e8377 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o obj-$(CONFIG_COMMON_CLK_A5_PLL) += a5-pll.o +obj-$(CONFIG_COMMON_CLK_A5_PERIPHERALS) += a5-peripherals.o obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o diff --git a/drivers/clk/meson/a5-peripherals.c b/drivers/clk/meson/a5-peripherals.c new file mode 100644 index 000000000000..c28da340a5af --- /dev/null +++ b/drivers/clk/meson/a5-peripherals.c @@ -0,0 +1,1471 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Amlogic A5 Peripherals Clock Controller Driver + * + * Copyright (c) 2024 Amlogic, inc. + * Author: Chuan Liu + */ + +#include +#include +#include "clk-regmap.h" +#include "clk-dualdiv.h" +#include "meson-clkc-utils.h" +#include + +#define CLKCTRL_RTC_BY_OSCIN_CTRL0 0x8 +#define CLKCTRL_RTC_BY_OSCIN_CTRL1 0xc +#define CLKCTRL_RTC_CTRL 0x10 +#define CLKCTRL_SYS_CLK_EN0_REG0 0x44 +#define CLKCTRL_SYS_CLK_EN0_REG1 0x48 +#define CLKCTRL_DSPA_CLK_CTRL0 0x9c +#define CLKCTRL_CLK12_24_CTRL 0xa8 +#define CLKCTRL_AXI_CLK_EN0 0xac +#define CLKCTRL_TS_CLK_CTRL 0x158 +#define CLKCTRL_ETH_CLK_CTRL 0x164 +#define CLKCTRL_NAND_CLK_CTRL 0x168 +#define CLKCTRL_SD_EMMC_CLK_CTRL 0x16c +#define CLKCTRL_SPICC_CLK_CTRL 0x174 +#define CLKCTRL_GEN_CLK_CTRL 0x178 +#define CLKCTRL_SAR_CLK_CTRL0 0x17c +#define CLKCTRL_PWM_CLK_AB_CTRL 0x180 +#define CLKCTRL_PWM_CLK_CD_CTRL 0x184 +#define CLKCTRL_PWM_CLK_EF_CTRL 0x188 +#define CLKCTRL_PWM_CLK_GH_CTRL 0x18c +#define CLKCTRL_NNA_CLK_CNTL 0x220 + +static struct clk_regmap rtc_xtal_clkin = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_xtal_clkin", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "oscin", + }, + .num_parents = 1, + }, +}; + +static const struct meson_clk_dualdiv_param rtc_32k_div_table[] = { + { 733, 732, 8, 11, 1 }, + { /* sentinel */ } +}; + +static struct clk_regmap rtc_32k_div = { + .data = &(struct meson_clk_dualdiv_data) { + .n1 = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .shift = 28, + .width = 1, + }, + .table = rtc_32k_div_table, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_32k_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &rtc_xtal_clkin.hw + }, + .num_parents = 1, + }, +}; + +static const struct clk_parent_data rtc_32k_mux_parent_data[] = { + { .hw = &rtc_32k_div.hw }, + { .hw = &rtc_xtal_clkin.hw } +}; + +static struct clk_regmap rtc_32k_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_32k_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = rtc_32k_mux_parent_data, + .num_parents = ARRAY_SIZE(rtc_32k_mux_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap rtc_32k = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_32k", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &rtc_32k_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data rtc_clk_mux_parent_data[] = { + { .fw_name = "oscin" }, + { .hw = &rtc_32k.hw }, + { .fw_name = "pad_osc" } +}; + +static struct clk_regmap rtc_clk = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_RTC_CTRL, + .mask = 0x3, + .shift = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_clk", + .ops = &clk_regmap_mux_ops, + .parent_data = rtc_clk_mux_parent_data, + .num_parents = ARRAY_SIZE(rtc_clk_mux_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +#define A4_CLK_GATE(_name, _reg, _bit, _fw_name, _ops, _flags) \ +struct clk_regmap _name = { \ + .data = &(struct clk_regmap_gate_data){ \ + .offset = (_reg), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = _ops, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = #_fw_name, \ + }, \ + .num_parents = 1, \ + .flags = (_flags), \ + }, \ +} + +#define A4_SYS_GATE(_name, _reg, _bit, _flags) \ + A4_CLK_GATE(_name, _reg, _bit, sysclk, \ + &clk_regmap_gate_ops, _flags) + +#define A4_SYS_GATE_RO(_name, _reg, _bit) \ + A4_CLK_GATE(_name, _reg, _bit, sysclk, \ + &clk_regmap_gate_ro_ops, 0) + +static A4_SYS_GATE(sys_reset_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 1, 0); +static A4_SYS_GATE(sys_pwr_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 3, 0); +static A4_SYS_GATE(sys_pad_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 4, 0); +static A4_SYS_GATE(sys_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 5, 0); +static A4_SYS_GATE(sys_ts_pll, CLKCTRL_SYS_CLK_EN0_REG0, 6, 0); + +/* + * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that + * access the AXI bus. + */ +static A4_SYS_GATE(sys_dev_arb, CLKCTRL_SYS_CLK_EN0_REG0, 7, 0); + +/* + * FIXME: sys_mmc_pclk provides the clock for the DDR PHY, DDR will only be + * initialized in bl2, and this clock should not be touched in linux. + */ +static A4_SYS_GATE_RO(sys_mmc_pclk, CLKCTRL_SYS_CLK_EN0_REG0, 8); +static A4_SYS_GATE(sys_mailbox, CLKCTRL_SYS_CLK_EN0_REG0, 10, 0); + +/* + * NOTE: sys_cpu_ctrl provides the clock for CPU controller. After clock is + * disabled, cpu_clk and other key CPU-related configurations cannot take effect. + */ +static A4_SYS_GATE(sys_cpu_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 11, CLK_IS_CRITICAL); +static A4_SYS_GATE(sys_jtag_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 12, 0); +static A4_SYS_GATE(sys_ir_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 13, 0); + +/* + * NOTE: sys_irq_ctrl provides the clock for IRQ controller. The IRQ controller + * collects and distributes the interrupt signal to the GIC, PWR_CTRL, and + * AOCPU. If the clock is disabled, interrupt-related functions will occurs an + * exception. + */ +static A4_SYS_GATE(sys_irq_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 14, CLK_IS_CRITICAL); +static A4_SYS_GATE(sys_msr_clk, CLKCTRL_SYS_CLK_EN0_REG0, 15, 0); +static A4_SYS_GATE(sys_rom, CLKCTRL_SYS_CLK_EN0_REG0, 16, 0); +static A4_SYS_GATE(sys_cpu_apb, CLKCTRL_SYS_CLK_EN0_REG0, 18, 0); +static A4_SYS_GATE(sys_rsa, CLKCTRL_SYS_CLK_EN0_REG0, 19, 0); +static A4_SYS_GATE(sys_sar_adc, CLKCTRL_SYS_CLK_EN0_REG0, 20, 0); +static A4_SYS_GATE(sys_startup, CLKCTRL_SYS_CLK_EN0_REG0, 21, 0); +static A4_SYS_GATE(sys_secure, CLKCTRL_SYS_CLK_EN0_REG0, 22, 0); +static A4_SYS_GATE(sys_spifc, CLKCTRL_SYS_CLK_EN0_REG0, 23, 0); +static A4_SYS_GATE(sys_dspa, CLKCTRL_SYS_CLK_EN0_REG0, 24, 0); +static A4_SYS_GATE(sys_nna, CLKCTRL_SYS_CLK_EN0_REG0, 25, 0); +static A4_SYS_GATE(sys_eth_mac, CLKCTRL_SYS_CLK_EN0_REG0, 26, 0); + +/* + * FIXME: sys_gic provides the clock for GIC(Generic Interrupt Controller). + * After clock is disabled, The GIC cannot work properly. At present, the driver + * used by our GIC is the public driver in kernel, and there is no management + * clock in the driver. + */ +static A4_SYS_GATE(sys_gic, CLKCTRL_SYS_CLK_EN0_REG0, 27, CLK_IS_CRITICAL); +static A4_SYS_GATE(sys_rama, CLKCTRL_SYS_CLK_EN0_REG0, 28, 0); + +/* + * NOTE: sys_big_nic provides the clock to the control bus of the NIC(Network + * Interface Controller) between multiple devices(CPU, DDR, RAM, ROM, GIC, + * SPIFC, CAPU, JTAG, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC) in the + * system. After clock is disabled, The NIC cannot work. + */ +static A4_SYS_GATE(sys_big_nic, CLKCTRL_SYS_CLK_EN0_REG0, 29, CLK_IS_CRITICAL); +static A4_SYS_GATE(sys_ramb, CLKCTRL_SYS_CLK_EN0_REG0, 30, 0); +static A4_SYS_GATE(sys_audio_top, CLKCTRL_SYS_CLK_EN0_REG1, 0, 0); +static A4_SYS_GATE(sys_audio_vad, CLKCTRL_SYS_CLK_EN0_REG1, 1, 0); +static A4_SYS_GATE(sys_usb, CLKCTRL_SYS_CLK_EN0_REG1, 2, 0); +static A4_SYS_GATE(sys_sd_emmc_a, CLKCTRL_SYS_CLK_EN0_REG1, 3, 0); +static A4_SYS_GATE(sys_sd_emmc_c, CLKCTRL_SYS_CLK_EN0_REG1, 4, 0); +static A4_SYS_GATE(sys_pwm_ab, CLKCTRL_SYS_CLK_EN0_REG1, 5, 0); +static A4_SYS_GATE(sys_pwm_cd, CLKCTRL_SYS_CLK_EN0_REG1, 6, 0); +static A4_SYS_GATE(sys_pwm_ef, CLKCTRL_SYS_CLK_EN0_REG1, 7, 0); +static A4_SYS_GATE(sys_pwm_gh, CLKCTRL_SYS_CLK_EN0_REG1, 8, 0); +static A4_SYS_GATE(sys_spicc_1, CLKCTRL_SYS_CLK_EN0_REG1, 9, 0); +static A4_SYS_GATE(sys_spicc_0, CLKCTRL_SYS_CLK_EN0_REG1, 10, 0); +static A4_SYS_GATE(sys_uart_a, CLKCTRL_SYS_CLK_EN0_REG1, 11, 0); +static A4_SYS_GATE(sys_uart_b, CLKCTRL_SYS_CLK_EN0_REG1, 12, 0); +static A4_SYS_GATE(sys_uart_c, CLKCTRL_SYS_CLK_EN0_REG1, 13, 0); +static A4_SYS_GATE(sys_uart_d, CLKCTRL_SYS_CLK_EN0_REG1, 14, 0); +static A4_SYS_GATE(sys_uart_e, CLKCTRL_SYS_CLK_EN0_REG1, 15, 0); +static A4_SYS_GATE(sys_i2c_m_a, CLKCTRL_SYS_CLK_EN0_REG1, 16, 0); +static A4_SYS_GATE(sys_i2c_m_b, CLKCTRL_SYS_CLK_EN0_REG1, 17, 0); +static A4_SYS_GATE(sys_i2c_m_c, CLKCTRL_SYS_CLK_EN0_REG1, 18, 0); +static A4_SYS_GATE(sys_i2c_m_d, CLKCTRL_SYS_CLK_EN0_REG1, 19, 0); +static A4_SYS_GATE(sys_rtc, CLKCTRL_SYS_CLK_EN0_REG1, 21, 0); + +#define A4_AXI_GATE(_name, _reg, _bit, _flags) \ + A4_CLK_GATE(_name, _reg, _bit, axiclk, \ + &clk_regmap_gate_ops, _flags) + +static A4_AXI_GATE(axi_audio_vad, CLKCTRL_AXI_CLK_EN0, 0, 0); +static A4_AXI_GATE(axi_audio_top, CLKCTRL_AXI_CLK_EN0, 1, 0); + +/* + * NOTE: axi_sys_nic provides the clock to the AXI bus of the system NIC. After + * clock is disabled, The NIC cannot work. + */ +static A4_AXI_GATE(axi_sys_nic, CLKCTRL_AXI_CLK_EN0, 2, CLK_IS_CRITICAL); +static A4_AXI_GATE(axi_ramb, CLKCTRL_AXI_CLK_EN0, 5, 0); +static A4_AXI_GATE(axi_rama, CLKCTRL_AXI_CLK_EN0, 6, 0); + +/* + * NOTE: axi_cpu_dmc provides the clock to the AXI bus where the CPU accesses + * the DDR. After clock is disabled, The CPU will not have access to the DDR. + */ +static A4_AXI_GATE(axi_cpu_dmc, CLKCTRL_AXI_CLK_EN0, 7, CLK_IS_CRITICAL); +static A4_AXI_GATE(axi_nna, CLKCTRL_AXI_CLK_EN0, 12, 0); + +/* + * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO, + * sec_top, USB, Audio) to access the AXI bus of the DDR. + */ +static A4_AXI_GATE(axi_dev1_dmc, CLKCTRL_AXI_CLK_EN0, 13, 0); + +/* + * NOTE: axi_dev0_dmc provides the clock for the peripherals(ETH and SPICC) + * to access the AXI bus of the DDR. + */ +static A4_AXI_GATE(axi_dev0_dmc, CLKCTRL_AXI_CLK_EN0, 14, 0); +static A4_AXI_GATE(axi_dsp_dmc, CLKCTRL_AXI_CLK_EN0, 15, 0); + +static struct clk_regmap clk_12_24m_in = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_CLK12_24_CTRL, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "clk_12_24m_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal_24m", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap clk_12_24m = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_CLK12_24_CTRL, + .shift = 10, + .width = 1, + }, + .hw.init = &(struct clk_init_data) { + .name = "clk_12_24m", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &clk_12_24m_in.hw + }, + .num_parents = 1, + }, +}; + +/* FIXME: set value 0 will div by 2 like value 1 */ +static struct clk_regmap fclk_25m_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_CLK12_24_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "fclk_25m_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fix", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap fclk_25m = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_CLK12_24_CTRL, + .bit_idx = 12, + }, + .hw.init = &(struct clk_init_data) { + .name = "fclk_25m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &fclk_25m_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * Channel 3(ddr_dpll_pt_clk) is manged by the DDR module; channel 12(cts_msr_clk) + * is manged by clock measures module. Their hardware are out of clock tree. + * Channel 4 5 8 9 10 11 13 14 15 16 18 are not connected. + * + * gp1 is designed for DSU (DynamIQ Shared Unit) alone. It cannot be changed + * arbitrarily. gp1 is read-only in the kernel and is only open for debug purposes. + */ +static u32 gen_parent_table[] = { 0, 1, 2, 6, 7, 17, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28}; + +static const struct clk_parent_data gen_parent_data[] = { + { .fw_name = "oscin" }, + { .hw = &rtc_clk.hw }, + { .fw_name = "sysplldiv16" }, + { .fw_name = "gp1" }, + { .fw_name = "hifi" }, + { .fw_name = "cpudiv16" }, + { .fw_name = "fdiv2" }, + { .fw_name = "fdiv2p5" }, + { .fw_name = "fdiv3" }, + { .fw_name = "fdiv4" }, + { .fw_name = "fdiv5" }, + { .fw_name = "fdiv7" }, + { .fw_name = "mpll0" }, + { .fw_name = "mpll1" }, + { .fw_name = "mpll2" }, + { .fw_name = "mpll3" } +}; + +static struct clk_regmap gen_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_GEN_CLK_CTRL, + .mask = 0x1f, + .shift = 12, + .table = gen_parent_table, + }, + .hw.init = &(struct clk_init_data) { + .name = "gen_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = gen_parent_data, + .num_parents = ARRAY_SIZE(gen_parent_data), + }, +}; + +static struct clk_regmap gen_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_GEN_CLK_CTRL, + .shift = 0, + .width = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "gen_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &gen_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gen = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_GEN_CLK_CTRL, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "gen", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &gen_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data saradc_parent_data[] = { + { .fw_name = "oscin" }, + { .fw_name = "sysclk" } +}; + +static struct clk_regmap saradc_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_SAR_CLK_CTRL0, + .mask = 0x1, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "saradc_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = saradc_parent_data, + .num_parents = ARRAY_SIZE(saradc_parent_data), + }, +}; + +static struct clk_regmap saradc_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_SAR_CLK_CTRL0, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "saradc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &saradc_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap saradc = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_SAR_CLK_CTRL0, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "saradc", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &saradc_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data pwm_parent_data[] = { + { .fw_name = "oscin" }, + { .hw = &rtc_clk.hw }, + { .fw_name = "fdiv4" }, + { .fw_name = "fdiv3" } +}; + +#define AML_PWM_CLK_MUX(_name, _reg, _shift) { \ + .data = &(struct clk_regmap_mux_data) { \ + .offset = _reg, \ + .mask = 0x3, \ + .shift = _shift, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name "_sel", \ + .ops = &clk_regmap_mux_ops, \ + .parent_data = pwm_parent_data, \ + .num_parents = ARRAY_SIZE(pwm_parent_data), \ + }, \ +} + +#define AML_PWM_CLK_DIV(_name, _reg, _shift) { \ + .data = &(struct clk_regmap_div_data) { \ + .offset = _reg, \ + .shift = _shift, \ + .width = 8, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name "_div", \ + .ops = &clk_regmap_divider_ops, \ + .parent_names = (const char *[]) { #_name "_sel" },\ + .num_parents = 1, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ +} + +#define AML_PWM_CLK_GATE(_name, _reg, _bit) { \ + .data = &(struct clk_regmap_gate_data) { \ + .offset = _reg, \ + .bit_idx = _bit, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_regmap_gate_ops, \ + .parent_names = (const char *[]) { #_name "_div" },\ + .num_parents = 1, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ +} + +static struct clk_regmap pwm_a_sel = + AML_PWM_CLK_MUX(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 9); +static struct clk_regmap pwm_a_div = + AML_PWM_CLK_DIV(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 0); +static struct clk_regmap pwm_a = + AML_PWM_CLK_GATE(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 8); + +static struct clk_regmap pwm_b_sel = + AML_PWM_CLK_MUX(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 25); +static struct clk_regmap pwm_b_div = + AML_PWM_CLK_DIV(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 16); +static struct clk_regmap pwm_b = + AML_PWM_CLK_GATE(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 24); + +static struct clk_regmap pwm_c_sel = + AML_PWM_CLK_MUX(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 9); +static struct clk_regmap pwm_c_div = + AML_PWM_CLK_DIV(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 0); +static struct clk_regmap pwm_c = + AML_PWM_CLK_GATE(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 8); + +static struct clk_regmap pwm_d_sel = + AML_PWM_CLK_MUX(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 25); +static struct clk_regmap pwm_d_div = + AML_PWM_CLK_DIV(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 16); +static struct clk_regmap pwm_d = + AML_PWM_CLK_GATE(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 24); + +static struct clk_regmap pwm_e_sel = + AML_PWM_CLK_MUX(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 9); +static struct clk_regmap pwm_e_div = + AML_PWM_CLK_DIV(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 0); +static struct clk_regmap pwm_e = + AML_PWM_CLK_GATE(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 8); + +static struct clk_regmap pwm_f_sel = + AML_PWM_CLK_MUX(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 25); +static struct clk_regmap pwm_f_div = + AML_PWM_CLK_DIV(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 16); +static struct clk_regmap pwm_f = + AML_PWM_CLK_GATE(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 24); + +static struct clk_regmap pwm_g_sel = + AML_PWM_CLK_MUX(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 9); +static struct clk_regmap pwm_g_div = + AML_PWM_CLK_DIV(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 0); +static struct clk_regmap pwm_g = + AML_PWM_CLK_GATE(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 8); + +static struct clk_regmap pwm_h_sel = + AML_PWM_CLK_MUX(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 25); +static struct clk_regmap pwm_h_div = + AML_PWM_CLK_DIV(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 16); +static struct clk_regmap pwm_h = + AML_PWM_CLK_GATE(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 24); + +/* Channel 7 is gp1. */ +static const struct clk_parent_data spicc_parent_data[] = { + { .fw_name = "oscin" }, + { .fw_name = "sysclk" }, + { .fw_name = "fdiv4" }, + { .fw_name = "fdiv3" }, + { .fw_name = "fdiv2" }, + { .fw_name = "fdiv5" }, + { .fw_name = "fdiv7" } +}; + +static struct clk_regmap spicc_0_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_SPICC_CLK_CTRL, + .mask = 0x7, + .shift = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = spicc_parent_data, + .num_parents = ARRAY_SIZE(spicc_parent_data), + }, +}; + +static struct clk_regmap spicc_0_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_SPICC_CLK_CTRL, + .shift = 0, + .width = 6, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &spicc_0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap spicc_0 = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_SPICC_CLK_CTRL, + .bit_idx = 6, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &spicc_0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap spicc_1_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_SPICC_CLK_CTRL, + .mask = 0x7, + .shift = 23, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = spicc_parent_data, + .num_parents = ARRAY_SIZE(spicc_parent_data), + }, +}; + +static struct clk_regmap spicc_1_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_SPICC_CLK_CTRL, + .shift = 16, + .width = 6, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &spicc_1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap spicc_1 = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_SPICC_CLK_CTRL, + .bit_idx = 22, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &spicc_1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data emmc_parent_data[] = { + { .fw_name = "oscin" }, + { .fw_name = "fdiv2" }, + { .fw_name = "fdiv3" }, + { .fw_name = "hifi" }, + { .fw_name = "fdiv2p5" }, + { .fw_name = "mpll2" }, + { .fw_name = "mpll3" }, + { .fw_name = "gp0" } +}; + +static struct clk_regmap sd_emmc_a_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_a_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = emmc_parent_data, + .num_parents = ARRAY_SIZE(emmc_parent_data), + }, +}; + +static struct clk_regmap sd_emmc_a_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_a_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &sd_emmc_a_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap sd_emmc_a = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .bit_idx = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_a", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &sd_emmc_a_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap sd_emmc_c_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_NAND_CLK_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_c_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = emmc_parent_data, + .num_parents = ARRAY_SIZE(emmc_parent_data), + }, +}; + +static struct clk_regmap sd_emmc_c_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_NAND_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_c_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &sd_emmc_c_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap sd_emmc_c = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_NAND_CLK_CTRL, + .bit_idx = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_c", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &sd_emmc_c_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap ts_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_TS_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "ts_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "oscin", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap ts = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_TS_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "ts", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &ts_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor eth_125m_div = { + .mult = 1, + .div = 8, + .hw.init = &(struct clk_init_data) { + .name = "eth_125m_div", + .ops = &clk_fixed_factor_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fdiv2", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap eth_125m = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_ETH_CLK_CTRL, + .bit_idx = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "eth_125m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + ð_125m_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap eth_rmii_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_ETH_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "eth_rmii_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fdiv2", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap eth_rmii = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_ETH_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "eth_rmii", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + ð_rmii_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* Channel 6 is gp1. */ +static u32 dspa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7}; + +static const struct clk_parent_data dspa_parent_data[] = { + { .fw_name = "oscin" }, + { .fw_name = "fdiv2p5" }, + { .fw_name = "fdiv3" }, + { .fw_name = "rtc" }, + { .fw_name = "hifi" }, + { .fw_name = "fdiv4" }, + { .hw = &rtc_clk.hw } +}; + +static struct clk_regmap dspa_0_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_DSPA_CLK_CTRL0, + .mask = 0x7, + .shift = 10, + .table = dspa_parent_table, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = dspa_parent_data, + .num_parents = ARRAY_SIZE(dspa_parent_data), + }, +}; + +static struct clk_regmap dspa_0_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_DSPA_CLK_CTRL0, + .shift = 0, + .width = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &dspa_0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap dspa_0 = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_DSPA_CLK_CTRL0, + .bit_idx = 13, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &dspa_0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap dspa_1_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_DSPA_CLK_CTRL0, + .mask = 0x7, + .shift = 26, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = dspa_parent_data, + .num_parents = ARRAY_SIZE(dspa_parent_data), + }, +}; + +static struct clk_regmap dspa_1_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_DSPA_CLK_CTRL0, + .shift = 16, + .width = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &dspa_1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap dspa_1 = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_DSPA_CLK_CTRL0, + .bit_idx = 29, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &dspa_1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap dspa = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_DSPA_CLK_CTRL0, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &dspa_0.hw, + &dspa_1.hw + }, + .num_parents = 2, + /* + * NOTE: This level of mux is "no glitch mux", and mux_0 + * (here dspa_0) is not only the clock source for mux, but also + * provides a working clock for "no glitch mux". "no glitch mux" + * can be switched only when mux_0 has a clock input. Therefore, + * add flag CLK_OPS_PARENT_ENABLE to ensure that mux_0 has clock + * when "no glitch mux" works. + */ + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + }, +}; + +/* Channel 6 is gp1. */ +static u32 nna_parent_table[] = { 0, 1, 2, 3, 4, 5, 7}; + +static const struct clk_parent_data nna_parent_data[] = { + { .fw_name = "oscin" }, + { .fw_name = "fdiv2p5" }, + { .fw_name = "fdiv4" }, + { .fw_name = "fdiv3" }, + { .fw_name = "fdiv5" }, + { .fw_name = "fdiv2" }, + { .fw_name = "hifi" } +}; + +static struct clk_regmap nna_core_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_NNA_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .table = nna_parent_table, + }, + .hw.init = &(struct clk_init_data) { + .name = "nna_core_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = nna_parent_data, + .num_parents = ARRAY_SIZE(nna_parent_data), + }, +}; + +static struct clk_regmap nna_core_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_NNA_CLK_CNTL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "nna_core_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &nna_core_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap nna_core = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_NNA_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "nna_core", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &nna_core_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap nna_axi_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_NNA_CLK_CNTL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data) { + .name = "nna_axi_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = nna_parent_data, + .num_parents = ARRAY_SIZE(nna_parent_data), + }, +}; + +static struct clk_regmap nna_axi_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_NNA_CLK_CNTL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "nna_axi_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &nna_axi_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap nna_axi = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_NNA_CLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "nna_axi", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &nna_axi_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_hw *a5_periphs_hw_clks[] = { + [CLKID_RTC_XTAL_CLKIN] = &rtc_xtal_clkin.hw, + [CLKID_RTC_32K_DIV] = &rtc_32k_div.hw, + [CLKID_RTC_32K_MUX] = &rtc_32k_mux.hw, + [CLKID_RTC_32K] = &rtc_32k.hw, + [CLKID_RTC_CLK] = &rtc_clk.hw, + [CLKID_SYS_RESET_CTRL] = &sys_reset_ctrl.hw, + [CLKID_SYS_PWR_CTRL] = &sys_pwr_ctrl.hw, + [CLKID_SYS_PAD_CTRL] = &sys_pad_ctrl.hw, + [CLKID_SYS_CTRL] = &sys_ctrl.hw, + [CLKID_SYS_TS_PLL] = &sys_ts_pll.hw, + [CLKID_SYS_DEV_ARB] = &sys_dev_arb.hw, + [CLKID_SYS_MMC_PCLK] = &sys_mmc_pclk.hw, + [CLKID_SYS_MAILBOX] = &sys_mailbox.hw, + [CLKID_SYS_CPU_CTRL] = &sys_cpu_ctrl.hw, + [CLKID_SYS_JTAG_CTRL] = &sys_jtag_ctrl.hw, + [CLKID_SYS_IR_CTRL] = &sys_ir_ctrl.hw, + [CLKID_SYS_IRQ_CTRL] = &sys_irq_ctrl.hw, + [CLKID_SYS_MSR_CLK] = &sys_msr_clk.hw, + [CLKID_SYS_ROM] = &sys_rom.hw, + [CLKID_SYS_CPU_ARB] = &sys_cpu_apb.hw, + [CLKID_SYS_RSA] = &sys_rsa.hw, + [CLKID_SYS_SAR_ADC] = &sys_sar_adc.hw, + [CLKID_SYS_STARTUP] = &sys_startup.hw, + [CLKID_SYS_SECURE] = &sys_secure.hw, + [CLKID_SYS_SPIFC] = &sys_spifc.hw, + [CLKID_SYS_DSPA] = &sys_dspa.hw, + [CLKID_SYS_NNA] = &sys_nna.hw, + [CLKID_SYS_ETH_MAC] = &sys_eth_mac.hw, + [CLKID_SYS_GIC] = &sys_gic.hw, + [CLKID_SYS_RAMA] = &sys_rama.hw, + [CLKID_SYS_BIG_NIC] = &sys_big_nic.hw, + [CLKID_SYS_RAMB] = &sys_ramb.hw, + [CLKID_SYS_AUDIO_TOP] = &sys_audio_top.hw, + [CLKID_SYS_AUDIO_VAD] = &sys_audio_vad.hw, + [CLKID_SYS_USB] = &sys_usb.hw, + [CLKID_SYS_SD_EMMC_A] = &sys_sd_emmc_a.hw, + [CLKID_SYS_SD_EMMC_C] = &sys_sd_emmc_c.hw, + [CLKID_SYS_PWM_AB] = &sys_pwm_ab.hw, + [CLKID_SYS_PWM_CD] = &sys_pwm_cd.hw, + [CLKID_SYS_PWM_EF] = &sys_pwm_ef.hw, + [CLKID_SYS_PWM_GH] = &sys_pwm_gh.hw, + [CLKID_SYS_SPICC_1] = &sys_spicc_1.hw, + [CLKID_SYS_SPICC_0] = &sys_spicc_0.hw, + [CLKID_SYS_UART_A] = &sys_uart_a.hw, + [CLKID_SYS_UART_B] = &sys_uart_b.hw, + [CLKID_SYS_UART_C] = &sys_uart_c.hw, + [CLKID_SYS_UART_D] = &sys_uart_d.hw, + [CLKID_SYS_UART_E] = &sys_uart_e.hw, + [CLKID_SYS_I2C_M_A] = &sys_i2c_m_a.hw, + [CLKID_SYS_I2C_M_B] = &sys_i2c_m_b.hw, + [CLKID_SYS_I2C_M_C] = &sys_i2c_m_c.hw, + [CLKID_SYS_I2C_M_D] = &sys_i2c_m_d.hw, + [CLKID_SYS_RTC] = &sys_rtc.hw, + [CLKID_AXI_AUDIO_VAD] = &axi_audio_vad.hw, + [CLKID_AXI_AUDIO_TOP] = &axi_audio_top.hw, + [CLKID_AXI_SYS_NIC] = &axi_sys_nic.hw, + [CLKID_AXI_RAMB] = &axi_ramb.hw, + [CLKID_AXI_RAMA] = &axi_rama.hw, + [CLKID_AXI_CPU_DMC] = &axi_cpu_dmc.hw, + [CLKID_AXI_NNA] = &axi_nna.hw, + [CLKID_AXI_DEV1_DMC] = &axi_dev1_dmc.hw, + [CLKID_AXI_DEV0_DMC] = &axi_dev0_dmc.hw, + [CLKID_AXI_DSP_DMC] = &axi_dsp_dmc.hw, + [CLKID_12_24M_IN] = &clk_12_24m_in.hw, + [CLKID_12M_24M] = &clk_12_24m.hw, + [CLKID_FCLK_25M_DIV] = &fclk_25m_div.hw, + [CLKID_FCLK_25M] = &fclk_25m.hw, + [CLKID_GEN_SEL] = &gen_sel.hw, + [CLKID_GEN_DIV] = &gen_div.hw, + [CLKID_GEN] = &gen.hw, + [CLKID_SARADC_SEL] = &saradc_sel.hw, + [CLKID_SARADC_DIV] = &saradc_div.hw, + [CLKID_SARADC] = &saradc.hw, + [CLKID_PWM_A_SEL] = &pwm_a_sel.hw, + [CLKID_PWM_A_DIV] = &pwm_a_div.hw, + [CLKID_PWM_A] = &pwm_a.hw, + [CLKID_PWM_B_SEL] = &pwm_b_sel.hw, + [CLKID_PWM_B_DIV] = &pwm_b_div.hw, + [CLKID_PWM_B] = &pwm_b.hw, + [CLKID_PWM_C_SEL] = &pwm_c_sel.hw, + [CLKID_PWM_C_DIV] = &pwm_c_div.hw, + [CLKID_PWM_C] = &pwm_c.hw, + [CLKID_PWM_D_SEL] = &pwm_d_sel.hw, + [CLKID_PWM_D_DIV] = &pwm_d_div.hw, + [CLKID_PWM_D] = &pwm_d.hw, + [CLKID_PWM_E_SEL] = &pwm_e_sel.hw, + [CLKID_PWM_E_DIV] = &pwm_e_div.hw, + [CLKID_PWM_E] = &pwm_e.hw, + [CLKID_PWM_F_SEL] = &pwm_f_sel.hw, + [CLKID_PWM_F_DIV] = &pwm_f_div.hw, + [CLKID_PWM_F] = &pwm_f.hw, + [CLKID_PWM_G_SEL] = &pwm_g_sel.hw, + [CLKID_PWM_G_DIV] = &pwm_g_div.hw, + [CLKID_PWM_G] = &pwm_g.hw, + [CLKID_PWM_H_SEL] = &pwm_h_sel.hw, + [CLKID_PWM_H_DIV] = &pwm_h_div.hw, + [CLKID_PWM_H] = &pwm_h.hw, + [CLKID_SPICC_0_SEL] = &spicc_0_sel.hw, + [CLKID_SPICC_0_DIV] = &spicc_0_div.hw, + [CLKID_SPICC_0] = &spicc_0.hw, + [CLKID_SPICC_1_SEL] = &spicc_1_sel.hw, + [CLKID_SPICC_1_DIV] = &spicc_1_div.hw, + [CLKID_SPICC_1] = &spicc_1.hw, + [CLKID_SD_EMMC_A_SEL] = &sd_emmc_a_sel.hw, + [CLKID_SD_EMMC_A_DIV] = &sd_emmc_a_div.hw, + [CLKID_SD_EMMC_A] = &sd_emmc_a.hw, + [CLKID_SD_EMMC_C_SEL] = &sd_emmc_c_sel.hw, + [CLKID_SD_EMMC_C_DIV] = &sd_emmc_c_div.hw, + [CLKID_SD_EMMC_C] = &sd_emmc_c.hw, + [CLKID_TS_DIV] = &ts_div.hw, + [CLKID_TS] = &ts.hw, + [CLKID_ETH_125M_DIV] = ð_125m_div.hw, + [CLKID_ETH_125M] = ð_125m.hw, + [CLKID_ETH_RMII_DIV] = ð_rmii_div.hw, + [CLKID_ETH_RMII] = ð_rmii.hw, + [CLKID_DSPA_0_SEL] = &dspa_0_sel.hw, + [CLKID_DSPA_0_DIV] = &dspa_0_div.hw, + [CLKID_DSPA_0] = &dspa_0.hw, + [CLKID_DSPA_1_SEL] = &dspa_1_sel.hw, + [CLKID_DSPA_1_DIV] = &dspa_1_div.hw, + [CLKID_DSPA_1] = &dspa_1.hw, + [CLKID_DSPA] = &dspa.hw, + [CLKID_NNA_CORE_SEL] = &nna_core_sel.hw, + [CLKID_NNA_CORE_DIV] = &nna_core_div.hw, + [CLKID_NNA_CORE] = &nna_core.hw, + [CLKID_NNA_AXI_SEL] = &nna_axi_sel.hw, + [CLKID_NNA_AXI_DIV] = &nna_axi_div.hw, + [CLKID_NNA_AXI] = &nna_axi.hw, +}; + +/* Convenience table to populate regmap in .probe */ +static struct clk_regmap *const a5_periphs_clk_regmaps[] = { + &rtc_xtal_clkin, + &rtc_32k_div, + &rtc_32k_mux, + &rtc_32k, + &rtc_clk, + &sys_reset_ctrl, + &sys_pwr_ctrl, + &sys_pad_ctrl, + &sys_ctrl, + &sys_ts_pll, + &sys_dev_arb, + &sys_mmc_pclk, + &sys_mailbox, + &sys_cpu_ctrl, + &sys_jtag_ctrl, + &sys_ir_ctrl, + &sys_irq_ctrl, + &sys_msr_clk, + &sys_rom, + &sys_cpu_apb, + &sys_rsa, + &sys_sar_adc, + &sys_startup, + &sys_secure, + &sys_spifc, + &sys_dspa, + &sys_nna, + &sys_eth_mac, + &sys_gic, + &sys_rama, + &sys_big_nic, + &sys_ramb, + &sys_audio_top, + &sys_audio_vad, + &sys_usb, + &sys_sd_emmc_a, + &sys_sd_emmc_c, + &sys_pwm_ab, + &sys_pwm_cd, + &sys_pwm_ef, + &sys_pwm_gh, + &sys_spicc_1, + &sys_spicc_0, + &sys_uart_a, + &sys_uart_b, + &sys_uart_c, + &sys_uart_d, + &sys_uart_e, + &sys_i2c_m_a, + &sys_i2c_m_b, + &sys_i2c_m_c, + &sys_i2c_m_d, + &sys_rtc, + &axi_audio_vad, + &axi_audio_top, + &axi_sys_nic, + &axi_ramb, + &axi_rama, + &axi_cpu_dmc, + &axi_nna, + &axi_dev1_dmc, + &axi_dev0_dmc, + &axi_dsp_dmc, + &clk_12_24m_in, + &clk_12_24m, + &fclk_25m_div, + &fclk_25m, + &gen_sel, + &gen_div, + &gen, + &saradc_sel, + &saradc_div, + &saradc, + &pwm_a_sel, + &pwm_a_div, + &pwm_a, + &pwm_b_sel, + &pwm_b_div, + &pwm_b, + &pwm_c_sel, + &pwm_c_div, + &pwm_c, + &pwm_d_sel, + &pwm_d_div, + &pwm_d, + &pwm_e_sel, + &pwm_e_div, + &pwm_e, + &pwm_f_sel, + &pwm_f_div, + &pwm_f, + &pwm_g_sel, + &pwm_g_div, + &pwm_g, + &pwm_h_sel, + &pwm_h_div, + &pwm_h, + &spicc_0_sel, + &spicc_0_div, + &spicc_0, + &spicc_1_sel, + &spicc_1_div, + &spicc_1, + &sd_emmc_a_sel, + &sd_emmc_a_div, + &sd_emmc_a, + &sd_emmc_c_sel, + &sd_emmc_c_div, + &sd_emmc_c, + &ts_div, + &ts, + ð_125m, + ð_rmii_div, + ð_rmii, + &dspa_0_sel, + &dspa_0_div, + &dspa_0, + &dspa_1_sel, + &dspa_1_div, + &dspa_1, + &dspa, + &nna_core_sel, + &nna_core_div, + &nna_core, + &nna_axi_sel, + &nna_axi_div, + &nna_axi +}; + +static const struct regmap_config clkc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = CLKCTRL_NNA_CLK_CNTL, +}; + +static struct meson_clk_hw_data a5_periphs_clks = { + .hws = a5_periphs_hw_clks, + .num = ARRAY_SIZE(a5_periphs_hw_clks), +}; + +static int aml_a5_peripherals_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *regmap; + void __iomem *base; + int clkid, ret, i; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Populate regmap for the regmap backed clocks */ + for (i = 0; i < ARRAY_SIZE(a5_periphs_clk_regmaps); i++) + a5_periphs_clk_regmaps[i]->map = regmap; + + for (clkid = 0; clkid < a5_periphs_clks.num; clkid++) { + /* array might be sparse */ + if (!a5_periphs_clks.hws[clkid]) + continue; + + ret = devm_clk_hw_register(dev, a5_periphs_clks.hws[clkid]); + if (ret) { + dev_err(dev, "Clock registration failed\n"); + return ret; + } + } + + return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, + &a5_periphs_clks); +} + +static const struct of_device_id a5_peripherals_clkc_match_table[] = { + { + .compatible = "amlogic,a5-peripherals-clkc", + }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, a5_peripherals_clkc_match_table); + +static struct platform_driver a5_peripherals_driver = { + .probe = aml_a5_peripherals_probe, + .driver = { + .name = "a5-peripherals-clkc", + .of_match_table = a5_peripherals_clkc_match_table, + }, +}; +module_platform_driver(a5_peripherals_driver); + +MODULE_DESCRIPTION("Amlogic A5 Peripherals Clock Controller driver"); +MODULE_AUTHOR("Chuan Liu "); +MODULE_LICENSE("GPL");