Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2195217/?format=api
{ "id": 2195217, "url": "http://patchwork.ozlabs.org/api/patches/2195217/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260210151459.2348758-8-raymondmaoca@gmail.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260210151459.2348758-8-raymondmaoca@gmail.com>", "list_archive_url": null, "date": "2026-02-10T15:14:50", "name": "[v2,07/16] clk: spacemit: Add support for K1 SoC", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "7eb47d708850047700510b7653cdcf5c842ce5f0", "submitter": { "id": 91989, "url": "http://patchwork.ozlabs.org/api/people/91989/?format=api", "name": "Raymond Mao", "email": "raymondmaoca@gmail.com" }, "delegate": { "id": 20174, "url": "http://patchwork.ozlabs.org/api/users/20174/?format=api", "username": "Andes", "first_name": "Andes", "last_name": "", "email": "uboot@andestech.com" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260210151459.2348758-8-raymondmaoca@gmail.com/mbox/", "series": [ { "id": 491690, "url": "http://patchwork.ozlabs.org/api/series/491690/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=491690", "date": "2026-02-10T15:14:43", "name": "Add board support for Spacemit K1 SoC in SPL", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/491690/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2195217/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2195217/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=ExMA8eD5;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)", "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.b=\"ExMA8eD5\";\n\tdkim-atps=neutral", "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=raymondmaoca@gmail.com" ], "Received": [ "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4f9QC40knPz1xwG\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 11 Feb 2026 02:16:48 +1100 (AEDT)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id C09E383E1E;\n\tTue, 10 Feb 2026 16:15:43 +0100 (CET)", "by phobos.denx.de (Postfix, from userid 109)\n id DD33E83D3D; Tue, 10 Feb 2026 16:15:40 +0100 (CET)", "from mail-qt1-x831.google.com (mail-qt1-x831.google.com\n [IPv6:2607:f8b0:4864:20::831])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 9A12683CF2\n for <u-boot@lists.denx.de>; Tue, 10 Feb 2026 16:15:35 +0100 (CET)", "by mail-qt1-x831.google.com with SMTP id\n d75a77b69052e-502f101d1cfso8201991cf.1\n for <u-boot@lists.denx.de>; Tue, 10 Feb 2026 07:15:35 -0800 (PST)", "from ubuntu.localdomain (174-138-202-16.cpe.distributel.net.\n [174.138.202.16]) by smtp.gmail.com with ESMTPSA id\n 6a1803df08f44-8953c057751sm101019286d6.43.2026.02.10.07.15.30\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 10 Feb 2026 07:15:31 -0800 (PST)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-1.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_GMAIL_RCVD,FREEMAIL_FROM,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=no\n autolearn_force=no version=3.4.2", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20230601; t=1770736534; x=1771341334; darn=lists.denx.de;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=Tts/pV2wS+5FclUYjLaCUYkNlYkVzb+Op0/PnXW8Fwk=;\n b=ExMA8eD5UNqtvZhCWMjpcgs4Rt5tZJWweufBsp0Jh7EChNrTPPRe518kxW5t3z1cbA\n ipv4VIDt803/ukQv5GB91Ad2Wh6rX3Hb96zOlct62/n5SY68dlzrZy2QbkXWzroUMxJs\n rnaeRjCK+UauacdXqp9Ms/hYUHbttO934lXs6glR5WSAF/FM0G2Vd1yCuOD7OGiCOfXR\n ef4BkrqJQ8vq2qUgG7+lVNvIl8hZIy7IoQ4yI+NqCjJfCOHFDk3B4gWO81aOqT4mP0i7\n vHjKGTNaW0IbTguglN5NRT+QCqVwnXzsjy5bK743nq16O3UZB6TBCUHCND7xaC7IZcmR\n qRSQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1770736534; x=1771341334;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=Tts/pV2wS+5FclUYjLaCUYkNlYkVzb+Op0/PnXW8Fwk=;\n b=BJXPDYXyBLz6OjrE1kgW1euyZum1a9dI+n1KElB6WDQ7MPhus839aUn35ELNoaykIb\n emx2J5u+zb6N9shVrRcgJLw6w8vzldmode2tWkcJuImtit8m8t6xYFPlPMs1EkjGZH7v\n rWvfHlAUrjpjMv1Sx9JrPG9ceTjoRAL2OMyRbj4bz53LA6NOJIGGv+Yvi6rFA26wXiXn\n cOtgZtozrHdjNtvSj96akKaMAx8zoGSdNQIOIJFlbEqLUGNbsG4Y9BpxGrt53d95exKO\n dxj2Kb7nrHKW5iaZHvtZvizJ0LttxLiYd4/MG3ZX+b9bOKhAx4yiy4oiIj0GVwwx3Pde\n WHow==", "X-Gm-Message-State": "AOJu0Yz/FFwzuD+15hU7W7WdBuboaVSF8Kl4eL+m242bhHIKBH2fb2Ax\n plsaXVoY/0UpeufVIQJdoL0m88GIpNCe3J4YFUlzVlFPPF7JkYJ3UTLTQRGrMA==", "X-Gm-Gg": "AZuq6aITQoGkyr+wLbJBEcktDAI2wtlo5gt64jZuLe234Gm9DkB8MJVsNA3yFCAtAWP\n K6AOcGhoPASH4NizzK/pd2egADdDU/8BncD8WhmkkGSD/Azp1pcW3z25BTXp6lYQ/qraug7EBfj\n 9qFV0mPiyfawR6Q3KWqf4FBsOrD4MuIxvUZEEZYsuqcVxHGRwki+QF/yJ698aIxEZxU9JhPfnh/\n L1m6TgbLtdJc9LG1Ol7W4aNaG/gPloXc0DrEcTm+RUwLbTlh5UWsrkcu6OPdn3hLmVygufIQGw5\n S2M+toN/uwYCEUb29Ykt/eF1QcbRUbnFEOGHujgKxMEXo3vQU5UhGefKa00xAcxD7HqJem8thXc\n EJky1QvR2u3yrFN91AHNhZFdmLs4Xu9Uw4021swTZDdWVGXlDwIuwPWn3FA8uc3RWGvmM7FQX00\n xu2BUfY4hawoCpLTqUxTL1oL7rvkH2K9gTLW3E9/FWt4C1szA2QdEpu/L7sENeXVGNAOO1ixQh1\n 9lSrxpWcVQ=", "X-Received": "by 2002:ac8:5dcc:0:b0:4ff:c295:3c3e with SMTP id\n d75a77b69052e-506398d461emr186729621cf.10.1770736531984;\n Tue, 10 Feb 2026 07:15:31 -0800 (PST)", "From": "Raymond Mao <raymondmaoca@gmail.com>", "To": "u-boot@lists.denx.de", "Cc": "uboot@riscstar.com, u-boot-spacemit@groups.io, raymond.mao@riscstar.com,\n rick@andestech.com, ycliang@andestech.com, trini@konsulko.com,\n lukma@denx.de, hs@nabladev.com, jh80.chung@samsung.com, peng.fan@nxp.com,\n xypron.glpk@gmx.de, randolph@andestech.com, dlan@gentoo.org,\n junhui.liu@pigmoral.tech, neil.armstrong@linaro.org,\n quentin.schulz@cherry.de, samuel@sholland.org, raymondmaoca@gmail.com,\n Raymond Mao <raymond.mao@riststar.com>", "Subject": "[PATCH v2 07/16] clk: spacemit: Add support for K1 SoC", "Date": "Tue, 10 Feb 2026 10:14:50 -0500", "Message-Id": "<20260210151459.2348758-8-raymondmaoca@gmail.com>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20260210151459.2348758-1-raymondmaoca@gmail.com>", "References": "<20260210151459.2348758-1-raymondmaoca@gmail.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.39", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "From: Junhui Liu <junhui.liu@pigmoral.tech>\n\nAdd clock support for Spacemit K1 SoC.\n\nSigned-off-by: Junhui Liu <junhui.liu@pigmoral.tech>\nSigned-off-by: Raymond Mao <raymond.mao@riststar.com>\n---\n drivers/clk/Kconfig | 5 +-\n drivers/clk/Makefile | 1 +\n drivers/clk/spacemit/Kconfig | 31 +\n drivers/clk/spacemit/Makefile | 7 +\n drivers/clk/spacemit/clk-k1.c | 1795 +++++++++++++++++++++++++++++\n drivers/clk/spacemit/clk_common.h | 79 ++\n drivers/clk/spacemit/clk_ddn.c | 93 ++\n drivers/clk/spacemit/clk_ddn.h | 53 +\n drivers/clk/spacemit/clk_mix.c | 403 +++++++\n drivers/clk/spacemit/clk_mix.h | 224 ++++\n drivers/clk/spacemit/clk_pll.c | 157 +++\n drivers/clk/spacemit/clk_pll.h | 81 ++\n include/soc/spacemit/k1-syscon.h | 149 +++\n 13 files changed, 3076 insertions(+), 2 deletions(-)\n create mode 100644 drivers/clk/spacemit/Kconfig\n create mode 100644 drivers/clk/spacemit/Makefile\n create mode 100644 drivers/clk/spacemit/clk-k1.c\n create mode 100644 drivers/clk/spacemit/clk_common.h\n create mode 100644 drivers/clk/spacemit/clk_ddn.c\n create mode 100644 drivers/clk/spacemit/clk_ddn.h\n create mode 100644 drivers/clk/spacemit/clk_mix.c\n create mode 100644 drivers/clk/spacemit/clk_mix.h\n create mode 100644 drivers/clk/spacemit/clk_pll.c\n create mode 100644 drivers/clk/spacemit/clk_pll.h\n create mode 100644 include/soc/spacemit/k1-syscon.h", "diff": "diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig\nindex 85cc472b4cb..85da15bcaad 100644\n--- a/drivers/clk/Kconfig\n+++ b/drivers/clk/Kconfig\n@@ -275,11 +275,12 @@ source \"drivers/clk/mvebu/Kconfig\"\n source \"drivers/clk/owl/Kconfig\"\n source \"drivers/clk/qcom/Kconfig\"\n source \"drivers/clk/renesas/Kconfig\"\n-source \"drivers/clk/sophgo/Kconfig\"\n-source \"drivers/clk/sunxi/Kconfig\"\n source \"drivers/clk/sifive/Kconfig\"\n+source \"drivers/clk/sophgo/Kconfig\"\n+source \"drivers/clk/spacemit/Kconfig\"\n source \"drivers/clk/starfive/Kconfig\"\n source \"drivers/clk/stm32/Kconfig\"\n+source \"drivers/clk/sunxi/Kconfig\"\n source \"drivers/clk/tegra/Kconfig\"\n source \"drivers/clk/ti/Kconfig\"\n source \"drivers/clk/thead/Kconfig\"\ndiff --git a/drivers/clk/Makefile b/drivers/clk/Makefile\nindex 5f0c0d8a5c2..dabbb3af4b6 100644\n--- a/drivers/clk/Makefile\n+++ b/drivers/clk/Makefile\n@@ -48,6 +48,7 @@ obj-$(CONFIG_CLK_RENESAS) += renesas/\n obj-$(CONFIG_$(PHASE_)CLK_SCMI) += clk_scmi.o\n obj-$(CONFIG_CLK_SIFIVE) += sifive/\n obj-$(CONFIG_CLK_SOPHGO) += sophgo/\n+obj-$(CONFIG_CLK_SPACEMIT) += spacemit/\n obj-$(CONFIG_CLK_SUNXI) += sunxi/\n obj-$(CONFIG_CLK_UNIPHIER) += uniphier/\n obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o\ndiff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig\nnew file mode 100644\nindex 00000000000..fd96ec8fd2e\n--- /dev/null\n+++ b/drivers/clk/spacemit/Kconfig\n@@ -0,0 +1,31 @@\n+# SPDX-License-Identifier: GPL-2.0-or-later\n+#\n+# Copyright (c) 2025, Junhui Liu <junhui.liu@pigmoral.tech>\n+\n+config CLK_SPACEMIT\n+\tbool \"Clock support for SpacemiT SoCs\"\n+\tdepends on CLK\n+\tselect REGMAP\n+\thelp\n+\t This enables support clock driver for Spacemit SoC\n+\t family.\n+\n+if CLK_SPACEMIT\n+\n+config CLK_SPACEMIT_K1\n+\tbool \"SpacemiT K1 clock support\"\n+\tselect CLK_CCF\n+\tdefault SPACEMIT_K1\n+\thelp\n+\t This enables support clock driver for Spacemit K1 SoC.\n+\t It's based on Common Clock Framework.\n+\n+config SPL_CLK_SPACEMIT_K1\n+\tbool \"Enable Spacemit K1 SoC clock support in SPL\"\n+\tselect SPL_CLK_CCF\n+\tdefault SPACEMIT_K1\n+\thelp\n+\t It allows to use the Spacemit K1 SoC clock driver in\n+\t SPL.\n+\n+endif\ndiff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile\nnew file mode 100644\nindex 00000000000..824e94d1f74\n--- /dev/null\n+++ b/drivers/clk/spacemit/Makefile\n@@ -0,0 +1,7 @@\n+# SPDX-License-Identifier: GPL-2.0-or-later\n+#\n+# Copyright (C) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+\n+obj-$(CONFIG_CLK_SPACEMIT) += clk_ddn.o clk_mix.o clk_pll.o\n+\n+obj-$(CONFIG_CLK_SPACEMIT_K1)\t+= clk-k1.o\ndiff --git a/drivers/clk/spacemit/clk-k1.c b/drivers/clk/spacemit/clk-k1.c\nnew file mode 100644\nindex 00000000000..063b6122e88\n--- /dev/null\n+++ b/drivers/clk/spacemit/clk-k1.c\n@@ -0,0 +1,1795 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd\n+ * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>\n+ * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+ * Copyright (c) 2025-2026 RISCstar Ltd.\n+ *\n+ * Authors: Haylen Chu <heylenay@4d2.org>\n+ */\n+\n+#include <dm.h>\n+#include <dm/device_compat.h>\n+#include <dm/lists.h>\n+#include <regmap.h>\n+#include <linux/clk-provider.h>\n+#include <soc/spacemit/k1-syscon.h>\n+\n+#include \"clk_common.h\"\n+#include \"clk_ddn.h\"\n+#include \"clk_mix.h\"\n+#include \"clk_pll.h\"\n+\n+#include <dt-bindings/clock/spacemit,k1-syscon.h>\n+\n+#define K1_PLL_ID\t\t100\n+#define K1_MPMU_ID\t\t200\n+#define K1_APBC_ID\t\t300\n+#define K1_APMU_ID\t\t400\n+\n+struct spacemit_ccu_data {\n+\tstruct clk **clks;\n+\tsize_t num;\n+\tunsigned long offset;\n+};\n+\n+/* APBS clocks start, APBS region contains and only contains all PLL clocks */\n+\n+/*\n+ * PLL{1,2} must run at fixed frequencies to provide clocks in correct rates for\n+ * peripherals.\n+ */\n+static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = {\n+\tCCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),\n+};\n+\n+static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = {\n+\tCCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000),\n+};\n+\n+static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = {\n+\tCCU_PLL_RATE(1600000000UL, 0x0050cd61, 0x43eaaaab),\n+\tCCU_PLL_RATE(1800000000UL, 0x0050cd61, 0x4b000000),\n+\tCCU_PLL_RATE(2000000000UL, 0x0050dd62, 0x2aeaaaab),\n+\tCCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),\n+\tCCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000),\n+\tCCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab),\n+};\n+\n+CCU_PLL_DEFINE(CLK_PLL1, pll1, pll1, \"clock-24m\", pll1_rate_tbl,\n+\t APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, MPMU_POSR, POSR_PLL1_LOCK,\n+\t CLK_SET_RATE_GATE);\n+CCU_PLL_DEFINE(CLK_PLL2, pll2, pll2, \"clock-24m\", pll2_rate_tbl,\n+\t APBS_PLL2_SWCR1, APBS_PLL2_SWCR3, MPMU_POSR, POSR_PLL2_LOCK,\n+\t CLK_SET_RATE_GATE);\n+CCU_PLL_DEFINE(CLK_PLL3, pll3, pll3, \"clock-24m\", pll3_rate_tbl,\n+\t APBS_PLL3_SWCR1, APBS_PLL3_SWCR3, MPMU_POSR, POSR_PLL3_LOCK,\n+\t CLK_SET_RATE_GATE);\n+\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D2, pll1_d2, pll1_d2, \"pll1\", APBS_PLL1_SWCR2,\n+\t\t BIT(1), 2, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D3, pll1_d3, pll1_d3, \"pll1\", APBS_PLL1_SWCR2,\n+\t\t BIT(2), 3, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D4, pll1_d4, pll1_d4, \"pll1\", APBS_PLL1_SWCR2,\n+\t\t BIT(3), 4, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D5, pll1_d5, pll1_d5, \"pll1\", APBS_PLL1_SWCR2,\n+\t\t BIT(4), 5, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D6, pll1_d6, pll1_d6, \"pll1\", APBS_PLL1_SWCR2,\n+\t\t BIT(5), 6, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D7, pll1_d7, pll1_d7, \"pll1\", APBS_PLL1_SWCR2,\n+\t\t BIT(6), 7, 1);\n+CCU_FACTOR_GATE_FLAGS_DEFINE(CLK_PLL1_D8, pll1_d8, pll1_d8, \"pll1\",\n+\t\t\t APBS_PLL1_SWCR2, BIT(7), 8, 1, CLK_IS_CRITICAL);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D11, pll1_d11_223p4, pll1_d11_223p4, \"pll1\",\n+\t\t APBS_PLL1_SWCR2, BIT(15), 11, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D13, pll1_d13_189, pll1_d13_189, \"pll1\",\n+\t\t APBS_PLL1_SWCR2, BIT(16), 13, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D23, pll1_d23_106p8, pll1_d23_106p8, \"pll1\",\n+\t\t APBS_PLL1_SWCR2, BIT(20), 23, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D64, pll1_d64_38p4, pll1_d64_38p4, \"pll1\",\n+\t\t APBS_PLL1_SWCR2, BIT(0), 64, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D10_AUD, pll1_aud_245p7, pll1_aud_245p7, \"pll1\",\n+\t\t APBS_PLL1_SWCR2, BIT(10), 10, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D100_AUD, pll1_aud_24p5, pll1_aud_24p5, \"pll1\",\n+\t\t APBS_PLL1_SWCR2, BIT(11), 100, 1);\n+\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D1, pll2_d1, pll2_d1, \"pll2\", APBS_PLL2_SWCR2,\n+\t\t BIT(0), 1, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D2, pll2_d2, pll2_d2, \"pll2\", APBS_PLL2_SWCR2,\n+\t\t BIT(1), 2, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D3, pll2_d3, pll2_d3, \"pll2\", APBS_PLL2_SWCR2,\n+\t\t BIT(2), 3, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D4, pll2_d4, pll2_d4, \"pll2\", APBS_PLL2_SWCR2,\n+\t\t BIT(3), 4, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D5, pll2_d5, pll2_d5, \"pll2\", APBS_PLL2_SWCR2,\n+\t\t BIT(4), 5, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D6, pll2_d6, pll2_d6, \"pll2\", APBS_PLL2_SWCR2,\n+\t\t BIT(5), 6, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D7, pll2_d7, pll2_d7, \"pll2\", APBS_PLL2_SWCR2,\n+\t\t BIT(6), 7, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D8, pll2_d8, pll2_d8, \"pll2\", APBS_PLL2_SWCR2,\n+\t\t BIT(7), 8, 1);\n+\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D1, pll3_d1, pll3_d1, \"pll3\", APBS_PLL3_SWCR2,\n+\t\t BIT(0), 1, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D2, pll3_d2, pll3_d2, \"pll3\", APBS_PLL3_SWCR2,\n+\t\t BIT(1), 2, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D3, pll3_d3, pll3_d3, \"pll3\", APBS_PLL3_SWCR2,\n+\t\t BIT(2), 3, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D4, pll3_d4, pll3_d4, \"pll3\", APBS_PLL3_SWCR2,\n+\t\t BIT(3), 4, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D5, pll3_d5, pll3_d5, \"pll3\", APBS_PLL3_SWCR2,\n+\t\t BIT(4), 5, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D6, pll3_d6, pll3_d6, \"pll3\", APBS_PLL3_SWCR2,\n+\t\t BIT(5), 6, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D7, pll3_d7, pll3_d7, \"pll3\", APBS_PLL3_SWCR2,\n+\t\t BIT(6), 7, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D8, pll3_d8, pll3_d8, \"pll3\", APBS_PLL3_SWCR2,\n+\t\t BIT(7), 8, 1);\n+\n+CCU_FACTOR_DEFINE(CLK_PLL3_20, pll3_20, pll3_20, \"pll3_d8\", 20, 1);\n+CCU_FACTOR_DEFINE(CLK_PLL3_40, pll3_40, pll3_40, \"pll3_d8\", 10, 1);\n+CCU_FACTOR_DEFINE(CLK_PLL3_80, pll3_80, pll3_80, \"pll3_d8\", 5, 1);\n+/* APBS clocks end */\n+\n+/* MPMU clocks start */\n+CCU_GATE_DEFINE(CLK_PLL1_307P2, pll1_d8_307p2, pll1_d8_307p2, \"pll1_d8\",\n+\t\tMPMU_ACGR, BIT(13), 0);\n+\n+CCU_FACTOR_DEFINE(CLK_PLL1_76P8, pll1_d32_76p8, pll1_d32_76p8, \"pll1_d8_307p2\",\n+\t\t 4, 1);\n+\n+CCU_FACTOR_DEFINE(CLK_PLL1_61P44, pll1_d40_61p44, pll1_d40_61p44,\n+\t\t \"pll1_d8_307p2\", 5, 1);\n+\n+CCU_FACTOR_DEFINE(CLK_PLL1_153P6, pll1_d16_153p6, pll1_d16_153p6,\n+\t\t \"pll1_d8\", 2, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_102P4, pll1_d24_102p4, pll1_d24_102p4,\n+\t\t \"pll1_d8\", MPMU_ACGR, BIT(12), 3, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2, pll1_d48_51p2, pll1_d48_51p2,\n+\t\t \"pll1_d8\", MPMU_ACGR, BIT(7), 6, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2_AP, pll1_d48_51p2_ap, pll1_d48_51p2_ap,\n+\t\t \"pll1_d8\", MPMU_ACGR, BIT(11), 6, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_57P6, pll1_m3d128_57p6, pll1_m3d128_57p6,\n+\t\t \"pll1_d8\", MPMU_ACGR, BIT(8), 16, 3);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_25P6, pll1_d96_25p6, pll1_d96_25p6,\n+\t\t \"pll1_d8\", MPMU_ACGR, BIT(4), 12, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_12P8, pll1_d192_12p8, pll1_d192_12p8,\n+\t\t \"pll1_d8\", MPMU_ACGR, BIT(3), 24, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_12P8_WDT, pll1_d192_12p8_wdt, pll1_d192_12p8_wdt,\n+\t\t \"pll1_d8\", MPMU_ACGR, BIT(19), 24, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_6P4, pll1_d384_6p4, pll1_d384_6p4,\n+\t\t \"pll1_d8\", MPMU_ACGR, BIT(2), 48, 1);\n+\n+CCU_FACTOR_DEFINE(CLK_PLL1_3P2, pll1_d768_3p2, pll1_d768_3p2,\n+\t\t \"pll1_d384_6p4\", 2, 1);\n+CCU_FACTOR_DEFINE(CLK_PLL1_1P6, pll1_d1536_1p6, pll1_d1536_1p6,\n+\t\t \"pll1_d384_6p4\", 4, 1);\n+CCU_FACTOR_DEFINE(CLK_PLL1_0P8, pll1_d3072_0p8, pll1_d3072_0p8,\n+\t\t \"pll1_d384_6p4\", 8, 1);\n+\n+CCU_GATE_DEFINE(CLK_PLL1_409P6, pll1_d6_409p6, pll1_d6_409p6, \"pll1_d6\",\n+\t\tMPMU_ACGR, BIT(0), 0);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_204P8, pll1_d12_204p8, pll1_d12_204p8,\n+\t\t \"pll1_d6\", MPMU_ACGR, BIT(5), 2, 1);\n+\n+CCU_GATE_DEFINE(CLK_PLL1_491, pll1_d5_491p52, pll1_d5_491p52, \"pll1_d5\",\n+\t\tMPMU_ACGR, BIT(21), 0);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_245P76, pll1_d10_245p76, pll1_d10_245p76,\n+\t\t \"pll1_d5\", MPMU_ACGR, BIT(18), 2, 1);\n+\n+CCU_GATE_DEFINE(CLK_PLL1_614, pll1_d4_614p4, pll1_d4_614p4, \"pll1_d4\",\n+\t\tMPMU_ACGR, BIT(15), 0);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_47P26, pll1_d52_47p26, pll1_d52_47p26,\n+\t\t \"pll1_d4\", MPMU_ACGR, BIT(10), 13, 1);\n+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_31P5, pll1_d78_31p5, pll1_d78_31p5,\n+\t\t \"pll1_d4\", MPMU_ACGR, BIT(6), 39, 2);\n+\n+CCU_GATE_DEFINE(CLK_PLL1_819, pll1_d3_819p2, pll1_d3_819p2, \"pll1_d3\",\n+\t\tMPMU_ACGR, BIT(14), 0);\n+\n+CCU_GATE_DEFINE(CLK_PLL1_1228, pll1_d2_1228p8, pll1_d2_1228p8, \"pll1_d2\",\n+\t\tMPMU_ACGR, BIT(16), 0);\n+\n+CCU_GATE_DEFINE(CLK_SLOW_UART, slow_uart, slow_uart, \"clock-32k\", MPMU_ACGR,\n+\t\tBIT(1), CLK_IGNORE_UNUSED);\n+CCU_DDN_DEFINE(CLK_SLOW_UART1, slow_uart1_14p74, slow_uart1_14p74,\n+\t \"pll1_d16_153p6\", MPMU_SUCCR,\n+\t CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);\n+CCU_DDN_DEFINE(CLK_SLOW_UART2, slow_uart2_48, slow_uart2_48,\n+\t \"pll1_d4_614p4\", MPMU_SUCCR_1,\n+\t CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);\n+\n+#if !IS_ENABLED(CONFIG_SPL_BUILD)\n+CCU_GATE_DEFINE(CLK_WDT, wdt_clk, wdt_clk, \"pll1_d96_25p6\", MPMU_WDTPCR,\n+\t\tBIT(1), 0);\n+\n+CCU_FACTOR_DEFINE(CLK_I2S_153P6, i2s_153p6, i2s_153p6, \"pll1_d8_307p2\", 2, 1);\n+\n+static const char * const i2s_153p6_base_parents[] = {\n+\t\"i2s_153p6\",\n+\t\"pll1_d8_307p2\",\n+};\n+\n+CCU_MUX_DEFINE(CLK_I2S_153P6_BASE, i2s_153p6_base, i2s_153p6_base,\n+\t i2s_153p6_base_parents, ARRAY_SIZE(i2s_153p6_base_parents),\n+\t MPMU_FCCR, 29, 1, 0);\n+\n+static const char * const i2s_sysclk_src_parents[] = {\n+\t\"pll1_d96_25p6\",\n+\t\"i2s_153p6_base\"\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_I2S_SYSCLK_SRC, i2s_sysclk_src, i2s_sysclk_src,\n+\t\t i2s_sysclk_src_parents, ARRAY_SIZE(i2s_sysclk_src_parents),\n+\t\t MPMU_ISCCR, 30, 1, BIT(31), 0);\n+\n+CCU_DDN_DEFINE(CLK_I2S_SYSCLK, i2s_sysclk, i2s_sysclk, \"i2s_sysclk_src\",\n+\t MPMU_ISCCR, CCU_DDN_MASK(0, 15), 0, CCU_DDN_MASK(15, 12),\n+\t 15, 1, 0);\n+\n+CCU_FACTOR_DEFINE(CLK_I2S_BCLK_FACTOR, i2s_bclk_factor, i2s_bclk_factor,\n+\t\t \"i2s_sysclk\", 2, 1);\n+/*\n+ * Divider of i2s_bclk always implies a 1/2 factor, which is\n+ * described by i2s_bclk_factor.\n+ */\n+CCU_DIV_GATE_DEFINE(CLK_I2S_BCLK, i2s_bclk, i2s_bclk, \"i2s_bclk_factor\",\n+\t\t MPMU_ISCCR, 27, 2, BIT(29), 0);\n+\n+static const char * const apb_parents[] = {\n+\t\"pll1_d96_25p6\",\n+\t\"pll1_d48_51p2\",\n+\t\"pll1_d96_25p6\",\n+\t\"pll1_d24_102p4\",\n+};\n+\n+CCU_MUX_DEFINE(CLK_APB, apb_clk, apb_clk, apb_parents, ARRAY_SIZE(apb_parents),\n+\t MPMU_APBCSCR, 0, 2, 0);\n+\n+CCU_GATE_DEFINE(CLK_WDT_BUS, wdt_bus_clk, wdt_bus_clk, \"apb_clk\", MPMU_WDTPCR,\n+\t\tBIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_RIPC, ripc_clk, ripc_clk, \"apb_clk\", MPMU_RIPCCR, 0x1, 0);\n+#endif\n+/* MPMU clocks end */\n+\n+/* APBC clocks start */\n+static const char * const uart_clk_parents[] = {\n+\t\"pll1_m3d128_57p6\",\n+\t\"slow_uart1_14p74\",\n+\t\"slow_uart2_48\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_UART0, uart0_clk, uart0_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART1_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+\n+static const char * const twsi_parents[] = {\n+\t\"pll1_d78_31p5\",\n+\t\"pll1_d48_51p2\",\n+\t\"pll1_d40_61p44\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents,\n+\t\t ARRAY_SIZE(twsi_parents), APBC_TWSI2_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+/*\n+ * APBC_TWSI8_CLK_RST has a quirk that reading always results in zero.\n+ * Combine functional and bus bits together as a gate to avoid sharing the\n+ * write-only register between different clock hardwares.\n+ */\n+CCU_GATE_DEFINE(CLK_TWSI8, twsi8_clk, twsi8_clk, \"pll1_d78_31p5\",\n+\t\tAPBC_TWSI8_CLK_RST, BIT(1) | BIT(0), 0);\n+\n+#if !IS_ENABLED(CONFIG_SPL_BUILD)\n+CCU_MUX_GATE_DEFINE(CLK_UART2, uart2_clk, uart2_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART2_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_UART3, uart3_clk, uart3_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART3_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_UART4, uart4_clk, uart4_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART4_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_UART5, uart5_clk, uart5_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART5_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_UART6, uart6_clk, uart6_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART6_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_UART7, uart7_clk, uart7_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART7_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_UART8, uart8_clk, uart8_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART8_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_UART9, uart9_clk, uart9_clk, uart_clk_parents,\n+\t\t ARRAY_SIZE(uart_clk_parents), APBC_UART9_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_GPIO, gpio_clk, gpio_clk, \"clock-24m\", APBC_GPIO_CLK_RST,\n+\t\tBIT(1) | BIT(0), 0);\n+\n+static const char * const pwm_parents[] = {\n+\t\"pll1_d192_12p8\",\n+\t\"clock-32k\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_PWM0, pwm0_clk, pwm0_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM0_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM1, pwm1_clk, pwm1_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM1_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM2, pwm2_clk, pwm2_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM2_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM3, pwm3_clk, pwm3_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM3_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM4, pwm4_clk, pwm4_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM4_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM5, pwm5_clk, pwm5_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM5_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM6, pwm6_clk, pwm6_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM6_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM7, pwm7_clk, pwm7_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM7_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM8, pwm8_clk, pwm8_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM8_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM9, pwm9_clk, pwm9_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM9_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM10, pwm10_clk, pwm10_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM10_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM11, pwm11_clk, pwm11_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM11_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM12, pwm12_clk, pwm12_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM12_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM13, pwm13_clk, pwm13_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM13_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM14, pwm14_clk, pwm14_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM14_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM15, pwm15_clk, pwm15_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM15_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM16, pwm16_clk, pwm16_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM16_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM17, pwm17_clk, pwm17_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM17_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM18, pwm18_clk, pwm18_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM18_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_PWM19, pwm19_clk, pwm19_clk, pwm_parents,\n+\t\t ARRAY_SIZE(pwm_parents), APBC_PWM19_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+\n+static const char * const ssp_parents[] = {\n+\t\"pll1_d384_6p4\",\n+\t\"pll1_d192_12p8\",\n+\t\"pll1_d96_25p6\",\n+\t\"pll1_d48_51p2\",\n+\t\"pll1_d768_3p2\",\n+\t\"pll1_d1536_1p6\",\n+\t\"pll1_d3072_0p8\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_SSP3, ssp3_clk, ssp3_clk, ssp_parents,\n+\t\t ARRAY_SIZE(ssp_parents), APBC_SSP3_CLK_RST, 4, 3,\n+\t\t BIT(1), 0);\n+\n+CCU_GATE_DEFINE(CLK_RTC, rtc_clk, rtc_clk, \"clock-32k\", APBC_RTC_CLK_RST,\n+\t\tBIT(7) | BIT(1) | BIT(0), 0);\n+\n+CCU_MUX_GATE_DEFINE(CLK_TWSI0, twsi0_clk, twsi0_clk, twsi_parents,\n+\t\t ARRAY_SIZE(twsi_parents), APBC_TWSI0_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_TWSI1, twsi1_clk, twsi1_clk, twsi_parents,\n+\t\t ARRAY_SIZE(twsi_parents), APBC_TWSI1_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_TWSI4, twsi4_clk, twsi4_clk, twsi_parents,\n+\t\t ARRAY_SIZE(twsi_parents), APBC_TWSI4_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_TWSI5, twsi5_clk, twsi5_clk, twsi_parents,\n+\t\t ARRAY_SIZE(twsi_parents), APBC_TWSI5_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_TWSI6, twsi6_clk, twsi6_clk, twsi_parents,\n+\t\t ARRAY_SIZE(twsi_parents), APBC_TWSI6_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_TWSI7, twsi7_clk, twsi7_clk, twsi_parents,\n+\t\t ARRAY_SIZE(twsi_parents), APBC_TWSI7_CLK_RST,\n+\t\t 4, 3, BIT(1) | BIT(0), 0);\n+\n+static const char * const timer_parents[] = {\n+\t\"pll1_d192_12p8\",\n+\t\"clock-32k\",\n+\t\"pll1_d384_6p4\",\n+\t\"clock-3m\",\n+\t\"clock-1m\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_TIMERS1, timers1_clk, timers1_clk, timer_parents,\n+\t\t ARRAY_SIZE(timer_parents), APBC_TIMERS1_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+CCU_MUX_GATE_DEFINE(CLK_TIMERS2, timers2_clk, timers2_clk, timer_parents,\n+\t\t ARRAY_SIZE(timer_parents), APBC_TIMERS2_CLK_RST, 4, 3,\n+\t\t BIT(1) | BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_AIB, aib_clk, aib_clk, \"clock-24m\", APBC_AIB_CLK_RST,\n+\t\tBIT(1) | BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_ONEWIRE, onewire_clk, onewire_clk, \"clock-24m\",\n+\t\tAPBC_ONEWIRE_CLK_RST, BIT(1) | BIT(0), 0);\n+\n+/*\n+ * When i2s_bclk is selected as the parent clock of sspa,\n+ * the hardware requires bit3 to be set\n+ */\n+CCU_GATE_DEFINE(CLK_SSPA0_I2S_BCLK, sspa0_i2s_bclk, sspa0_i2s_bclk, \"i2s_bclk\",\n+\t\tAPBC_SSPA0_CLK_RST, BIT(3), 0);\n+CCU_GATE_DEFINE(CLK_SSPA1_I2S_BCLK, sspa1_i2s_bclk, sspa1_i2s_bclk, \"i2s_bclk\",\n+\t\tAPBC_SSPA1_CLK_RST, BIT(3), 0);\n+\n+static const char * const sspa0_parents[] = {\n+\t\"pll1_d384_6p4\",\n+\t\"pll1_d192_12p8\",\n+\t\"pll1_d96_25p6\",\n+\t\"pll1_d48_51p2\",\n+\t\"pll1_d768_3p2\",\n+\t\"pll1_d1536_1p6\",\n+\t\"pll1_d3072_0p8\",\n+\t\"sspa0_i2s_bclk\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_SSPA0, sspa0_clk, sspa0_clk, sspa0_parents,\n+\t\t ARRAY_SIZE(sspa0_parents), APBC_SSPA0_CLK_RST, 4, 3,\n+\t\t BIT(1), 0);\n+\n+static const char * const sspa1_parents[] = {\n+\t\"pll1_d384_6p4\",\n+\t\"pll1_d192_12p8\",\n+\t\"pll1_d96_25p6\",\n+\t\"pll1_d48_51p2\",\n+\t\"pll1_d768_3p2\",\n+\t\"pll1_d1536_1p6\",\n+\t\"pll1_d3072_0p8\",\n+\t\"sspa1_i2s_bclk\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_SSPA1, sspa1_clk, sspa1_clk, sspa1_parents,\n+\t\t ARRAY_SIZE(sspa1_parents), APBC_SSPA1_CLK_RST, 4, 3,\n+\t\t BIT(1), 0);\n+\n+CCU_GATE_DEFINE(CLK_DRO, dro_clk, dro_clk, \"apb_clk\", APBC_DRO_CLK_RST,\n+\t\tBIT(1) | BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_IR, ir_clk, ir_clk, \"apb_clk\", APBC_IR_CLK_RST,\n+\t\tBIT(1) | BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_TSEN, tsen_clk, tsen_clk, \"apb_clk\", APBC_TSEN_CLK_RST,\n+\t\tBIT(1) | BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_IPC_AP2AUD, ipc_ap2aud_clk, ipc_ap2aud_clk, \"apb_clk\",\n+\t\tAPBC_IPC_AP2AUD_CLK_RST, BIT(1) | BIT(0), 0);\n+\n+static const char * const can_parents[] = {\n+\t\"pll3_20\",\n+\t\"pll3_40\",\n+\t\"pll3_80\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_CAN0, can0_clk, can0_clk, can_parents,\n+\t\t ARRAY_SIZE(can_parents), APBC_CAN0_CLK_RST, 4, 3,\n+\t\t BIT(1), 0);\n+CCU_GATE_DEFINE(CLK_CAN0_BUS, can0_bus_clk, can0_bus_clk, \"clock-24m\",\n+\t\tAPBC_CAN0_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_UART0_BUS, uart0_bus_clk, uart0_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART1_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_UART2_BUS, uart2_bus_clk, uart2_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART2_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_UART3_BUS, uart3_bus_clk, uart3_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART3_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_UART4_BUS, uart4_bus_clk, uart4_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART4_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_UART5_BUS, uart5_bus_clk, uart5_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART5_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_UART6_BUS, uart6_bus_clk, uart6_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART6_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_UART7_BUS, uart7_bus_clk, uart7_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART7_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_UART8_BUS, uart8_bus_clk, uart8_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART8_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_UART9_BUS, uart9_bus_clk, uart9_bus_clk, \"apb_clk\",\n+\t\tAPBC_UART9_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_GPIO_BUS, gpio_bus_clk, gpio_bus_clk, \"apb_clk\",\n+\t\tAPBC_GPIO_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_PWM0_BUS, pwm0_bus_clk, pwm0_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM0_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM1_BUS, pwm1_bus_clk, pwm1_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM1_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM2_BUS, pwm2_bus_clk, pwm2_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM2_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM3_BUS, pwm3_bus_clk, pwm3_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM3_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM4_BUS, pwm4_bus_clk, pwm4_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM4_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM5_BUS, pwm5_bus_clk, pwm5_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM5_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM6_BUS, pwm6_bus_clk, pwm6_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM6_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM7_BUS, pwm7_bus_clk, pwm7_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM7_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM8_BUS, pwm8_bus_clk, pwm8_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM8_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM9_BUS, pwm9_bus_clk, pwm9_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM9_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM10_BUS, pwm10_bus_clk, pwm10_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM10_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM11_BUS, pwm11_bus_clk, pwm11_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM11_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM12_BUS, pwm12_bus_clk, pwm12_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM12_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM13_BUS, pwm13_bus_clk, pwm13_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM13_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM14_BUS, pwm14_bus_clk, pwm14_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM14_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM15_BUS, pwm15_bus_clk, pwm15_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM15_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM16_BUS, pwm16_bus_clk, pwm16_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM16_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM17_BUS, pwm17_bus_clk, pwm17_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM17_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM18_BUS, pwm18_bus_clk, pwm18_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM18_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_PWM19_BUS, pwm19_bus_clk, pwm19_bus_clk, \"apb_clk\",\n+\t\tAPBC_PWM19_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_SSP3_BUS, ssp3_bus_clk, ssp3_bus_clk, \"apb_clk\",\n+\t\tAPBC_SSP3_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_RTC_BUS, rtc_bus_clk, rtc_bus_clk, \"apb_clk\",\n+\t\tAPBC_RTC_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_TWSI0_BUS, twsi0_bus_clk, twsi0_bus_clk, \"apb_clk\",\n+\t\tAPBC_TWSI0_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_TWSI1_BUS, twsi1_bus_clk, twsi1_bus_clk, \"apb_clk\",\n+\t\tAPBC_TWSI1_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_TWSI2_BUS, twsi2_bus_clk, twsi2_bus_clk, \"apb_clk\",\n+\t\tAPBC_TWSI2_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_TWSI4_BUS, twsi4_bus_clk, twsi4_bus_clk, \"apb_clk\",\n+\t\tAPBC_TWSI4_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_TWSI5_BUS, twsi5_bus_clk, twsi5_bus_clk, \"apb_clk\",\n+\t\tAPBC_TWSI5_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_TWSI6_BUS, twsi6_bus_clk, twsi6_bus_clk, \"apb_clk\",\n+\t\tAPBC_TWSI6_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_TWSI7_BUS, twsi7_bus_clk, twsi7_bus_clk, \"apb_clk\",\n+\t\tAPBC_TWSI7_CLK_RST, BIT(0), 0);\n+CCU_FACTOR_DEFINE(CLK_TWSI8_BUS, twsi8_bus_clk, twsi8_bus_clk, \"apb_clk\", 1, 1);\n+\n+CCU_GATE_DEFINE(CLK_TIMERS1_BUS, timers1_bus_clk, timers1_bus_clk, \"apb_clk\",\n+\t\tAPBC_TIMERS1_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_TIMERS2_BUS, timers2_bus_clk, timers2_bus_clk, \"apb_clk\",\n+\t\tAPBC_TIMERS2_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_AIB_BUS, aib_bus_clk, aib_bus_clk, \"apb_clk\",\n+\t\tAPBC_AIB_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_ONEWIRE_BUS, onewire_bus_clk, onewire_bus_clk, \"apb_clk\",\n+\t\tAPBC_ONEWIRE_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_SSPA0_BUS, sspa0_bus_clk, sspa0_bus_clk, \"apb_clk\",\n+\t\tAPBC_SSPA0_CLK_RST, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_SSPA1_BUS, sspa1_bus_clk, sspa1_bus_clk, \"apb_clk\",\n+\t\tAPBC_SSPA1_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_TSEN_BUS, tsen_bus_clk, tsen_bus_clk, \"apb_clk\",\n+\t\tAPBC_TSEN_CLK_RST, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_IPC_AP2AUD_BUS, ipc_ap2aud_bus_clk, ipc_ap2aud_bus_clk,\n+\t\t\"apb_clk\", APBC_IPC_AP2AUD_CLK_RST, BIT(0), 0);\n+#endif\n+/* APBC clocks end */\n+\n+/* APMU clocks start */\n+static const char * const pmua_aclk_parents[] = {\n+\t\"pll1_d10_245p76\",\n+\t\"pll1_d8_307p2\",\n+};\n+\n+CCU_MUX_DIV_FC_DEFINE(CLK_PMUA_ACLK, pmua_aclk, pmua_aclk, pmua_aclk_parents,\n+\t\t ARRAY_SIZE(pmua_aclk_parents),\n+\t\t APMU_ACLK_CLK_CTRL, APMU_ACLK_CLK_CTRL, 1, 2, BIT(4),\n+\t\t 0, 1, 0);\n+\n+static const char * const emmc_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d52_47p26\",\n+\t\"pll1_d3_819p2\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_EMMC, emmc_clk, emmc_clk, emmc_parents,\n+\t\t\t\t ARRAY_SIZE(emmc_parents),\n+\t\t\t\t APMU_PMUA_EM_CLK_RES_CTRL,\n+\t\t\t\t APMU_PMUA_EM_CLK_RES_CTRL, 8, 3, BIT(11),\n+\t\t\t\t 6, 2, BIT(4), 0);\n+CCU_DIV_GATE_DEFINE(CLK_EMMC_X, emmc_x_clk, emmc_x_clk, \"pll1_d2_1228p8\",\n+\t\t APMU_PMUA_EM_CLK_RES_CTRL, 12,\n+\t\t 3, BIT(15), 0);\n+\n+CCU_GATE_DEFINE(CLK_EMMC_BUS, emmc_bus_clk, emmc_bus_clk, \"pmua_aclk\",\n+\t\tAPMU_PMUA_EM_CLK_RES_CTRL, BIT(3), 0);\n+\n+#if !IS_ENABLED(CONFIG_SPL_BUILD)\n+static const char * const cci550_clk_parents[] = {\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll2_d3\",\n+};\n+\n+CCU_MUX_DIV_FC_DEFINE(CLK_CCI550, cci550_clk, cci550_clk, cci550_clk_parents,\n+\t\t ARRAY_SIZE(cci550_clk_parents),\n+\t\t APMU_CCI550_CLK_CTRL, APMU_CCI550_CLK_CTRL, 8, 3,\n+\t\t BIT(12), 0, 2, CLK_IS_CRITICAL);\n+\n+static const char * const cpu_c0_hi_clk_parents[] = {\n+\t\"pll3_d2\",\n+\t\"pll3_d1\",\n+};\n+\n+CCU_MUX_DEFINE(CLK_CPU_C0_HI, cpu_c0_hi_clk, cpu_c0_hi_clk,\n+\t cpu_c0_hi_clk_parents, ARRAY_SIZE(cpu_c0_hi_clk_parents),\n+\t APMU_CPU_C0_CLK_CTRL, 13, 1, 0);\n+static const char * const cpu_c0_clk_parents[] = {\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d2_1228p8\",\n+\t\"pll3_d3\",\n+\t\"pll2_d3\",\n+\t\"cpu_c0_hi_clk\",\n+};\n+\n+CCU_MUX_FC_DEFINE(CLK_CPU_C0_CORE, cpu_c0_core_clk, cpu_c0_core_clk,\n+\t\t cpu_c0_clk_parents, ARRAY_SIZE(cpu_c0_clk_parents),\n+\t\t APMU_CPU_C0_CLK_CTRL, APMU_CPU_C0_CLK_CTRL,\n+\t\t BIT(12), 0, 3, CLK_IS_CRITICAL);\n+CCU_DIV_DEFINE(CLK_CPU_C0_ACE, cpu_c0_ace_clk, cpu_c0_ace_clk,\n+\t \"cpu_c0_core_clk\", APMU_CPU_C0_CLK_CTRL, 6, 3, CLK_IS_CRITICAL);\n+CCU_DIV_DEFINE(CLK_CPU_C0_TCM, cpu_c0_tcm_clk, cpu_c0_tcm_clk,\n+\t \"cpu_c0_core_clk\", APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL);\n+\n+static const char * const cpu_c1_hi_clk_parents[] = {\n+\t\"pll3_d2\",\n+\t\"pll3_d1\",\n+};\n+\n+CCU_MUX_DEFINE(CLK_CPU_C1_HI, cpu_c1_hi_clk, cpu_c1_hi_clk,\n+\t cpu_c1_hi_clk_parents, ARRAY_SIZE(cpu_c1_hi_clk_parents),\n+\t APMU_CPU_C1_CLK_CTRL, 13, 1, 0);\n+static const char * const cpu_c1_clk_parents[] = {\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d2_1228p8\",\n+\t\"pll3_d3\",\n+\t\"pll2_d3\",\n+\t\"cpu_c1_hi_clk\",\n+};\n+\n+CCU_MUX_FC_DEFINE(CLK_CPU_C1_CORE, cpu_c1_core_clk, cpu_c1_core_clk,\n+\t\t cpu_c1_clk_parents, ARRAY_SIZE(cpu_c1_clk_parents),\n+\t\t APMU_CPU_C1_CLK_CTRL, APMU_CPU_C1_CLK_CTRL,\n+\t\t BIT(12), 0, 3, CLK_IS_CRITICAL);\n+CCU_DIV_DEFINE(CLK_CPU_C1_ACE, cpu_c1_ace_clk, cpu_c1_ace_clk,\n+\t \"cpu_c1_core_clk\", APMU_CPU_C1_CLK_CTRL, 6, 3, CLK_IS_CRITICAL);\n+\n+static const char * const jpg_parents[] = {\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll1_d2_1228p8\",\n+\t\"pll2_d4\",\n+\t\"pll2_d3\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_JPG, jpg_clk, jpg_clk, jpg_parents,\n+\t\t\t\t ARRAY_SIZE(jpg_parents),\n+\t\t\t\t APMU_JPG_CLK_RES_CTRL,\n+\t\t\t\t APMU_JPG_CLK_RES_CTRL,\n+\t\t\t\t 5, 3, BIT(15), 2, 3, BIT(1), 0);\n+\n+static const char * const ccic2phy_parents[] = {\n+\t\"pll1_d24_102p4\",\n+\t\"pll1_d48_51p2_ap\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_CCIC2PHY, ccic2phy_clk, ccic2phy_clk, ccic2phy_parents,\n+\t\t ARRAY_SIZE(ccic2phy_parents), APMU_CSI_CCIC2_CLK_RES_CTRL,\n+\t\t 7, 1, BIT(5), 0);\n+\n+static const char * const ccic3phy_parents[] = {\n+\t\"pll1_d24_102p4\",\n+\t\"pll1_d48_51p2_ap\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_CCIC3PHY, ccic3phy_clk, ccic3phy_clk, ccic3phy_parents,\n+\t\t ARRAY_SIZE(ccic3phy_parents), APMU_CSI_CCIC2_CLK_RES_CTRL,\n+\t\t 31, 1, BIT(30), 0);\n+\n+static const char * const csi_parents[] = {\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll2_d2\",\n+\t\"pll2_d3\",\n+\t\"pll2_d4\",\n+\t\"pll1_d2_1228p8\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_CSI, csi_clk, csi_clk, csi_parents,\n+\t\t\t\t ARRAY_SIZE(csi_parents),\n+\t\t\t\t APMU_CSI_CCIC2_CLK_RES_CTRL,\n+\t\t\t\t APMU_CSI_CCIC2_CLK_RES_CTRL, 20, 3, BIT(15),\n+\t\t\t\t 16, 3, BIT(4), 0);\n+\n+static const char * const camm_parents[] = {\n+\t\"pll1_d8_307p2\",\n+\t\"pll2_d5\",\n+\t\"pll1_d6_409p6\",\n+\t\"clock-24m\",\n+};\n+\n+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM0, camm0_clk, camm0_clk, camm_parents,\n+\t\t\tARRAY_SIZE(camm_parents),\n+\t\t\tAPMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,\n+\t\t\tBIT(28), 0);\n+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM1, camm1_clk, camm1_clk, camm_parents,\n+\t\t\tARRAY_SIZE(camm_parents),\n+\t\t\tAPMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,\n+\t\t\tBIT(6), 0);\n+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM2, camm2_clk, camm2_clk, camm_parents,\n+\t\t\tARRAY_SIZE(camm_parents),\n+\t\t\tAPMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,\n+\t\t\tBIT(3), 0);\n+\n+static const char * const isp_cpp_parents[] = {\n+\t\"pll1_d8_307p2\",\n+\t\"pll1_d6_409p6\",\n+};\n+\n+CCU_MUX_DIV_GATE_DEFINE(CLK_ISP_CPP, isp_cpp_clk, isp_cpp_clk, isp_cpp_parents,\n+\t\t\tARRAY_SIZE(isp_cpp_parents),\n+\t\t\tAPMU_ISP_CLK_RES_CTRL, 24, 2, 26, 1,\n+\t\t\tBIT(28), 0);\n+static const char * const isp_bus_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d8_307p2\",\n+\t\"pll1_d10_245p76\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_ISP_BUS, isp_bus_clk, isp_bus_clk,\n+\t\t\t\t isp_bus_parents, ARRAY_SIZE(isp_cpp_parents),\n+\t\t\t\t APMU_ISP_CLK_RES_CTRL,\n+\t\t\t\t APMU_ISP_CLK_RES_CTRL, 18, 3, BIT(23),\n+\t\t\t\t 21, 2, BIT(17), 0);\n+static const char * const isp_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d8_307p2\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_ISP, isp_clk, isp_clk, isp_parents,\n+\t\t\t\t ARRAY_SIZE(isp_parents),\n+\t\t\t\t APMU_ISP_CLK_RES_CTRL,\n+\t\t\t\t APMU_ISP_CLK_RES_CTRL,\n+\t\t\t\t 4, 3, BIT(7), 8, 2, BIT(1), 0);\n+\n+static const char * const dpumclk_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d8_307p2\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_MCLK, dpu_mclk, dpu_mclk,\n+\t\t\t\t dpumclk_parents, ARRAY_SIZE(dpumclk_parents),\n+\t\t\t\t APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1,\n+\t\t\t\t 1, 4, BIT(29), 5, 3, BIT(0), 0);\n+\n+static const char * const dpuesc_parents[] = {\n+\t\"pll1_d48_51p2_ap\",\n+\t\"pll1_d52_47p26\",\n+\t\"pll1_d96_25p6\",\n+\t\"pll1_d32_76p8\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_DPU_ESC, dpu_esc_clk, dpu_esc_clk, dpuesc_parents,\n+\t\t ARRAY_SIZE(dpuesc_parents), APMU_LCD_CLK_RES_CTRL1, 0, 2,\n+\t\t BIT(2), 0);\n+\n+static const char * const dpubit_parents[] = {\n+\t\"pll1_d3_819p2\",\n+\t\"pll2_d2\",\n+\t\"pll2_d3\",\n+\t\"pll1_d2_1228p8\",\n+\t\"pll2_d4\",\n+\t\"pll2_d5\",\n+\t\"pll2_d7\",\n+\t\"pll2_d8\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_BIT, dpu_bit_clk, dpu_bit_clk,\n+\t\t\t\t dpubit_parents, ARRAY_SIZE(dpubit_parents),\n+\t\t\t\t APMU_LCD_CLK_RES_CTRL1,\n+\t\t\t\t APMU_LCD_CLK_RES_CTRL1, 17, 3, BIT(31),\n+\t\t\t\t 20, 3, BIT(16), 0);\n+\n+static const char * const dpupx_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d8_307p2\",\n+\t\"pll2_d7\",\n+\t\"pll2_d8\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_PXCLK, dpu_pxclk, dpu_pxclk,\n+\t\t\t\t dpupx_parents, ARRAY_SIZE(dpupx_parents),\n+\t\t\t\t APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1,\n+\t\t\t\t 17, 4, BIT(30), 21, 3, BIT(16), 0);\n+\n+CCU_GATE_DEFINE(CLK_DPU_HCLK, dpu_hclk, dpu_hclk, \"pmua_aclk\",\n+\t\tAPMU_LCD_CLK_RES_CTRL1, BIT(5), 0);\n+\n+static const char * const dpu_spi_parents[] = {\n+\t\"pll1_d8_307p2\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d10_245p76\",\n+\t\"pll1_d11_223p4\",\n+\t\"pll1_d13_189\",\n+\t\"pll1_d23_106p8\",\n+\t\"pll2_d3\",\n+\t\"pll2_d5\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_SPI, dpu_spi_clk, dpu_spi_clk,\n+\t\t\t\t dpu_spi_parents, ARRAY_SIZE(dpu_spi_parents),\n+\t\t\t\t APMU_LCD_SPI_CLK_RES_CTRL,\n+\t\t\t\t APMU_LCD_SPI_CLK_RES_CTRL, 8, 3,\n+\t\t\t\t BIT(7), 12, 3, BIT(1), 0);\n+CCU_GATE_DEFINE(CLK_DPU_SPI_HBUS, dpu_spi_hbus_clk, dpu_spi_hbus_clk,\n+\t\t\"pmua_aclk\", APMU_LCD_SPI_CLK_RES_CTRL, BIT(3), 0);\n+CCU_GATE_DEFINE(CLK_DPU_SPIBUS, dpu_spi_bus_clk, dpu_spi_bus_clk,\n+\t\t\"pmua_aclk\", APMU_LCD_SPI_CLK_RES_CTRL, BIT(5), 0);\n+CCU_GATE_DEFINE(CLK_DPU_SPI_ACLK, dpu_spi_aclk, dpu_spi_aclk,\n+\t\t\"pmua_aclk\", APMU_LCD_SPI_CLK_RES_CTRL, BIT(6), 0);\n+\n+static const char * const v2d_parents[] = {\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d8_307p2\",\n+\t\"pll1_d4_614p4\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_V2D, v2d_clk, v2d_clk, v2d_parents,\n+\t\t\t\t ARRAY_SIZE(v2d_parents),\n+\t\t\t\t APMU_LCD_CLK_RES_CTRL1,\n+\t\t\t\t APMU_LCD_CLK_RES_CTRL1, 9, 3, BIT(28), 12, 2,\n+\t\t\t\t BIT(8), 0);\n+\n+static const char * const ccic_4x_parents[] = {\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll2_d2\",\n+\t\"pll2_d3\",\n+\t\"pll2_d4\",\n+\t\"pll1_d2_1228p8\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_CCIC_4X, ccic_4x_clk, ccic_4x_clk,\n+\t\t\t\t ccic_4x_parents, ARRAY_SIZE(ccic_4x_parents),\n+\t\t\t\t APMU_CCIC_CLK_RES_CTRL,\n+\t\t\t\t APMU_CCIC_CLK_RES_CTRL, 18, 3,\n+\t\t\t\t BIT(15), 23, 2, BIT(4), 0);\n+\n+static const char * const ccic1phy_parents[] = {\n+\t\"pll1_d24_102p4\",\n+\t\"pll1_d48_51p2_ap\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_CCIC1PHY, ccic1phy_clk, ccic1phy_clk, ccic1phy_parents,\n+\t\t ARRAY_SIZE(ccic1phy_parents), APMU_CCIC_CLK_RES_CTRL, 7, 1,\n+\t\t BIT(5), 0);\n+\n+CCU_GATE_DEFINE(CLK_SDH_AXI, sdh_axi_aclk, sdh_axi_aclk, \"pmua_aclk\",\n+\t\tAPMU_SDH0_CLK_RES_CTRL, BIT(3), 0);\n+static const char * const sdh01_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll2_d8\",\n+\t\"pll2_d5\",\n+\t\"pll1_d11_223p4\",\n+\t\"pll1_d13_189\",\n+\t\"pll1_d23_106p8\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH0, sdh0_clk, sdh0_clk, sdh01_parents,\n+\t\t\t\t ARRAY_SIZE(sdh01_parents),\n+\t\t\t\t APMU_SDH0_CLK_RES_CTRL,\n+\t\t\t\t APMU_SDH0_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,\n+\t\t\t\t BIT(4), 0);\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH1, sdh1_clk, sdh1_clk, sdh01_parents,\n+\t\t\t\t ARRAY_SIZE(sdh01_parents),\n+\t\t\t\t APMU_SDH1_CLK_RES_CTRL,\n+\t\t\t\t APMU_SDH1_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,\n+\t\t\t\t BIT(4), 0);\n+static const char * const sdh2_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll2_d8\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll1_d11_223p4\",\n+\t\"pll1_d13_189\",\n+\t\"pll1_d23_106p8\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH2, sdh2_clk, sdh2_clk, sdh2_parents,\n+\t\t\t\t ARRAY_SIZE(sdh2_parents),\n+\t\t\t\t APMU_SDH2_CLK_RES_CTRL,\n+\t\t\t\t APMU_SDH2_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,\n+\t\t\t\t BIT(4), 0);\n+\n+CCU_GATE_DEFINE(CLK_USB_AXI, usb_axi_clk, usb_axi_clk, \"pmua_aclk\",\n+\t\tAPMU_USB_CLK_RES_CTRL, BIT(1), 0);\n+CCU_GATE_DEFINE(CLK_USB_P1, usb_p1_aclk, usb_p1_aclk, \"pmua_aclk\",\n+\t\tAPMU_USB_CLK_RES_CTRL, BIT(5), 0);\n+CCU_GATE_DEFINE(CLK_USB30, usb30_clk, usb30_clk, \"pmua_aclk\",\n+\t\tAPMU_USB_CLK_RES_CTRL, BIT(8), 0);\n+\n+static const char * const qspi_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll2_d8\",\n+\t\"pll1_d8_307p2\",\n+\t\"pll1_d10_245p76\",\n+\t\"pll1_d11_223p4\",\n+\t\"pll1_d23_106p8\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d13_189\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_QSPI, qspi_clk, qspi_clk, qspi_parents,\n+\t\t\t\t ARRAY_SIZE(qspi_parents),\n+\t\t\t\t APMU_QSPI_CLK_RES_CTRL,\n+\t\t\t\t APMU_QSPI_CLK_RES_CTRL, 9, 3, BIT(12), 6, 3,\n+\t\t\t\t BIT(4), 0);\n+CCU_GATE_DEFINE(CLK_QSPI_BUS, qspi_bus_clk, qspi_bus_clk, \"pmua_aclk\",\n+\t\tAPMU_QSPI_CLK_RES_CTRL, BIT(3), 0);\n+CCU_GATE_DEFINE(CLK_DMA, dma_clk, dma_clk, \"pmua_aclk\", APMU_DMA_CLK_RES_CTRL,\n+\t\tBIT(3), 0);\n+\n+static const char * const aes_parents[] = {\n+\t\"pll1_d12_204p8\",\n+\t\"pll1_d24_102p4\",\n+};\n+\n+CCU_MUX_GATE_DEFINE(CLK_AES, aes_clk, aes_clk, aes_parents,\n+\t\t ARRAY_SIZE(aes_parents), APMU_AES_CLK_RES_CTRL, 6, 1,\n+\t\t BIT(5), 0);\n+\n+static const char * const vpu_parents[] = {\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll3_d6\",\n+\t\"pll2_d3\",\n+\t\"pll2_d4\",\n+\t\"pll2_d5\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_VPU, vpu_clk, vpu_clk, vpu_parents,\n+\t\t\t\t ARRAY_SIZE(vpu_parents), APMU_VPU_CLK_RES_CTRL,\n+\t\t\t\t APMU_VPU_CLK_RES_CTRL, 13, 3, BIT(21), 10, 3,\n+\t\t\t\t BIT(3), 0);\n+\n+static const char * const gpu_parents[] = {\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d3_819p2\",\n+\t\"pll1_d6_409p6\",\n+\t\"pll3_d6\",\n+\t\"pll2_d3\",\n+\t\"pll2_d4\",\n+\t\"pll2_d5\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_GPU, gpu_clk, gpu_clk, gpu_parents,\n+\t\t\t\t ARRAY_SIZE(gpu_parents), APMU_GPU_CLK_RES_CTRL,\n+\t\t\t\t APMU_GPU_CLK_RES_CTRL, 12, 3, BIT(15), 18, 3,\n+\t\t\t\t BIT(4), 0);\n+\n+static const char * const audio_parents[] = {\n+\t\"pll1_aud_245p7\",\n+\t\"pll1_d8_307p2\",\n+\t\"pll1_d6_409p6\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_AUDIO, audio_clk, audio_clk, audio_parents,\n+\t\t\t\t ARRAY_SIZE(audio_parents),\n+\t\t\t\t APMU_AUDIO_CLK_RES_CTRL,\n+\t\t\t\t APMU_AUDIO_CLK_RES_CTRL, 4, 3, BIT(15),\n+\t\t\t\t 7, 3, BIT(12), 0);\n+\n+static const char * const hdmi_parents[] = {\n+\t\"pll1_d6_409p6\",\n+\t\"pll1_d5_491p52\",\n+\t\"pll1_d4_614p4\",\n+\t\"pll1_d8_307p2\",\n+};\n+\n+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_HDMI, hdmi_mclk, hdmi_mclk, hdmi_parents,\n+\t\t\t\t ARRAY_SIZE(hdmi_parents),\n+\t\t\t\t APMU_HDMI_CLK_RES_CTRL,\n+\t\t\t\t APMU_HDMI_CLK_RES_CTRL, 1, 4, BIT(29), 5,\n+\t\t\t\t 3, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_PCIE0_MASTER, pcie0_master_clk, pcie0_master_clk,\n+\t\t\"pmua_aclk\", APMU_PCIE_CLK_RES_CTRL_0, BIT(2), 0);\n+CCU_GATE_DEFINE(CLK_PCIE0_SLAVE, pcie0_slave_clk, pcie0_slave_clk, \"pmua_aclk\",\n+\t\tAPMU_PCIE_CLK_RES_CTRL_0, BIT(1), 0);\n+CCU_GATE_DEFINE(CLK_PCIE0_DBI, pcie0_dbi_clk, pcie0_dbi_clk, \"pmua_aclk\",\n+\t\tAPMU_PCIE_CLK_RES_CTRL_0, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_PCIE1_MASTER, pcie1_master_clk, pcie1_master_clk,\n+\t\t\"pmua_aclk\", APMU_PCIE_CLK_RES_CTRL_1, BIT(2), 0);\n+CCU_GATE_DEFINE(CLK_PCIE1_SLAVE, pcie1_slave_clk, pcie1_slave_clk, \"pmua_aclk\",\n+\t\tAPMU_PCIE_CLK_RES_CTRL_1, BIT(1), 0);\n+CCU_GATE_DEFINE(CLK_PCIE1_DBI, pcie1_dbi_clk, pcie1_dbi_clk, \"pmua_aclk\",\n+\t\tAPMU_PCIE_CLK_RES_CTRL_1, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_PCIE2_MASTER, pcie2_master_clk, pcie2_master_clk,\n+\t\t\"pmua_aclk\", APMU_PCIE_CLK_RES_CTRL_2, BIT(2), 0);\n+CCU_GATE_DEFINE(CLK_PCIE2_SLAVE, pcie2_slave_clk, pcie2_slave_clk, \"pmua_aclk\",\n+\t\tAPMU_PCIE_CLK_RES_CTRL_2, BIT(1), 0);\n+CCU_GATE_DEFINE(CLK_PCIE2_DBI, pcie2_dbi_clk, pcie2_dbi_clk, \"pmua_aclk\",\n+\t\tAPMU_PCIE_CLK_RES_CTRL_2, BIT(0), 0);\n+\n+CCU_GATE_DEFINE(CLK_EMAC0_BUS, emac0_bus_clk, emac0_bus_clk, \"pmua_aclk\",\n+\t\tAPMU_EMAC0_CLK_RES_CTRL, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_EMAC0_PTP, emac0_ptp_clk, emac0_ptp_clk, \"pll2_d6\",\n+\t\tAPMU_EMAC0_CLK_RES_CTRL, BIT(15), 0);\n+CCU_GATE_DEFINE(CLK_EMAC1_BUS, emac1_bus_clk, emac1_bus_clk, \"pmua_aclk\",\n+\t\tAPMU_EMAC1_CLK_RES_CTRL, BIT(0), 0);\n+CCU_GATE_DEFINE(CLK_EMAC1_PTP, emac1_ptp_clk, emac1_ptp_clk, \"pll2_d6\",\n+\t\tAPMU_EMAC1_CLK_RES_CTRL, BIT(15), 0);\n+\n+#endif\n+/* APMU clocks end */\n+\n+static struct clk *k1_ccu_pll_clks[] = {\n+\t&pll1.common.clk,\n+\t&pll2.common.clk,\n+\t&pll3.common.clk,\n+\t&pll1_d2.common.clk,\n+\t&pll1_d3.common.clk,\n+\t&pll1_d4.common.clk,\n+\t&pll1_d5.common.clk,\n+\t&pll1_d6.common.clk,\n+\t&pll1_d7.common.clk,\n+\t&pll1_d8.common.clk,\n+\t&pll1_d11_223p4.common.clk,\n+\t&pll1_d13_189.common.clk,\n+\t&pll1_d23_106p8.common.clk,\n+\t&pll1_d64_38p4.common.clk,\n+\t&pll1_aud_245p7.common.clk,\n+\t&pll1_aud_24p5.common.clk,\n+\t&pll2_d1.common.clk,\n+\t&pll2_d2.common.clk,\n+\t&pll2_d3.common.clk,\n+\t&pll2_d4.common.clk,\n+\t&pll2_d5.common.clk,\n+\t&pll2_d6.common.clk,\n+\t&pll2_d7.common.clk,\n+\t&pll2_d8.common.clk,\n+\t&pll3_d1.common.clk,\n+\t&pll3_d2.common.clk,\n+\t&pll3_d3.common.clk,\n+\t&pll3_d4.common.clk,\n+\t&pll3_d5.common.clk,\n+\t&pll3_d6.common.clk,\n+\t&pll3_d7.common.clk,\n+\t&pll3_d8.common.clk,\n+\t&pll3_80.common.clk,\n+\t&pll3_40.common.clk,\n+\t&pll3_20.common.clk,\n+};\n+\n+static const struct spacemit_ccu_data k1_ccu_pll_data = {\n+\t.clks\t\t= k1_ccu_pll_clks,\n+\t.num\t\t= ARRAY_SIZE(k1_ccu_pll_clks),\n+\t.offset\t\t= K1_PLL_ID,\n+};\n+\n+#if IS_ENABLED(CONFIG_SPL_BUILD)\n+static struct clk *k1_ccu_mpmu_clks[] = {\n+\t&pll1_d8_307p2.common.clk,\n+\t&pll1_d32_76p8.common.clk,\n+\t&pll1_d40_61p44.common.clk,\n+\t&pll1_d16_153p6.common.clk,\n+\t&pll1_d24_102p4.common.clk,\n+\t&pll1_d48_51p2.common.clk,\n+\t&pll1_d48_51p2_ap.common.clk,\n+\t&pll1_m3d128_57p6.common.clk,\n+\t&pll1_d96_25p6.common.clk,\n+\t&pll1_d192_12p8.common.clk,\n+\t&pll1_d192_12p8_wdt.common.clk,\n+\t&pll1_d384_6p4.common.clk,\n+\t&pll1_d768_3p2.common.clk,\n+\t&pll1_d1536_1p6.common.clk,\n+\t&pll1_d3072_0p8.common.clk,\n+\t&pll1_d6_409p6.common.clk,\n+\t&pll1_d12_204p8.common.clk,\n+\t&pll1_d5_491p52.common.clk,\n+\t&pll1_d10_245p76.common.clk,\n+\t&pll1_d4_614p4.common.clk,\n+\t&pll1_d52_47p26.common.clk,\n+\t&pll1_d78_31p5.common.clk,\n+\t&pll1_d3_819p2.common.clk,\n+\t&pll1_d2_1228p8.common.clk,\n+\t&slow_uart.common.clk,\n+\t&slow_uart1_14p74.common.clk,\n+\t&slow_uart2_48.common.clk,\n+};\n+#else\n+static struct clk *k1_ccu_mpmu_clks[] = {\n+\t&pll1_d8_307p2.common.clk,\n+\t&pll1_d32_76p8.common.clk,\n+\t&pll1_d40_61p44.common.clk,\n+\t&pll1_d16_153p6.common.clk,\n+\t&pll1_d24_102p4.common.clk,\n+\t&pll1_d48_51p2.common.clk,\n+\t&pll1_d48_51p2_ap.common.clk,\n+\t&pll1_m3d128_57p6.common.clk,\n+\t&pll1_d96_25p6.common.clk,\n+\t&pll1_d192_12p8.common.clk,\n+\t&pll1_d192_12p8_wdt.common.clk,\n+\t&pll1_d384_6p4.common.clk,\n+\t&pll1_d768_3p2.common.clk,\n+\t&pll1_d1536_1p6.common.clk,\n+\t&pll1_d3072_0p8.common.clk,\n+\t&pll1_d6_409p6.common.clk,\n+\t&pll1_d12_204p8.common.clk,\n+\t&pll1_d5_491p52.common.clk,\n+\t&pll1_d10_245p76.common.clk,\n+\t&pll1_d4_614p4.common.clk,\n+\t&pll1_d52_47p26.common.clk,\n+\t&pll1_d78_31p5.common.clk,\n+\t&pll1_d3_819p2.common.clk,\n+\t&pll1_d2_1228p8.common.clk,\n+\t&slow_uart.common.clk,\n+\t&slow_uart1_14p74.common.clk,\n+\t&slow_uart2_48.common.clk,\n+\t&wdt_clk.common.clk,\n+\t&apb_clk.common.clk,\n+\t&ripc_clk.common.clk,\n+\t&i2s_153p6.common.clk,\n+\t&i2s_153p6_base.common.clk,\n+\t&i2s_sysclk_src.common.clk,\n+\t&i2s_sysclk.common.clk,\n+\t&i2s_bclk_factor.common.clk,\n+\t&i2s_bclk.common.clk,\n+\t&wdt_bus_clk.common.clk,\n+};\n+#endif\n+\n+static const struct spacemit_ccu_data k1_ccu_mpmu_data = {\n+\t.clks\t\t= k1_ccu_mpmu_clks,\n+\t.num\t\t= ARRAY_SIZE(k1_ccu_mpmu_clks),\n+\t.offset\t\t= K1_MPMU_ID,\n+};\n+\n+#if IS_ENABLED(CONFIG_SPL_BUILD)\n+static struct clk *k1_ccu_apbc_clks[] = {\n+\t&uart0_clk.common.clk,\n+\t&twsi2_clk.common.clk,\n+\t&twsi8_clk.common.clk,\n+};\n+#else\n+static struct clk *k1_ccu_apbc_clks[] = {\n+\t&uart0_clk.common.clk,\n+\t&uart2_clk.common.clk,\n+\t&uart3_clk.common.clk,\n+\t&uart4_clk.common.clk,\n+\t&uart5_clk.common.clk,\n+\t&uart6_clk.common.clk,\n+\t&uart7_clk.common.clk,\n+\t&uart8_clk.common.clk,\n+\t&uart9_clk.common.clk,\n+\t&gpio_clk.common.clk,\n+\t&pwm0_clk.common.clk,\n+\t&pwm1_clk.common.clk,\n+\t&pwm2_clk.common.clk,\n+\t&pwm3_clk.common.clk,\n+\t&pwm4_clk.common.clk,\n+\t&pwm5_clk.common.clk,\n+\t&pwm6_clk.common.clk,\n+\t&pwm7_clk.common.clk,\n+\t&pwm8_clk.common.clk,\n+\t&pwm9_clk.common.clk,\n+\t&pwm10_clk.common.clk,\n+\t&pwm11_clk.common.clk,\n+\t&pwm12_clk.common.clk,\n+\t&pwm13_clk.common.clk,\n+\t&pwm14_clk.common.clk,\n+\t&pwm15_clk.common.clk,\n+\t&pwm16_clk.common.clk,\n+\t&pwm17_clk.common.clk,\n+\t&pwm18_clk.common.clk,\n+\t&pwm19_clk.common.clk,\n+\t&ssp3_clk.common.clk,\n+\t&rtc_clk.common.clk,\n+\t&twsi0_clk.common.clk,\n+\t&twsi1_clk.common.clk,\n+\t&twsi2_clk.common.clk,\n+\t&twsi4_clk.common.clk,\n+\t&twsi5_clk.common.clk,\n+\t&twsi6_clk.common.clk,\n+\t&twsi7_clk.common.clk,\n+\t&twsi8_clk.common.clk,\n+\t&timers1_clk.common.clk,\n+\t&timers2_clk.common.clk,\n+\t&aib_clk.common.clk,\n+\t&onewire_clk.common.clk,\n+\t&sspa0_clk.common.clk,\n+\t&sspa1_clk.common.clk,\n+\t&dro_clk.common.clk,\n+\t&ir_clk.common.clk,\n+\t&tsen_clk.common.clk,\n+\t&ipc_ap2aud_clk.common.clk,\n+\t&can0_clk.common.clk,\n+\t&can0_bus_clk.common.clk,\n+\t&uart0_bus_clk.common.clk,\n+\t&uart2_bus_clk.common.clk,\n+\t&uart3_bus_clk.common.clk,\n+\t&uart4_bus_clk.common.clk,\n+\t&uart5_bus_clk.common.clk,\n+\t&uart6_bus_clk.common.clk,\n+\t&uart7_bus_clk.common.clk,\n+\t&uart8_bus_clk.common.clk,\n+\t&uart9_bus_clk.common.clk,\n+\t&gpio_bus_clk.common.clk,\n+\t&pwm0_bus_clk.common.clk,\n+\t&pwm1_bus_clk.common.clk,\n+\t&pwm2_bus_clk.common.clk,\n+\t&pwm3_bus_clk.common.clk,\n+\t&pwm4_bus_clk.common.clk,\n+\t&pwm5_bus_clk.common.clk,\n+\t&pwm6_bus_clk.common.clk,\n+\t&pwm7_bus_clk.common.clk,\n+\t&pwm8_bus_clk.common.clk,\n+\t&pwm9_bus_clk.common.clk,\n+\t&pwm10_bus_clk.common.clk,\n+\t&pwm11_bus_clk.common.clk,\n+\t&pwm12_bus_clk.common.clk,\n+\t&pwm13_bus_clk.common.clk,\n+\t&pwm14_bus_clk.common.clk,\n+\t&pwm15_bus_clk.common.clk,\n+\t&pwm16_bus_clk.common.clk,\n+\t&pwm17_bus_clk.common.clk,\n+\t&pwm18_bus_clk.common.clk,\n+\t&pwm19_bus_clk.common.clk,\n+\t&ssp3_bus_clk.common.clk,\n+\t&rtc_bus_clk.common.clk,\n+\t&twsi0_bus_clk.common.clk,\n+\t&twsi1_bus_clk.common.clk,\n+\t&twsi2_bus_clk.common.clk,\n+\t&twsi4_bus_clk.common.clk,\n+\t&twsi5_bus_clk.common.clk,\n+\t&twsi6_bus_clk.common.clk,\n+\t&twsi7_bus_clk.common.clk,\n+\t&twsi8_bus_clk.common.clk,\n+\t&timers1_bus_clk.common.clk,\n+\t&timers2_bus_clk.common.clk,\n+\t&aib_bus_clk.common.clk,\n+\t&onewire_bus_clk.common.clk,\n+\t&sspa0_bus_clk.common.clk,\n+\t&sspa1_bus_clk.common.clk,\n+\t&tsen_bus_clk.common.clk,\n+\t&ipc_ap2aud_bus_clk.common.clk,\n+\t&sspa0_i2s_bclk.common.clk,\n+\t&sspa1_i2s_bclk.common.clk,\n+};\n+#endif\n+\n+static const struct spacemit_ccu_data k1_ccu_apbc_data = {\n+\t.clks\t\t= k1_ccu_apbc_clks,\n+\t.num\t\t= ARRAY_SIZE(k1_ccu_apbc_clks),\n+\t.offset\t\t= K1_APBC_ID,\n+};\n+\n+#if IS_ENABLED(CONFIG_SPL_BUILD)\n+static struct clk *k1_ccu_apmu_clks[] = {\n+\t&emmc_clk.common.clk,\n+\t&emmc_x_clk.common.clk,\n+\t&pmua_aclk.common.clk,\n+\t&emmc_bus_clk.common.clk,\n+};\n+#else\n+static struct clk *k1_ccu_apmu_clks[] = {\n+\t&cci550_clk.common.clk,\n+\t&cpu_c0_hi_clk.common.clk,\n+\t&cpu_c0_core_clk.common.clk,\n+\t&cpu_c0_ace_clk.common.clk,\n+\t&cpu_c0_tcm_clk.common.clk,\n+\t&cpu_c1_hi_clk.common.clk,\n+\t&cpu_c1_core_clk.common.clk,\n+\t&cpu_c1_ace_clk.common.clk,\n+\t&ccic_4x_clk.common.clk,\n+\t&ccic1phy_clk.common.clk,\n+\t&sdh_axi_aclk.common.clk,\n+\t&sdh0_clk.common.clk,\n+\t&sdh1_clk.common.clk,\n+\t&sdh2_clk.common.clk,\n+\t&usb_p1_aclk.common.clk,\n+\t&usb_axi_clk.common.clk,\n+\t&usb30_clk.common.clk,\n+\t&qspi_clk.common.clk,\n+\t&qspi_bus_clk.common.clk,\n+\t&dma_clk.common.clk,\n+\t&aes_clk.common.clk,\n+\t&vpu_clk.common.clk,\n+\t&gpu_clk.common.clk,\n+\t&emmc_clk.common.clk,\n+\t&emmc_x_clk.common.clk,\n+\t&audio_clk.common.clk,\n+\t&hdmi_mclk.common.clk,\n+\t&pmua_aclk.common.clk,\n+\t&pcie0_master_clk.common.clk,\n+\t&pcie0_slave_clk.common.clk,\n+\t&pcie0_dbi_clk.common.clk,\n+\t&pcie1_master_clk.common.clk,\n+\t&pcie1_slave_clk.common.clk,\n+\t&pcie1_dbi_clk.common.clk,\n+\t&pcie2_master_clk.common.clk,\n+\t&pcie2_slave_clk.common.clk,\n+\t&pcie2_dbi_clk.common.clk,\n+\t&emac0_bus_clk.common.clk,\n+\t&emac0_ptp_clk.common.clk,\n+\t&emac1_bus_clk.common.clk,\n+\t&emac1_ptp_clk.common.clk,\n+\t&jpg_clk.common.clk,\n+\t&ccic2phy_clk.common.clk,\n+\t&ccic3phy_clk.common.clk,\n+\t&csi_clk.common.clk,\n+\t&camm0_clk.common.clk,\n+\t&camm1_clk.common.clk,\n+\t&camm2_clk.common.clk,\n+\t&isp_cpp_clk.common.clk,\n+\t&isp_bus_clk.common.clk,\n+\t&isp_clk.common.clk,\n+\t&dpu_mclk.common.clk,\n+\t&dpu_esc_clk.common.clk,\n+\t&dpu_bit_clk.common.clk,\n+\t&dpu_pxclk.common.clk,\n+\t&dpu_hclk.common.clk,\n+\t&dpu_spi_clk.common.clk,\n+\t&dpu_spi_hbus_clk.common.clk,\n+\t&dpu_spi_bus_clk.common.clk,\n+\t&dpu_spi_aclk.common.clk,\n+\t&v2d_clk.common.clk,\n+\t&emmc_bus_clk.common.clk,\n+};\n+#endif\n+\n+static int clk_k1_enable(struct clk *clk)\n+{\n+\tconst struct spacemit_ccu_data *data;\n+\tstruct clk *c;\n+\tstruct clk *pclk;\n+\tint ret, i;\n+\n+\tdata = (struct spacemit_ccu_data *)dev_get_driver_data(clk->dev);\n+\tfor (i = 0; i < data->num; i++) {\n+\t\tif (clk->id == data->clks[i]->id) {\n+\t\t\tc = data->clks[i];\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tif (i == data->num)\n+\t\tc = clk;\n+\n+\tpclk = clk_get_parent(c);\n+\tif (!IS_ERR_OR_NULL(pclk)) {\n+\t\tret = ccf_clk_enable(pclk);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\tret = ccu_gate_enable(c);\n+\treturn ret;\n+}\n+\n+static int clk_k1_disable(struct clk *clk)\n+{\n+\tconst struct spacemit_ccu_data *data;\n+\tstruct clk *c;\n+\tstruct clk *pclk;\n+\tint ret, i;\n+\n+\tdata = (struct spacemit_ccu_data *)dev_get_driver_data(clk->dev);\n+\tfor (i = 0; i < data->num; i++) {\n+\t\tif (clk->id == data->clks[i]->id) {\n+\t\t\tc = data->clks[i];\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tif (i == data->num)\n+\t\tc = clk;\n+\n+\tpclk = clk_get_parent(c);\n+\tif (!IS_ERR_OR_NULL(pclk)) {\n+\t\tret = ccf_clk_disable(pclk);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\tret = ccu_gate_disable(c);\n+\treturn ret;\n+}\n+\n+#define K1_CLK_OPS(name)\t\t\t\t\\\n+static const struct clk_ops k1_##name##_clk_ops = {\t\\\n+\t\t.set_rate = ccf_clk_set_rate,\t\t\\\n+\t\t.get_rate = ccf_clk_get_rate,\t\t\\\n+\t\t.enable = clk_k1_enable,\t\t\\\n+\t\t.disable = clk_k1_disable,\t\t\\\n+\t\t.set_parent = ccf_clk_set_parent,\t\\\n+\t\t.of_xlate = k1_##name##_clk_of_xlate,\t\\\n+}\n+\n+static const struct spacemit_ccu_data k1_ccu_apmu_data = {\n+\t.clks\t\t= k1_ccu_apmu_clks,\n+\t.num\t\t= ARRAY_SIZE(k1_ccu_apmu_clks),\n+\t.offset\t\t= K1_APMU_ID,\n+};\n+\n+struct clk_retry_item {\n+\tstruct ccu_common *common;\n+\tstruct list_head link;\n+};\n+\n+static LIST_HEAD(retry_list);\n+\n+static int k1_clk_retry_register(void)\n+{\n+\tstruct clk_retry_item *item, *tmp;\n+\tint retries = 5;\n+\tint ret;\n+\n+\twhile (!list_empty(&retry_list) && retries) {\n+\t\tlist_for_each_entry_safe(item, tmp, &retry_list, link) {\n+\t\t\tstruct ccu_common *common = item->common;\n+\n+\t\t\tret = common->init(common);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\n+\t\t\tlist_del(&item->link);\n+\t\t\tkfree(item);\n+\t\t}\n+\t\tretries--;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int k1_clk_register(struct udevice *dev, struct regmap *regmap,\n+\t\t\t struct regmap *lock_regmap,\n+\t\t\t const struct spacemit_ccu_data *data)\n+{\n+\tint i, ret;\n+\n+\tfor (i = 0; i < data->num; i++) {\n+\t\tstruct clk *clk = data->clks[i];\n+\t\tstruct ccu_common *common;\n+\n+\t\tif (!clk)\n+\t\t\tcontinue;\n+\n+\t\tcommon = clk_to_ccu_common(clk);\n+\t\tcommon->regmap = regmap;\n+\t\tcommon->lock_regmap = lock_regmap;\n+\n+\t\tclk->id = common->clk.id + data->offset;\n+\n+\t\tret = common->init(common);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int k1_clk_probe(struct udevice *dev)\n+{\n+\tstruct regmap *base_regmap, *lock_regmap = NULL;\n+\tconst struct spacemit_ccu_data *data;\n+\tint ret;\n+\n+\tclk_register_fixed_rate(NULL, \"clock-1m\", 1000000);\n+\tclk_register_fixed_rate(NULL, \"clock-24m\", 24000000);\n+\tclk_register_fixed_rate(NULL, \"clock-3m\", 3000000);\n+\tclk_register_fixed_rate(NULL, \"clock-32k\", 32000);\n+\n+\tret = regmap_init_mem(dev_ofnode(dev), &base_regmap);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/*\n+\t * The lock status of PLLs locate in MPMU region, while PLLs themselves\n+\t * are in APBS region. Reference to MPMU syscon is required to check PLL\n+\t * status.\n+\t */\n+\tif (device_is_compatible(dev, \"spacemit,k1-pll\")) {\n+\t\tstruct ofnode_phandle_args mpmu_args;\n+\n+\t\tret = dev_read_phandle_with_args(dev, \"spacemit,mpmu\", NULL, 0, 0,\n+\t\t\t\t\t\t &mpmu_args);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = regmap_init_mem(mpmu_args.node, &lock_regmap);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tdata = (struct spacemit_ccu_data *)dev_get_driver_data(dev);\n+\n+\tret = k1_clk_register(dev, base_regmap, lock_regmap, data);\n+\tif (ret)\n+\t\treturn -EPROBE_DEFER;\n+\n+\treturn k1_clk_retry_register();\n+}\n+\n+static int k1_apbc_clk_probe(struct udevice *dev)\n+{\n+\tstruct regmap *base_regmap, *lock_regmap = NULL;\n+\tconst struct spacemit_ccu_data *data;\n+\tint ret;\n+\tstruct clk clk;\n+\n+\tret = regmap_init_mem(dev_ofnode(dev), &base_regmap);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tclk_register_fixed_rate(NULL, \"clock-1m\", 1000000);\n+\tclk_register_fixed_rate(NULL, \"clock-24m\", 24000000);\n+\tclk_register_fixed_rate(NULL, \"clock-3m\", 3000000);\n+\tclk_register_fixed_rate(NULL, \"clock-32k\", 32000);\n+\n+\t/* probe PLL controller */\n+\tret = clk_get_by_index(dev, 5, &clk);\n+\tif (ret)\n+\t\treturn -EPROBE_DEFER;\n+\n+\t/* probe MPMU controller */\n+\tret = clk_get_by_index(dev, 4, &clk);\n+\tif (ret)\n+\t\treturn -EPROBE_DEFER;\n+\n+\tret = regmap_init_mem(dev_ofnode(dev), &base_regmap);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/*\n+\t * The lock status of PLLs locate in MPMU region, while PLLs themselves\n+\t * are in APBS region. Reference to MPMU syscon is required to check PLL\n+\t * status.\n+\t */\n+\tif (device_is_compatible(dev, \"spacemit,k1-pll\")) {\n+\t\tstruct ofnode_phandle_args mpmu_args;\n+\n+\t\tret = dev_read_phandle_with_args(dev, \"spacemit,mpmu\", NULL, 0, 0,\n+\t\t\t\t\t\t &mpmu_args);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = regmap_init_mem(mpmu_args.node, &lock_regmap);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tdata = (struct spacemit_ccu_data *)dev_get_driver_data(dev);\n+\n+\tret = k1_clk_register(dev, base_regmap, lock_regmap, data);\n+\tif (ret)\n+\t\treturn -EPROBE_DEFER;\n+\n+\treturn k1_clk_retry_register();\n+}\n+\n+static int k1_pll_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)\n+{\n+\tif (args->args_count > 1) {\n+\t\tdebug(\"Invalid args_count: %d\\n\", args->args_count);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (args->args_count)\n+\t\tclk->id = K1_PLL_ID + args->args[0];\n+\telse\n+\t\tclk->id = K1_PLL_ID;\n+\n+\treturn 0;\n+}\n+\n+static int k1_mpmu_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)\n+{\n+\tif (args->args_count > 1) {\n+\t\tdebug(\"Invalid args_count: %d\\n\", args->args_count);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (args->args_count)\n+\t\tclk->id = K1_MPMU_ID + args->args[0];\n+\telse\n+\t\tclk->id = K1_MPMU_ID;\n+\n+\treturn 0;\n+}\n+\n+static int k1_apbc_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)\n+{\n+\tif (args->args_count > 1) {\n+\t\tdebug(\"Invalid args_count: %d\\n\", args->args_count);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (args->args_count)\n+\t\tclk->id = K1_APBC_ID + args->args[0];\n+\telse\n+\t\tclk->id = K1_APBC_ID;\n+\n+\treturn 0;\n+}\n+\n+static int k1_apmu_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)\n+{\n+\tif (args->args_count > 1) {\n+\t\tdebug(\"Invalid args_count: %d\\n\", args->args_count);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (args->args_count)\n+\t\tclk->id = K1_APMU_ID + args->args[0];\n+\telse\n+\t\tclk->id = K1_APMU_ID;\n+\n+\treturn 0;\n+}\n+\n+static const struct udevice_id k1_pll_clk_match[] = {\n+\t{ .compatible = \"spacemit,k1-pll\",\n+\t .data = (ulong)&k1_ccu_pll_data },\n+\t{ /* sentinel */ },\n+};\n+\n+K1_CLK_OPS(pll);\n+\n+U_BOOT_DRIVER(k1_pll_clk) = {\n+\t.name\t\t= \"k1_pll_clk\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= k1_pll_clk_match,\n+\t.probe\t\t= k1_clk_probe,\n+\t.ops\t\t= &k1_pll_clk_ops,\n+\t.flags\t\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+static const struct udevice_id k1_mpmu_clk_match[] = {\n+\t{ .compatible = \"spacemit,k1-syscon-mpmu\",\n+\t .data = (ulong)&k1_ccu_mpmu_data },\n+\t{ /* sentinel */ },\n+};\n+\n+K1_CLK_OPS(mpmu);\n+\n+U_BOOT_DRIVER(k1_mpmu_clk) = {\n+\t.name\t\t= \"k1_mpmu_clk\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= k1_mpmu_clk_match,\n+\t.probe\t\t= k1_clk_probe,\n+\t.ops\t\t= &k1_mpmu_clk_ops,\n+\t.flags\t\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+static const struct udevice_id k1_apbc_clk_match[] = {\n+\t{ .compatible = \"spacemit,k1-syscon-apbc\",\n+\t .data = (ulong)&k1_ccu_apbc_data },\n+\t{ /* sentinel */ },\n+};\n+\n+K1_CLK_OPS(apbc);\n+\n+U_BOOT_DRIVER(k1_apbc_clk) = {\n+\t.name\t\t= \"k1_apbc_clk\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= k1_apbc_clk_match,\n+\t.probe\t\t= k1_apbc_clk_probe,\n+\t.ops\t\t= &k1_apbc_clk_ops,\n+\t.flags\t\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+static const struct udevice_id k1_apmu_clk_match[] = {\n+\t{ .compatible = \"spacemit,k1-syscon-apmu\",\n+\t .data = (ulong)&k1_ccu_apmu_data },\n+\t{ /* sentinel */ },\n+};\n+\n+K1_CLK_OPS(apmu);\n+\n+U_BOOT_DRIVER(k1_apmu_clk) = {\n+\t.name\t\t= \"k1_apmu_clk\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= k1_apmu_clk_match,\n+\t.probe\t\t= k1_clk_probe,\n+\t.ops\t\t= &k1_apmu_clk_ops,\n+\t.flags\t\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+static const struct udevice_id k1_rcpu_clk_match[] = {\n+\t{ .compatible = \"spacemit,k1-syscon-rcpu\" },\n+\t{ /* sentinel */ },\n+};\n+\n+U_BOOT_DRIVER(k1_rcpu_clk) = {\n+\t.name\t\t= \"k1_rcpu_clk\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= k1_rcpu_clk_match,\n+\t.flags\t\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+static const struct udevice_id k1_rcpu2_clk_match[] = {\n+\t{ .compatible = \"spacemit,k1-syscon-rcpu2\" },\n+\t{ /* sentinel */ },\n+};\n+\n+U_BOOT_DRIVER(k1_rcpu2_clk) = {\n+\t.name\t\t= \"k1_rcpu2_clk\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= k1_rcpu2_clk_match,\n+\t.flags\t\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+static const struct udevice_id k1_apbc2_clk_match[] = {\n+\t{ .compatible = \"spacemit,k1-syscon-apbc2\" },\n+\t{ /* sentinel */ },\n+};\n+\n+U_BOOT_DRIVER(k1_apbc2_clk) = {\n+\t.name\t\t= \"k1_apbc2_clk\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= k1_apbc2_clk_match,\n+\t.flags\t\t= DM_FLAG_PRE_RELOC,\n+};\ndiff --git a/drivers/clk/spacemit/clk_common.h b/drivers/clk/spacemit/clk_common.h\nnew file mode 100644\nindex 00000000000..ea5ebf57784\n--- /dev/null\n+++ b/drivers/clk/spacemit/clk_common.h\n@@ -0,0 +1,79 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/*\n+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd\n+ * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>\n+ * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+ * Copyright (c) 2025-2026 RISCstar Ltd.\n+ *\n+ * Authors: Haylen Chu <heylenay@4d2.org>\n+ */\n+\n+#ifndef _CLK_COMMON_H_\n+#define _CLK_COMMON_H_\n+\n+#include <linux/clk-provider.h>\n+\n+struct ccu_common;\n+\n+typedef int (*ccu_init_fn)(struct ccu_common *common);\n+\n+struct ccu_common {\n+\tstruct regmap *regmap;\n+\tstruct regmap *lock_regmap;\n+\tconst char *name;\n+\tconst char * const *parents;\n+\tsize_t num_parents;\n+\tccu_init_fn init;\n+\n+\tunion {\n+\t\t/* For DDN and MIX */\n+\t\tstruct {\n+\t\t\tu32 reg_ctrl;\n+\t\t\tu32 reg_fc;\n+\t\t\tu32 mask_fc;\n+\t\t};\n+\n+\t\t/* For PLL */\n+\t\tstruct {\n+\t\t\tu32 reg_swcr1;\n+\t\t\tu32 reg_swcr3;\n+\t\t};\n+\t};\n+\n+\tstruct clk clk;\n+};\n+\n+#define CCU_COMMON(_id, _name, _parent, _init, _flags)\t\t\t\\\n+\t.name\t\t= #_name,\t\t\t\t\t\\\n+\t.parents\t= (const char *[]) { _parent },\t\t\t\\\n+\t.num_parents\t= 1,\t\t\t\t\t\t\\\n+\t.init\t\t= _init,\t\t\t\t\t\\\n+\t.clk\t\t= { .flags = _flags, .id = _id, }\t\t\\\n+\n+#define CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, _init, _flags)\t\\\n+\t.name\t\t= #_name,\t\t\t\t\t\\\n+\t.parents\t= _parents,\t\t\t\t\t\\\n+\t.num_parents\t= _num_p,\t\t\t\t\t\\\n+\t.init\t\t= _init,\t\t\t\t\t\\\n+\t.clk\t\t= { .flags = _flags, .id = _id, }\t\t\\\n+\n+static inline struct ccu_common *clk_to_ccu_common(struct clk *clk)\n+{\n+\treturn container_of(clk, struct ccu_common, clk);\n+}\n+\n+#define ccu_read(c, reg)\t\t\t\t\t\t\\\n+\t({\t\t\t\t\t\t\t\t\\\n+\t\tstruct ccu_common * const __ccu = (c);\t\t\t\\\n+\t\tu32 tmp;\t\t\t\t\t\t\\\n+\t\tregmap_read(__ccu->regmap, __ccu->reg_##reg, &tmp);\t\\\n+\t\ttmp;\t\t\t\t\t\t\t\\\n+\t })\n+#define ccu_update(c, reg, mask, val) \\\n+\t({\t\t\t\t\t\t\t\t\\\n+\t\tstruct ccu_common * const __ccu = (c);\t\t\t\\\n+\t\tregmap_update_bits(__ccu->regmap, __ccu->reg_##reg,\t\\\n+\t\t\t\t mask, val);\t\t\t\t\\\n+\t})\n+\n+#endif /* _CLK_COMMON_H_ */\ndiff --git a/drivers/clk/spacemit/clk_ddn.c b/drivers/clk/spacemit/clk_ddn.c\nnew file mode 100644\nindex 00000000000..7b93f30d5c3\n--- /dev/null\n+++ b/drivers/clk/spacemit/clk_ddn.c\n@@ -0,0 +1,93 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd\n+ * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>\n+ * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+ * Authors: Haylen Chu <heylenay@4d2.org>\n+ *\n+ * DDN stands for \"Divider Denominator Numerator\", it's M/N clock with a\n+ * constant x2 factor. This clock hardware follows the equation below,\n+ *\n+ *\t numerator Fin\n+ *\t2 * ------------- = -------\n+ *\t denominator Fout\n+ *\n+ * Thus, Fout could be calculated with,\n+ *\n+ *\t\tFin\tdenominator\n+ *\tFout = ----- * -------------\n+ *\t\t 2\t numerator\n+ */\n+\n+#include <dm/device.h>\n+#include <regmap.h>\n+#include <linux/clk-provider.h>\n+#include <linux/rational.h>\n+\n+#include \"clk_ddn.h\"\n+\n+#define UBOOT_DM_SPACEMIT_CLK_DDN \"spacemit_clk_ddn\"\n+\n+static unsigned long ccu_ddn_calc_rate(unsigned long prate, unsigned long num,\n+\t\t\t\t unsigned long den, unsigned int pre_div)\n+{\n+\treturn prate * den / pre_div / num;\n+}\n+\n+static unsigned long ccu_ddn_calc_best_rate(struct ccu_ddn *ddn,\n+\t\t\t\t\t unsigned long rate, unsigned long prate,\n+\t\t\t\t\t unsigned long *num, unsigned long *den)\n+{\n+\trational_best_approximation(rate, prate / ddn->pre_div,\n+\t\t\t\t ddn->den_mask >> ddn->den_shift,\n+\t\t\t\t ddn->num_mask >> ddn->num_shift,\n+\t\t\t\t den, num);\n+\treturn ccu_ddn_calc_rate(prate, *num, *den, ddn->pre_div);\n+}\n+\n+static unsigned long ccu_ddn_recalc_rate(struct clk *clk)\n+{\n+\tstruct ccu_ddn *ddn = clk_to_ccu_ddn(clk);\n+\tunsigned int val, num, den;\n+\n+\tval = ccu_read(&ddn->common, ctrl);\n+\n+\tnum = (val & ddn->num_mask) >> ddn->num_shift;\n+\tden = (val & ddn->den_mask) >> ddn->den_shift;\n+\n+\treturn ccu_ddn_calc_rate(clk_get_parent_rate(clk), num, den, ddn->pre_div);\n+}\n+\n+static unsigned long ccu_ddn_set_rate(struct clk *clk, unsigned long rate)\n+{\n+\tstruct ccu_ddn *ddn = clk_to_ccu_ddn(clk);\n+\tunsigned long num, den;\n+\n+\tccu_ddn_calc_best_rate(ddn, rate, clk_get_parent_rate(clk), &num, &den);\n+\n+\tccu_update(&ddn->common, ctrl,\n+\t\t ddn->num_mask | ddn->den_mask,\n+\t\t (num << ddn->num_shift) | (den << ddn->den_shift));\n+\n+\treturn 0;\n+}\n+\n+static const struct clk_ops spacemit_clk_ddn_ops = {\n+\t.get_rate = ccu_ddn_recalc_rate,\n+\t.set_rate = ccu_ddn_set_rate,\n+};\n+\n+int spacemit_ddn_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DDN,\n+\t\t\t common->name, common->parents[0]);\n+}\n+\n+U_BOOT_DRIVER(spacemit_clk_ddn) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_DDN,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_ddn_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\ndiff --git a/drivers/clk/spacemit/clk_ddn.h b/drivers/clk/spacemit/clk_ddn.h\nnew file mode 100644\nindex 00000000000..1330ced23b1\n--- /dev/null\n+++ b/drivers/clk/spacemit/clk_ddn.h\n@@ -0,0 +1,53 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/*\n+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd\n+ * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>\n+ * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+ * Copyright (c) 2025-2026 RISCstar Ltd.\n+ *\n+ * Authors: Haylen Chu <heylenay@4d2.org>\n+ */\n+\n+#ifndef _CLK_DDN_H_\n+#define _CLK_DDN_H_\n+\n+#include <linux/clk-provider.h>\n+\n+#include \"clk_common.h\"\n+\n+struct ccu_ddn {\n+\tstruct ccu_common common;\n+\tunsigned int num_mask;\n+\tunsigned int num_shift;\n+\tunsigned int den_mask;\n+\tunsigned int den_shift;\n+\tunsigned int pre_div;\n+};\n+\n+#define CCU_DDN_MASK(_num_shift, _num_width)\t\t\t\t\t\\\n+\tGENMASK((_num_shift) + (_num_width) - 1, _num_shift)\n+\n+#define CCU_DDN_DEFINE(_id, _var, _name, _parent, _reg_ctrl, _num_mask,\t\t\\\n+\t\t _num_shift, _den_mask, _den_shift, _pre_div, _flags)\t\\\n+static struct ccu_ddn _var = {\t\t\t\t\t\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\t\\\n+\t\tCCU_COMMON(_id, _name, _parent, spacemit_ddn_init, _flags)\t\\\n+\t},\t\t\t\t\t\t\t\t\t\\\n+\t.num_mask\t= _num_mask,\t\t\t\t\t\t\\\n+\t.num_shift\t= _num_shift,\t\t\t\t\t\t\\\n+\t.den_mask\t= _den_mask,\t\t\t\t\t\t\\\n+\t.den_shift\t= _den_shift,\t\t\t\t\t\t\\\n+\t.pre_div\t= _pre_div,\t\t\t\t\t\t\\\n+}\n+\n+static inline struct ccu_ddn *clk_to_ccu_ddn(struct clk *clk)\n+{\n+\tstruct ccu_common *common = clk_to_ccu_common(clk);\n+\n+\treturn container_of(common, struct ccu_ddn, common);\n+}\n+\n+int spacemit_ddn_init(struct ccu_common *common);\n+\n+#endif /* _CLK_DDN_H_ */\ndiff --git a/drivers/clk/spacemit/clk_mix.c b/drivers/clk/spacemit/clk_mix.c\nnew file mode 100644\nindex 00000000000..a1158512a92\n--- /dev/null\n+++ b/drivers/clk/spacemit/clk_mix.c\n@@ -0,0 +1,403 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd\n+ * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>\n+ * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+ * Authors: Haylen Chu <heylenay@4d2.org>\n+ *\n+ * MIX clock type is the combination of mux, factor or divider, and gate\n+ */\n+\n+#include <dm/device.h>\n+#include <dm/uclass.h>\n+#include <div64.h>\n+#include <regmap.h>\n+#include <linux/clk-provider.h>\n+#include <linux/kernel.h>\n+\n+#include \"clk_mix.h\"\n+\n+#define UBOOT_DM_SPACEMIT_CLK_GATE\t\t\"spacemit_clk_gate\"\n+#define UBOOT_DM_SPACEMIT_CLK_FACTOR\t\t\"spacemit_clk_factor\"\n+#define UBOOT_DM_SPACEMIT_CLK_MUX\t\t\"spacemit_clk_mux\"\n+#define UBOOT_DM_SPACEMIT_CLK_DIV\t\t\"spacemit_clk_div\"\n+#define UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE\t\"spacemit_clk_factor_gate\"\n+#define UBOOT_DM_SPACEMIT_CLK_MUX_GATE\t\t\"spacemit_clk_mux_gate\"\n+#define UBOOT_DM_SPACEMIT_CLK_DIV_GATE\t\t\"spacemit_clk_div_gate\"\n+#define UBOOT_DM_SPACEMIT_CLK_MUX_DIV\t\t\"spacemit_clk_mux_div\"\n+#define UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE\t\"spacemit_clk_mux_div_gate\"\n+\n+#define MIX_FC_TIMEOUT_US\t10000\n+#define MIX_FC_DELAY_US\t\t5\n+\n+int ccu_gate_disable(struct clk *clk)\n+{\n+\tstruct ccu_mix *mix = clk_to_ccu_mix(clk);\n+\n+\tccu_update(&mix->common, ctrl, mix->gate.mask, 0);\n+\n+\treturn 0;\n+}\n+\n+int ccu_gate_enable(struct clk *clk)\n+{\n+\tstruct ccu_mix *mix = clk_to_ccu_mix(clk);\n+\tstruct ccu_gate_config *gate = &mix->gate;\n+\n+\tccu_update(&mix->common, ctrl, gate->mask, gate->mask);\n+\n+\treturn 0;\n+}\n+\n+static unsigned long ccu_factor_recalc_rate(struct clk *clk)\n+{\n+\tstruct ccu_mix *mix = clk_to_ccu_mix(clk);\n+\n+\treturn clk_get_parent_rate(clk) * mix->factor.mul / mix->factor.div;\n+}\n+\n+static unsigned long ccu_div_recalc_rate(struct clk *clk)\n+{\n+\tstruct ccu_mix *mix = clk_to_ccu_mix(clk);\n+\tstruct ccu_div_config *div = &mix->div;\n+\tunsigned long val;\n+\n+\tval = ccu_read(&mix->common, ctrl) >> div->shift;\n+\tval &= (1 << div->width) - 1;\n+\n+\treturn divider_recalc_rate(clk, clk_get_parent_rate(clk), val, NULL, 0, div->width);\n+}\n+\n+/*\n+ * Some clocks require a \"FC\" (frequency change) bit to be set after changing\n+ * their rates or reparenting. This bit will be automatically cleared by\n+ * hardware in MIX_FC_TIMEOUT_US, which indicates the operation is completed.\n+ */\n+static int ccu_mix_trigger_fc(struct clk *clk)\n+{\n+\tstruct ccu_common *common = clk_to_ccu_common(clk);\n+\tunsigned int val;\n+\n+\tif (common->reg_fc)\n+\t\treturn 0;\n+\n+\tccu_update(common, fc, common->mask_fc, common->mask_fc);\n+\n+\treturn regmap_read_poll_timeout(common->regmap, common->reg_fc,\n+\t\t\t\t\tval, !(val & common->mask_fc),\n+\t\t\t\t\tMIX_FC_DELAY_US,\n+\t\t\t\t\tMIX_FC_TIMEOUT_US);\n+}\n+\n+static unsigned long\n+ccu_mix_calc_best_rate(struct clk *clk, unsigned long rate,\n+\t\t struct clk **best_parent,\n+\t\t unsigned long *best_parent_rate,\n+\t\t u32 *div_val)\n+{\n+\tstruct ccu_common *common = clk_to_ccu_common(clk);\n+\tstruct ccu_mix *mix = clk_to_ccu_mix(clk);\n+\tunsigned int parent_num = common->num_parents;\n+\tstruct ccu_div_config *div = &mix->div;\n+\tu32 div_max = 1 << div->width;\n+\tunsigned long best_rate = 0;\n+\n+\tfor (int i = 0; i < parent_num; i++) {\n+\t\tstruct udevice *parent_dev;\n+\t\tunsigned long parent_rate;\n+\t\tstruct clk *parent;\n+\n+\t\tif (uclass_get_device_by_name(UCLASS_CLK, common->parents[i],\n+\t\t\t\t\t &parent_dev))\n+\t\t\tcontinue;\n+\t\tparent = dev_get_clk_ptr(parent_dev);\n+\t\tif (!parent)\n+\t\t\tcontinue;\n+\n+\t\tparent_rate = clk_get_rate(parent);\n+\n+\t\tfor (int j = 1; j <= div_max; j++) {\n+\t\t\tunsigned long tmp = DIV_ROUND_CLOSEST_ULL(parent_rate, j);\n+\n+\t\t\tif (abs(tmp - rate) < abs(best_rate - rate)) {\n+\t\t\t\tbest_rate = tmp;\n+\n+\t\t\t\tif (div_val)\n+\t\t\t\t\t*div_val = j - 1;\n+\n+\t\t\t\tif (best_parent) {\n+\t\t\t\t\t*best_parent = parent;\n+\t\t\t\t\t*best_parent_rate = parent_rate;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn best_rate;\n+}\n+\n+static unsigned long ccu_mix_set_rate(struct clk *clk, unsigned long rate)\n+{\n+\tstruct ccu_mix *mix = clk_to_ccu_mix(clk);\n+\tstruct ccu_common *common = &mix->common;\n+\tstruct ccu_div_config *div = &mix->div;\n+\tu32 current_div, target_div, mask;\n+\n+\tccu_mix_calc_best_rate(clk, rate, NULL, NULL, &target_div);\n+\n+\tcurrent_div = ccu_read(common, ctrl) >> div->shift;\n+\tcurrent_div &= (1 << div->width) - 1;\n+\n+\tif (current_div == target_div)\n+\t\treturn 0;\n+\n+\tmask = GENMASK(div->width + div->shift - 1, div->shift);\n+\n+\tccu_update(common, ctrl, mask, target_div << div->shift);\n+\n+\treturn ccu_mix_trigger_fc(clk);\n+}\n+\n+static u8 ccu_mux_get_parent(struct clk *clk)\n+{\n+\tstruct ccu_mix *mix = clk_to_ccu_mix(clk);\n+\tstruct ccu_mux_config *mux = &mix->mux;\n+\tu8 parent;\n+\n+\tparent = ccu_read(&mix->common, ctrl) >> mux->shift;\n+\tparent &= (1 << mux->width) - 1;\n+\n+\treturn parent;\n+}\n+\n+static int ccu_mux_set_parent(struct clk *clk, struct clk *parent)\n+{\n+\tstruct ccu_common *common = clk_to_ccu_common(clk);\n+\tstruct ccu_mix *mix = clk_to_ccu_mix(clk);\n+\tstruct ccu_mux_config *mux = &mix->mux;\n+\tu32 mask;\n+\tint i = 0;\n+\n+\tmask = GENMASK(mux->width + mux->shift - 1, mux->shift);\n+\n+\tfor (i = 0; i < common->num_parents; i++) {\n+\t\tif (!strcmp(parent->dev->name, common->parents[i]))\n+\t\t\tbreak;\n+\t}\n+\n+\tif (i == common->num_parents)\n+\t\treturn -EINVAL;\n+\n+\tccu_update(&mix->common, ctrl, mask, i << mux->shift);\n+\n+\treturn ccu_mix_trigger_fc(clk);\n+}\n+\n+int spacemit_gate_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_GATE,\n+\t\t\t common->name, common->parents[0]);\n+}\n+\n+static const struct clk_ops spacemit_clk_gate_ops = {\n+\t.disable\t= ccu_gate_disable,\n+\t.enable\t\t= ccu_gate_enable,\n+\t.get_rate\t= clk_generic_get_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_gate) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_GATE,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_gate_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+int spacemit_factor_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_FACTOR,\n+\t\t\t common->name, common->parents[0]);\n+}\n+\n+static const struct clk_ops spacemit_clk_factor_ops = {\n+\t.get_rate\t= ccu_factor_recalc_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_factor) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_FACTOR,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_factor_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+int spacemit_mux_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\tu8 index;\n+\n+\tindex = ccu_mux_get_parent(clk);\n+\tif (index >= common->num_parents)\n+\t\tindex = 0;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX,\n+\t\t\t common->name, common->parents[index]);\n+}\n+\n+static const struct clk_ops spacemit_clk_mux_ops = {\n+\t.set_parent\t= ccu_mux_set_parent,\n+\t.get_rate\t= clk_generic_get_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_mux) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_MUX,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_mux_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+int spacemit_div_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DIV,\n+\t\t\t common->name, common->parents[0]);\n+}\n+\n+static const struct clk_ops spacemit_clk_div_ops = {\n+\t.get_rate\t= ccu_div_recalc_rate,\n+\t.set_rate\t= ccu_mix_set_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_div) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_DIV,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_div_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+int spacemit_factor_gate_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE,\n+\t\t\t common->name, common->parents[0]);\n+}\n+\n+static const struct clk_ops spacemit_clk_factor_gate_ops = {\n+\t.disable\t= ccu_gate_disable,\n+\t.enable\t\t= ccu_gate_enable,\n+\t.get_rate\t= ccu_factor_recalc_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_factor_gate) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_factor_gate_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+int spacemit_mux_gate_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\tu8 index;\n+\n+\tindex = ccu_mux_get_parent(clk);\n+\tif (index >= common->num_parents)\n+\t\tindex = 0;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_GATE,\n+\t\t\t common->name, common->parents[index]);\n+}\n+\n+static const struct clk_ops spacemit_clk_mux_gate_ops = {\n+\t.disable\t= ccu_gate_disable,\n+\t.enable\t\t= ccu_gate_enable,\n+\t.set_parent\t= ccu_mux_set_parent,\n+\t.get_rate\t= clk_generic_get_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_mux_gate) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_MUX_GATE,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_mux_gate_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+int spacemit_div_gate_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DIV_GATE,\n+\t\t\t common->name, common->parents[0]);\n+}\n+\n+static const struct clk_ops spacemit_clk_div_gate_ops = {\n+\t.disable\t= ccu_gate_disable,\n+\t.enable\t\t= ccu_gate_enable,\n+\t.get_rate\t= ccu_div_recalc_rate,\n+\t.set_rate\t= ccu_mix_set_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_div_gate) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_DIV_GATE,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_div_gate_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+int spacemit_mux_div_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\tu8 index;\n+\n+\tindex = ccu_mux_get_parent(clk);\n+\tif (index >= common->num_parents)\n+\t\tindex = 0;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_DIV,\n+\t\t\t common->name, common->parents[index]);\n+}\n+\n+static const struct clk_ops spacemit_clk_mux_div_ops = {\n+\t.set_parent\t= ccu_mux_set_parent,\n+\t.get_rate\t= ccu_div_recalc_rate,\n+\t.set_rate\t= ccu_mix_set_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_mux_div) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_MUX_DIV,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_mux_div_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\n+\n+int spacemit_mux_div_gate_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\tu8 index;\n+\n+\tindex = ccu_mux_get_parent(clk);\n+\tif (index >= common->num_parents)\n+\t\tindex = 0;\n+\n+\treturn clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE,\n+\t\t\t common->name, common->parents[index]);\n+}\n+\n+static const struct clk_ops spacemit_clk_mux_div_gate_ops = {\n+\t.disable\t= ccu_gate_disable,\n+\t.enable\t\t= ccu_gate_enable,\n+\t.set_parent\t= ccu_mux_set_parent,\n+\t.get_rate\t= ccu_div_recalc_rate,\n+\t.set_rate\t= ccu_mix_set_rate,\n+};\n+\n+U_BOOT_DRIVER(spacemit_clk_mux_div_gate) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_mux_div_gate_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\ndiff --git a/drivers/clk/spacemit/clk_mix.h b/drivers/clk/spacemit/clk_mix.h\nnew file mode 100644\nindex 00000000000..26a12cedd0d\n--- /dev/null\n+++ b/drivers/clk/spacemit/clk_mix.h\n@@ -0,0 +1,224 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/*\n+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd\n+ * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>\n+ * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+ * Copyright (c) 2025-2026 RISCstar Ltd.\n+ *\n+ * Authors: Haylen Chu <heylenay@4d2.org>\n+ */\n+\n+#ifndef _CLK_MIX_H_\n+#define _CLK_MIX_H_\n+\n+#include <linux/clk-provider.h>\n+\n+#include \"clk_common.h\"\n+\n+/**\n+ * struct ccu_gate_config - Gate configuration\n+ *\n+ * @mask:\tMask to enable the gate. Some clocks may have more than one bit\n+ *\t\tset in this field.\n+ */\n+struct ccu_gate_config {\n+\tu32 mask;\n+};\n+\n+struct ccu_factor_config {\n+\tu32 div;\n+\tu32 mul;\n+};\n+\n+struct ccu_mux_config {\n+\tu8 shift;\n+\tu8 width;\n+};\n+\n+struct ccu_div_config {\n+\tu8 shift;\n+\tu8 width;\n+};\n+\n+struct ccu_mix {\n+\tstruct ccu_factor_config factor;\n+\tstruct ccu_gate_config gate;\n+\tstruct ccu_div_config div;\n+\tstruct ccu_mux_config mux;\n+\tstruct ccu_common common;\n+};\n+\n+#define CCU_GATE_INIT(_mask)\t\t{ .mask = _mask }\n+#define CCU_FACTOR_INIT(_div, _mul)\t{ .div = _div, .mul = _mul }\n+#define CCU_MUX_INIT(_shift, _width)\t{ .shift = _shift, .width = _width }\n+#define CCU_DIV_INIT(_shift, _width)\t{ .shift = _shift, .width = _width }\n+\n+#define CCU_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl,\t\t\\\n+\t\t\t_mask_gate, _flags)\t\t\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.gate\t= CCU_GATE_INIT(_mask_gate),\t\t\t\t\\\n+\t.common\t= {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\tCCU_COMMON(_id, _name, _parent, spacemit_gate_init,\t\\\n+\t\t\t _flags)\t\t\t\t\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_FACTOR_DEFINE(_id, _var, _name, _parent, _div, _mul)\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.factor\t= CCU_FACTOR_INIT(_div, _mul),\t\t\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\\\n+\t\tCCU_COMMON(_id, _name, _parent, spacemit_factor_init,\t\\\n+\t\t\t 0)\t\t\t\t\t\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_MUX_DEFINE(_id, _var, _name, _parents, _num_p, _reg_ctrl,\t\\\n+\t\t _shift, _width, _flags)\t\t\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.mux\t= CCU_MUX_INIT(_shift, _width),\t\t\t\t\\\n+\t.common\t= {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\tCCU_COMMON_PARENTS(_id, _name, _parents, _num_p,\t\\\n+\t\t\t\t spacemit_mux_init, _flags)\t\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_DIV_DEFINE(_id, _var, _name, _parent, _reg_ctrl, _shift,\t\\\n+\t\t _width, _flags)\t\t\t\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.div\t= CCU_DIV_INIT(_shift, _width),\t\t\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\tCCU_COMMON(_id, _name, _parent, spacemit_div_init,\t\\\n+\t\t\t _flags)\t\t\t\t\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_FACTOR_GATE_FLAGS_DEFINE(_id, _var, _name, _parent,\t\t\\\n+\t\t\t\t _reg_ctrl,\t_mask_gate, _div, _mul,\t\\\n+\t\t\t\t _flags)\t\t\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.gate\t= CCU_GATE_INIT(_mask_gate),\t\t\t\t\\\n+\t.factor\t= CCU_FACTOR_INIT(_div, _mul),\t\t\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\tCCU_COMMON(_id, _name, _parent,\t\t\t\t\\\n+\t\t\t spacemit_factor_gate_init, _flags)\t\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_FACTOR_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl,\t\\\n+\t\t\t _mask_gate, _div, _mul)\t\t\t\\\n+\tCCU_FACTOR_GATE_FLAGS_DEFINE(_id, _var, _name, _parent,\t\t\\\n+\t\t\t\t _reg_ctrl,\t_mask_gate, _div, _mul,\t\\\n+\t\t\t\t 0)\n+\n+#define CCU_MUX_GATE_DEFINE(_id, _var, _name, _parents, _num_p,\t\t\\\n+\t\t\t _reg_ctrl, _shift, _width, _mask_gate,\t\\\n+\t\t\t _flags)\t\t\t\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.gate\t= CCU_GATE_INIT(_mask_gate),\t\t\t\t\\\n+\t.mux\t= CCU_MUX_INIT(_shift, _width),\t\t\t\t\\\n+\t.common\t= {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\tCCU_COMMON_PARENTS(_id, _name, _parents, _num_p,\t\\\n+\t\t\t\t spacemit_mux_gate_init, _flags)\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_DIV_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl,\t\\\n+\t\t\t _shift, _width, _mask_gate,\t_flags)\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.gate\t= CCU_GATE_INIT(_mask_gate),\t\t\t\t\\\n+\t.div\t= CCU_DIV_INIT(_shift, _width),\t\t\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\tCCU_COMMON(_id, _name, _parent,\t\t\t\t\\\n+\t\t\t spacemit_div_gate_init, _flags)\t\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_MUX_DIV_GATE_DEFINE(_id, _var, _name, _parents, _num_p,\t\\\n+\t\t\t\t_reg_ctrl, _mshift, _mwidth, _muxshift,\t\\\n+\t\t\t\t_muxwidth, _mask_gate, _flags)\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.gate\t= CCU_GATE_INIT(_mask_gate),\t\t\t\t\\\n+\t.div\t= CCU_DIV_INIT(_mshift, _mwidth),\t\t\t\\\n+\t.mux\t= CCU_MUX_INIT(_muxshift, _muxwidth),\t\t\t\\\n+\t.common\t= {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\tCCU_COMMON_PARENTS(_id, _name, _parents, _num_p,\t\\\n+\t\t\t\t spacemit_mux_div_gate_init, _flags)\t\\\n+\t},\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_id, _var, _name, _parents,\t\\\n+\t\t\t\t\t _num_p, _reg_ctrl, _reg_fc,\t\\\n+\t\t\t\t\t _mshift, _mwidth, _mask_fc,\t\\\n+\t\t\t\t\t _muxshift, _muxwidth,\t\t\\\n+\t\t\t\t\t _mask_gate, _flags)\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.gate\t= CCU_GATE_INIT(_mask_gate),\t\t\t\t\\\n+\t.div\t= CCU_DIV_INIT(_mshift, _mwidth),\t\t\t\\\n+\t.mux\t= CCU_MUX_INIT(_muxshift, _muxwidth),\t\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\t.reg_fc\t\t= _reg_fc,\t\t\t\t\\\n+\t\t.mask_fc\t= _mask_fc,\t\t\t\t\\\n+\t\tCCU_COMMON_PARENTS(_id, _name, _parents, _num_p,\t\\\n+\t\t\t\t spacemit_mux_div_gate_init, _flags)\t\\\n+\t},\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_MUX_DIV_FC_DEFINE(_id, _var, _name, _parents, _num_p,\t\\\n+\t\t\t _reg_ctrl, _reg_fc, _mshift, _mwidth,\t\\\n+\t\t\t _mask_fc,\t_muxshift, _muxwidth, _flags)\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.div\t= CCU_DIV_INIT(_mshift, _mwidth),\t\t\t\\\n+\t.mux\t= CCU_MUX_INIT(_muxshift, _muxwidth),\t\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\t.reg_fc\t\t= _reg_fc,\t\t\t\t\\\n+\t\t.mask_fc\t= _mask_fc,\t\t\t\t\\\n+\t\tCCU_COMMON_PARENTS(_id, _name, _parents, _num_p,\t\\\n+\t\t\t\t spacemit_mux_div_init, _flags)\t\\\n+\t},\t\t\t\t\t\t\t\t\\\n+}\n+\n+#define CCU_MUX_FC_DEFINE(_id, _var, _name, _parents, _num_p,\t\t\\\n+\t\t\t _reg_ctrl, _reg_fc, _mask_fc, _muxshift,\t\\\n+\t\t\t _muxwidth, _flags)\t\t\t\t\\\n+static struct ccu_mix _var = {\t\t\t\t\t\t\\\n+\t.mux\t= CCU_MUX_INIT(_muxshift, _muxwidth),\t\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\\\n+\t\t.reg_ctrl\t= _reg_ctrl,\t\t\t\t\\\n+\t\t.reg_fc\t\t= _reg_fc,\t\t\t\t\\\n+\t\t.mask_fc\t= _mask_fc,\t\t\t\t\\\n+\t\tCCU_COMMON_PARENTS(_id, _name, _parents, _num_p,\t\\\n+\t\t\t\t spacemit_mux_init,\t\t\t\\\n+\t\t\t\t _flags)\t\t\t\t\\\n+\t},\t\t\t\t\t\t\t\t\\\n+}\n+\n+static inline struct ccu_mix *clk_to_ccu_mix(struct clk *clk)\n+{\n+\tstruct ccu_common *common = clk_to_ccu_common(clk);\n+\n+\treturn container_of(common, struct ccu_mix, common);\n+}\n+\n+int ccu_gate_enable(struct clk *clk);\n+int ccu_gate_disable(struct clk *clk);\n+\n+int spacemit_gate_init(struct ccu_common *common);\n+int spacemit_factor_init(struct ccu_common *common);\n+int spacemit_mux_init(struct ccu_common *common);\n+int spacemit_div_init(struct ccu_common *common);\n+int spacemit_factor_gate_init(struct ccu_common *common);\n+int spacemit_div_gate_init(struct ccu_common *common);\n+int spacemit_mux_gate_init(struct ccu_common *common);\n+int spacemit_mux_div_init(struct ccu_common *common);\n+int spacemit_mux_div_gate_init(struct ccu_common *common);\n+\n+#endif /* _CLK_MIX_H_ */\ndiff --git a/drivers/clk/spacemit/clk_pll.c b/drivers/clk/spacemit/clk_pll.c\nnew file mode 100644\nindex 00000000000..56da70af58a\n--- /dev/null\n+++ b/drivers/clk/spacemit/clk_pll.c\n@@ -0,0 +1,157 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd\n+ * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>\n+ * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+ * Authors: Haylen Chu <heylenay@4d2.org>\n+ */\n+\n+#include <dm/device.h>\n+#include <regmap.h>\n+#include <linux/bug.h>\n+#include <linux/clk-provider.h>\n+\n+#include \"clk_pll.h\"\n+\n+#define UBOOT_DM_SPACEMIT_CLK_PLL \"spacemit_clk_pll\"\n+\n+#define PLL_TIMEOUT_US\t\t3000\n+#define PLL_DELAY_US\t\t5\n+\n+#define PLL_SWCR3_EN\t\t((u32)BIT(31))\n+#define PLL_SWCR3_MASK\t\tGENMASK(30, 0)\n+\n+static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_pll *pll,\n+\t\t\t\t\t\t\t unsigned long rate)\n+{\n+\tstruct ccu_pll_config *config = &pll->config;\n+\tconst struct ccu_pll_rate_tbl *best_entry;\n+\tunsigned long best_delta = ULONG_MAX;\n+\tint i;\n+\n+\tfor (i = 0; i < config->tbl_num; i++) {\n+\t\tconst struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i];\n+\t\tunsigned long delta = abs(entry->rate - rate);\n+\n+\t\tif (delta < best_delta) {\n+\t\t\tbest_delta = delta;\n+\t\t\tbest_entry = entry;\n+\t\t}\n+\t}\n+\n+\treturn best_entry;\n+}\n+\n+static const struct ccu_pll_rate_tbl *ccu_pll_lookup_matched_entry(struct ccu_pll *pll)\n+{\n+\tstruct ccu_pll_config *config = &pll->config;\n+\tu32 swcr1, swcr3;\n+\tint i;\n+\n+\tswcr1 = ccu_read(&pll->common, swcr1);\n+\tswcr3 = ccu_read(&pll->common, swcr3);\n+\tswcr3 &= PLL_SWCR3_MASK;\n+\n+\tfor (i = 0; i < config->tbl_num; i++) {\n+\t\tconst struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i];\n+\n+\t\tif (swcr1 == entry->swcr1 && swcr3 == entry->swcr3)\n+\t\t\treturn entry;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static void ccu_pll_update_param(struct ccu_pll *pll, const struct ccu_pll_rate_tbl *entry)\n+{\n+\tstruct ccu_common *common = &pll->common;\n+\n+\tregmap_write(common->regmap, common->reg_swcr1, entry->swcr1);\n+\tccu_update(common, swcr3, PLL_SWCR3_MASK, entry->swcr3);\n+}\n+\n+static int ccu_pll_enable(struct clk *clk)\n+{\n+\tstruct ccu_pll *pll = clk_to_ccu_pll(clk);\n+\tstruct ccu_common *common = &pll->common;\n+\tunsigned int tmp;\n+\n+\tccu_update(common, swcr3, PLL_SWCR3_EN, PLL_SWCR3_EN);\n+\n+\t/* check lock status */\n+\treturn regmap_read_poll_timeout(common->lock_regmap,\n+\t\t\t\t\tpll->config.reg_lock,\n+\t\t\t\t\ttmp,\n+\t\t\t\t\ttmp & pll->config.mask_lock,\n+\t\t\t\t\tPLL_DELAY_US, PLL_TIMEOUT_US);\n+}\n+\n+static int ccu_pll_disable(struct clk *clk)\n+{\n+\tstruct ccu_common *common = clk_to_ccu_common(clk);\n+\n+\tccu_update(common, swcr3, PLL_SWCR3_EN, 0);\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * PLLs must be gated before changing rate, which is ensured by\n+ * flag CLK_SET_RATE_GATE.\n+ */\n+static unsigned long ccu_pll_set_rate(struct clk *clk, unsigned long rate)\n+{\n+\tstruct ccu_pll *pll = clk_to_ccu_pll(clk);\n+\tconst struct ccu_pll_rate_tbl *entry;\n+\n+\tentry = ccu_pll_lookup_best_rate(pll, rate);\n+\tccu_pll_update_param(pll, entry);\n+\n+\treturn 0;\n+}\n+\n+static unsigned long ccu_pll_recalc_rate(struct clk *clk)\n+{\n+\tstruct ccu_pll *pll = clk_to_ccu_pll(clk);\n+\tconst struct ccu_pll_rate_tbl *entry;\n+\n+\tentry = ccu_pll_lookup_matched_entry(pll);\n+\n+\tWARN_ON_ONCE(!entry);\n+\n+\treturn entry ? entry->rate : 0;\n+}\n+\n+static const struct clk_ops spacemit_clk_pll_ops = {\n+\t.enable = ccu_pll_enable,\n+\t.disable = ccu_pll_disable,\n+\t.set_rate = ccu_pll_set_rate,\n+\t.get_rate = ccu_pll_recalc_rate,\n+};\n+\n+int spacemit_pll_init(struct ccu_common *common)\n+{\n+\tstruct clk *clk = &common->clk;\n+\tstruct ccu_pll *pll = clk_to_ccu_pll(clk);\n+\tint ret;\n+\n+\tret = clk_register(clk, UBOOT_DM_SPACEMIT_CLK_PLL,\n+\t\t\t common->name, common->parents[0]);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (ccu_pll_lookup_matched_entry(pll))\n+\t\treturn 0;\n+\n+\tccu_pll_disable(clk);\n+\tccu_pll_update_param(pll, &pll->config.rate_tbl[0]);\n+\n+\treturn 0;\n+}\n+\n+U_BOOT_DRIVER(spacemit_clk_pll) = {\n+\t.name\t= UBOOT_DM_SPACEMIT_CLK_PLL,\n+\t.id\t= UCLASS_CLK,\n+\t.ops\t= &spacemit_clk_pll_ops,\n+\t.flags\t= DM_FLAG_PRE_RELOC,\n+};\ndiff --git a/drivers/clk/spacemit/clk_pll.h b/drivers/clk/spacemit/clk_pll.h\nnew file mode 100644\nindex 00000000000..3987cc1141b\n--- /dev/null\n+++ b/drivers/clk/spacemit/clk_pll.h\n@@ -0,0 +1,81 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/*\n+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd\n+ * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>\n+ * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech>\n+ * Copyright (c) 2025-2026 RISCstar Ltd.\n+ *\n+ * Authors: Haylen Chu <heylenay@4d2.org>\n+ */\n+\n+#ifndef _CLK_PLL_H_\n+#define _CLK_PLL_H_\n+\n+#include <linux/clk-provider.h>\n+\n+#include \"clk_common.h\"\n+\n+/**\n+ * struct ccu_pll_rate_tbl - Structure mapping between PLL rate and register\n+ * configuration.\n+ *\n+ * @rate:\tPLL rate\n+ * @swcr1:\tRegister value of PLLX_SW1_CTRL (PLLx_SWCR1).\n+ * @swcr3:\tRegister value of the PLLx_SW3_CTRL's lowest 31 bits of\n+ *\t\tPLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling\n+ *\t\tthe PLL and not contained in this field.\n+ */\n+struct ccu_pll_rate_tbl {\n+\tunsigned long rate;\n+\tu32 swcr1;\n+\tu32 swcr3;\n+};\n+\n+#define CCU_PLL_RATE(_rate, _swcr1, _swcr3)\t\\\n+\t{\t\t\t\t\t\\\n+\t\t.rate\t= _rate,\t\t\\\n+\t\t.swcr1\t= _swcr1,\t\t\\\n+\t\t.swcr3\t= _swcr3,\t\t\\\n+\t}\n+\n+struct ccu_pll_config {\n+\tconst struct ccu_pll_rate_tbl *rate_tbl;\n+\tu32 tbl_num;\n+\tu32 reg_lock;\n+\tu32 mask_lock;\n+};\n+\n+struct ccu_pll {\n+\tstruct ccu_common\tcommon;\n+\tstruct ccu_pll_config\tconfig;\n+};\n+\n+#define CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock) \\\n+\t{\t\t\t\t\t\t\t\t\t\\\n+\t\t.rate_tbl\t= (_table),\t\t\t\t\t\\\n+\t\t.tbl_num\t= sizeof(_table) / sizeof((_table)[0]),\t\t\\\n+\t\t.reg_lock\t= (_reg_lock),\t\t\t\t\t\\\n+\t\t.mask_lock\t= (_mask_lock),\t\t\t\t\t\\\n+\t}\n+\n+#define CCU_PLL_DEFINE(_id, _var, _name, _parent, _table, _reg_swcr1,\t\t\\\n+\t\t _reg_swcr3, _reg_lock, _mask_lock, _flags)\t\t\\\n+static struct ccu_pll _var = {\t\t\t\t\t\t\t\\\n+\t.config\t= CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock),\t\t\\\n+\t.common = {\t\t\t\t\t\t\t\t\\\n+\t\t.reg_swcr1\t= _reg_swcr1,\t\t\t\t\t\\\n+\t\t.reg_swcr3\t= _reg_swcr3,\t\t\t\t\t\\\n+\t\tCCU_COMMON(_id, _name, _parent, spacemit_pll_init, _flags)\t\\\n+\t}\t\t\t\t\t\t\t\t\t\\\n+}\n+\n+static inline struct ccu_pll *clk_to_ccu_pll(struct clk *clk)\n+{\n+\tstruct ccu_common *common = clk_to_ccu_common(clk);\n+\n+\treturn container_of(common, struct ccu_pll, common);\n+}\n+\n+int spacemit_pll_init(struct ccu_common *common);\n+\n+#endif /* _CLK_PLL_H_ */\ndiff --git a/include/soc/spacemit/k1-syscon.h b/include/soc/spacemit/k1-syscon.h\nnew file mode 100644\nindex 00000000000..331cc1d35bb\n--- /dev/null\n+++ b/include/soc/spacemit/k1-syscon.h\n@@ -0,0 +1,149 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+\n+/* SpacemiT clock and reset driver definitions for the K1 SoC */\n+\n+#ifndef __SOC_K1_SYSCON_H__\n+#define __SOC_K1_SYSCON_H__\n+\n+/* APBS register offset */\n+#define APBS_PLL1_SWCR1\t\t\t0x100\n+#define APBS_PLL1_SWCR2\t\t\t0x104\n+#define APBS_PLL1_SWCR3\t\t\t0x108\n+#define APBS_PLL2_SWCR1\t\t\t0x118\n+#define APBS_PLL2_SWCR2\t\t\t0x11c\n+#define APBS_PLL2_SWCR3\t\t\t0x120\n+#define APBS_PLL3_SWCR1\t\t\t0x124\n+#define APBS_PLL3_SWCR2\t\t\t0x128\n+#define APBS_PLL3_SWCR3\t\t\t0x12c\n+\n+/* MPMU register offset */\n+#define MPMU_POSR\t\t\t0x0010\n+#define MPMU_FCCR\t\t\t0x0008\n+#define POSR_PLL1_LOCK\t\t\tBIT(27)\n+#define POSR_PLL2_LOCK\t\t\tBIT(28)\n+#define POSR_PLL3_LOCK\t\t\tBIT(29)\n+#define MPMU_SUCCR\t\t\t0x0014\n+#define MPMU_ISCCR\t\t\t0x0044\n+#define MPMU_WDTPCR\t\t\t0x0200\n+#define MPMU_RIPCCR\t\t\t0x0210\n+#define MPMU_ACGR\t\t\t0x1024\n+#define MPMU_APBCSCR\t\t\t0x1050\n+#define MPMU_SUCCR_1\t\t\t0x10b0\n+\n+/* APBC register offset */\n+#define APBC_UART1_CLK_RST\t\t0x00\n+#define APBC_UART2_CLK_RST\t\t0x04\n+#define APBC_GPIO_CLK_RST\t\t0x08\n+#define APBC_PWM0_CLK_RST\t\t0x0c\n+#define APBC_PWM1_CLK_RST\t\t0x10\n+#define APBC_PWM2_CLK_RST\t\t0x14\n+#define APBC_PWM3_CLK_RST\t\t0x18\n+#define APBC_TWSI8_CLK_RST\t\t0x20\n+#define APBC_UART3_CLK_RST\t\t0x24\n+#define APBC_RTC_CLK_RST\t\t0x28\n+#define APBC_TWSI0_CLK_RST\t\t0x2c\n+#define APBC_TWSI1_CLK_RST\t\t0x30\n+#define APBC_TIMERS1_CLK_RST\t\t0x34\n+#define APBC_TWSI2_CLK_RST\t\t0x38\n+#define APBC_AIB_CLK_RST\t\t0x3c\n+#define APBC_TWSI4_CLK_RST\t\t0x40\n+#define APBC_TIMERS2_CLK_RST\t\t0x44\n+#define APBC_ONEWIRE_CLK_RST\t\t0x48\n+#define APBC_TWSI5_CLK_RST\t\t0x4c\n+#define APBC_DRO_CLK_RST\t\t0x58\n+#define APBC_IR_CLK_RST\t\t\t0x5c\n+#define APBC_TWSI6_CLK_RST\t\t0x60\n+#define APBC_COUNTER_CLK_SEL\t\t0x64\n+#define APBC_TWSI7_CLK_RST\t\t0x68\n+#define APBC_TSEN_CLK_RST\t\t0x6c\n+#define APBC_UART4_CLK_RST\t\t0x70\n+#define APBC_UART5_CLK_RST\t\t0x74\n+#define APBC_UART6_CLK_RST\t\t0x78\n+#define APBC_SSP3_CLK_RST\t\t0x7c\n+#define APBC_SSPA0_CLK_RST\t\t0x80\n+#define APBC_SSPA1_CLK_RST\t\t0x84\n+#define APBC_IPC_AP2AUD_CLK_RST\t\t0x90\n+#define APBC_UART7_CLK_RST\t\t0x94\n+#define APBC_UART8_CLK_RST\t\t0x98\n+#define APBC_UART9_CLK_RST\t\t0x9c\n+#define APBC_CAN0_CLK_RST\t\t0xa0\n+#define APBC_PWM4_CLK_RST\t\t0xa8\n+#define APBC_PWM5_CLK_RST\t\t0xac\n+#define APBC_PWM6_CLK_RST\t\t0xb0\n+#define APBC_PWM7_CLK_RST\t\t0xb4\n+#define APBC_PWM8_CLK_RST\t\t0xb8\n+#define APBC_PWM9_CLK_RST\t\t0xbc\n+#define APBC_PWM10_CLK_RST\t\t0xc0\n+#define APBC_PWM11_CLK_RST\t\t0xc4\n+#define APBC_PWM12_CLK_RST\t\t0xc8\n+#define APBC_PWM13_CLK_RST\t\t0xcc\n+#define APBC_PWM14_CLK_RST\t\t0xd0\n+#define APBC_PWM15_CLK_RST\t\t0xd4\n+#define APBC_PWM16_CLK_RST\t\t0xd8\n+#define APBC_PWM17_CLK_RST\t\t0xdc\n+#define APBC_PWM18_CLK_RST\t\t0xe0\n+#define APBC_PWM19_CLK_RST\t\t0xe4\n+\n+/* APMU register offset */\n+#define APMU_JPG_CLK_RES_CTRL\t\t0x020\n+#define APMU_CSI_CCIC2_CLK_RES_CTRL\t0x024\n+#define APMU_ISP_CLK_RES_CTRL\t\t0x038\n+#define APMU_LCD_CLK_RES_CTRL1\t\t0x044\n+#define APMU_LCD_SPI_CLK_RES_CTRL\t0x048\n+#define APMU_LCD_CLK_RES_CTRL2\t\t0x04c\n+#define APMU_CCIC_CLK_RES_CTRL\t\t0x050\n+#define APMU_SDH0_CLK_RES_CTRL\t\t0x054\n+#define APMU_SDH1_CLK_RES_CTRL\t\t0x058\n+#define APMU_USB_CLK_RES_CTRL\t\t0x05c\n+#define APMU_QSPI_CLK_RES_CTRL\t\t0x060\n+#define APMU_DMA_CLK_RES_CTRL\t\t0x064\n+#define APMU_AES_CLK_RES_CTRL\t\t0x068\n+#define APMU_VPU_CLK_RES_CTRL\t\t0x0a4\n+#define APMU_GPU_CLK_RES_CTRL\t\t0x0cc\n+#define APMU_SDH2_CLK_RES_CTRL\t\t0x0e0\n+#define APMU_PMUA_MC_CTRL\t\t0x0e8\n+#define APMU_PMU_CC2_AP\t\t\t0x100\n+#define APMU_PMUA_EM_CLK_RES_CTRL\t0x104\n+#define APMU_AUDIO_CLK_RES_CTRL\t\t0x14c\n+#define APMU_HDMI_CLK_RES_CTRL\t\t0x1b8\n+#define APMU_CCI550_CLK_CTRL\t\t0x300\n+#define APMU_ACLK_CLK_CTRL\t\t0x388\n+#define APMU_CPU_C0_CLK_CTRL\t\t0x38C\n+#define APMU_CPU_C1_CLK_CTRL\t\t0x390\n+#define APMU_PCIE_CLK_RES_CTRL_0\t0x3cc\n+#define APMU_PCIE_CLK_RES_CTRL_1\t0x3d4\n+#define APMU_PCIE_CLK_RES_CTRL_2\t0x3dc\n+#define APMU_EMAC0_CLK_RES_CTRL\t\t0x3e4\n+#define APMU_EMAC1_CLK_RES_CTRL\t\t0x3ec\n+\n+/* RCPU register offsets */\n+#define RCPU_SSP0_CLK_RST\t\t0x0028\n+#define RCPU_I2C0_CLK_RST\t\t0x0030\n+#define RCPU_UART1_CLK_RST\t\t0x003c\n+#define RCPU_CAN_CLK_RST\t\t0x0048\n+#define RCPU_IR_CLK_RST\t\t\t0x004c\n+#define RCPU_UART0_CLK_RST\t\t0x00d8\n+#define AUDIO_HDMI_CLK_CTRL\t\t0x2044\n+\n+/* RCPU2 register offsets */\n+#define RCPU2_PWM0_CLK_RST\t\t0x0000\n+#define RCPU2_PWM1_CLK_RST\t\t0x0004\n+#define RCPU2_PWM2_CLK_RST\t\t0x0008\n+#define RCPU2_PWM3_CLK_RST\t\t0x000c\n+#define RCPU2_PWM4_CLK_RST\t\t0x0010\n+#define RCPU2_PWM5_CLK_RST\t\t0x0014\n+#define RCPU2_PWM6_CLK_RST\t\t0x0018\n+#define RCPU2_PWM7_CLK_RST\t\t0x001c\n+#define RCPU2_PWM8_CLK_RST\t\t0x0020\n+#define RCPU2_PWM9_CLK_RST\t\t0x0024\n+\n+/* APBC2 register offsets */\n+#define APBC2_UART1_CLK_RST\t\t0x0000\n+#define APBC2_SSP2_CLK_RST\t\t0x0004\n+#define APBC2_TWSI3_CLK_RST\t\t0x0008\n+#define APBC2_RTC_CLK_RST\t\t0x000c\n+#define APBC2_TIMERS0_CLK_RST\t\t0x0010\n+#define APBC2_KPC_CLK_RST\t\t0x0014\n+#define APBC2_GPIO_CLK_RST\t\t0x001c\n+\n+#endif /* __SOC_K1_SYSCON_H__ */\n", "prefixes": [ "v2", "07/16" ] }