From patchwork Fri Nov 29 14:45:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jian Hu X-Patchwork-Id: 11267249 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9FFE8921 for ; Fri, 29 Nov 2019 14:47:01 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 51BBA21736 for ; Fri, 29 Nov 2019 14:47:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="NQpWQLPN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 51BBA21736 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amlogic.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=lNKx0+L4sScxxU7Rh7pL0mHG2q36IKplx/fkkQM1Tlo=; b=NQpWQLPN07Lgbl 6etQhp7yxiaiJONnAF1HLCPnDBF8T2Qhae4CUNZNEUULxiIJ5fr+e0JhAg7QTgCZbLYciN4E6sZeK 5NEOq+1QrRnHzhb2GlES99cDjBjh1qHsfM9untXkeHwN/SZKbYcwvOSnP+GrrCqM+57AqcMmW7il5 Zox0RubkvFXqpifC2E/wRdtx5l2MxHLLd/NRn1JP0KErLK40WhwfbzkvktOClSSYxzf/SsQ9HztzV 0spSrqtnN7DriCi/ye4pOPy7EKXnYHauGmIDz24bdoZhg/ERZmeSZ3irFqjiMVN3gbd/028SMSSyt tf2jmQxc6lqx5tSCecIA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahXu-00040Q-Je; Fri, 29 Nov 2019 14:46:58 +0000 Received: from mail-sz.amlogic.com ([211.162.65.117]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahXb-0003gZ-6m; Fri, 29 Nov 2019 14:46:44 +0000 Received: from droid15-sz.amlogic.com (10.28.8.25) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.1591.10; Fri, 29 Nov 2019 22:46:36 +0800 From: Jian Hu To: Jerome Brunet , Neil Armstrong Subject: [PATCH v3 1/7] dt-bindings: clock: meson: add A1 PLL clock controller bindings Date: Fri, 29 Nov 2019 22:45:59 +0800 Message-ID: <20191129144605.182774-2-jian.hu@amlogic.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191129144605.182774-1-jian.hu@amlogic.com> References: <20191129144605.182774-1-jian.hu@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.28.8.25] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191129_064640_382830_D43FB5E0 X-CRM114-Status: UNSURE ( 9.38 ) X-CRM114-Notice: Please train this message. X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Victor Wan , Jianxin Pan , devicetree@vger.kernel.org, Martin Blumenstingl , Kevin Hilman , Michael Turquette , linux-kernel@vger.kernel.org, Stephen Boyd , Jian Hu , linux-arm-kernel@lists.infradead.org, Qiufang Dai , linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, Chandle Zou Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add the documentation to support Amlogic A1 PLL clock driver, and add A1 PLL clock controller bindings. Signed-off-by: Jian Hu --- .../bindings/clock/amlogic,a1-pll-clkc.yaml | 56 +++++++++++++++++++ include/dt-bindings/clock/a1-pll-clkc.h | 16 ++++++ 2 files changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml create mode 100644 include/dt-bindings/clock/a1-pll-clkc.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml new file mode 100644 index 000000000000..d008bfeb3c3a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/clock/amlogic,a1-pll-clkc.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Amlogic Meson A/C serials PLL Clock Control Unit Device Tree Bindings + +maintainers: + - Neil Armstrong + - Jerome Brunet + - Jian Hu + +properties: + compatible: + - enum: + - amlogic,a1-pll-clkc + "#clock-cells": + const: 1 + + reg: + maxItems: 1 + +clocks: + minItems: 2 + maxItems: 2 + items: + - description: Input xtal_fixpll + - description: Input xtal_hifipll + +clock-names: + minItems: 2 + maxItems: 2 + items: + - const: xtal_fixpll + - const: xtal_hifipll + +required: + - compatible + - "#clock-cells" + - reg + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + clkc_pll: pll-clock-controller { + compatible = "amlogic,a1-pll-clkc"; + reg = <0 0x7c80 0 0x18c>; + #clock-cells = <1>; + }; diff --git a/include/dt-bindings/clock/a1-pll-clkc.h b/include/dt-bindings/clock/a1-pll-clkc.h new file mode 100644 index 000000000000..58eae237e503 --- /dev/null +++ b/include/dt-bindings/clock/a1-pll-clkc.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ + +#ifndef __A1_PLL_CLKC_H +#define __A1_PLL_CLKC_H + +#define CLKID_FIXED_PLL 1 +#define CLKID_FCLK_DIV2 6 +#define CLKID_FCLK_DIV3 7 +#define CLKID_FCLK_DIV5 8 +#define CLKID_FCLK_DIV7 9 +#define CLKID_HIFI_PLL 10 + +#endif /* __A1_PLL_CLKC_H */ From patchwork Fri Nov 29 14:46:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jian Hu X-Patchwork-Id: 11267253 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C0E5D6C1 for ; Fri, 29 Nov 2019 14:47:18 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9DCD5217AB for ; Fri, 29 Nov 2019 14:47:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="dJd7bDt6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9DCD5217AB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amlogic.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=6SiV0ikVuUgy434w7ir3f/1jgQkfrw1rP7iOc2VwyOU=; b=dJd7bDt6reU+T4 M97XKyBqvaZ1IJHZYrl+hQHhA/2o5ywG43/P8dS/zZ0AW/gbfKconAq4BbuTDmrrfwxiYnKZGjB6V 83u7U59f2diDyYnueHAFQRccM2n6T4V5creINYnEwC7uBy8BUA+dO3TACUNnid5lCSO+FYMp0rp1M +hWyCRmSJjNPn9jQx0tpoZfdIz8UqiKUOCtYc36ON/4jipwYPPtHjpTEJvYOd9yL1vg5J7UhKZfBw SPjxbivfkwhghDPpdlj/uY619gekl8C7myAD2TmStkLESjy1T7BfyJh5x6Fu15ZcQakfBJ272JvSy SzCWvRDLjy7Nw57Kv9qQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahYB-0004Ge-74; Fri, 29 Nov 2019 14:47:15 +0000 Received: from mail-sz.amlogic.com ([211.162.65.117]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahXh-0003gZ-1R; Fri, 29 Nov 2019 14:46:47 +0000 Received: from droid15-sz.amlogic.com (10.28.8.25) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.1591.10; Fri, 29 Nov 2019 22:46:37 +0800 From: Jian Hu To: Jerome Brunet , Neil Armstrong Subject: [PATCH v3 2/7] clk: meson: add support for A1 PLL clock ops Date: Fri, 29 Nov 2019 22:46:00 +0800 Message-ID: <20191129144605.182774-3-jian.hu@amlogic.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191129144605.182774-1-jian.hu@amlogic.com> References: <20191129144605.182774-1-jian.hu@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.28.8.25] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191129_064645_548180_46B57BA3 X-CRM114-Status: GOOD ( 10.88 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Victor Wan , Jianxin Pan , devicetree@vger.kernel.org, Martin Blumenstingl , Kevin Hilman , Michael Turquette , linux-kernel@vger.kernel.org, Stephen Boyd , Jian Hu , linux-arm-kernel@lists.infradead.org, Qiufang Dai , linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, Chandle Zou Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The A1 PLL design is different with previous SoCs. The PLL internal analog modules Power-on sequence is different with previous, and thus requires a strict register sequence to enable the PLL. Signed-off-by: Jian Hu --- drivers/clk/meson/clk-pll.c | 21 +++++++++++++++++++++ drivers/clk/meson/clk-pll.h | 1 + drivers/clk/meson/parm.h | 1 + 3 files changed, 23 insertions(+) diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index ddb1e5634739..4aff31a51589 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -318,6 +318,23 @@ static int meson_clk_pll_enable(struct clk_hw *hw) struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); + /* + * The A1 design is different with previous SoCs.The PLL + * internal analog modules Power-on sequence is different with + * previous, and thus requires a strict register sequence to + * enable the PLL. + */ + if (MESON_PARM_APPLICABLE(&pll->current_en)) { + /* Enable the pll */ + meson_parm_write(clk->map, &pll->en, 1); + udelay(10); + /* Enable the pll self-adaption module current */ + meson_parm_write(clk->map, &pll->current_en, 1); + udelay(40); + meson_parm_write(clk->map, &pll->rst, 1); + meson_parm_write(clk->map, &pll->rst, 0); + } + /* do nothing if the PLL is already enabled */ if (clk_hw_is_enabled(hw)) return 0; @@ -347,6 +364,10 @@ static void meson_clk_pll_disable(struct clk_hw *hw) /* Disable the pll */ meson_parm_write(clk->map, &pll->en, 0); + + /* Disable PLL internal self-adaption module current */ + if (MESON_PARM_APPLICABLE(&pll->current_en)) + meson_parm_write(clk->map, &pll->current_en, 0); } static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h index 367efd0f6410..30f039242a65 100644 --- a/drivers/clk/meson/clk-pll.h +++ b/drivers/clk/meson/clk-pll.h @@ -36,6 +36,7 @@ struct meson_clk_pll_data { struct parm frac; struct parm l; struct parm rst; + struct parm current_en; const struct reg_sequence *init_regs; unsigned int init_count; const struct pll_params_table *table; diff --git a/drivers/clk/meson/parm.h b/drivers/clk/meson/parm.h index 3c9ef1b505ce..c53fb26577e3 100644 --- a/drivers/clk/meson/parm.h +++ b/drivers/clk/meson/parm.h @@ -20,6 +20,7 @@ (((reg) & CLRPMASK(width, shift)) | ((val) << (shift))) #define MESON_PARM_APPLICABLE(p) (!!((p)->width)) +#define MESON_PARM_CURRENT(p) (!!((p)->width)) struct parm { u16 reg_off; From patchwork Fri Nov 29 14:46:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jian Hu X-Patchwork-Id: 11267261 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B4A406C1 for ; Fri, 29 Nov 2019 14:47:39 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 909C621736 for ; Fri, 29 Nov 2019 14:47:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="WpNTdUQG" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 909C621736 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amlogic.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=BlphDeXeLx3l4yWneSHXbwz9clMx1/8L44Uoqt8TtR4=; b=WpNTdUQGu+i9LP iCFnPv8YyI+kYHIV8vWzSMaOAe2VLDk8NjfAt+H91quwAQPnp7RWCUpoXjlJmFk1K9MYrDp8cAsDN wOWqRjKRY1qMB0TUTkEUCQM8AtxNhbIIi9vIuVwuyZj9R1L93jTkn2eV4c6HdMdhCIrIZXi1wvGwX +gQNsIySD99teSvc68oKeS6cKdP444Qr63wmmopA1F62O7BiZoJS0IHgbSdOshBu5RGR7AuNr9w47 NxjO5tdjsq8hig5bl/SYrUqUPbEdm9jrAPl40XKCcpmg6hEr/UcDajFS2tyuUZyHXZNhQ9B6CgY0M gGId/MNEFYTooTgNJJaQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahYW-0004cE-5G; Fri, 29 Nov 2019 14:47:36 +0000 Received: from mail-sz.amlogic.com ([211.162.65.117]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahXk-0003gZ-GU; Fri, 29 Nov 2019 14:46:50 +0000 Received: from droid15-sz.amlogic.com (10.28.8.25) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.1591.10; Fri, 29 Nov 2019 22:46:37 +0800 From: Jian Hu To: Jerome Brunet , Neil Armstrong Subject: [PATCH v3 3/7] clk: meson: eeclk: refactor eeclk common driver to support A1 Date: Fri, 29 Nov 2019 22:46:01 +0800 Message-ID: <20191129144605.182774-4-jian.hu@amlogic.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191129144605.182774-1-jian.hu@amlogic.com> References: <20191129144605.182774-1-jian.hu@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.28.8.25] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191129_064648_642903_781A1420 X-CRM114-Status: GOOD ( 10.01 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Victor Wan , Jianxin Pan , Martin Blumenstingl , Kevin Hilman , Michael Turquette , linux-kernel@vger.kernel.org, Stephen Boyd , Jian Hu , linux-arm-kernel@lists.infradead.org, Qiufang Dai , linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, Chandle Zou Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Introduce a common probe function for A1 series, the way to get regmap is different between A1 series and the previous series. The register region is only for one clock driver, the function of meson_eeclkc_probe is not fit for A1, So it is necessary to introduce a new function. --- drivers/clk/meson/meson-eeclk.c | 59 +++++++++++++++++++++++++++------ drivers/clk/meson/meson-eeclk.h | 2 ++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c index a7cb1e7aedc4..6f9c8ee38c20 100644 --- a/drivers/clk/meson/meson-eeclk.c +++ b/drivers/clk/meson/meson-eeclk.c @@ -13,25 +13,37 @@ #include "clk-regmap.h" #include "meson-eeclk.h" -int meson_eeclkc_probe(struct platform_device *pdev) +static struct regmap_config clkc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +struct regmap *meson_regmap_resource(struct platform_device *pdev) +{ + struct resource *res; + void __iomem *base; + struct device *dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return ERR_CAST(base); + + return devm_regmap_init_mmio(dev, base, &clkc_regmap_config); +} + +int meson_common_probe(struct platform_device *pdev, struct regmap *map) { const struct meson_eeclkc_data *data; struct device *dev = &pdev->dev; - struct regmap *map; int ret, i; data = of_device_get_match_data(dev); if (!data) return -EINVAL; - /* Get the hhi system controller node */ - map = syscon_node_to_regmap(of_get_parent(dev->of_node)); - if (IS_ERR(map)) { - dev_err(dev, - "failed to get HHI regmap\n"); - return PTR_ERR(map); - } - if (data->init_count) regmap_multi_reg_write(map, data->init_regs, data->init_count); @@ -54,3 +66,30 @@ int meson_eeclkc_probe(struct platform_device *pdev) return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data->hw_onecell_data); } + +int meson_eeclkc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *map; + + /* Get the hhi system controller node */ + map = syscon_node_to_regmap(of_get_parent(dev->of_node)); + if (IS_ERR(map)) { + dev_err(dev, + "failed to get HHI regmap\n"); + return PTR_ERR(map); + } + + return meson_common_probe(pdev, map); +} + +int meson_clkc_probe(struct platform_device *pdev) +{ + struct regmap *map; + + map = meson_regmap_resource(pdev); + if (IS_ERR(map)) + return PTR_ERR(map); + + return meson_common_probe(pdev, map); +} diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h index 77316207bde1..db0bfba8f6b3 100644 --- a/drivers/clk/meson/meson-eeclk.h +++ b/drivers/clk/meson/meson-eeclk.h @@ -20,6 +20,8 @@ struct meson_eeclkc_data { struct clk_hw_onecell_data *hw_onecell_data; }; +struct regmap *meson_regmap_resource(struct platform_device *pdev); int meson_eeclkc_probe(struct platform_device *pdev); +int meson_clkc_probe(struct platform_device *pdev); #endif /* __MESON_CLKC_H */ From patchwork Fri Nov 29 14:46:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jian Hu X-Patchwork-Id: 11267265 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C72136C1 for ; Fri, 29 Nov 2019 14:47:54 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A1FAA217AB for ; Fri, 29 Nov 2019 14:47:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="gBC8RM9o" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A1FAA217AB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amlogic.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WJW2C/LKFSufV78vPCJOl2RjsOcsRziV9Oa5CB/BpQI=; b=gBC8RM9ossyAG9 djfkWL+T7Oxq0Gfb56a49NSQfhOFHEMjq/92dorfkGEy4Ih3h2ABxyDuUntH9xmFP99bncd6PrRr2 4TcINTFeIOoFrxu0j5ONmTV9B6uzA7UkGRYa3mT9sqpvMCMHjkJD6rX2h6XbEp72XNP5F8I8Ka6Y/ Ou95jM8I1gIeCtOxCgod2HDX4Qu1moJ6dn4ePYybRZkgojTrprDmro2tdY5JG0Mf/Mxi7kmDZ+VrE qGmO72Ilt9vS25lj5sQGAPbfSy2nj4eI2f/6rT8OxDl77VVsYGw3nZNQViER5HtvipGVtTORYT8iZ 4QNdyAEUkxuT/jJBMXag==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahYl-0004tz-Eo; Fri, 29 Nov 2019 14:47:51 +0000 Received: from mail-sz.amlogic.com ([211.162.65.117]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahXp-0003gZ-17; Fri, 29 Nov 2019 14:46:57 +0000 Received: from droid15-sz.amlogic.com (10.28.8.25) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.1591.10; Fri, 29 Nov 2019 22:46:37 +0800 From: Jian Hu To: Jerome Brunet , Neil Armstrong Subject: [PATCH v3 4/7] clk: meson: a1: add support for Amlogic A1 PLL clock driver Date: Fri, 29 Nov 2019 22:46:02 +0800 Message-ID: <20191129144605.182774-5-jian.hu@amlogic.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191129144605.182774-1-jian.hu@amlogic.com> References: <20191129144605.182774-1-jian.hu@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.28.8.25] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191129_064654_791923_6C1BB217 X-CRM114-Status: GOOD ( 16.20 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Victor Wan , Jianxin Pan , Martin Blumenstingl , Kevin Hilman , Michael Turquette , linux-kernel@vger.kernel.org, Stephen Boyd , Jian Hu , linux-arm-kernel@lists.infradead.org, Qiufang Dai , linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, Chandle Zou Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The Amlogic A1 clock includes three drivers: pll clocks, peripheral clocks, CPU clocks. sys pll and CPU clocks will be sent in next patch. Unlike the previous series, there is no EE/AO domain in A1 CLK controllers. Signed-off-by: Jian Hu --- drivers/clk/meson/Kconfig | 10 ++ drivers/clk/meson/Makefile | 1 + drivers/clk/meson/a1-pll.c | 334 +++++++++++++++++++++++++++++++++++++ drivers/clk/meson/a1-pll.h | 56 +++++++ 4 files changed, 401 insertions(+) create mode 100644 drivers/clk/meson/a1-pll.c create mode 100644 drivers/clk/meson/a1-pll.h diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index dabeb435d067..14e7936ae18e 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -93,6 +93,16 @@ config COMMON_CLK_AXG_AUDIO Support for the audio clock controller on AmLogic A113D devices, aka axg, Say Y if you want audio subsystem to work. +config COMMON_CLK_A1_PLL + bool + depends on ARCH_MESON + select COMMON_CLK_MESON_EE_CLKC + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_PLL + help + Support for the PLL clock controller on Amlogic A113L device, + aka a1. Say Y if you want PLL to work. + config COMMON_CLK_G12A bool depends on ARCH_MESON diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 3939f218587a..71d3b8e6fb8a 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o 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_GXBB) += gxbb.o gxbb-aoclk.o obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c new file mode 100644 index 000000000000..b248ac81ddd8 --- /dev/null +++ b/drivers/clk/meson/a1-pll.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + */ + +#include +#include +#include +#include "a1-pll.h" +#include "clk-pll.h" +#include "meson-eeclk.h" + +static struct clk_regmap a1_fixed_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = ANACTRL_FIXPLL_CTRL1, + .shift = 0, + .width = 19, + }, + .l = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xtal_fixpll", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_fixed_pll = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL0, + .bit_idx = 20, + }, + .hw.init = &(struct clk_init_data) { + .name = "fixed_pll", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fixed_pll_dco.hw + }, + .num_parents = 1, + /* + * This clock is fclk_div2/3/5's parent, + * However, fclk_div2/3/5 feeds AXI/APB/DDR. + * It is required by the platform to operate correctly. + */ + .flags = CLK_IGNORE_UNUSED, + }, +}; + +static const struct pll_mult_range a1_hifi_pll_mult_range = { + .min = 32, + .max = 64, +}; + +static const struct reg_sequence a1_hifi_init_regs[] = { + { .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x01800000 }, + { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00001100 }, + { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x100a1100 }, + { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x00302000 }, + { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x01f18440 }, +}; + +static struct clk_regmap a1_hifi_pll = { + .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, + }, + .n = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = ANACTRL_HIFIPLL_CTRL1, + .shift = 0, + .width = 19, + }, + .l = { + .reg_off = ANACTRL_HIFIPLL_STS, + .shift = 31, + .width = 1, + }, + .current_en = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 26, + .width = 1, + }, + .rst = { + .reg_off = ANACTRL_HIFIPLL_CTRL2, + .shift = 6, + .width = 1, + }, + .range = &a1_hifi_pll_mult_range, + .init_regs = a1_hifi_init_regs, + .init_count = ARRAY_SIZE(a1_hifi_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xtal_hifipll", + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor a1_fclk_div2_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fixed_pll.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_fclk_div2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL0, + .bit_idx = 21, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fclk_div2_div.hw + }, + .num_parents = 1, + /* + * This clock is used by DDR clock in BL2 firmware + * and is required by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_IS_CRITICAL, + }, +}; + +static struct clk_fixed_factor a1_fclk_div3_div = { + .mult = 1, + .div = 3, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fixed_pll.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_fclk_div3 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL0, + .bit_idx = 22, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fclk_div3_div.hw + }, + .num_parents = 1, + /* + * This clock is used by APB bus which setted in Romcode + * and is required by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_IS_CRITICAL, + }, +}; + +static struct clk_fixed_factor a1_fclk_div5_div = { + .mult = 1, + .div = 5, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div5_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fixed_pll.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_fclk_div5 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL0, + .bit_idx = 23, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div5", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fclk_div5_div.hw + }, + .num_parents = 1, + /* + * This clock is used by AXI bus which setted in Romcode + * and is required by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_IS_CRITICAL, + }, +}; + +static struct clk_fixed_factor a1_fclk_div7_div = { + .mult = 1, + .div = 7, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div7_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fixed_pll.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_fclk_div7 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL0, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div7", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fclk_div7_div.hw + }, + .num_parents = 1, + }, +}; + +/* Array of all clocks provided by this provider */ +static struct clk_hw_onecell_data a1_pll_hw_onecell_data = { + .hws = { + [CLKID_FIXED_PLL_DCO] = &a1_fixed_pll_dco.hw, + [CLKID_FIXED_PLL] = &a1_fixed_pll.hw, + [CLKID_HIFI_PLL] = &a1_hifi_pll.hw, + [CLKID_FCLK_DIV2] = &a1_fclk_div2.hw, + [CLKID_FCLK_DIV3] = &a1_fclk_div3.hw, + [CLKID_FCLK_DIV5] = &a1_fclk_div5.hw, + [CLKID_FCLK_DIV7] = &a1_fclk_div7.hw, + [CLKID_FCLK_DIV2_DIV] = &a1_fclk_div2_div.hw, + [CLKID_FCLK_DIV3_DIV] = &a1_fclk_div3_div.hw, + [CLKID_FCLK_DIV5_DIV] = &a1_fclk_div5_div.hw, + [CLKID_FCLK_DIV7_DIV] = &a1_fclk_div7_div.hw, + [NR_PLL_CLKS] = NULL, + }, + .num = NR_PLL_CLKS, +}; + +static struct clk_regmap *const a1_pll_regmaps[] = { + &a1_fixed_pll_dco, + &a1_fixed_pll, + &a1_hifi_pll, + &a1_fclk_div2, + &a1_fclk_div3, + &a1_fclk_div5, + &a1_fclk_div7, +}; + +static const struct meson_eeclkc_data a1_pll_data = { + .regmap_clks = a1_pll_regmaps, + .regmap_clk_num = ARRAY_SIZE(a1_pll_regmaps), + .hw_onecell_data = &a1_pll_hw_onecell_data, +}; +static const struct of_device_id clkc_match_table[] = { + { + .compatible = "amlogic,a1-pll-clkc", + .data = &a1_pll_data + }, + {} +}; + +static struct platform_driver a1_pll_driver = { + .probe = meson_clkc_probe, + .driver = { + .name = "a1-pll-clkc", + .of_match_table = clkc_match_table, + }, +}; + +builtin_platform_driver(a1_pll_driver); diff --git a/drivers/clk/meson/a1-pll.h b/drivers/clk/meson/a1-pll.h new file mode 100644 index 000000000000..8ded267061ad --- /dev/null +++ b/drivers/clk/meson/a1-pll.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ + +#ifndef __A1_PLL_H +#define __A1_PLL_H + +/* PLL register offset */ +#define ANACTRL_FIXPLL_CTRL0 0x0 +#define ANACTRL_FIXPLL_CTRL1 0x4 +#define ANACTRL_FIXPLL_CTRL2 0x8 +#define ANACTRL_FIXPLL_CTRL3 0xc +#define ANACTRL_FIXPLL_CTRL4 0x10 +#define ANACTRL_FIXPLL_STS 0x14 +#define ANACTRL_SYSPLL_CTRL0 0x80 +#define ANACTRL_SYSPLL_CTRL1 0x84 +#define ANACTRL_SYSPLL_CTRL2 0x88 +#define ANACTRL_SYSPLL_CTRL3 0x8c +#define ANACTRL_SYSPLL_CTRL4 0x90 +#define ANACTRL_SYSPLL_STS 0x94 +#define ANACTRL_HIFIPLL_CTRL0 0xc0 +#define ANACTRL_HIFIPLL_CTRL1 0xc4 +#define ANACTRL_HIFIPLL_CTRL2 0xc8 +#define ANACTRL_HIFIPLL_CTRL3 0xcc +#define ANACTRL_HIFIPLL_CTRL4 0xd0 +#define ANACTRL_HIFIPLL_STS 0xd4 +#define ANACTRL_AUDDDS_CTRL0 0x100 +#define ANACTRL_AUDDDS_CTRL1 0x104 +#define ANACTRL_AUDDDS_CTRL2 0x108 +#define ANACTRL_AUDDDS_CTRL3 0x10c +#define ANACTRL_AUDDDS_CTRL4 0x110 +#define ANACTRL_AUDDDS_STS 0x114 +#define ANACTRL_MISCTOP_CTRL0 0x140 +#define ANACTRL_POR_CNTL 0x188 + +/* + * CLKID index values + * + * These indices are entirely contrived and do not map onto the hardware. + * It has now been decided to expose everything by default in the DT header: + * include/dt-bindings/clock/a1-pll-clkc.h. Only the clocks ids we don't want + * to expose, such as the internal muxes and dividers of composite clocks, + * will remain defined here. + */ +#define CLKID_FIXED_PLL_DCO 0 +#define CLKID_FCLK_DIV2_DIV 2 +#define CLKID_FCLK_DIV3_DIV 3 +#define CLKID_FCLK_DIV5_DIV 4 +#define CLKID_FCLK_DIV7_DIV 5 +#define NR_PLL_CLKS 11 + +/* include the CLKIDs that have been made part of the DT binding */ +#include + +#endif /* __A1_PLL_H */ From patchwork Fri Nov 29 14:46:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jian Hu X-Patchwork-Id: 11267271 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 20DC66C1 for ; Fri, 29 Nov 2019 14:48:09 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F22DA217AB for ; Fri, 29 Nov 2019 14:48:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="SK+S6kRb" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F22DA217AB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amlogic.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=kFolT7+ZPUj7l4Xfcj3eBzxqvXtyBcsW1DdhzekDvcs=; b=SK+S6kRb4W/0ot AW/+EkAhD4r9lagxX5cjpB9nncq/Bj93ALQUFtK+DWKiD1wZbLVMasR8IjrYZnzJSNjvu/u+NH60x VqtJIf826lJfZR8OboavHarsC76N0ebyKNxhAwOS1erGuPr6QO06hUHYy15m7iuGUhcbgFAAQv5mQ wYNd2RFJGjd9MxqrDDpv/lNMPzkeQqSiXmJbaXr3VnjQ7CeVDGnp4WW3YllWDnZoQee4lFqGZBIdD NWi0qimhvH7b6qI4IGwtL0kfk2Y8I1YNQG3hBhw7q7U2aDXrSaLOefOsPxOJ1V8qq39QEgMSkjPGu T8mDLzm3daB1gYYDb+PQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahZ1-0005Dt-HA; Fri, 29 Nov 2019 14:48:07 +0000 Received: from mail-sz.amlogic.com ([211.162.65.117]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahYH-0004ND-Fc; Fri, 29 Nov 2019 14:47:26 +0000 Received: from droid15-sz.amlogic.com (10.28.8.25) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.1591.10; Fri, 29 Nov 2019 22:47:47 +0800 From: Jian Hu To: Jerome Brunet , Neil Armstrong Subject: [PATCH v3 5/7] dt-bindings: clock: meson: add A1 peripheral clock controller bindings Date: Fri, 29 Nov 2019 22:46:03 +0800 Message-ID: <20191129144605.182774-6-jian.hu@amlogic.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191129144605.182774-1-jian.hu@amlogic.com> References: <20191129144605.182774-1-jian.hu@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.28.8.25] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191129_064721_766109_D583F737 X-CRM114-Status: UNSURE ( 9.96 ) X-CRM114-Notice: Please train this message. X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Victor Wan , Jianxin Pan , Martin Blumenstingl , Kevin Hilman , Michael Turquette , linux-kernel@vger.kernel.org, Stephen Boyd , Jian Hu , linux-arm-kernel@lists.infradead.org, Qiufang Dai , linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, Chandle Zou Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add the documentation to support Amlogic A1 peripheral clock driver, and add A1 peripheral clock controller bindings. Signed-off-by: Jian Hu --- .../bindings/clock/amlogic,a1-clkc.yaml | 70 +++++++++++++ include/dt-bindings/clock/a1-clkc.h | 98 +++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml create mode 100644 include/dt-bindings/clock/a1-clkc.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml new file mode 100644 index 000000000000..dd3ce071834e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/clock/amlogic,a1-clkc.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Amlogic Meson A/C serials Peripheral Clock Control Unit Device Tree Bindings + +maintainers: + - Neil Armstrong + - Jerome Brunet + - Jian Hu + +properties: + "#clock-cells": + const: 1 + compatible: + - enum: + - amlogic,a1-periphs-clkc + + reg: + maxItems: 1 + + clocks: + minItems: 6 + maxItems: 6 + items: + - description: Input fixed pll div2 + - description: Input fixed pll div3 + - description: Input fixed pll div5 + - description: Input fixed pll div7 + - description: HIFI PLL + - description: Input Oscillator (usually at 24MHz) + + clock-names: + minItems: 6 + maxItems: 6 + items: + - const: fclk_div2 + - const: fclk_div3 + - const: fclk_div5 + - const: fclk_div7 + - const: hifi_pll + - const: xtal + +required: + - "#clock-cells" + - compatible + - reg + - clocks + - clock-names + +examples: + - | + clkc_periphs: periphs-clock-controller { + compatible = "amlogic,a1-periphs-clkc"; + reg = <0 0x800 0 0x104>; + #clock-cells = <1>; + clocks = <&clkc_pll CLKID_FCLK_DIV2>, + <&clkc_pll CLKID_FCLK_DIV3>, + <&clkc_pll CLKID_FCLK_DIV5>, + <&clkc_pll CLKID_FCLK_DIV7>, + <&clkc_pll CLKID_HIFI_PLL>, + <&xtal>; + clock-names = "fclk_div2", "fclk_div3", "fclk_div5", + "fclk_div7", "hifi_pll", "xtal"; + }; diff --git a/include/dt-bindings/clock/a1-clkc.h b/include/dt-bindings/clock/a1-clkc.h new file mode 100644 index 000000000000..1ba01122457c --- /dev/null +++ b/include/dt-bindings/clock/a1-clkc.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ + +#ifndef __A1_CLKC_H +#define __A1_CLKC_H + +#define CLKID_XTAL_FIXPLL 1 +#define CLKID_XTAL_USB_PHY 2 +#define CLKID_XTAL_USB_CTRL 3 +#define CLKID_XTAL_HIFIPLL 4 +#define CLKID_XTAL_SYSPLL 5 +#define CLKID_XTAL_DDS 6 +#define CLKID_SYS_CLK 7 +#define CLKID_CLKTREE 8 +#define CLKID_RESET_CTRL 9 +#define CLKID_ANALOG_CTRL 10 +#define CLKID_PWR_CTRL 11 +#define CLKID_PAD_CTRL 12 +#define CLKID_SYS_CTRL 13 +#define CLKID_TEMP_SENSOR 14 +#define CLKID_AM2AXI_DIV 15 +#define CLKID_SPICC_B 16 +#define CLKID_SPICC_A 17 +#define CLKID_CLK_MSR 18 +#define CLKID_AUDIO 19 +#define CLKID_JTAG_CTRL 20 +#define CLKID_SARADC 21 +#define CLKID_PWM_EF 22 +#define CLKID_PWM_CD 23 +#define CLKID_PWM_AB 24 +#define CLKID_CEC 25 +#define CLKID_I2C_S 26 +#define CLKID_IR_CTRL 27 +#define CLKID_I2C_M_D 28 +#define CLKID_I2C_M_C 29 +#define CLKID_I2C_M_B 30 +#define CLKID_I2C_M_A 31 +#define CLKID_ACODEC 32 +#define CLKID_OTP 33 +#define CLKID_SD_EMMC_A 34 +#define CLKID_USB_PHY 35 +#define CLKID_USB_CTRL 36 +#define CLKID_SYS_DSPB 37 +#define CLKID_SYS_DSPA 38 +#define CLKID_DMA 39 +#define CLKID_IRQ_CTRL 40 +#define CLKID_NIC 41 +#define CLKID_GIC 42 +#define CLKID_UART_C 43 +#define CLKID_UART_B 44 +#define CLKID_UART_A 45 +#define CLKID_SYS_PSRAM 46 +#define CLKID_RSA 47 +#define CLKID_CORESIGHT 48 +#define CLKID_AM2AXI_VAD 49 +#define CLKID_AUDIO_VAD 50 +#define CLKID_AXI_DMC 51 +#define CLKID_AXI_PSRAM 52 +#define CLKID_RAMB 53 +#define CLKID_RAMA 54 +#define CLKID_AXI_SPIFC 55 +#define CLKID_AXI_NIC 56 +#define CLKID_AXI_DMA 57 +#define CLKID_CPU_CTRL 58 +#define CLKID_ROM 59 +#define CLKID_PROC_I2C 60 +#define CLKID_DSPA_SEL 61 +#define CLKID_DSPB_SEL 62 +#define CLKID_DSPA_EN_DSPA 63 +#define CLKID_DSPA_EN_NIC 64 +#define CLKID_DSPB_EN_DSPB 65 +#define CLKID_DSPB_EN_NIC 66 +#define CLKID_RTC_CLK 67 +#define CLKID_CECA_32K 68 +#define CLKID_CECB_32K 69 +#define CLKID_24M 70 +#define CLKID_12M 71 +#define CLKID_FCLK_DIV2_DIVN 72 +#define CLKID_GEN 73 +#define CLKID_SARADC_SEL 74 +#define CLKID_SARADC_CLK 75 +#define CLKID_PWM_A 76 +#define CLKID_PWM_B 77 +#define CLKID_PWM_C 78 +#define CLKID_PWM_D 79 +#define CLKID_PWM_E 80 +#define CLKID_PWM_F 81 +#define CLKID_SPICC 82 +#define CLKID_TS 83 +#define CLKID_SPIFC 84 +#define CLKID_USB_BUS 85 +#define CLKID_SD_EMMC 86 +#define CLKID_PSRAM 87 +#define CLKID_DMC 88 + +#endif /* __A1_CLKC_H */ From patchwork Fri Nov 29 14:46:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jian Hu X-Patchwork-Id: 11267275 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EFB5B6C1 for ; Fri, 29 Nov 2019 14:48:27 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C5280217BA for ; Fri, 29 Nov 2019 14:48:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="rR8yXjXk" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C5280217BA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amlogic.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=30KtwjOKkaSDbazryYd/bZ4rFGfiq9OVkYOF+9JqT8A=; b=rR8yXjXkipPHeu QI5fLZKJpQM1sB6I5GZzf+e5X4ld+QlX0OLgG1/JW/x/msnOuYj2g1WxTp0krqYO/+AHNmqCWXP37 +eBkK+ON/yMwMHhcVirZpHzrIANZSsfUErs7h7dla1ky1A0YLqdZ4+yJvvA8PpZlP7cUerlEHqt38 hQ5y0iaC8jczgyOCCg3OQJ3YDWWaL3Db/YJ1kC56IJHSZk2RVRoIUuFyYVnYAQp0lLtgzPocXKneu GvWElmSz+iB4EKcDhhbQ8xaAuNSQMwbKchjOCvO302ySgMgTXKbfoga4kGpy7i28tChp7NnHb5HTJ aBqVP8lMoJYeJIiyA56w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahZF-0005WD-OS; Fri, 29 Nov 2019 14:48:21 +0000 Received: from mail-sz.amlogic.com ([211.162.65.117]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahYN-0004ND-CS; Fri, 29 Nov 2019 14:47:36 +0000 Received: from droid15-sz.amlogic.com (10.28.8.25) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.1591.10; Fri, 29 Nov 2019 22:47:48 +0800 From: Jian Hu To: Jerome Brunet , Neil Armstrong Subject: [PATCH v3 6/7] clk: meson: a1: add support for Amlogic A1 Peripheral clock driver Date: Fri, 29 Nov 2019 22:46:04 +0800 Message-ID: <20191129144605.182774-7-jian.hu@amlogic.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191129144605.182774-1-jian.hu@amlogic.com> References: <20191129144605.182774-1-jian.hu@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.28.8.25] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191129_064729_810547_A298AAFA X-CRM114-Status: GOOD ( 14.07 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Victor Wan , Jianxin Pan , Martin Blumenstingl , Kevin Hilman , Michael Turquette , linux-kernel@vger.kernel.org, Stephen Boyd , Jian Hu , linux-arm-kernel@lists.infradead.org, Qiufang Dai , linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, Chandle Zou Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add Amlogic Meson A1 peripheral clock driver, it depends on the A1 PLL driver. Signed-off-by: Jian Hu --- drivers/clk/meson/Kconfig | 10 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/a1.c | 2309 ++++++++++++++++++++++++++++++++++++ drivers/clk/meson/a1.h | 120 ++ 4 files changed, 2440 insertions(+) create mode 100644 drivers/clk/meson/a1.c create mode 100644 drivers/clk/meson/a1.h diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 14e7936ae18e..d6b2b51316b7 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -103,6 +103,16 @@ config COMMON_CLK_A1_PLL Support for the PLL clock controller on Amlogic A113L device, aka a1. Say Y if you want PLL to work. +config COMMON_CLK_A1 + bool + depends on ARCH_MESON + select COMMON_CLK_MESON_EE_CLKC + select COMMON_CLK_MESON_DUALDIV + select COMMON_CLK_MESON_REGMAP + help + Support for the Peripheral clock controller on Amlogic A113L device, + aka a1. Say Y if you want Peripherals to work. + config COMMON_CLK_G12A bool depends on ARCH_MESON diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 71d3b8e6fb8a..0f3890030118 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o 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) += a1.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c new file mode 100644 index 000000000000..184f244bed06 --- /dev/null +++ b/drivers/clk/meson/a1.c @@ -0,0 +1,2309 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + */ + +#include +#include +#include +#include "a1.h" +#include "clk-dualdiv.h" +#include "meson-eeclk.h" + +/* PLLs clock in gates, its parent is xtal */ +static struct clk_regmap a1_xtal_clktree = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_OSCIN_CTRL, + .bit_idx = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal_clktree", + .ops = &clk_regmap_gate_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_xtal_fixpll = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_OSCIN_CTRL, + .bit_idx = 1, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal_fixpll", + .ops = &clk_regmap_gate_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_xtal_usb_phy = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_OSCIN_CTRL, + .bit_idx = 2, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal_usb_phy", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_xtal_usb_ctrl = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_OSCIN_CTRL, + .bit_idx = 3, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal_usb_ctrl", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_xtal_hifipll = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_OSCIN_CTRL, + .bit_idx = 4, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal_hifipll", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_xtal_syspll = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_OSCIN_CTRL, + .bit_idx = 5, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal_syspll", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_xtal_dds = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_OSCIN_CTRL, + .bit_idx = 6, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal_dds", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static const struct clk_parent_data sys_clk_parents[] = { + { .fw_name = "xtal" }, + { .fw_name = "fclk_div2"}, + { .fw_name = "fclk_div3"}, + { .fw_name = "fclk_div5"}, +}; + +static struct clk_regmap a1_sys_b_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = SYS_CLK_CTRL0, + .mask = 0x7, + .shift = 26, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_b_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = sys_clk_parents, + .num_parents = ARRAY_SIZE(sys_clk_parents), + }, +}; + +static struct clk_regmap a1_sys_b_div = { + .data = &(struct clk_regmap_div_data){ + .offset = SYS_CLK_CTRL0, + .shift = 16, + .width = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_b_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_sys_b_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_sys_b = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_CLK_CTRL0, + .bit_idx = 29, + }, + .hw.init = &(struct clk_init_data) { + .name = "sys_b", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_sys_b_div.hw + }, + .num_parents = 1, + /* + * This clock is used by APB bus which setted in Romcode + * and is required by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + }, +}; + +static struct clk_regmap a1_sys_a_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = SYS_CLK_CTRL0, + .mask = 0x7, + .shift = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_a_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = sys_clk_parents, + .num_parents = ARRAY_SIZE(sys_clk_parents), + }, +}; + +static struct clk_regmap a1_sys_a_div = { + .data = &(struct clk_regmap_div_data){ + .offset = SYS_CLK_CTRL0, + .shift = 0, + .width = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_a_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_sys_a_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_sys_a = { + .data = &(struct clk_regmap_gate_data){ + .offset = SYS_CLK_CTRL0, + .bit_idx = 13, + }, + .hw.init = &(struct clk_init_data) { + .name = "sys_a", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_sys_a_div.hw + }, + .num_parents = 1, + /* + * This clock is used by APB bus which setted in Romcode + * and is required by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + }, +}; + +static struct clk_regmap a1_sys_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = SYS_CLK_CTRL0, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_clk", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_sys_a.hw, &a1_sys_b.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* rtc 32k clock in */ +static struct clk_regmap a1_rtc_32k_clkin = { + .data = &(struct clk_regmap_gate_data){ + .offset = RTC_BY_OSCIN_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_32k_clkin", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static const struct meson_clk_dualdiv_param a1_32k_div_table[] = { + { + .dual = 1, + .n1 = 733, + .m1 = 8, + .n2 = 732, + .m2 = 11, + }, {} +}; + +static struct clk_regmap a1_rtc_32k_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = RTC_BY_OSCIN_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = RTC_BY_OSCIN_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 28, + .width = 1, + }, + .table = a1_32k_div_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_32k_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_rtc_32k_clkin.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_rtc_32k_xtal = { + .data = &(struct clk_regmap_gate_data){ + .offset = RTC_BY_OSCIN_CTRL1, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_32k_xtal", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_rtc_32k_clkin.hw + }, + .num_parents = 1, + }, +}; + +static u32 rtc_32k_sel[] = { 0, 1 }; + +static struct clk_regmap a1_rtc_32k_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = RTC_CTRL, + .mask = 0x3, + .shift = 0, + .table = rtc_32k_sel, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_32k_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_rtc_32k_xtal.hw, + &a1_rtc_32k_div.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +struct clk_regmap a1_rtc_clk = { + .data = &(struct clk_regmap_gate_data){ + .offset = RTC_BY_OSCIN_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_clk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_rtc_32k_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* dsp a clk */ +static u32 mux_table_dsp_ab[] = { 0, 1, 2, 3, 4, 7 }; +static const struct clk_parent_data dsp_ab_clk_parent_data[] = { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div2", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "hifi_pll", }, + { .hw = &a1_rtc_clk.hw }, +}; + +static struct clk_regmap a1_dspa_a_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPA_CLK_CTRL0, + .mask = 0x7, + .shift = 10, + .table = mux_table_dsp_ab, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspa_a_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = dsp_ab_clk_parent_data, + .num_parents = ARRAY_SIZE(dsp_ab_clk_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspa_a_div = { + .data = &(struct clk_regmap_div_data){ + .offset = DSPA_CLK_CTRL0, + .shift = 0, + .width = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspa_a_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspa_a_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspa_a = { + .data = &(struct clk_regmap_gate_data){ + .offset = DSPA_CLK_CTRL0, + .bit_idx = 13, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_a", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspa_a_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspa_b_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPA_CLK_CTRL0, + .mask = 0x7, + .shift = 26, + .table = mux_table_dsp_ab, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspa_b_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = dsp_ab_clk_parent_data, + .num_parents = ARRAY_SIZE(dsp_ab_clk_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspa_b_div = { + .data = &(struct clk_regmap_div_data){ + .offset = DSPA_CLK_CTRL0, + .shift = 16, + .width = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspa_b_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspa_b_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspa_b = { + .data = &(struct clk_regmap_gate_data){ + .offset = DSPA_CLK_CTRL0, + .bit_idx = 29, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_b", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspa_b_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspa_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPA_CLK_CTRL0, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspa_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a1_dspa_a.hw }, + { .hw = &a1_dspa_b.hw }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspa_en_dspa = { + .data = &(struct clk_regmap_gate_data){ + .offset = DSPA_CLK_EN, + .bit_idx = 1, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_en_dspa", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspa_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspa_en_nic = { + .data = &(struct clk_regmap_gate_data){ + .offset = DSPA_CLK_EN, + .bit_idx = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspa_en_nic", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspa_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* dsp b clk */ +static struct clk_regmap a1_dspb_a_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPB_CLK_CTRL0, + .mask = 0x7, + .shift = 10, + .table = mux_table_dsp_ab, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspb_a_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = dsp_ab_clk_parent_data, + .num_parents = ARRAY_SIZE(dsp_ab_clk_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspb_a_div = { + .data = &(struct clk_regmap_div_data){ + .offset = DSPB_CLK_CTRL0, + .shift = 0, + .width = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspb_a_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspb_a_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspb_a = { + .data = &(struct clk_regmap_gate_data){ + .offset = DSPB_CLK_CTRL0, + .bit_idx = 13, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspb_a", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspb_a_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap a1_dspb_b_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPB_CLK_CTRL0, + .mask = 0x7, + .shift = 26, + .table = mux_table_dsp_ab, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspb_b_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = dsp_ab_clk_parent_data, + .num_parents = ARRAY_SIZE(dsp_ab_clk_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspb_b_div = { + .data = &(struct clk_regmap_div_data){ + .offset = DSPB_CLK_CTRL0, + .shift = 16, + .width = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspb_b_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspb_b_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspb_b = { + .data = &(struct clk_regmap_gate_data){ + .offset = DSPB_CLK_CTRL0, + .bit_idx = 29, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspb_b", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspb_b_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap a1_dspb_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPB_CLK_CTRL0, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspb_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspb_a.hw, &a1_dspb_b.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dspb_en_dspb = { + .data = &(struct clk_regmap_gate_data){ + .offset = DSPB_CLK_EN, + .bit_idx = 1, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspb_en_dspb", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspb_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap a1_dspb_en_nic = { + .data = &(struct clk_regmap_gate_data){ + .offset = DSPB_CLK_EN, + .bit_idx = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "dspb_en_nic", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dspb_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +/* 12M/24M clock */ +static struct clk_regmap a1_24m = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "24m", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor a1_24m_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "24m_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_24m.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_12m = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "12m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_24m_div2.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_fclk_div2_divn_pre = { + .data = &(struct clk_regmap_div_data){ + .offset = CLK12_24_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2_divn_pre", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fclk_div2", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_fclk_div2_divn = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 12, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2_divn", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_fclk_div2_divn_pre.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* gen clk */ +/* + * the second parent is sys_pll_div16, it will complete in the CPU clock, + * the forth parent is the clock measurement source, it relies on + * the clock measurement register configuration. + */ +static u32 gen_clk_table[] = { 0, 1, 3, 5, 6, 7, 8 }; +static const struct clk_parent_data gen_clk_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &a1_rtc_clk.hw }, + { .fw_name = "hifi_pll", }, + { .fw_name = "fclk_div2", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, +}; + +static struct clk_regmap a1_gen_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = GEN_CLK_CTRL, + .mask = 0xf, + .shift = 12, + .table = gen_clk_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "gen_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = gen_clk_parent_data, + .num_parents = ARRAY_SIZE(gen_clk_parent_data), + }, +}; + +static struct clk_regmap a1_gen_div = { + .data = &(struct clk_regmap_div_data){ + .offset = 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 *[]) { + &a1_gen_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_gen = { + .data = &(struct clk_regmap_gate_data){ + .offset = 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 *[]) { + &a1_gen_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_saradc_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = SAR_ADC_CLK_CTRL, + .mask = 0x1, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "saradc_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &a1_sys_clk.hw, }, + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap a1_saradc_div = { + .data = &(struct clk_regmap_div_data){ + .offset = SAR_ADC_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "saradc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_saradc_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_saradc_clk = { + .data = &(struct clk_regmap_gate_data){ + .offset = SAR_ADC_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "saradc_clk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_saradc_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* pwm a clk */ +static struct clk_regmap a1_pwm_a_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = PWM_CLK_AB_CTRL, + .mask = 0x1, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_a_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &a1_sys_clk.hw, }, + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap a1_pwm_a_div = { + .data = &(struct clk_regmap_div_data){ + .offset = PWM_CLK_AB_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_a_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_a_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_pwm_a = { + .data = &(struct clk_regmap_gate_data){ + .offset = PWM_CLK_AB_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "pwm_a", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_a_div.hw + }, + .num_parents = 1, + /* + * The CPU working voltage is controlled by pwm_a + * in BL2 firmware. add the CLK_IGNORE_UNUSED flag + * to avoid changing at runtime. + * and is required by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + }, +}; + +/* pwm b clk */ +static struct clk_regmap a1_pwm_b_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = PWM_CLK_AB_CTRL, + .mask = 0x1, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_b_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &a1_sys_clk.hw, }, + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap a1_pwm_b_div = { + .data = &(struct clk_regmap_div_data){ + .offset = PWM_CLK_AB_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_b_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_b_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_pwm_b = { + .data = &(struct clk_regmap_gate_data){ + .offset = PWM_CLK_AB_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "pwm_b", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_b_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* pwm c clk */ +static struct clk_regmap a1_pwm_c_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = PWM_CLK_CD_CTRL, + .mask = 0x1, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_c_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &a1_sys_clk.hw, }, + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap a1_pwm_c_div = { + .data = &(struct clk_regmap_div_data){ + .offset = PWM_CLK_CD_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_c_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_c_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_pwm_c = { + .data = &(struct clk_regmap_gate_data){ + .offset = PWM_CLK_CD_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "pwm_c", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_c_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* pwm d clk */ +static struct clk_regmap a1_pwm_d_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = PWM_CLK_CD_CTRL, + .mask = 0x1, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_d_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &a1_sys_clk.hw, }, + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap a1_pwm_d_div = { + .data = &(struct clk_regmap_div_data){ + .offset = PWM_CLK_CD_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_d_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_d_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_pwm_d = { + .data = &(struct clk_regmap_gate_data){ + .offset = PWM_CLK_CD_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "pwm_d", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_d_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data pwm_ef_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &a1_sys_clk.hw }, + { .fw_name = "fclk_div5", }, + { .hw = &a1_rtc_clk.hw }, +}; + +/* pwm e clk */ +static struct clk_regmap a1_pwm_e_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = PWM_CLK_EF_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_e_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = pwm_ef_parent_data, + .num_parents = ARRAY_SIZE(pwm_ef_parent_data), + }, +}; + +static struct clk_regmap a1_pwm_e_div = { + .data = &(struct clk_regmap_div_data){ + .offset = PWM_CLK_EF_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_e_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_e_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_pwm_e = { + .data = &(struct clk_regmap_gate_data){ + .offset = PWM_CLK_EF_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "pwm_e", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_e_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* pwm f clk */ +static struct clk_regmap a1_pwm_f_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = PWM_CLK_EF_CTRL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_f_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = pwm_ef_parent_data, + .num_parents = ARRAY_SIZE(pwm_ef_parent_data), + }, +}; + +static struct clk_regmap a1_pwm_f_div = { + .data = &(struct clk_regmap_div_data){ + .offset = PWM_CLK_EF_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_f_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_f_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_pwm_f = { + .data = &(struct clk_regmap_gate_data){ + .offset = PWM_CLK_EF_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "pwm_f", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_pwm_f_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* spicc clk */ + +/* div2 |\ |\ _____ + * ---------| |---DIV--| | | | spicc out + * ---------| | | |-----|GATE |--------- + * ..... |/ | / |_____| + * --------------------|/ + * 24M + */ +static const struct clk_parent_data spicc_parents[] = { + { .fw_name = "fclk_div2"}, + { .fw_name = "fclk_div3"}, + { .fw_name = "fclk_div5"}, + { .fw_name = "hifi_pll" }, +}; + +static struct clk_regmap a1_spicc_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = SPICC_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = spicc_parents, + .num_parents = 4, + }, +}; + +static struct clk_regmap a1_spicc_div = { + .data = &(struct clk_regmap_div_data){ + .offset = SPICC_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_spicc_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_spicc_sel2 = { + .data = &(struct clk_regmap_mux_data){ + .offset = SPICC_CLK_CTRL, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc_sel2", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a1_spicc_div.hw }, + { .fw_name = "xtal", }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_spicc = { + .data = &(struct clk_regmap_gate_data){ + .offset = SPICC_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_spicc_sel2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* ts clk */ +static struct clk_regmap a1_ts_div = { + .data = &(struct clk_regmap_div_data){ + .offset = 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 = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_ts = { + .data = &(struct clk_regmap_gate_data){ + .offset = 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 *[]) { + &a1_ts_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* spifc clk */ +static struct clk_regmap a1_spifc_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = SPIFC_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "spifc_sel", + .ops = &clk_regmap_mux_ops, + /* the same parent with spicc */ + .parent_data = spicc_parents, + .num_parents = 4, + }, +}; + +static struct clk_regmap a1_spifc_div = { + .data = &(struct clk_regmap_div_data){ + .offset = SPIFC_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "spifc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_spifc_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_spifc_sel2 = { + .data = &(struct clk_regmap_mux_data){ + .offset = SPIFC_CLK_CTRL, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "spifc_sel2", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a1_spifc_div.hw }, + { .fw_name = "xtal", }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_spifc = { + .data = &(struct clk_regmap_gate_data){ + .offset = SPIFC_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "spifc", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_spifc_sel2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* usb bus clk */ +static const struct clk_parent_data usb_bus_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &a1_sys_clk.hw }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, +}; + +static struct clk_regmap a1_usb_bus_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = USB_BUSCLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "usb_bus_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = usb_bus_parent_data, + .num_parents = ARRAY_SIZE(usb_bus_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_usb_bus_div = { + .data = &(struct clk_regmap_div_data){ + .offset = USB_BUSCLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "usb_bus_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_usb_bus_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_usb_bus = { + .data = &(struct clk_regmap_gate_data){ + .offset = USB_BUSCLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "usb_bus", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_usb_bus_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* sd emmc clk */ +static const struct clk_parent_data sd_emmc_parents[] = { + { .fw_name = "fclk_div2", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "hifi_pll", }, +}; + +static struct clk_regmap a1_sd_emmc_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = SD_EMMC_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = sd_emmc_parents, + .num_parents = 4, + }, +}; + +static struct clk_regmap a1_sd_emmc_div = { + .data = &(struct clk_regmap_div_data){ + .offset = SD_EMMC_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_sd_emmc_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_sd_emmc_sel2 = { + .data = &(struct clk_regmap_mux_data){ + .offset = SD_EMMC_CLK_CTRL, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_sel2", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a1_sd_emmc_div.hw }, + { .fw_name = "xtal", }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_sd_emmc = { + .data = &(struct clk_regmap_gate_data){ + .offset = SD_EMMC_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_sd_emmc_sel2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_psram_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = PSRAM_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "psram_sel", + .ops = &clk_regmap_mux_ops, + /* the same parent with sd_emmc */ + .parent_data = sd_emmc_parents, + .num_parents = 4, + }, +}; + +static struct clk_regmap a1_psram_div = { + .data = &(struct clk_regmap_div_data){ + .offset = PSRAM_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "psram_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_psram_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_psram_sel2 = { + .data = &(struct clk_regmap_mux_data){ + .offset = PSRAM_CLK_CTRL, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "psram_sel2", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a1_psram_div.hw }, + { .fw_name = "xtal", }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_psram = { + .data = &(struct clk_regmap_gate_data){ + .offset = PSRAM_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "psram", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_psram_sel2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* dmc clk */ +static struct clk_regmap a1_dmc_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = DMC_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "dmc_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = sd_emmc_parents, + .num_parents = 4, + }, +}; + +static struct clk_regmap a1_dmc_div = { + .data = &(struct clk_regmap_div_data){ + .offset = DMC_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "dmc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dmc_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dmc_sel2 = { + .data = &(struct clk_regmap_mux_data){ + .offset = DMC_CLK_CTRL, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "dmc_sel2", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a1_dmc_div.hw }, + { .fw_name = "xtal", }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_dmc = { + .data = &(struct clk_regmap_gate_data){ + .offset = DMC_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "dmc", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_dmc_sel2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* cec A clock */ +static struct clk_regmap a1_ceca_32k_clkin = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECA_CLK_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "ceca_32k_clkin", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_ceca_32k_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CECA_CLK_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CECA_CLK_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CECA_CLK_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CECA_CLK_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CECA_CLK_CTRL0, + .shift = 28, + .width = 1, + }, + .table = a1_32k_div_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_32k_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_ceca_32k_clkin.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_ceca_32k_sel_pre = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECA_CLK_CTRL1, + .mask = 0x1, + .shift = 24, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_32k_sel_pre", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_ceca_32k_div.hw, + &a1_ceca_32k_clkin.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_ceca_32k_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECA_CLK_CTRL1, + .mask = 0x1, + .shift = 31, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_32k_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_ceca_32k_sel_pre.hw, + &a1_rtc_clk.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_ceca_32k_clkout = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECA_CLK_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_32k_clkout", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_ceca_32k_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* cec B clock */ +static struct clk_regmap a1_cecb_32k_clkin = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECB_CLK_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "cecb_32k_clkin", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_cecb_32k_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CECB_CLK_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CECB_CLK_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CECB_CLK_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CECB_CLK_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CECB_CLK_CTRL0, + .shift = 28, + .width = 1, + }, + .table = a1_32k_div_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_32k_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_cecb_32k_clkin.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a1_cecb_32k_sel_pre = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECB_CLK_CTRL1, + .mask = 0x1, + .shift = 24, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_32k_sel_pre", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_cecb_32k_div.hw, + &a1_cecb_32k_clkin.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_cecb_32k_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECB_CLK_CTRL1, + .mask = 0x1, + .shift = 31, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_32k_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_cecb_32k_sel_pre.hw, + &a1_rtc_clk.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a1_cecb_32k_clkout = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECB_CLK_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_32k_clkout", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a1_cecb_32k_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &a1_sys_clk.hw) + +static MESON_GATE(a1_clk_tree, SYS_CLK_EN0, 0); +static MESON_GATE(a1_reset_ctrl, SYS_CLK_EN0, 1); +static MESON_GATE(a1_analog_ctrl, SYS_CLK_EN0, 2); +static MESON_GATE(a1_pwr_ctrl, SYS_CLK_EN0, 3); +static MESON_GATE(a1_pad_ctrl, SYS_CLK_EN0, 4); +static MESON_GATE(a1_sys_ctrl, SYS_CLK_EN0, 5); +static MESON_GATE(a1_temp_sensor, SYS_CLK_EN0, 6); +static MESON_GATE(a1_am2axi_dev, SYS_CLK_EN0, 7); +static MESON_GATE(a1_spicc_b, SYS_CLK_EN0, 8); +static MESON_GATE(a1_spicc_a, SYS_CLK_EN0, 9); +static MESON_GATE(a1_clk_msr, SYS_CLK_EN0, 10); +static MESON_GATE(a1_audio, SYS_CLK_EN0, 11); +static MESON_GATE(a1_jtag_ctrl, SYS_CLK_EN0, 12); +static MESON_GATE(a1_saradc, SYS_CLK_EN0, 13); +static MESON_GATE(a1_pwm_ef, SYS_CLK_EN0, 14); +static MESON_GATE(a1_pwm_cd, SYS_CLK_EN0, 15); +static MESON_GATE(a1_pwm_ab, SYS_CLK_EN0, 16); +static MESON_GATE(a1_cec, SYS_CLK_EN0, 17); +static MESON_GATE(a1_i2c_s, SYS_CLK_EN0, 18); +static MESON_GATE(a1_ir_ctrl, SYS_CLK_EN0, 19); +static MESON_GATE(a1_i2c_m_d, SYS_CLK_EN0, 20); +static MESON_GATE(a1_i2c_m_c, SYS_CLK_EN0, 21); +static MESON_GATE(a1_i2c_m_b, SYS_CLK_EN0, 22); +static MESON_GATE(a1_i2c_m_a, SYS_CLK_EN0, 23); +static MESON_GATE(a1_acodec, SYS_CLK_EN0, 24); +static MESON_GATE(a1_otp, SYS_CLK_EN0, 25); +static MESON_GATE(a1_sd_emmc_a, SYS_CLK_EN0, 26); +static MESON_GATE(a1_usb_phy, SYS_CLK_EN0, 27); +static MESON_GATE(a1_usb_ctrl, SYS_CLK_EN0, 28); +static MESON_GATE(a1_sys_dspb, SYS_CLK_EN0, 29); +static MESON_GATE(a1_sys_dspa, SYS_CLK_EN0, 30); +static MESON_GATE(a1_dma, SYS_CLK_EN0, 31); +static MESON_GATE(a1_irq_ctrl, SYS_CLK_EN1, 0); +static MESON_GATE(a1_nic, SYS_CLK_EN1, 1); +static MESON_GATE(a1_gic, SYS_CLK_EN1, 2); +static MESON_GATE(a1_uart_c, SYS_CLK_EN1, 3); +static MESON_GATE(a1_uart_b, SYS_CLK_EN1, 4); +static MESON_GATE(a1_uart_a, SYS_CLK_EN1, 5); +static MESON_GATE(a1_sys_psram, SYS_CLK_EN1, 6); +static MESON_GATE(a1_rsa, SYS_CLK_EN1, 8); +static MESON_GATE(a1_coresight, SYS_CLK_EN1, 9); +static MESON_GATE(a1_am2axi_vad, AXI_CLK_EN, 0); +static MESON_GATE(a1_audio_vad, AXI_CLK_EN, 1); +static MESON_GATE(a1_axi_dmc, AXI_CLK_EN, 3); +static MESON_GATE(a1_axi_psram, AXI_CLK_EN, 4); +static MESON_GATE(a1_ramb, AXI_CLK_EN, 5); +static MESON_GATE(a1_rama, AXI_CLK_EN, 6); +static MESON_GATE(a1_axi_spifc, AXI_CLK_EN, 7); +static MESON_GATE(a1_axi_nic, AXI_CLK_EN, 8); +static MESON_GATE(a1_axi_dma, AXI_CLK_EN, 9); +static MESON_GATE(a1_cpu_ctrl, AXI_CLK_EN, 10); +static MESON_GATE(a1_rom, AXI_CLK_EN, 11); +static MESON_GATE(a1_prod_i2c, AXI_CLK_EN, 12); + +/* Array of all clocks provided by this provider */ +static struct clk_hw_onecell_data a1_periphs_hw_onecell_data = { + .hws = { + [CLKID_SYS_B_SEL] = &a1_sys_b_sel.hw, + [CLKID_SYS_B_DIV] = &a1_sys_b_div.hw, + [CLKID_SYS_B] = &a1_sys_b.hw, + [CLKID_SYS_A_SEL] = &a1_sys_a_sel.hw, + [CLKID_SYS_A_DIV] = &a1_sys_a_div.hw, + [CLKID_SYS_A] = &a1_sys_a.hw, + [CLKID_SYS_CLK] = &a1_sys_clk.hw, + [CLKID_XTAL_CLKTREE] = &a1_xtal_clktree.hw, + [CLKID_XTAL_FIXPLL] = &a1_xtal_fixpll.hw, + [CLKID_XTAL_USB_PHY] = &a1_xtal_usb_phy.hw, + [CLKID_XTAL_USB_CTRL] = &a1_xtal_usb_ctrl.hw, + [CLKID_XTAL_HIFIPLL] = &a1_xtal_hifipll.hw, + [CLKID_XTAL_SYSPLL] = &a1_xtal_syspll.hw, + [CLKID_XTAL_DDS] = &a1_xtal_dds.hw, + [CLKID_CLKTREE] = &a1_clk_tree.hw, + [CLKID_RESET_CTRL] = &a1_reset_ctrl.hw, + [CLKID_ANALOG_CTRL] = &a1_analog_ctrl.hw, + [CLKID_PWR_CTRL] = &a1_pwr_ctrl.hw, + [CLKID_PAD_CTRL] = &a1_pad_ctrl.hw, + [CLKID_SYS_CTRL] = &a1_sys_ctrl.hw, + [CLKID_TEMP_SENSOR] = &a1_temp_sensor.hw, + [CLKID_AM2AXI_DIV] = &a1_am2axi_dev.hw, + [CLKID_SPICC_B] = &a1_spicc_b.hw, + [CLKID_SPICC_A] = &a1_spicc_a.hw, + [CLKID_CLK_MSR] = &a1_clk_msr.hw, + [CLKID_AUDIO] = &a1_audio.hw, + [CLKID_JTAG_CTRL] = &a1_jtag_ctrl.hw, + [CLKID_SARADC] = &a1_saradc.hw, + [CLKID_PWM_EF] = &a1_pwm_ef.hw, + [CLKID_PWM_CD] = &a1_pwm_cd.hw, + [CLKID_PWM_AB] = &a1_pwm_ab.hw, + [CLKID_CEC] = &a1_cec.hw, + [CLKID_I2C_S] = &a1_i2c_s.hw, + [CLKID_IR_CTRL] = &a1_ir_ctrl.hw, + [CLKID_I2C_M_D] = &a1_i2c_m_d.hw, + [CLKID_I2C_M_C] = &a1_i2c_m_c.hw, + [CLKID_I2C_M_B] = &a1_i2c_m_b.hw, + [CLKID_I2C_M_A] = &a1_i2c_m_a.hw, + [CLKID_ACODEC] = &a1_acodec.hw, + [CLKID_OTP] = &a1_otp.hw, + [CLKID_SD_EMMC_A] = &a1_sd_emmc_a.hw, + [CLKID_USB_PHY] = &a1_usb_phy.hw, + [CLKID_USB_CTRL] = &a1_usb_ctrl.hw, + [CLKID_SYS_DSPB] = &a1_sys_dspb.hw, + [CLKID_SYS_DSPA] = &a1_sys_dspa.hw, + [CLKID_DMA] = &a1_dma.hw, + [CLKID_IRQ_CTRL] = &a1_irq_ctrl.hw, + [CLKID_NIC] = &a1_nic.hw, + [CLKID_GIC] = &a1_gic.hw, + [CLKID_UART_C] = &a1_uart_c.hw, + [CLKID_UART_B] = &a1_uart_b.hw, + [CLKID_UART_A] = &a1_uart_a.hw, + [CLKID_SYS_PSRAM] = &a1_sys_psram.hw, + [CLKID_RSA] = &a1_rsa.hw, + [CLKID_CORESIGHT] = &a1_coresight.hw, + [CLKID_AM2AXI_VAD] = &a1_am2axi_vad.hw, + [CLKID_AUDIO_VAD] = &a1_audio_vad.hw, + [CLKID_AXI_DMC] = &a1_axi_dmc.hw, + [CLKID_AXI_PSRAM] = &a1_axi_psram.hw, + [CLKID_RAMB] = &a1_ramb.hw, + [CLKID_RAMA] = &a1_rama.hw, + [CLKID_AXI_SPIFC] = &a1_axi_spifc.hw, + [CLKID_AXI_NIC] = &a1_axi_nic.hw, + [CLKID_AXI_DMA] = &a1_axi_dma.hw, + [CLKID_CPU_CTRL] = &a1_cpu_ctrl.hw, + [CLKID_ROM] = &a1_rom.hw, + [CLKID_PROC_I2C] = &a1_prod_i2c.hw, + [CLKID_DSPA_A_SEL] = &a1_dspa_a_sel.hw, + [CLKID_DSPA_A_DIV] = &a1_dspa_a_div.hw, + [CLKID_DSPA_A] = &a1_dspa_a.hw, + [CLKID_DSPA_B_SEL] = &a1_dspa_b_sel.hw, + [CLKID_DSPA_B_DIV] = &a1_dspa_b_div.hw, + [CLKID_DSPA_B] = &a1_dspa_b.hw, + [CLKID_DSPA_SEL] = &a1_dspa_sel.hw, + [CLKID_DSPB_A_SEL] = &a1_dspb_a_sel.hw, + [CLKID_DSPB_A_DIV] = &a1_dspb_a_div.hw, + [CLKID_DSPB_A] = &a1_dspb_a.hw, + [CLKID_DSPB_B_SEL] = &a1_dspb_b_sel.hw, + [CLKID_DSPB_B_DIV] = &a1_dspb_b_div.hw, + [CLKID_DSPB_B] = &a1_dspb_b.hw, + [CLKID_DSPB_SEL] = &a1_dspb_sel.hw, + [CLKID_DSPA_EN_DSPA] = &a1_dspa_en_dspa.hw, + [CLKID_DSPA_EN_NIC] = &a1_dspa_en_nic.hw, + [CLKID_DSPB_EN_DSPB] = &a1_dspb_en_dspb.hw, + [CLKID_DSPB_EN_NIC] = &a1_dspb_en_nic.hw, + [CLKID_24M] = &a1_24m.hw, + [CLKID_24M_DIV2] = &a1_24m_div2.hw, + [CLKID_12M] = &a1_12m.hw, + [CLKID_DIV2_PRE] = &a1_fclk_div2_divn_pre.hw, + [CLKID_FCLK_DIV2_DIVN] = &a1_fclk_div2_divn.hw, + [CLKID_GEN_SEL] = &a1_gen_sel.hw, + [CLKID_GEN_DIV] = &a1_gen_div.hw, + [CLKID_GEN] = &a1_gen.hw, + [CLKID_SARADC_SEL] = &a1_saradc_sel.hw, + [CLKID_SARADC_DIV] = &a1_saradc_div.hw, + [CLKID_SARADC_CLK] = &a1_saradc_clk.hw, + [CLKID_PWM_A_SEL] = &a1_pwm_a_sel.hw, + [CLKID_PWM_A_DIV] = &a1_pwm_a_div.hw, + [CLKID_PWM_A] = &a1_pwm_a.hw, + [CLKID_PWM_B_SEL] = &a1_pwm_b_sel.hw, + [CLKID_PWM_B_DIV] = &a1_pwm_b_div.hw, + [CLKID_PWM_B] = &a1_pwm_b.hw, + [CLKID_PWM_C_SEL] = &a1_pwm_c_sel.hw, + [CLKID_PWM_C_DIV] = &a1_pwm_c_div.hw, + [CLKID_PWM_C] = &a1_pwm_c.hw, + [CLKID_PWM_D_SEL] = &a1_pwm_d_sel.hw, + [CLKID_PWM_D_DIV] = &a1_pwm_d_div.hw, + [CLKID_PWM_D] = &a1_pwm_d.hw, + [CLKID_PWM_E_SEL] = &a1_pwm_e_sel.hw, + [CLKID_PWM_E_DIV] = &a1_pwm_e_div.hw, + [CLKID_PWM_E] = &a1_pwm_e.hw, + [CLKID_PWM_F_SEL] = &a1_pwm_f_sel.hw, + [CLKID_PWM_F_DIV] = &a1_pwm_f_div.hw, + [CLKID_PWM_F] = &a1_pwm_f.hw, + [CLKID_SPICC_SEL] = &a1_spicc_sel.hw, + [CLKID_SPICC_DIV] = &a1_spicc_div.hw, + [CLKID_SPICC_SEL2] = &a1_spicc_sel2.hw, + [CLKID_SPICC] = &a1_spicc.hw, + [CLKID_TS_DIV] = &a1_ts_div.hw, + [CLKID_TS] = &a1_ts.hw, + [CLKID_SPIFC_SEL] = &a1_spifc_sel.hw, + [CLKID_SPIFC_DIV] = &a1_spifc_div.hw, + [CLKID_SPIFC_SEL2] = &a1_spifc_sel2.hw, + [CLKID_SPIFC] = &a1_spifc.hw, + [CLKID_USB_BUS_SEL] = &a1_usb_bus_sel.hw, + [CLKID_USB_BUS_DIV] = &a1_usb_bus_div.hw, + [CLKID_USB_BUS] = &a1_usb_bus.hw, + [CLKID_SD_EMMC_SEL] = &a1_sd_emmc_sel.hw, + [CLKID_SD_EMMC_DIV] = &a1_sd_emmc_div.hw, + [CLKID_SD_EMMC_SEL2] = &a1_sd_emmc_sel2.hw, + [CLKID_SD_EMMC] = &a1_sd_emmc.hw, + [CLKID_PSRAM_SEL] = &a1_psram_sel.hw, + [CLKID_PSRAM_DIV] = &a1_psram_div.hw, + [CLKID_PSRAM_SEL2] = &a1_psram_sel2.hw, + [CLKID_PSRAM] = &a1_psram.hw, + [CLKID_DMC_SEL] = &a1_dmc_sel.hw, + [CLKID_DMC_DIV] = &a1_dmc_div.hw, + [CLKID_DMC_SEL2] = &a1_dmc_sel2.hw, + [CLKID_DMC] = &a1_dmc.hw, + [CLKID_RTC_32K_CLKIN] = &a1_rtc_32k_clkin.hw, + [CLKID_RTC_32K_DIV] = &a1_rtc_32k_div.hw, + [CLKID_RTC_32K_XTAL] = &a1_rtc_32k_xtal.hw, + [CLKID_RTC_32K_SEL] = &a1_rtc_32k_sel.hw, + [CLKID_RTC_CLK] = &a1_rtc_clk.hw, + [CLKID_CECA_32K_CLKIN] = &a1_ceca_32k_clkin.hw, + [CLKID_CECA_32K_DIV] = &a1_ceca_32k_div.hw, + [CLKID_CECA_32K_SEL_PRE] = &a1_ceca_32k_sel_pre.hw, + [CLKID_CECA_32K_SEL] = &a1_ceca_32k_sel.hw, + [CLKID_CECA_32K] = &a1_ceca_32k_clkout.hw, + [CLKID_CECB_32K_CLKIN] = &a1_cecb_32k_clkin.hw, + [CLKID_CECB_32K_DIV] = &a1_cecb_32k_div.hw, + [CLKID_CECB_32K_SEL_PRE] = &a1_cecb_32k_sel_pre.hw, + [CLKID_CECB_32K_SEL] = &a1_cecb_32k_sel.hw, + [CLKID_CECB_32K] = &a1_cecb_32k_clkout.hw, + [NR_CLKS] = NULL, + }, + .num = NR_CLKS, +}; + +/* Convenience table to populate regmap in .probe */ +static struct clk_regmap *const a1_periphs_regmaps[] = { + &a1_xtal_clktree, + &a1_xtal_fixpll, + &a1_xtal_usb_phy, + &a1_xtal_usb_ctrl, + &a1_xtal_hifipll, + &a1_xtal_syspll, + &a1_xtal_dds, + &a1_clk_tree, + &a1_reset_ctrl, + &a1_analog_ctrl, + &a1_pwr_ctrl, + &a1_sys_ctrl, + &a1_temp_sensor, + &a1_am2axi_dev, + &a1_spicc_b, + &a1_spicc_a, + &a1_clk_msr, + &a1_audio, + &a1_jtag_ctrl, + &a1_saradc, + &a1_pwm_ef, + &a1_pwm_cd, + &a1_pwm_ab, + &a1_cec, + &a1_i2c_s, + &a1_ir_ctrl, + &a1_i2c_m_d, + &a1_i2c_m_c, + &a1_i2c_m_b, + &a1_i2c_m_a, + &a1_acodec, + &a1_otp, + &a1_sd_emmc_a, + &a1_usb_phy, + &a1_usb_ctrl, + &a1_sys_dspb, + &a1_sys_dspa, + &a1_dma, + &a1_irq_ctrl, + &a1_nic, + &a1_gic, + &a1_uart_c, + &a1_uart_b, + &a1_uart_a, + &a1_sys_psram, + &a1_rsa, + &a1_coresight, + &a1_am2axi_vad, + &a1_audio_vad, + &a1_axi_dmc, + &a1_axi_psram, + &a1_ramb, + &a1_rama, + &a1_axi_spifc, + &a1_axi_nic, + &a1_axi_dma, + &a1_cpu_ctrl, + &a1_rom, + &a1_prod_i2c, + &a1_dspa_a_sel, + &a1_dspa_a_div, + &a1_dspa_a, + &a1_dspa_b_sel, + &a1_dspa_b_div, + &a1_dspa_b, + &a1_dspa_sel, + &a1_dspb_a_sel, + &a1_dspb_a_div, + &a1_dspb_a, + &a1_dspb_b_sel, + &a1_dspb_b_div, + &a1_dspb_b, + &a1_dspb_sel, + &a1_dspa_en_dspa, + &a1_dspa_en_nic, + &a1_dspb_en_dspb, + &a1_dspb_en_nic, + &a1_24m, + &a1_12m, + &a1_fclk_div2_divn_pre, + &a1_fclk_div2_divn, + &a1_gen_sel, + &a1_gen_div, + &a1_gen, + &a1_saradc_sel, + &a1_saradc_div, + &a1_saradc_clk, + &a1_pwm_a_sel, + &a1_pwm_a_div, + &a1_pwm_a, + &a1_pwm_b_sel, + &a1_pwm_b_div, + &a1_pwm_b, + &a1_pwm_c_sel, + &a1_pwm_c_div, + &a1_pwm_c, + &a1_pwm_d_sel, + &a1_pwm_d_div, + &a1_pwm_d, + &a1_pwm_e_sel, + &a1_pwm_e_div, + &a1_pwm_e, + &a1_pwm_f_sel, + &a1_pwm_f_div, + &a1_pwm_f, + &a1_spicc_sel, + &a1_spicc_div, + &a1_spicc_sel2, + &a1_spicc, + &a1_ts_div, + &a1_ts, + &a1_spifc_sel, + &a1_spifc_div, + &a1_spifc_sel2, + &a1_spifc, + &a1_usb_bus_sel, + &a1_usb_bus_div, + &a1_usb_bus, + &a1_sd_emmc_sel, + &a1_sd_emmc_div, + &a1_sd_emmc_sel2, + &a1_sd_emmc, + &a1_psram_sel, + &a1_psram_div, + &a1_psram_sel2, + &a1_psram, + &a1_dmc_sel, + &a1_dmc_div, + &a1_dmc_sel2, + &a1_dmc, + &a1_sys_b_sel, + &a1_sys_b_div, + &a1_sys_b, + &a1_sys_a_sel, + &a1_sys_a_div, + &a1_sys_a, + &a1_sys_clk, + &a1_rtc_32k_clkin, + &a1_rtc_32k_div, + &a1_rtc_32k_xtal, + &a1_rtc_32k_sel, + &a1_rtc_clk, + &a1_ceca_32k_clkin, + &a1_ceca_32k_div, + &a1_ceca_32k_sel_pre, + &a1_ceca_32k_sel, + &a1_ceca_32k_clkout, + &a1_cecb_32k_clkin, + &a1_cecb_32k_div, + &a1_cecb_32k_sel_pre, + &a1_cecb_32k_sel, + &a1_cecb_32k_clkout, +}; + +static const struct meson_eeclkc_data a1_periphs_data = { + .regmap_clks = a1_periphs_regmaps, + .regmap_clk_num = ARRAY_SIZE(a1_periphs_regmaps), + .hw_onecell_data = &a1_periphs_hw_onecell_data, +}; +static const struct of_device_id clkc_match_table[] = { + { + .compatible = "amlogic,a1-periphs-clkc", + .data = &a1_periphs_data + }, + {} +}; + +static int a1_periphs_clkc_probe(struct platform_device *pdev) +{ + const struct meson_eeclkc_data *data; + struct device *dev = &pdev->dev; + int ret, i; + struct regmap *map; + struct clk_hw_onecell_data *hw_data; + + map = meson_regmap_resource(pdev); + if (IS_ERR(map)) + return PTR_ERR(map); + + data = of_device_get_match_data(dev); + if (!data) + return -EINVAL; + + hw_data = data->hw_onecell_data; + /* Populate regmap for the regmap backed clocks */ + for (i = 0; i < data->regmap_clk_num; i++) + data->regmap_clks[i]->map = map; + + for (i = 0; i < data->hw_onecell_data->num; i++) { + /* array might be sparse */ + if (!data->hw_onecell_data->hws[i]) + continue; + + /* + * To avoid fixed_pll and hifi_pll being orphan clock, + * skip registering their parent clock first, register + * them after the provider registration. + */ + if (i == CLKID_XTAL_FIXPLL || i == CLKID_XTAL_HIFIPLL) + continue; + + ret = devm_clk_hw_register(dev, data->hw_onecell_data->hws[i]); + if (ret) { + dev_err(dev, "Clock registration failed\n"); + return ret; + } + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + data->hw_onecell_data); + if (ret) { + dev_err(dev, "provider registration failed\n"); + return ret; + } + + ret = devm_clk_hw_register(dev, hw_data->hws[CLKID_XTAL_FIXPLL]); + if (ret) { + dev_err(dev, "xtal_fixpll clock registration failed\n"); + return ret; + } + + ret = devm_clk_hw_register(dev, hw_data->hws[CLKID_XTAL_HIFIPLL]); + if (ret) { + dev_err(dev, "xtal_hifipll clock registration failed\n"); + return ret; + } + + return 0; +} + +static struct platform_driver a1_periphs_driver = { + .probe = a1_periphs_clkc_probe, + .driver = { + .name = "a1-periphs-clkc", + .of_match_table = clkc_match_table, + }, +}; + +builtin_platform_driver(a1_periphs_driver); diff --git a/drivers/clk/meson/a1.h b/drivers/clk/meson/a1.h new file mode 100644 index 000000000000..1ae5e04848d6 --- /dev/null +++ b/drivers/clk/meson/a1.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ + +#ifndef __A1_H +#define __A1_H + +/* peripheral clock controller register offset */ +#define SYS_OSCIN_CTRL 0x0 +#define RTC_BY_OSCIN_CTRL0 0x4 +#define RTC_BY_OSCIN_CTRL1 0x8 +#define RTC_CTRL 0xc +#define SYS_CLK_CTRL0 0x10 +#define AXI_CLK_CTRL0 0x14 +#define SYS_CLK_EN0 0x1c +#define SYS_CLK_EN1 0x20 +#define AXI_CLK_EN 0x24 +#define DSPA_CLK_EN 0x28 +#define DSPB_CLK_EN 0x2c +#define DSPA_CLK_CTRL0 0x30 +#define DSPB_CLK_CTRL0 0x34 +#define CLK12_24_CTRL 0x38 +#define GEN_CLK_CTRL 0x3c +#define TIMESTAMP_CTRL0 0x40 +#define TIMESTAMP_CTRL1 0x44 +#define TIMESTAMP_CTRL2 0x48 +#define TIMESTAMP_VAL0 0x4c +#define TIMESTAMP_VAL1 0x50 +#define TIMEBASE_CTRL0 0x54 +#define TIMEBASE_CTRL1 0x58 +#define SAR_ADC_CLK_CTRL 0xc0 +#define PWM_CLK_AB_CTRL 0xc4 +#define PWM_CLK_CD_CTRL 0xc8 +#define PWM_CLK_EF_CTRL 0xcc +#define SPICC_CLK_CTRL 0xd0 +#define TS_CLK_CTRL 0xd4 +#define SPIFC_CLK_CTRL 0xd8 +#define USB_BUSCLK_CTRL 0xdc +#define SD_EMMC_CLK_CTRL 0xe0 +#define CECA_CLK_CTRL0 0xe4 +#define CECA_CLK_CTRL1 0xe8 +#define CECB_CLK_CTRL0 0xec +#define CECB_CLK_CTRL1 0xf0 +#define PSRAM_CLK_CTRL 0xf4 +#define DMC_CLK_CTRL 0xf8 +#define FCLK_DIV1_SEL 0xfc +#define TST_CTRL 0x100 + +#define CLKID_XTAL_CLKTREE 0 +#define CLKID_SYS_A_SEL 89 +#define CLKID_SYS_A_DIV 90 +#define CLKID_SYS_A 91 +#define CLKID_SYS_B_SEL 92 +#define CLKID_SYS_B_DIV 93 +#define CLKID_SYS_B 94 +#define CLKID_DSPA_A_SEL 95 +#define CLKID_DSPA_A_DIV 96 +#define CLKID_DSPA_A 97 +#define CLKID_DSPA_B_SEL 98 +#define CLKID_DSPA_B_DIV 99 +#define CLKID_DSPA_B 100 +#define CLKID_DSPB_A_SEL 101 +#define CLKID_DSPB_A_DIV 102 +#define CLKID_DSPB_A 103 +#define CLKID_DSPB_B_SEL 104 +#define CLKID_DSPB_B_DIV 105 +#define CLKID_DSPB_B 106 +#define CLKID_RTC_32K_CLKIN 107 +#define CLKID_RTC_32K_DIV 108 +#define CLKID_RTC_32K_XTAL 109 +#define CLKID_RTC_32K_SEL 110 +#define CLKID_CECB_32K_CLKIN 111 +#define CLKID_CECB_32K_DIV 112 +#define CLKID_CECB_32K_SEL_PRE 113 +#define CLKID_CECB_32K_SEL 114 +#define CLKID_CECA_32K_CLKIN 115 +#define CLKID_CECA_32K_DIV 116 +#define CLKID_CECA_32K_SEL_PRE 117 +#define CLKID_CECA_32K_SEL 118 +#define CLKID_DIV2_PRE 119 +#define CLKID_24M_DIV2 120 +#define CLKID_GEN_SEL 121 +#define CLKID_GEN_DIV 122 +#define CLKID_SARADC_DIV 123 +#define CLKID_PWM_A_SEL 124 +#define CLKID_PWM_A_DIV 125 +#define CLKID_PWM_B_SEL 126 +#define CLKID_PWM_B_DIV 127 +#define CLKID_PWM_C_SEL 128 +#define CLKID_PWM_C_DIV 129 +#define CLKID_PWM_D_SEL 130 +#define CLKID_PWM_D_DIV 131 +#define CLKID_PWM_E_SEL 132 +#define CLKID_PWM_E_DIV 133 +#define CLKID_PWM_F_SEL 134 +#define CLKID_PWM_F_DIV 135 +#define CLKID_SPICC_SEL 136 +#define CLKID_SPICC_DIV 137 +#define CLKID_SPICC_SEL2 138 +#define CLKID_TS_DIV 139 +#define CLKID_SPIFC_SEL 140 +#define CLKID_SPIFC_DIV 141 +#define CLKID_SPIFC_SEL2 142 +#define CLKID_USB_BUS_SEL 143 +#define CLKID_USB_BUS_DIV 144 +#define CLKID_SD_EMMC_SEL 145 +#define CLKID_SD_EMMC_DIV 146 +#define CLKID_SD_EMMC_SEL2 147 +#define CLKID_PSRAM_SEL 148 +#define CLKID_PSRAM_DIV 149 +#define CLKID_PSRAM_SEL2 150 +#define CLKID_DMC_SEL 151 +#define CLKID_DMC_DIV 152 +#define CLKID_DMC_SEL2 153 +#define NR_CLKS 154 + +#include + +#endif /* __A1_H */ From patchwork Fri Nov 29 14:46:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jian Hu X-Patchwork-Id: 11267279 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CA8AB921 for ; Fri, 29 Nov 2019 14:48:48 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9126420869 for ; Fri, 29 Nov 2019 14:48:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="F/j5PUEz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9126420869 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amlogic.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=pJkxTU/cW0L22r4b2F5oA5yp564MdRxlQSzj9aM8hhs=; b=F/j5PUEz8REpfs 8h/v7wFiVcO3nOwt3J5SFDCWDV3+Q+Tw1jBENsmmgB97V8/YxXnT9ZIH+Fsj+n1MT/soY/oCt/n7n Za8EUd38iZ3zVmCzz+V1sFRXz5gLnCAvMGiWzW5cVoiYgdVcVL22jK9kOMdAWMYMR6Lg04ic/pPa5 4OY5XTHTPoqGwVKW99tTlzdjObRMjj6+Gw016pdADMCFHAMJR55R/ouxlpS7ZB896eLTACaHhN7ZK yTOmFVWukmS1QeePkwbnaxkkY6nh9RlQOyPIsqwLT/PqvdIJEu4E6uHhD9jHVngm58C9LNFpyG+l9 sSS20x4UkZw90gGJeikw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahZc-0005ri-QD; Fri, 29 Nov 2019 14:48:44 +0000 Received: from mail-sz.amlogic.com ([211.162.65.117]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iahYX-0004ND-3e; Fri, 29 Nov 2019 14:47:39 +0000 Received: from droid15-sz.amlogic.com (10.28.8.25) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.1591.10; Fri, 29 Nov 2019 22:47:48 +0800 From: Jian Hu To: Jerome Brunet , Neil Armstrong Subject: [PATCH v3 7/7] arm64: dts: meson: add A1 PLL and periphs clock controller Date: Fri, 29 Nov 2019 22:46:05 +0800 Message-ID: <20191129144605.182774-8-jian.hu@amlogic.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191129144605.182774-1-jian.hu@amlogic.com> References: <20191129144605.182774-1-jian.hu@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.28.8.25] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191129_064737_170167_4E68D1DB X-CRM114-Status: UNSURE ( 7.18 ) X-CRM114-Notice: Please train this message. X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Victor Wan , Jianxin Pan , Martin Blumenstingl , Kevin Hilman , Michael Turquette , linux-kernel@vger.kernel.org, Stephen Boyd , Jian Hu , linux-arm-kernel@lists.infradead.org, Qiufang Dai , linux-amlogic@lists.infradead.org, linux-clk@vger.kernel.org, Chandle Zou Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add A1 PLL and periphs clock controller node, there are parent clocks in periphs clocks for PLL clocks, and there are parent clocks in PLL clocks for periphs clocks. They rely on each other. Signed-off-by: Jian Hu --- arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi index 7210ad049d1d..ba1cb4aa594b 100644 --- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi @@ -5,6 +5,8 @@ #include #include +#include +#include / { compatible = "amlogic,a1"; @@ -74,6 +76,30 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x1000000>; + clkc_pll: pll-clock-controller { + compatible = "amlogic,a1-pll-clkc"; + #clock-cells = <1>; + reg = <0 0x7c80 0 0x21c>; + clocks = <&clkc_periphs CLKID_XTAL_FIXPLL>, + <&clkc_periphs CLKID_XTAL_HIFIPLL>; + clock-names = "xtal_fixpll", "xtal_hifipll"; + }; + + clkc_periphs: periphs-clock-controller { + compatible = "amlogic,a1-periphs-clkc"; + #clock-cells = <1>; + reg = <0 0x800 0 0x104>; + clocks = <&clkc_pll CLKID_FCLK_DIV2>, + <&clkc_pll CLKID_FCLK_DIV3>, + <&clkc_pll CLKID_FCLK_DIV5>, + <&clkc_pll CLKID_FCLK_DIV7>, + <&clkc_pll CLKID_HIFI_PLL>, + <&xtal>; + clock-names = "fclk_div2", "fclk_div3", + "fclk_div5", "fclk_div7", + "hifi_pll", "xtal"; + }; + uart_AO: serial@1c00 { compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";