From patchwork Thu Mar 6 17:57:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haylen Chu X-Patchwork-Id: 14005083 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3C165C28B24 for ; Thu, 6 Mar 2025 18:00:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=zCCy4JfXK0PWdoZriS+0/cKb8mFtm3hgNOfovjfg4FQ=; b=y7g0NtKmUzf7qr gisv5chuUyD3Ih5CFV3LQiWqaj47HPpvG5wwS8cfiZsyNFpDRFTQlueHxAve4OR57qGKYhQ9twcUt ZtOnJJa829lnZ+QTQxoS+UA1cwoIWoMYBK7qQeDcvfo/kOqlKnSFalFjVroHmSwhKHR+FHxEwlcU4 EYeRrziMztHkZWAbskrT36Q7Mm+oroMY0zpMy0X4Bis+TexdA/op26XNT32P6trH2TiIwLcWXEhw8 as7U3YpUZgN8CNiA1KtaHa3tw5Ua78D9R8qItWED2L2sc6p9FrftN4ZutZbhJQukpHQOvZmAsGNWs qqwyI/TZb99ARBQm74rA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tqFVm-0000000BljQ-06wo; Thu, 06 Mar 2025 17:59:58 +0000 Received: from bayard.4d2.org ([155.254.16.17]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tqFVi-0000000Blhp-3syB for linux-riscv@lists.infradead.org; Thu, 06 Mar 2025 17:59:56 +0000 Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1]) by bayard.4d2.org (Postfix) with ESMTP id 42068EC59F5; Thu, 06 Mar 2025 09:59:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741283994; bh=pBpY3vSiCJ0IC8h4F+XRlrj+Tvn/Dd4xA1lbHaifk94=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Jbq2Oe+KjwO1KT0BvCdCbfz48uo/yBHNy+pqecv6A+1OyT/k9rJy/BPncU3ThYyUF CTEqKsHJ7+NkkOB59E7Y0ys4tJ4hsNfvHWqQ5YXt4EvipVhb+wlyHqQ7s8g0vyEA90 MFEB8s8xtgA4OqKSveIX69J2BA9yKHUIs8ITt3it0xUiXQjEcspOhtbTzD67NhaTNT NLuKNkws1N59DGfHfk/36SsXPxmTamGh58vg9n+Fhbe+ybUltj+HR4YKB54djgru4P +NqUpiq7oZ4d8uN4qWJf7I38c4T0olCgjdqZvuLstNjO0Mu1iiUHbF2i1lR5TouRCd yMbt4IUboke8A== X-Virus-Scanned: amavisd-new at 4d2.org Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key) header.d=4d2.org Received: from bayard.4d2.org ([127.0.0.1]) by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qDI-AcHUpMCP; Thu, 6 Mar 2025 09:59:52 -0800 (PST) Received: from localhost.localdomain (unknown [183.217.80.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) (Authenticated sender: heylenay@4d2.org) by bayard.4d2.org (Postfix) with ESMTPSA id 55A42EC59F6; Thu, 06 Mar 2025 09:59:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741283992; bh=pBpY3vSiCJ0IC8h4F+XRlrj+Tvn/Dd4xA1lbHaifk94=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JoGcLgTssZp7AUy1kLjjBySCN4vwwQ04wDg+p+WB4+uTzDcMR1YiLXPeI9mEArgvn 8NvdM+Po9xcb18N9mRLoSpokVQlgpMXmIIpqMo51O6A8RR5sPNXgkl1adyged7G7wP YggDvLT5N1gFjvV3YBoxsuoc7q00g+PrHhTAknptFDM/CngUgejIn+fGTzR7g6uj7f U4ahD9Aj7NSUA3fKGeI9nUXy7EnLuccqR4eIaXiLzJIGK259HDx90iQnJzc+v1mmGj 901nlKbn7LggGsCNu/q5onoyqI4aCFAFaCkHo1smnZcnAxf9dbH4MhHbVps3tigybF 55f70Tukz9sqw== From: Haylen Chu To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Haylen Chu , Yixun Lan Cc: linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, spacemit@lists.linux.dev, Inochi Amaoto , Chen Wang , Jisheng Zhang , Meng Zhang , Haylen Chu Subject: [PATCH v5 1/5] dt-bindings: soc: spacemit: Add spacemit,k1-syscon Date: Thu, 6 Mar 2025 17:57:47 +0000 Message-ID: <20250306175750.22480-3-heylenay@4d2.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250306175750.22480-2-heylenay@4d2.org> References: <20250306175750.22480-2-heylenay@4d2.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_095954_992291_8F87AD6B X-CRM114-Status: GOOD ( 11.95 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Document APMU, MPMU and APBC syscons found on Spacemit K1 SoC, which are capable of generating clock and reset signals. Additionally, APMU and MPMU manage power domains. Signed-off-by: Haylen Chu Reviewed-by: Krzysztof Kozlowski --- .../soc/spacemit/spacemit,k1-syscon.yaml | 80 +++++++ include/dt-bindings/clock/spacemit,k1-ccu.h | 210 ++++++++++++++++++ 2 files changed, 290 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml create mode 100644 include/dt-bindings/clock/spacemit,k1-ccu.h diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml new file mode 100644 index 000000000000..07a6728e6f86 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Spacemit K1 SoC System Controller + +maintainers: + - Haylen Chu + +description: + System controllers found on Spacemit K1 SoC, which are capable of + clock, reset and power-management functions. + +properties: + compatible: + enum: + - spacemit,k1-syscon-apbc + - spacemit,k1-syscon-apmu + - spacemit,k1-syscon-mpmu + + reg: + maxItems: 1 + + clocks: + maxItems: 4 + + clock-names: + items: + - const: osc + - const: vctcxo_1m + - const: vctcxo_3m + - const: vctcxo_24m + + "#clock-cells": + const: 1 + description: + See for valid indices. + + "#power-domain-cells": + const: 1 + + "#reset-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + - "#reset-cells" + +allOf: + - if: + properties: + compatible: + contains: + const: spacemit,k1-syscon-apbc + then: + properties: + "#power-domain-cells": false + else: + required: + - "#power-domain-cells" + +additionalProperties: false + +examples: + - | + system-controller@d4050000 { + compatible = "spacemit,k1-syscon-mpmu"; + reg = <0xd4050000 0x209c>; + clocks = <&osc>, <&vctcxo_1m>, <&vctcxo_3m>, <&vctcxo_24m>; + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", "vctcxo_24m"; + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; + }; diff --git a/include/dt-bindings/clock/spacemit,k1-ccu.h b/include/dt-bindings/clock/spacemit,k1-ccu.h new file mode 100644 index 000000000000..1f8b01db44ca --- /dev/null +++ b/include/dt-bindings/clock/spacemit,k1-ccu.h @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2024 Haylen Chu + */ + +#ifndef _DT_BINDINGS_SPACEMIT_CCU_H_ +#define _DT_BINDINGS_SPACEMIT_CCU_H_ + +/* MPMU clocks */ +#define CLK_PLL1_307P2 0 +#define CLK_PLL1_76P8 1 +#define CLK_PLL1_61P44 2 +#define CLK_PLL1_153P6 3 +#define CLK_PLL1_102P4 4 +#define CLK_PLL1_51P2 5 +#define CLK_PLL1_51P2_AP 6 +#define CLK_PLL1_57P6 7 +#define CLK_PLL1_25P6 8 +#define CLK_PLL1_12P8 9 +#define CLK_PLL1_12P8_WDT 10 +#define CLK_PLL1_6P4 11 +#define CLK_PLL1_3P2 12 +#define CLK_PLL1_1P6 13 +#define CLK_PLL1_0P8 14 +#define CLK_PLL1_409P6 15 +#define CLK_PLL1_204P8 16 +#define CLK_PLL1_491 17 +#define CLK_PLL1_245P76 18 +#define CLK_PLL1_614 19 +#define CLK_PLL1_47P26 20 +#define CLK_PLL1_31P5 21 +#define CLK_PLL1_819 22 +#define CLK_PLL1_1228 23 +#define CLK_SLOW_UART 24 +#define CLK_SLOW_UART1 25 +#define CLK_SLOW_UART2 26 +#define CLK_WDT 27 +#define CLK_RIPC 28 +#define CLK_I2S_SYSCLK 29 +#define CLK_I2S_BCLK 30 +#define CLK_APB 31 +#define CLK_WDT_BUS 32 + +/* APBC clocks */ +#define CLK_UART0 0 +#define CLK_UART2 1 +#define CLK_UART3 2 +#define CLK_UART4 3 +#define CLK_UART5 4 +#define CLK_UART6 5 +#define CLK_UART7 6 +#define CLK_UART8 7 +#define CLK_UART9 8 +#define CLK_GPIO 9 +#define CLK_PWM0 10 +#define CLK_PWM1 11 +#define CLK_PWM2 12 +#define CLK_PWM3 13 +#define CLK_PWM4 14 +#define CLK_PWM5 15 +#define CLK_PWM6 16 +#define CLK_PWM7 17 +#define CLK_PWM8 18 +#define CLK_PWM9 19 +#define CLK_PWM10 20 +#define CLK_PWM11 21 +#define CLK_PWM12 22 +#define CLK_PWM13 23 +#define CLK_PWM14 24 +#define CLK_PWM15 25 +#define CLK_PWM16 26 +#define CLK_PWM17 27 +#define CLK_PWM18 28 +#define CLK_PWM19 29 +#define CLK_SSP3 30 +#define CLK_RTC 31 +#define CLK_TWSI0 32 +#define CLK_TWSI1 33 +#define CLK_TWSI2 34 +#define CLK_TWSI4 35 +#define CLK_TWSI5 36 +#define CLK_TWSI6 37 +#define CLK_TWSI7 38 +#define CLK_TWSI8 39 +#define CLK_TIMERS1 40 +#define CLK_TIMERS2 41 +#define CLK_AIB 42 +#define CLK_ONEWIRE 43 +#define CLK_SSPA0 44 +#define CLK_SSPA1 45 +#define CLK_DRO 46 +#define CLK_IR 47 +#define CLK_TSEN 48 +#define CLK_IPC_AP2AUD 49 +#define CLK_CAN0 50 +#define CLK_CAN0_BUS 51 +#define CLK_UART0_BUS 52 +#define CLK_UART2_BUS 53 +#define CLK_UART3_BUS 54 +#define CLK_UART4_BUS 55 +#define CLK_UART5_BUS 56 +#define CLK_UART6_BUS 57 +#define CLK_UART7_BUS 58 +#define CLK_UART8_BUS 59 +#define CLK_UART9_BUS 60 +#define CLK_GPIO_BUS 61 +#define CLK_PWM0_BUS 62 +#define CLK_PWM1_BUS 63 +#define CLK_PWM2_BUS 64 +#define CLK_PWM3_BUS 65 +#define CLK_PWM4_BUS 66 +#define CLK_PWM5_BUS 67 +#define CLK_PWM6_BUS 68 +#define CLK_PWM7_BUS 69 +#define CLK_PWM8_BUS 70 +#define CLK_PWM9_BUS 71 +#define CLK_PWM10_BUS 72 +#define CLK_PWM11_BUS 73 +#define CLK_PWM12_BUS 74 +#define CLK_PWM13_BUS 75 +#define CLK_PWM14_BUS 76 +#define CLK_PWM15_BUS 77 +#define CLK_PWM16_BUS 78 +#define CLK_PWM17_BUS 79 +#define CLK_PWM18_BUS 80 +#define CLK_PWM19_BUS 81 +#define CLK_SSP3_BUS 82 +#define CLK_RTC_BUS 83 +#define CLK_TWSI0_BUS 84 +#define CLK_TWSI1_BUS 85 +#define CLK_TWSI2_BUS 86 +#define CLK_TWSI4_BUS 87 +#define CLK_TWSI5_BUS 88 +#define CLK_TWSI6_BUS 89 +#define CLK_TWSI7_BUS 90 +#define CLK_TWSI8_BUS 91 +#define CLK_TIMERS1_BUS 92 +#define CLK_TIMERS2_BUS 93 +#define CLK_AIB_BUS 94 +#define CLK_ONEWIRE_BUS 95 +#define CLK_SSPA0_BUS 96 +#define CLK_SSPA1_BUS 97 +#define CLK_TSEN_BUS 98 +#define CLK_IPC_AP2AUD_BUS 99 + +/* APMU clocks */ +#define CLK_CCI550 0 +#define CLK_CPU_C0_HI 1 +#define CLK_CPU_C0_CORE 2 +#define CLK_CPU_C0_ACE 3 +#define CLK_CPU_C0_TCM 4 +#define CLK_CPU_C1_HI 5 +#define CLK_CPU_C1_CORE 6 +#define CLK_CPU_C1_ACE 7 +#define CLK_CCIC_4X 8 +#define CLK_CCIC1PHY 9 +#define CLK_SDH_AXI 10 +#define CLK_SDH0 11 +#define CLK_SDH1 12 +#define CLK_SDH2 13 +#define CLK_USB_P1 14 +#define CLK_USB_AXI 15 +#define CLK_USB30 16 +#define CLK_QSPI 17 +#define CLK_QSPI_BUS 18 +#define CLK_DMA 19 +#define CLK_AES 20 +#define CLK_VPU 21 +#define CLK_GPU 22 +#define CLK_EMMC 23 +#define CLK_EMMC_X 24 +#define CLK_AUDIO 25 +#define CLK_HDMI 26 +#define CLK_PMUA_ACLK 27 +#define CLK_PCIE0_MASTER 28 +#define CLK_PCIE0_SLAVE 29 +#define CLK_PCIE0_DBI 30 +#define CLK_PCIE1_MASTER 31 +#define CLK_PCIE1_SLAVE 32 +#define CLK_PCIE1_DBI 33 +#define CLK_PCIE2_MASTER 34 +#define CLK_PCIE2_SLAVE 35 +#define CLK_PCIE2_DBI 36 +#define CLK_EMAC0_BUS 37 +#define CLK_EMAC0_PTP 38 +#define CLK_EMAC1_BUS 39 +#define CLK_EMAC1_PTP 40 +#define CLK_JPG 41 +#define CLK_CCIC2PHY 42 +#define CLK_CCIC3PHY 43 +#define CLK_CSI 44 +#define CLK_CAMM0 45 +#define CLK_CAMM1 46 +#define CLK_CAMM2 47 +#define CLK_ISP_CPP 48 +#define CLK_ISP_BUS 49 +#define CLK_ISP 50 +#define CLK_DPU_MCLK 51 +#define CLK_DPU_ESC 52 +#define CLK_DPU_BIT 53 +#define CLK_DPU_PXCLK 54 +#define CLK_DPU_HCLK 55 +#define CLK_DPU_SPI 56 +#define CLK_DPU_SPI_HBUS 57 +#define CLK_DPU_SPIBUS 58 +#define CLK_DPU_SPI_ACLK 59 +#define CLK_V2D 60 +#define CLK_EMMC_BUS 61 + +#endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */ From patchwork Thu Mar 6 17:57:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haylen Chu X-Patchwork-Id: 14005084 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B8462C282D1 for ; Thu, 6 Mar 2025 18:00:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=xboZw0BbNjUKU1oHOn4Kexkd2mz+Uf/iQAxqOChU8EM=; b=TuozvUODYzDuop k35cTtb6bKFCXa/ZQ4i1kT0jVPfW0zit7ItIwlAEqeMaG3GNv9iCK1ZXaMnPKyiWlo5Ac4WbLOYsx FAkiMLEvxRVda+bRmTGQiUyYnmGSWAfJUBDXNI/c2bLk/Jo+gR/ln31vaMKOiPAef9vTjNwSnfePC 4ff5BbqGnlPY/S6IiQXiHA5Le6uep+j05X/NhNuwId8+5+eQOSRx8cQ5ihGtTw8ahO9kmI2Q+QlnQ mKkMx3hmdzirxjmXblMNVnr8GHV6pMfUA9a2FmTBlAQ4fS0ZehAxH3LF76AXVn/IQIbnzXINKq+gC LrrqWirhgPXEJC8daFcg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tqFVp-0000000Blm3-2f6m; Thu, 06 Mar 2025 18:00:01 +0000 Received: from bayard.4d2.org ([155.254.16.17]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tqFVm-0000000BlkB-3UbM for linux-riscv@lists.infradead.org; Thu, 06 Mar 2025 18:00:00 +0000 Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1]) by bayard.4d2.org (Postfix) with ESMTP id 44C43EC59F9; Thu, 06 Mar 2025 09:59:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741283998; bh=dgfOnH6vaz3LkYGcL/Dct4SIHTh2z+vvYg+nnzOSCU4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PjXw0kq35mn3snnLe7pv3CntmmjT8Jz1N/4I2HEeVU8ufzlvWrgyXFDz3ew1uDTN7 hVZJWT7Zg7cAzeuI8CFIbrPfAFvAZgFcC/a1pup2QaXqbMuYqUms5XLRVGrR/ALbna FKk4ezXoBuQmiSWlszBP2Bh9zrSfb57K+W6a2G/CY5jrkf8ZO+dici6bIxAfv/yqmt 7v+pIvDGTwv3hmr3zVAjvf0MN/5F80PGm/iE3oUZjvQRXNcur2J48uuGxzS4lFE5JJ fPYxyHZXUdrOEPe3VjLBdeHXuUUtYk0vKIpkUfgWEBng9DatoWVqnHILYbWkZVsc0d CAmtCiDjBzp2Q== X-Virus-Scanned: amavisd-new at 4d2.org Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key) header.d=4d2.org Received: from bayard.4d2.org ([127.0.0.1]) by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id onNjsI1Wy5tz; Thu, 6 Mar 2025 09:59:56 -0800 (PST) Received: from localhost.localdomain (unknown [183.217.80.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) (Authenticated sender: heylenay@4d2.org) by bayard.4d2.org (Postfix) with ESMTPSA id CEF69EC59F2; Thu, 06 Mar 2025 09:59:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741283996; bh=dgfOnH6vaz3LkYGcL/Dct4SIHTh2z+vvYg+nnzOSCU4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cOI8oZDTz/pdDx/qJhqBY/ETwnfyGNorWVt9UHeIZgUqFTu3LCYzlofG62KbjBWyo 4K3rFAGozl2dhpnw20SbHrag2ood+I1luFSPe/F/xaFc/+FqUvo6t+5viBNvCpPueq +vf/mTlOCYm0EQo8no++oiSCkk+8dKvSCS5taHCbmsfrDY4mE57djqaWqUopgC/pbA 7EOOzcaudTVL8QQkTk2u2wNNWRj9zJ9bQV+hyw4+a8rErCwcoPIwthlrSIrprC1PCx 9Nv7vdcmV2bLdE2qmTs6da7dA8jPBbu4o/vpFbtaKjcKFtekKIkUAMLDSSynsMZGw0 o3StRxU57Euag== From: Haylen Chu To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Haylen Chu , Yixun Lan Cc: linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, spacemit@lists.linux.dev, Inochi Amaoto , Chen Wang , Jisheng Zhang , Meng Zhang , Haylen Chu Subject: [PATCH v5 2/5] dt-bindings: clock: spacemit: Add spacemit,k1-pll Date: Thu, 6 Mar 2025 17:57:48 +0000 Message-ID: <20250306175750.22480-4-heylenay@4d2.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250306175750.22480-2-heylenay@4d2.org> References: <20250306175750.22480-2-heylenay@4d2.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_095958_922119_CA2B76BB X-CRM114-Status: GOOD ( 13.02 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Add definition for the PLL found on Spacemit K1 SoC, which takes the external 24MHz oscillator as input and generates clocks in various frequencies for the system. Signed-off-by: Haylen Chu Reviewed-by: Krzysztof Kozlowski --- .../bindings/clock/spacemit,k1-pll.yaml | 50 +++++++++++++++++++ include/dt-bindings/clock/spacemit,k1-ccu.h | 37 ++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml diff --git a/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml new file mode 100644 index 000000000000..23d7aa1bc573 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/spacemit,k1-pll.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Spacemit K1 PLL + +maintainers: + - Haylen Chu + +properties: + compatible: + const: spacemit,k1-pll + + reg: + maxItems: 1 + + clocks: + description: External 24MHz oscillator + + spacemit,mpmu: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to the "Main PMU (MPMU)" syscon. It is used to check PLL + lock status. + + "#clock-cells": + const: 1 + description: + See for valid indices. + +required: + - compatible + - reg + - clocks + - spacemit,mpmu + - "#clock-cells" + +additionalProperties: false + +examples: + - | + clock-controller@d4090000 { + compatible = "spacemit,k1-pll"; + reg = <0xd4090000 0x1000>; + clocks = <&vctcxo_24m>; + spacemit,mpmu = <&sysctl_mpmu>; + #clock-cells = <1>; + }; diff --git a/include/dt-bindings/clock/spacemit,k1-ccu.h b/include/dt-bindings/clock/spacemit,k1-ccu.h index 1f8b01db44ca..4a0c7163257e 100644 --- a/include/dt-bindings/clock/spacemit,k1-ccu.h +++ b/include/dt-bindings/clock/spacemit,k1-ccu.h @@ -6,6 +6,43 @@ #ifndef _DT_BINDINGS_SPACEMIT_CCU_H_ #define _DT_BINDINGS_SPACEMIT_CCU_H_ +/* APBS (PLL) clocks */ +#define CLK_PLL1 0 +#define CLK_PLL2 1 +#define CLK_PLL3 2 +#define CLK_PLL1_D2 3 +#define CLK_PLL1_D3 4 +#define CLK_PLL1_D4 5 +#define CLK_PLL1_D5 6 +#define CLK_PLL1_D6 7 +#define CLK_PLL1_D7 8 +#define CLK_PLL1_D8 9 +#define CLK_PLL1_D11 10 +#define CLK_PLL1_D13 11 +#define CLK_PLL1_D23 12 +#define CLK_PLL1_D64 13 +#define CLK_PLL1_D10_AUD 14 +#define CLK_PLL1_D100_AUD 15 +#define CLK_PLL2_D1 16 +#define CLK_PLL2_D2 17 +#define CLK_PLL2_D3 18 +#define CLK_PLL2_D4 19 +#define CLK_PLL2_D5 20 +#define CLK_PLL2_D6 21 +#define CLK_PLL2_D7 22 +#define CLK_PLL2_D8 23 +#define CLK_PLL3_D1 24 +#define CLK_PLL3_D2 25 +#define CLK_PLL3_D3 26 +#define CLK_PLL3_D4 27 +#define CLK_PLL3_D5 28 +#define CLK_PLL3_D6 29 +#define CLK_PLL3_D7 30 +#define CLK_PLL3_D8 31 +#define CLK_PLL3_80 32 +#define CLK_PLL3_40 33 +#define CLK_PLL3_20 34 + /* MPMU clocks */ #define CLK_PLL1_307P2 0 #define CLK_PLL1_76P8 1 From patchwork Thu Mar 6 17:57:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haylen Chu X-Patchwork-Id: 14005086 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6C85AC282D1 for ; Thu, 6 Mar 2025 18:00:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=nyLhOfRTQ9TCknpiKj7omffVjPJazb4tn+njMwZTwp8=; b=qghYHj7pFNlzmi mwNHx1vMGI0LuSi2juiyo3J2un10lkdyBUkAqeb1CyVlD+QnBZ6Z6HI1tG1jI5VnGEww7NvGkiWUG +j/DT1J3bWL3wrb+Ggbuovu5Gv9+sExWIf0+8UE0N4CibXZIyF2WkKc0DV/p1bkWbmIDwYn9TkCHw 8udJUDsB5tgfOIxeMEEIrF+V9NBwNF22nIpBxgK9XxoRpzpPUkivKa3cFtR/t4AhMIaX7FhqvdyqP FPGCr624VEBHr6+vpvvE/ZzRnGZzk0u0UH3kOp1cczcqsupPrbDZyBIvzm8+VUx47krAAQk/yFcoF 2wxKS6svMf1/0lVyIudw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tqFVx-0000000Blrf-17dL; Thu, 06 Mar 2025 18:00:09 +0000 Received: from bayard.4d2.org ([155.254.16.17]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tqFVu-0000000Blox-0icf for linux-riscv@lists.infradead.org; Thu, 06 Mar 2025 18:00:08 +0000 Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1]) by bayard.4d2.org (Postfix) with ESMTP id 975B1EC59F8; Thu, 06 Mar 2025 10:00:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741284005; bh=vDE0X+bqvGG/58Jhlrp2fVXVcCOq2I+Pi26zrm4aRdc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mcltjaYJHY/UDgRucqayYjzlVq8QmBUmar8H5C14Dj3K3/cYw9z89nLQLsNylWpJ7 1RnaLA51N5hea+94JH/Q+K+Nz5Wb9Ui6UJLHb98OuGkHTXS6ju2M9Tas9JyRmxZKZF mblGJmElXnvIv++h+rYDKijT7R1QJH8jzo8miX45q/aDVlOZ7xAFLCeQCLcQhFF/FZ CK/VxUj3eEaBvZx33KLZ2JPFAHeypF3ojAFmp51/3ZprPbzbASNMSpvjGP7lN+BCHy Jxq9zKf0AZhwwhY5TLS2MujoU26qR2JRt3RtSjfwUNvR5xNKxgil+wimJjbip7TAF6 S7lLg79by8sQA== X-Virus-Scanned: amavisd-new at 4d2.org Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key) header.d=4d2.org Received: from bayard.4d2.org ([127.0.0.1]) by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WOYFz1oZcDGZ; Thu, 6 Mar 2025 10:00:03 -0800 (PST) Received: from localhost.localdomain (unknown [183.217.80.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) (Authenticated sender: heylenay@4d2.org) by bayard.4d2.org (Postfix) with ESMTPSA id 27023EC59F6; Thu, 06 Mar 2025 09:59:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741284003; bh=vDE0X+bqvGG/58Jhlrp2fVXVcCOq2I+Pi26zrm4aRdc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jw8fIKBMLDkbLx6A3VMB2uJ2MUxdBPY396yYcI7MWmbPouL87SdYqlgx2cuz57Dsy q8ZtOjbIbqIQZXKaBlz43JA4s956Zxm4ZgwAogdyC6WiyF6badEg2zWY+w2VTOPVXO T/W4WyXsLanZKyI3rYFBe9y+ZOIUWaByWTg0U+taVtdCYtYlM6nfFiSSxvxQ8BwrV3 ONbt1XZKAVGkE675QM3yPWcMQkbzhfZu8rlZvWkDAhEJC1T2vZZ++atPqRGz3EiZwo IseYNfBjptqljyVziTc6Jc9d0Q7NImmzdSE/sfXDo9bH1Q7zsfhxLbWmGZE/BCQIJm /LI46HhcWG6mw== From: Haylen Chu To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Haylen Chu , Yixun Lan Cc: linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, spacemit@lists.linux.dev, Inochi Amaoto , Chen Wang , Jisheng Zhang , Meng Zhang , Haylen Chu Subject: [PATCH v5 3/5] clk: spacemit: Add clock support for Spacemit K1 SoC Date: Thu, 6 Mar 2025 17:57:49 +0000 Message-ID: <20250306175750.22480-5-heylenay@4d2.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250306175750.22480-2-heylenay@4d2.org> References: <20250306175750.22480-2-heylenay@4d2.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_100006_313510_9CDCDDAF X-CRM114-Status: GOOD ( 16.10 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org The clock tree of K1 SoC contains three main types of clock hardware (PLL/DDN/MIX) and has control registers split into several multifunction devices: APBS (PLLs), MPMU, APBC and APMU. All register operations are done through regmap to ensure atomiciy between concurrent operations of clock driver and reset, power-domain driver that will be introduced in the future. Signed-off-by: Haylen Chu --- drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/spacemit/Kconfig | 20 + drivers/clk/spacemit/Makefile | 5 + drivers/clk/spacemit/ccu-k1.c | 1714 +++++++++++++++++++++++++++++ drivers/clk/spacemit/ccu_common.h | 47 + drivers/clk/spacemit/ccu_ddn.c | 80 ++ drivers/clk/spacemit/ccu_ddn.h | 48 + drivers/clk/spacemit/ccu_mix.c | 284 +++++ drivers/clk/spacemit/ccu_mix.h | 246 +++++ drivers/clk/spacemit/ccu_pll.c | 146 +++ drivers/clk/spacemit/ccu_pll.h | 76 ++ 12 files changed, 2668 insertions(+) create mode 100644 drivers/clk/spacemit/Kconfig create mode 100644 drivers/clk/spacemit/Makefile create mode 100644 drivers/clk/spacemit/ccu-k1.c create mode 100644 drivers/clk/spacemit/ccu_common.h create mode 100644 drivers/clk/spacemit/ccu_ddn.c create mode 100644 drivers/clk/spacemit/ccu_ddn.h create mode 100644 drivers/clk/spacemit/ccu_mix.c create mode 100644 drivers/clk/spacemit/ccu_mix.h create mode 100644 drivers/clk/spacemit/ccu_pll.c create mode 100644 drivers/clk/spacemit/ccu_pll.h diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 713573b6c86c..19c1ed280fd7 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -517,6 +517,7 @@ source "drivers/clk/samsung/Kconfig" source "drivers/clk/sifive/Kconfig" source "drivers/clk/socfpga/Kconfig" source "drivers/clk/sophgo/Kconfig" +source "drivers/clk/spacemit/Kconfig" source "drivers/clk/sprd/Kconfig" source "drivers/clk/starfive/Kconfig" source "drivers/clk/sunxi/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index bf4bd45adc3a..42867cd37c33 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -145,6 +145,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ obj-$(CONFIG_CLK_SIFIVE) += sifive/ obj-y += socfpga/ obj-y += sophgo/ +obj-y += spacemit/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-y += sprd/ obj-$(CONFIG_ARCH_STI) += st/ diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig new file mode 100644 index 000000000000..76090cd85668 --- /dev/null +++ b/drivers/clk/spacemit/Kconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config SPACEMIT_CCU + tristate "Clock support for Spacemit SoCs" + default y + depends on ARCH_SPACEMIT || COMPILE_TEST + select MFD_SYSCON + help + Say Y to enable clock controller unit support for Spacemit SoCs. + +if SPACEMIT_CCU + +config SPACEMIT_K1_CCU + tristate "Support for Spacemit K1 SoC" + default y + depends on ARCH_SPACEMIT || COMPILE_TEST + help + Support for clock controller unit in Spacemit K1 SoC. + +endif diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile new file mode 100644 index 000000000000..5ec6da61db98 --- /dev/null +++ b/drivers/clk/spacemit/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_SPACEMIT_K1_CCU) = spacemit-ccu-k1.o +spacemit-ccu-k1-y = ccu_pll.o ccu_mix.o ccu_ddn.o +spacemit-ccu-k1-y += ccu-k1.o diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c new file mode 100644 index 000000000000..5974a0a1b5f6 --- /dev/null +++ b/drivers/clk/spacemit/ccu-k1.c @@ -0,0 +1,1714 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024 Haylen Chu + */ + +#include +#include +#include +#include +#include +#include + +#include "ccu_common.h" +#include "ccu_pll.h" +#include "ccu_mix.h" +#include "ccu_ddn.h" + +#include + +/* APBS register offset */ +#define APBS_PLL1_SWCR1 0x100 +#define APBS_PLL1_SWCR2 0x104 +#define APBS_PLL1_SWCR3 0x108 +#define APBS_PLL2_SWCR1 0x118 +#define APBS_PLL2_SWCR2 0x11c +#define APBS_PLL2_SWCR3 0x120 +#define APBS_PLL3_SWCR1 0x124 +#define APBS_PLL3_SWCR2 0x128 +#define APBS_PLL3_SWCR3 0x12c + +/* MPMU register offset */ +#define MPMU_POSR 0x10 +#define POSR_PLL1_LOCK BIT(27) +#define POSR_PLL2_LOCK BIT(28) +#define POSR_PLL3_LOCK BIT(29) + +#define MPMU_WDTPCR 0x200 +#define MPMU_RIPCCR 0x210 +#define MPMU_ACGR 0x1024 +#define MPMU_SUCCR 0x14 +#define MPMU_ISCCR 0x44 +#define MPMU_SUCCR_1 0x10b0 +#define MPMU_APBCSCR 0x1050 + +/* APBC register offset */ +#define APBC_UART1_CLK_RST 0x0 +#define APBC_UART2_CLK_RST 0x4 +#define APBC_GPIO_CLK_RST 0x8 +#define APBC_PWM0_CLK_RST 0xc +#define APBC_PWM1_CLK_RST 0x10 +#define APBC_PWM2_CLK_RST 0x14 +#define APBC_PWM3_CLK_RST 0x18 +#define APBC_TWSI8_CLK_RST 0x20 +#define APBC_UART3_CLK_RST 0x24 +#define APBC_RTC_CLK_RST 0x28 +#define APBC_TWSI0_CLK_RST 0x2c +#define APBC_TWSI1_CLK_RST 0x30 +#define APBC_TIMERS1_CLK_RST 0x34 +#define APBC_TWSI2_CLK_RST 0x38 +#define APBC_AIB_CLK_RST 0x3c +#define APBC_TWSI4_CLK_RST 0x40 +#define APBC_TIMERS2_CLK_RST 0x44 +#define APBC_ONEWIRE_CLK_RST 0x48 +#define APBC_TWSI5_CLK_RST 0x4c +#define APBC_DRO_CLK_RST 0x58 +#define APBC_IR_CLK_RST 0x5c +#define APBC_TWSI6_CLK_RST 0x60 +#define APBC_COUNTER_CLK_SEL 0x64 +#define APBC_TWSI7_CLK_RST 0x68 +#define APBC_TSEN_CLK_RST 0x6c +#define APBC_UART4_CLK_RST 0x70 +#define APBC_UART5_CLK_RST 0x74 +#define APBC_UART6_CLK_RST 0x78 +#define APBC_SSP3_CLK_RST 0x7c +#define APBC_SSPA0_CLK_RST 0x80 +#define APBC_SSPA1_CLK_RST 0x84 +#define APBC_IPC_AP2AUD_CLK_RST 0x90 +#define APBC_UART7_CLK_RST 0x94 +#define APBC_UART8_CLK_RST 0x98 +#define APBC_UART9_CLK_RST 0x9c +#define APBC_CAN0_CLK_RST 0xa0 +#define APBC_PWM4_CLK_RST 0xa8 +#define APBC_PWM5_CLK_RST 0xac +#define APBC_PWM6_CLK_RST 0xb0 +#define APBC_PWM7_CLK_RST 0xb4 +#define APBC_PWM8_CLK_RST 0xb8 +#define APBC_PWM9_CLK_RST 0xbc +#define APBC_PWM10_CLK_RST 0xc0 +#define APBC_PWM11_CLK_RST 0xc4 +#define APBC_PWM12_CLK_RST 0xc8 +#define APBC_PWM13_CLK_RST 0xcc +#define APBC_PWM14_CLK_RST 0xd0 +#define APBC_PWM15_CLK_RST 0xd4 +#define APBC_PWM16_CLK_RST 0xd8 +#define APBC_PWM17_CLK_RST 0xdc +#define APBC_PWM18_CLK_RST 0xe0 +#define APBC_PWM19_CLK_RST 0xe4 + +/* APMU register offset */ +#define APMU_JPG_CLK_RES_CTRL 0x20 +#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x24 +#define APMU_ISP_CLK_RES_CTRL 0x38 +#define APMU_LCD_CLK_RES_CTRL1 0x44 +#define APMU_LCD_SPI_CLK_RES_CTRL 0x48 +#define APMU_LCD_CLK_RES_CTRL2 0x4c +#define APMU_CCIC_CLK_RES_CTRL 0x50 +#define APMU_SDH0_CLK_RES_CTRL 0x54 +#define APMU_SDH1_CLK_RES_CTRL 0x58 +#define APMU_USB_CLK_RES_CTRL 0x5c +#define APMU_QSPI_CLK_RES_CTRL 0x60 +#define APMU_DMA_CLK_RES_CTRL 0x64 +#define APMU_AES_CLK_RES_CTRL 0x68 +#define APMU_VPU_CLK_RES_CTRL 0xa4 +#define APMU_GPU_CLK_RES_CTRL 0xcc +#define APMU_SDH2_CLK_RES_CTRL 0xe0 +#define APMU_PMUA_MC_CTRL 0xe8 +#define APMU_PMU_CC2_AP 0x100 +#define APMU_PMUA_EM_CLK_RES_CTRL 0x104 +#define APMU_AUDIO_CLK_RES_CTRL 0x14c +#define APMU_HDMI_CLK_RES_CTRL 0x1b8 +#define APMU_CCI550_CLK_CTRL 0x300 +#define APMU_ACLK_CLK_CTRL 0x388 +#define APMU_CPU_C0_CLK_CTRL 0x38C +#define APMU_CPU_C1_CLK_CTRL 0x390 +#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc +#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4 +#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc +#define APMU_EMAC0_CLK_RES_CTRL 0x3e4 +#define APMU_EMAC1_CLK_RES_CTRL 0x3ec + +/* APBS clocks start */ + +/* Frequency of pll{1,2} should not be updated at runtime */ +static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = { + CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd), +}; + +static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = { + CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000), +}; + +static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = { + CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd), + CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000), + CCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab), +}; + +static CCU_PLL_DEFINE(pll1, pll1_rate_tbl, + APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, + MPMU_POSR, POSR_PLL1_LOCK, CLK_SET_RATE_GATE); +static CCU_PLL_DEFINE(pll2, pll2_rate_tbl, + APBS_PLL2_SWCR1, APBS_PLL2_SWCR3, + MPMU_POSR, POSR_PLL2_LOCK, CLK_SET_RATE_GATE); +static CCU_PLL_DEFINE(pll3, pll3_rate_tbl, + APBS_PLL3_SWCR1, APBS_PLL2_SWCR3, + MPMU_POSR, POSR_PLL3_LOCK, CLK_SET_RATE_GATE); + +static CCU_GATE_FACTOR_DEFINE(pll1_d2, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(1), 2, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d3, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(2), 3, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d4, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(3), 4, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d5, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(4), 5, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d6, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(5), 6, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d7, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(6), 7, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d8, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(7), 8, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d11_223p4, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(15), 11, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d13_189, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(16), 13, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d23_106p8, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(20), 23, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d64_38p4, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(0), 64, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_aud_245p7, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(10), 10, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_aud_24p5, CCU_PARENT_HW(pll1), + APBS_PLL1_SWCR2, + BIT(11), 100, 1, 0); + +static CCU_GATE_FACTOR_DEFINE(pll2_d1, CCU_PARENT_HW(pll2), + APBS_PLL2_SWCR2, + BIT(0), 1, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll2_d2, CCU_PARENT_HW(pll2), + APBS_PLL2_SWCR2, + BIT(1), 2, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll2_d3, CCU_PARENT_HW(pll2), + APBS_PLL2_SWCR2, + BIT(2), 3, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll2_d4, CCU_PARENT_HW(pll2), + APBS_PLL2_SWCR2, + BIT(3), 4, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll2_d5, CCU_PARENT_HW(pll2), + APBS_PLL2_SWCR2, + BIT(4), 5, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll2_d6, CCU_PARENT_HW(pll2), + APBS_PLL2_SWCR2, + BIT(5), 6, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll2_d7, CCU_PARENT_HW(pll2), + APBS_PLL2_SWCR2, + BIT(6), 7, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll2_d8, CCU_PARENT_HW(pll2), + APBS_PLL2_SWCR2, + BIT(7), 8, 1, 0); + +static CCU_GATE_FACTOR_DEFINE(pll3_d1, CCU_PARENT_HW(pll3), + APBS_PLL3_SWCR2, + BIT(0), 1, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll3_d2, CCU_PARENT_HW(pll3), + APBS_PLL3_SWCR2, + BIT(1), 2, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll3_d3, CCU_PARENT_HW(pll3), + APBS_PLL3_SWCR2, + BIT(2), 3, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll3_d4, CCU_PARENT_HW(pll3), + APBS_PLL3_SWCR2, + BIT(3), 4, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll3_d5, CCU_PARENT_HW(pll3), + APBS_PLL3_SWCR2, + BIT(4), 5, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll3_d6, CCU_PARENT_HW(pll3), + APBS_PLL3_SWCR2, + BIT(5), 6, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll3_d7, CCU_PARENT_HW(pll3), + APBS_PLL3_SWCR2, + BIT(6), 7, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll3_d8, CCU_PARENT_HW(pll3), + APBS_PLL3_SWCR2, + BIT(7), 8, 1, 0); + +static CCU_FACTOR_DEFINE(pll3_20, CCU_PARENT_HW(pll3_d8), 20, 1); +static CCU_FACTOR_DEFINE(pll3_40, CCU_PARENT_HW(pll3_d8), 10, 1); +static CCU_FACTOR_DEFINE(pll3_80, CCU_PARENT_HW(pll3_d8), 5, 1); + +/* APBS clocks end */ + +/* MPMU clocks start */ +static CCU_GATE_DEFINE(pll1_d8_307p2, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(13), 0); +static CCU_FACTOR_DEFINE(pll1_d32_76p8, CCU_PARENT_HW(pll1_d8_307p2), + 4, 1); +static CCU_FACTOR_DEFINE(pll1_d40_61p44, CCU_PARENT_HW(pll1_d8_307p2), + 5, 1); +static CCU_FACTOR_DEFINE(pll1_d16_153p6, CCU_PARENT_HW(pll1_d8), + 2, 1); +static CCU_GATE_FACTOR_DEFINE(pll1_d24_102p4, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(12), 3, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d48_51p2, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(7), 6, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d48_51p2_ap, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(11), 6, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_m3d128_57p6, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(8), 16, 3, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d96_25p6, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(4), 12, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d192_12p8, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(3), 24, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d192_12p8_wdt, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(19), 24, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d384_6p4, CCU_PARENT_HW(pll1_d8), + MPMU_ACGR, + BIT(2), 48, 1, 0); +static CCU_FACTOR_DEFINE(pll1_d768_3p2, CCU_PARENT_HW(pll1_d384_6p4), + 2, 1); +static CCU_FACTOR_DEFINE(pll1_d1536_1p6, CCU_PARENT_HW(pll1_d384_6p4), + 4, 1); +static CCU_FACTOR_DEFINE(pll1_d3072_0p8, CCU_PARENT_HW(pll1_d384_6p4), + 8, 1); + +static CCU_GATE_DEFINE(pll1_d6_409p6, CCU_PARENT_HW(pll1_d6), + MPMU_ACGR, + BIT(0), 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d12_204p8, CCU_PARENT_HW(pll1_d6), + MPMU_ACGR, + BIT(5), 2, 1, 0); + +static CCU_GATE_DEFINE(pll1_d5_491p52, CCU_PARENT_HW(pll1_d5), + MPMU_ACGR, + BIT(21), 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d10_245p76, CCU_PARENT_HW(pll1_d5), + MPMU_ACGR, + BIT(18), 2, 1, 0); + +static CCU_GATE_DEFINE(pll1_d4_614p4, CCU_PARENT_HW(pll1_d4), + MPMU_ACGR, + BIT(15), 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d52_47p26, CCU_PARENT_HW(pll1_d4), + MPMU_ACGR, + BIT(10), 13, 1, 0); +static CCU_GATE_FACTOR_DEFINE(pll1_d78_31p5, CCU_PARENT_HW(pll1_d4), + MPMU_ACGR, + BIT(6), 39, 2, 0); + +static CCU_GATE_DEFINE(pll1_d3_819p2, CCU_PARENT_HW(pll1_d3), + MPMU_ACGR, + BIT(14), 0); + +static CCU_GATE_DEFINE(pll1_d2_1228p8, CCU_PARENT_HW(pll1_d2), + MPMU_ACGR, + BIT(16), 0); + +static CCU_GATE_DEFINE(slow_uart, CCU_PARENT_NAME(osc), + MPMU_ACGR, + BIT(1), CLK_IGNORE_UNUSED); +static CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, + MPMU_SUCCR, + GENMASK(28, 16), 16, GENMASK(12, 0), 0, + 0); +static CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, + MPMU_SUCCR_1, + GENMASK(28, 16), 16, GENMASK(12, 0), 0, + 0); + +static CCU_GATE_DEFINE(wdt_clk, CCU_PARENT_HW(pll1_d96_25p6), + MPMU_WDTPCR, + BIT(1), + 0); + +static CCU_GATE_FACTOR_DEFINE(i2s_sysclk, CCU_PARENT_HW(pll1_d16_153p6), + MPMU_ISCCR, + BIT(31), 50, 1, + 0); +static CCU_GATE_FACTOR_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s_sysclk), + MPMU_ISCCR, + BIT(29), 1, 1, + 0); + +static const struct clk_parent_data apb_parents[] = { + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d24_102p4), +}; +static CCU_MUX_DEFINE(apb_clk, apb_parents, + MPMU_APBCSCR, + 0, 2, + 0); + +static CCU_GATE_DEFINE(wdt_bus_clk, CCU_PARENT_HW(apb_clk), + MPMU_WDTPCR, + BIT(0), + 0); + +static CCU_GATE_DEFINE(ripc_clk, CCU_PARENT_HW(apb_clk), + MPMU_RIPCCR, + 0x1, + 0); +/* MPMU clocks end */ + +/* APBC clocks start */ +static const struct clk_parent_data uart_clk_parents[] = { + CCU_PARENT_HW(pll1_m3d128_57p6), + CCU_PARENT_HW(slow_uart1_14p74), + CCU_PARENT_HW(slow_uart2_48), +}; +static CCU_MUX_GATE_DEFINE(uart0_clk, uart_clk_parents, + APBC_UART1_CLK_RST, + 4, 3, BIT(1), + CLK_IS_CRITICAL); +static CCU_MUX_GATE_DEFINE(uart2_clk, uart_clk_parents, + APBC_UART2_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(uart3_clk, uart_clk_parents, + APBC_UART3_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(uart4_clk, uart_clk_parents, + APBC_UART4_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(uart5_clk, uart_clk_parents, + APBC_UART5_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(uart6_clk, uart_clk_parents, + APBC_UART6_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(uart7_clk, uart_clk_parents, + APBC_UART7_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(uart8_clk, uart_clk_parents, + APBC_UART8_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(uart9_clk, uart_clk_parents, + APBC_UART9_CLK_RST, + 4, 3, BIT(1), + 0); + +static CCU_GATE_DEFINE(gpio_clk, CCU_PARENT_NAME(vctcxo_24m), + APBC_GPIO_CLK_RST, + BIT(1), + 0); + +static const struct clk_parent_data pwm_parents[] = { + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_NAME(osc), +}; +static CCU_MUX_GATE_DEFINE(pwm0_clk, pwm_parents, + APBC_PWM0_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm1_clk, pwm_parents, + APBC_PWM1_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm2_clk, pwm_parents, + APBC_PWM2_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm3_clk, pwm_parents, + APBC_PWM3_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm4_clk, pwm_parents, + APBC_PWM4_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm5_clk, pwm_parents, + APBC_PWM5_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm6_clk, pwm_parents, + APBC_PWM6_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm7_clk, pwm_parents, + APBC_PWM7_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm8_clk, pwm_parents, + APBC_PWM8_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm9_clk, pwm_parents, + APBC_PWM9_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm10_clk, pwm_parents, + APBC_PWM10_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm11_clk, pwm_parents, + APBC_PWM11_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm12_clk, pwm_parents, + APBC_PWM12_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm13_clk, pwm_parents, + APBC_PWM13_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm14_clk, pwm_parents, + APBC_PWM14_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm15_clk, pwm_parents, + APBC_PWM15_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm16_clk, pwm_parents, + APBC_PWM16_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm17_clk, pwm_parents, + APBC_PWM17_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm18_clk, pwm_parents, + APBC_PWM18_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(pwm19_clk, pwm_parents, + APBC_PWM19_CLK_RST, + 4, 3, BIT(1), + 0); + +static const struct clk_parent_data ssp_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), +}; +static CCU_MUX_GATE_DEFINE(ssp3_clk, ssp_parents, + APBC_SSP3_CLK_RST, + 4, 3, BIT(1), + 0); + +static CCU_GATE_DEFINE(rtc_clk, CCU_PARENT_NAME(osc), + APBC_RTC_CLK_RST, + BIT(7) | BIT(1), + 0); + +static const struct clk_parent_data twsi_parents[] = { + CCU_PARENT_HW(pll1_d78_31p5), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d40_61p44), +}; +static CCU_MUX_GATE_DEFINE(twsi0_clk, twsi_parents, + APBC_TWSI0_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(twsi1_clk, twsi_parents, + APBC_TWSI1_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(twsi2_clk, twsi_parents, + APBC_TWSI2_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(twsi4_clk, twsi_parents, + APBC_TWSI4_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(twsi5_clk, twsi_parents, + APBC_TWSI5_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(twsi6_clk, twsi_parents, + APBC_TWSI6_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(twsi7_clk, twsi_parents, + APBC_TWSI7_CLK_RST, + 4, 3, BIT(1), + 0); + +static const struct clk_parent_data timer_parents[] = { + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_NAME(osc), + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_NAME(vctcxo_3m), + CCU_PARENT_NAME(vctcxo_1m), +}; +static CCU_MUX_GATE_DEFINE(timers1_clk, timer_parents, + APBC_TIMERS1_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(timers2_clk, timer_parents, + APBC_TIMERS2_CLK_RST, + 4, 3, BIT(1), + 0); + +static CCU_GATE_DEFINE(aib_clk, CCU_PARENT_NAME(vctcxo_24m), + APBC_AIB_CLK_RST, + BIT(1), + 0); + +static CCU_GATE_DEFINE(onewire_clk, CCU_PARENT_NAME(vctcxo_24m), + APBC_ONEWIRE_CLK_RST, + BIT(1), + 0); + +static const struct clk_parent_data sspa_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s_bclk), +}; +static CCU_MUX_GATE_DEFINE(sspa0_clk, sspa_parents, + APBC_SSPA0_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_MUX_GATE_DEFINE(sspa1_clk, sspa_parents, + APBC_SSPA1_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_GATE_DEFINE(dro_clk, CCU_PARENT_HW(apb_clk), + APBC_DRO_CLK_RST, + BIT(1), + 0); +static CCU_GATE_DEFINE(ir_clk, CCU_PARENT_HW(apb_clk), + APBC_IR_CLK_RST, + BIT(1), + 0); +static CCU_GATE_DEFINE(tsen_clk, CCU_PARENT_HW(apb_clk), + APBC_TSEN_CLK_RST, + BIT(1), + 0); +static CCU_GATE_DEFINE(ipc_ap2aud_clk, CCU_PARENT_HW(apb_clk), + APBC_IPC_AP2AUD_CLK_RST, + BIT(1), + 0); + +static const struct clk_parent_data can_parents[] = { + CCU_PARENT_HW(pll3_20), + CCU_PARENT_HW(pll3_40), + CCU_PARENT_HW(pll3_80), +}; +static CCU_MUX_GATE_DEFINE(can0_clk, can_parents, + APBC_CAN0_CLK_RST, + 4, 3, BIT(1), + 0); +static CCU_GATE_DEFINE(can0_bus_clk, CCU_PARENT_NAME(vctcxo_24m), + APBC_CAN0_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(uart0_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART1_CLK_RST, + BIT(0), + CLK_IS_CRITICAL); +static CCU_GATE_DEFINE(uart2_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART2_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(uart3_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART3_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(uart4_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART4_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(uart5_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART5_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(uart6_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART6_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(uart7_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART7_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(uart8_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART8_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(uart9_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_UART9_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(gpio_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_GPIO_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(pwm0_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM0_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm1_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM1_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm2_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM2_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm3_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM3_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm4_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM4_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm5_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM5_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm6_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM6_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm7_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM7_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm8_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM8_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm9_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM9_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm10_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM10_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm11_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM11_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm12_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM12_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm13_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM13_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm14_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM14_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm15_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM15_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm16_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM16_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm17_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM17_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm18_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM18_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(pwm19_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_PWM19_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(ssp3_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_SSP3_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(rtc_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_RTC_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(twsi0_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TWSI0_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(twsi1_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TWSI1_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(twsi2_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TWSI2_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(twsi4_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TWSI4_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(twsi5_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TWSI5_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(twsi6_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TWSI6_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(twsi7_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TWSI7_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(timers1_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TIMERS1_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(timers2_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TIMERS2_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(aib_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_AIB_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(onewire_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_ONEWIRE_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(sspa0_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_SSPA0_CLK_RST, + BIT(0), + 0); +static CCU_GATE_DEFINE(sspa1_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_SSPA1_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(tsen_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_TSEN_CLK_RST, + BIT(0), + 0); + +static CCU_GATE_DEFINE(ipc_ap2aud_bus_clk, CCU_PARENT_HW(apb_clk), + APBC_IPC_AP2AUD_CLK_RST, + BIT(0), + 0); +/* APBC clocks end */ + +/* APMU clocks start */ +static const struct clk_parent_data pmua_aclk_parents[] = { + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll1_d8_307p2), +}; +static CCU_DIV_FC_MUX_DEFINE(pmua_aclk, pmua_aclk_parents, + APMU_ACLK_CLK_CTRL, + 1, 2, BIT(4), + 0, 1, + 0); + +static const struct clk_parent_data cci550_clk_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll2_d3), +}; +static CCU_DIV_FC_MUX_DEFINE(cci550_clk, cci550_clk_parents, + APMU_CCI550_CLK_CTRL, + 8, 3, BIT(12), 0, 2, CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c0_hi_clk_parents[] = { + CCU_PARENT_HW(pll3_d2), + CCU_PARENT_HW(pll3_d1), +}; +static CCU_MUX_DEFINE(cpu_c0_hi_clk, cpu_c0_hi_clk_parents, + APMU_CPU_C0_CLK_CTRL, + 13, 1, 0); +static const struct clk_parent_data cpu_c0_clk_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll3_d3), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(cpu_c0_hi_clk), +}; +static CCU_MUX_FC_DEFINE(cpu_c0_core_clk, cpu_c0_clk_parents, + APMU_CPU_C0_CLK_CTRL, + BIT(12), 0, 3, CLK_IS_CRITICAL); +static CCU_DIV_DEFINE(cpu_c0_ace_clk, CCU_PARENT_HW(cpu_c0_core_clk), + APMU_CPU_C0_CLK_CTRL, + 6, 3, CLK_IS_CRITICAL); +static CCU_DIV_DEFINE(cpu_c0_tcm_clk, CCU_PARENT_HW(cpu_c0_core_clk), + APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c1_hi_clk_parents[] = { + CCU_PARENT_HW(pll3_d2), + CCU_PARENT_HW(pll3_d1), +}; +static CCU_MUX_DEFINE(cpu_c1_hi_clk, cpu_c1_hi_clk_parents, + APMU_CPU_C1_CLK_CTRL, + 13, 1, CLK_IS_CRITICAL); +static const struct clk_parent_data cpu_c1_clk_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll3_d3), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(cpu_c1_hi_clk), +}; +static CCU_MUX_FC_DEFINE(cpu_c1_core_clk, cpu_c1_clk_parents, + APMU_CPU_C1_CLK_CTRL, + BIT(12), 0, 3, CLK_IS_CRITICAL); +static CCU_DIV_DEFINE(cpu_c1_ace_clk, CCU_PARENT_HW(cpu_c1_core_clk), + APMU_CPU_C1_CLK_CTRL, + 6, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data jpg_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll2_d3), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(jpg_clk, jpg_parents, + APMU_JPG_CLK_RES_CTRL, + 5, 3, BIT(15), + 2, 3, BIT(1), + 0); + +static const struct clk_parent_data ccic2phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +static CCU_MUX_GATE_DEFINE(ccic2phy_clk, ccic2phy_parents, + APMU_CSI_CCIC2_CLK_RES_CTRL, + 7, 1, BIT(5), + 0); + +static const struct clk_parent_data ccic3phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +static CCU_MUX_GATE_DEFINE(ccic3phy_clk, ccic3phy_parents, + APMU_CSI_CCIC2_CLK_RES_CTRL, + 31, 1, BIT(30), + 0); + +static const struct clk_parent_data csi_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d2_1228p8), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(csi_clk, csi_parents, + APMU_CSI_CCIC2_CLK_RES_CTRL, + 20, 3, BIT(15), + 16, 3, BIT(4), + 0); + +static const struct clk_parent_data camm_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll2_d5), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_NAME(vctcxo_24m), +}; +static CCU_DIV_MUX_GATE_DEFINE(camm0_clk, camm_parents, + APMU_CSI_CCIC2_CLK_RES_CTRL, + 23, 4, 8, 2, + BIT(28), + 0); +static CCU_DIV_MUX_GATE_DEFINE(camm1_clk, camm_parents, + APMU_CSI_CCIC2_CLK_RES_CTRL, + 23, 4, 8, 2, BIT(6), + 0); +static CCU_DIV_MUX_GATE_DEFINE(camm2_clk, camm_parents, + APMU_CSI_CCIC2_CLK_RES_CTRL, + 23, 4, 8, 2, BIT(3), + 0); + +static const struct clk_parent_data isp_cpp_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), +}; +static CCU_DIV_MUX_GATE_DEFINE(isp_cpp_clk, isp_cpp_parents, + APMU_ISP_CLK_RES_CTRL, + 24, 2, 26, 1, BIT(28), + 0); +static const struct clk_parent_data isp_bus_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d10_245p76), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(isp_bus_clk, isp_bus_parents, + APMU_ISP_CLK_RES_CTRL, + 18, 3, BIT(23), + 21, 2, BIT(17), + 0); +static const struct clk_parent_data isp_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(isp_clk, isp_parents, + APMU_ISP_CLK_RES_CTRL, + 4, 3, BIT(7), + 8, 2, BIT(1), + 0); + +static const struct clk_parent_data dpumclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), +}; +static CCU_DIV_SPLIT_FC_MUX_GATE_DEFINE(dpu_mclk, dpumclk_parents, + APMU_LCD_CLK_RES_CTRL2, + APMU_LCD_CLK_RES_CTRL1, + 1, 4, BIT(29), + 5, 3, BIT(0), + 0); + +static const struct clk_parent_data dpuesc_parents[] = { + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll1_d52_47p26), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d32_76p8), +}; +static CCU_MUX_GATE_DEFINE(dpu_esc_clk, dpuesc_parents, + APMU_LCD_CLK_RES_CTRL1, + 0, 2, BIT(2), + 0); + +static const struct clk_parent_data dpubit_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll2_d5), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll2_d8), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(dpu_bit_clk, dpubit_parents, + APMU_LCD_CLK_RES_CTRL1, + 17, 3, BIT(31), + 20, 3, BIT(16), + 0); + +static const struct clk_parent_data dpupx_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll2_d8), +}; +static CCU_DIV_SPLIT_FC_MUX_GATE_DEFINE(dpu_pxclk, dpupx_parents, + APMU_LCD_CLK_RES_CTRL2, + APMU_LCD_CLK_RES_CTRL1, + 17, 4, BIT(30), + 21, 3, BIT(16), + 0); + +static CCU_GATE_DEFINE(dpu_hclk, CCU_PARENT_HW(pmua_aclk), + APMU_LCD_CLK_RES_CTRL1, + BIT(5), + 0); + +static const struct clk_parent_data dpu_spi_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll1_d11_223p4), + CCU_PARENT_HW(pll1_d13_189), + CCU_PARENT_HW(pll1_d23_106p8), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d5), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(dpu_spi_clk, dpu_spi_parents, + APMU_LCD_SPI_CLK_RES_CTRL, + 8, 3, BIT(7), + 12, 3, BIT(1), + 0); +static CCU_GATE_DEFINE(dpu_spi_hbus_clk, CCU_PARENT_HW(pmua_aclk), + APMU_LCD_SPI_CLK_RES_CTRL, + BIT(3), + 0); +static CCU_GATE_DEFINE(dpu_spi_bus_clk, CCU_PARENT_HW(pmua_aclk), + APMU_LCD_SPI_CLK_RES_CTRL, + BIT(5), + 0); +static CCU_GATE_DEFINE(dpu_spi_aclk, CCU_PARENT_HW(pmua_aclk), + APMU_LCD_SPI_CLK_RES_CTRL, + BIT(6), + 0); + +static const struct clk_parent_data v2d_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d4_614p4), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(v2d_clk, v2d_parents, + APMU_LCD_CLK_RES_CTRL1, + 9, 3, BIT(28), + 12, 2, BIT(8), + 0); + +static const struct clk_parent_data ccic_4x_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d2_1228p8), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(ccic_4x_clk, ccic_4x_parents, + APMU_CCIC_CLK_RES_CTRL, + 18, 3, BIT(15), + 23, 2, BIT(4), + 0); + +static const struct clk_parent_data ccic1phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +static CCU_MUX_GATE_DEFINE(ccic1phy_clk, ccic1phy_parents, + APMU_CCIC_CLK_RES_CTRL, + 7, 1, BIT(5), + 0); + +static CCU_GATE_DEFINE(sdh_axi_aclk, CCU_PARENT_HW(pmua_aclk), + APMU_SDH0_CLK_RES_CTRL, + BIT(3), + 0); +static const struct clk_parent_data sdh01_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll2_d5), + CCU_PARENT_HW(pll1_d11_223p4), + CCU_PARENT_HW(pll1_d13_189), + CCU_PARENT_HW(pll1_d23_106p8), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(sdh0_clk, sdh01_parents, + APMU_SDH0_CLK_RES_CTRL, + 8, 3, BIT(11), + 5, 3, BIT(4), + 0); +static CCU_DIV_FC_MUX_GATE_DEFINE(sdh1_clk, sdh01_parents, + APMU_SDH1_CLK_RES_CTRL, + 8, 3, BIT(11), + 5, 3, BIT(4), + 0); +static const struct clk_parent_data sdh2_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d11_223p4), + CCU_PARENT_HW(pll1_d13_189), + CCU_PARENT_HW(pll1_d23_106p8), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(sdh2_clk, sdh2_parents, + APMU_SDH2_CLK_RES_CTRL, + 8, 3, BIT(11), + 5, 3, BIT(4), + 0); + +static CCU_GATE_DEFINE(usb_axi_clk, CCU_PARENT_HW(pmua_aclk), + APMU_USB_CLK_RES_CTRL, + BIT(1), + 0); +static CCU_GATE_DEFINE(usb_p1_aclk, CCU_PARENT_HW(pmua_aclk), + APMU_USB_CLK_RES_CTRL, + BIT(5), + 0); +static CCU_GATE_DEFINE(usb30_clk, CCU_PARENT_HW(pmua_aclk), + APMU_USB_CLK_RES_CTRL, + BIT(8), + 0); + +static const struct clk_parent_data qspi_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll1_d11_223p4), + CCU_PARENT_HW(pll1_d23_106p8), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d13_189), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(qspi_clk, qspi_parents, + APMU_QSPI_CLK_RES_CTRL, + 9, 3, BIT(12), + 6, 3, BIT(4), + 0); +static CCU_GATE_DEFINE(qspi_bus_clk, CCU_PARENT_HW(pmua_aclk), + APMU_QSPI_CLK_RES_CTRL, + BIT(3), + 0); +static CCU_GATE_DEFINE(dma_clk, CCU_PARENT_HW(pmua_aclk), + APMU_DMA_CLK_RES_CTRL, + BIT(3), + 0); + +static const struct clk_parent_data aes_parents[] = { + CCU_PARENT_HW(pll1_d12_204p8), + CCU_PARENT_HW(pll1_d24_102p4), +}; +static CCU_MUX_GATE_DEFINE(aes_clk, aes_parents, + APMU_AES_CLK_RES_CTRL, + 6, 1, BIT(5), + 0); + +static const struct clk_parent_data vpu_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll3_d6), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll2_d5), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(vpu_clk, vpu_parents, + APMU_VPU_CLK_RES_CTRL, + 13, 3, BIT(21), + 10, 3, + BIT(3), + 0); + +static const struct clk_parent_data gpu_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll3_d6), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll2_d5), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(gpu_clk, gpu_parents, + APMU_GPU_CLK_RES_CTRL, + 12, 3, BIT(15), + 18, 3, + BIT(4), + 0); + +static const struct clk_parent_data emmc_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d52_47p26), + CCU_PARENT_HW(pll1_d3_819p2), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(emmc_clk, emmc_parents, + APMU_PMUA_EM_CLK_RES_CTRL, + 8, 3, BIT(11), + 6, 2, + BIT(4), + 0); +static CCU_DIV_GATE_DEFINE(emmc_x_clk, CCU_PARENT_HW(pll1_d2_1228p8), + APMU_PMUA_EM_CLK_RES_CTRL, + 12, 3, BIT(15), + 0); + +static const struct clk_parent_data audio_parents[] = { + CCU_PARENT_HW(pll1_aud_245p7), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(audio_clk, audio_parents, + APMU_AUDIO_CLK_RES_CTRL, + 4, 3, BIT(15), + 7, 3, + BIT(12), + 0); + +static const struct clk_parent_data hdmi_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), +}; +static CCU_DIV_FC_MUX_GATE_DEFINE(hdmi_mclk, hdmi_parents, + APMU_HDMI_CLK_RES_CTRL, + 1, 4, BIT(29), + 5, 3, + BIT(0), + 0); + +static CCU_GATE_DEFINE(pcie0_master_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_0, + BIT(2), + 0); +static CCU_GATE_DEFINE(pcie0_slave_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_0, + BIT(1), + 0); +static CCU_GATE_DEFINE(pcie0_dbi_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_0, + BIT(0), + 0); + +static CCU_GATE_DEFINE(pcie1_master_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_1, + BIT(2), + 0); +static CCU_GATE_DEFINE(pcie1_slave_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_1, + BIT(1), + 0); +static CCU_GATE_DEFINE(pcie1_dbi_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_1, + BIT(0), + 0); + +static CCU_GATE_DEFINE(pcie2_master_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_2, + BIT(2), + 0); +static CCU_GATE_DEFINE(pcie2_slave_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_2, + BIT(1), + 0); +static CCU_GATE_DEFINE(pcie2_dbi_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PCIE_CLK_RES_CTRL_2, + BIT(0), + 0); + +static CCU_GATE_DEFINE(emac0_bus_clk, CCU_PARENT_HW(pmua_aclk), + APMU_EMAC0_CLK_RES_CTRL, + BIT(0), + 0); +static CCU_GATE_DEFINE(emac0_ptp_clk, CCU_PARENT_HW(pll2_d6), + APMU_EMAC0_CLK_RES_CTRL, + BIT(15), + 0); +static CCU_GATE_DEFINE(emac1_bus_clk, CCU_PARENT_HW(pmua_aclk), + APMU_EMAC1_CLK_RES_CTRL, + BIT(0), + 0); +static CCU_GATE_DEFINE(emac1_ptp_clk, CCU_PARENT_HW(pll2_d6), + APMU_EMAC1_CLK_RES_CTRL, + BIT(15), + 0); + +static CCU_GATE_DEFINE(emmc_bus_clk, CCU_PARENT_HW(pmua_aclk), + APMU_PMUA_EM_CLK_RES_CTRL, + BIT(3), + 0); +/* APMU clocks end */ + +struct spacemit_ccu_clk { + int id; + struct clk_hw *hw; +}; + +static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = { + { CLK_PLL1, &pll1.common.hw }, + { CLK_PLL2, &pll2.common.hw }, + { CLK_PLL3, &pll3.common.hw }, + { CLK_PLL1_D2, &pll1_d2.common.hw }, + { CLK_PLL1_D3, &pll1_d3.common.hw }, + { CLK_PLL1_D4, &pll1_d4.common.hw }, + { CLK_PLL1_D5, &pll1_d5.common.hw }, + { CLK_PLL1_D6, &pll1_d6.common.hw }, + { CLK_PLL1_D7, &pll1_d7.common.hw }, + { CLK_PLL1_D8, &pll1_d8.common.hw }, + { CLK_PLL1_D11, &pll1_d11_223p4.common.hw }, + { CLK_PLL1_D13, &pll1_d13_189.common.hw }, + { CLK_PLL1_D23, &pll1_d23_106p8.common.hw }, + { CLK_PLL1_D64, &pll1_d64_38p4.common.hw }, + { CLK_PLL1_D10_AUD, &pll1_aud_245p7.common.hw }, + { CLK_PLL1_D100_AUD, &pll1_aud_24p5.common.hw }, + { CLK_PLL2_D1, &pll2_d1.common.hw }, + { CLK_PLL2_D2, &pll2_d2.common.hw }, + { CLK_PLL2_D3, &pll2_d3.common.hw }, + { CLK_PLL2_D4, &pll2_d4.common.hw }, + { CLK_PLL2_D5, &pll2_d5.common.hw }, + { CLK_PLL2_D6, &pll2_d6.common.hw }, + { CLK_PLL2_D7, &pll2_d7.common.hw }, + { CLK_PLL2_D8, &pll2_d8.common.hw }, + { CLK_PLL3_D1, &pll3_d1.common.hw }, + { CLK_PLL3_D2, &pll3_d2.common.hw }, + { CLK_PLL3_D3, &pll3_d3.common.hw }, + { CLK_PLL3_D4, &pll3_d4.common.hw }, + { CLK_PLL3_D5, &pll3_d5.common.hw }, + { CLK_PLL3_D6, &pll3_d6.common.hw }, + { CLK_PLL3_D7, &pll3_d7.common.hw }, + { CLK_PLL3_D8, &pll3_d8.common.hw }, + { CLK_PLL3_80, &pll3_80.common.hw }, + { CLK_PLL3_40, &pll3_40.common.hw }, + { CLK_PLL3_20, &pll3_20.common.hw }, + { 0, NULL }, +}; + +static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = { + { CLK_PLL1_307P2, &pll1_d8_307p2.common.hw }, + { CLK_PLL1_76P8, &pll1_d32_76p8.common.hw }, + { CLK_PLL1_61P44, &pll1_d40_61p44.common.hw }, + { CLK_PLL1_153P6, &pll1_d16_153p6.common.hw }, + { CLK_PLL1_102P4, &pll1_d24_102p4.common.hw }, + { CLK_PLL1_51P2, &pll1_d48_51p2.common.hw }, + { CLK_PLL1_51P2_AP, &pll1_d48_51p2_ap.common.hw }, + { CLK_PLL1_57P6, &pll1_m3d128_57p6.common.hw }, + { CLK_PLL1_25P6, &pll1_d96_25p6.common.hw }, + { CLK_PLL1_12P8, &pll1_d192_12p8.common.hw }, + { CLK_PLL1_12P8_WDT, &pll1_d192_12p8_wdt.common.hw }, + { CLK_PLL1_6P4, &pll1_d384_6p4.common.hw }, + { CLK_PLL1_3P2, &pll1_d768_3p2.common.hw }, + { CLK_PLL1_1P6, &pll1_d1536_1p6.common.hw }, + { CLK_PLL1_0P8, &pll1_d3072_0p8.common.hw }, + { CLK_PLL1_409P6, &pll1_d6_409p6.common.hw }, + { CLK_PLL1_204P8, &pll1_d12_204p8.common.hw }, + { CLK_PLL1_491, &pll1_d5_491p52.common.hw }, + { CLK_PLL1_245P76, &pll1_d10_245p76.common.hw }, + { CLK_PLL1_614, &pll1_d4_614p4.common.hw }, + { CLK_PLL1_47P26, &pll1_d52_47p26.common.hw }, + { CLK_PLL1_31P5, &pll1_d78_31p5.common.hw }, + { CLK_PLL1_819, &pll1_d3_819p2.common.hw }, + { CLK_PLL1_1228, &pll1_d2_1228p8.common.hw }, + { CLK_SLOW_UART, &slow_uart.common.hw }, + { CLK_SLOW_UART1, &slow_uart1_14p74.common.hw }, + { CLK_SLOW_UART2, &slow_uart2_48.common.hw }, + { CLK_WDT, &wdt_clk.common.hw }, + { CLK_RIPC, &ripc_clk.common.hw }, + { CLK_I2S_SYSCLK, &i2s_sysclk.common.hw }, + { CLK_I2S_BCLK, &i2s_bclk.common.hw }, + { CLK_APB, &apb_clk.common.hw }, + { CLK_WDT_BUS, &wdt_bus_clk.common.hw }, + { 0, NULL }, +}; + +static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = { + { CLK_UART0, &uart0_clk.common.hw }, + { CLK_UART2, &uart2_clk.common.hw }, + { CLK_UART3, &uart3_clk.common.hw }, + { CLK_UART4, &uart4_clk.common.hw }, + { CLK_UART5, &uart5_clk.common.hw }, + { CLK_UART6, &uart6_clk.common.hw }, + { CLK_UART7, &uart7_clk.common.hw }, + { CLK_UART8, &uart8_clk.common.hw }, + { CLK_UART9, &uart9_clk.common.hw }, + { CLK_GPIO, &gpio_clk.common.hw }, + { CLK_PWM0, &pwm0_clk.common.hw }, + { CLK_PWM1, &pwm1_clk.common.hw }, + { CLK_PWM2, &pwm2_clk.common.hw }, + { CLK_PWM3, &pwm3_clk.common.hw }, + { CLK_PWM4, &pwm4_clk.common.hw }, + { CLK_PWM5, &pwm5_clk.common.hw }, + { CLK_PWM6, &pwm6_clk.common.hw }, + { CLK_PWM7, &pwm7_clk.common.hw }, + { CLK_PWM8, &pwm8_clk.common.hw }, + { CLK_PWM9, &pwm9_clk.common.hw }, + { CLK_PWM10, &pwm10_clk.common.hw }, + { CLK_PWM11, &pwm11_clk.common.hw }, + { CLK_PWM12, &pwm12_clk.common.hw }, + { CLK_PWM13, &pwm13_clk.common.hw }, + { CLK_PWM14, &pwm14_clk.common.hw }, + { CLK_PWM15, &pwm15_clk.common.hw }, + { CLK_PWM16, &pwm16_clk.common.hw }, + { CLK_PWM17, &pwm17_clk.common.hw }, + { CLK_PWM18, &pwm18_clk.common.hw }, + { CLK_PWM19, &pwm19_clk.common.hw }, + { CLK_SSP3, &ssp3_clk.common.hw }, + { CLK_RTC, &rtc_clk.common.hw }, + { CLK_TWSI0, &twsi0_clk.common.hw }, + { CLK_TWSI1, &twsi1_clk.common.hw }, + { CLK_TWSI2, &twsi2_clk.common.hw }, + { CLK_TWSI4, &twsi4_clk.common.hw }, + { CLK_TWSI5, &twsi5_clk.common.hw }, + { CLK_TWSI6, &twsi6_clk.common.hw }, + { CLK_TWSI7, &twsi7_clk.common.hw }, + { CLK_TWSI8, &twsi8_clk.common.hw }, + { CLK_TIMERS1, &timers1_clk.common.hw }, + { CLK_TIMERS2, &timers2_clk.common.hw }, + { CLK_AIB, &aib_clk.common.hw }, + { CLK_ONEWIRE, &onewire_clk.common.hw }, + { CLK_SSPA0, &sspa0_clk.common.hw }, + { CLK_SSPA1, &sspa1_clk.common.hw }, + { CLK_DRO, &dro_clk.common.hw }, + { CLK_IR, &ir_clk.common.hw }, + { CLK_TSEN, &tsen_clk.common.hw }, + { CLK_IPC_AP2AUD, &ipc_ap2aud_clk.common.hw }, + { CLK_CAN0, &can0_clk.common.hw }, + { CLK_CAN0_BUS, &can0_bus_clk.common.hw }, + { CLK_UART0_BUS, &uart0_bus_clk.common.hw }, + { CLK_UART2_BUS, &uart2_bus_clk.common.hw }, + { CLK_UART3_BUS, &uart3_bus_clk.common.hw }, + { CLK_UART4_BUS, &uart4_bus_clk.common.hw }, + { CLK_UART5_BUS, &uart5_bus_clk.common.hw }, + { CLK_UART6_BUS, &uart6_bus_clk.common.hw }, + { CLK_UART7_BUS, &uart7_bus_clk.common.hw }, + { CLK_UART8_BUS, &uart8_bus_clk.common.hw }, + { CLK_UART9_BUS, &uart9_bus_clk.common.hw }, + { CLK_GPIO_BUS, &gpio_bus_clk.common.hw }, + { CLK_PWM0_BUS, &pwm0_bus_clk.common.hw }, + { CLK_PWM1_BUS, &pwm1_bus_clk.common.hw }, + { CLK_PWM2_BUS, &pwm2_bus_clk.common.hw }, + { CLK_PWM3_BUS, &pwm3_bus_clk.common.hw }, + { CLK_PWM4_BUS, &pwm4_bus_clk.common.hw }, + { CLK_PWM5_BUS, &pwm5_bus_clk.common.hw }, + { CLK_PWM6_BUS, &pwm6_bus_clk.common.hw }, + { CLK_PWM7_BUS, &pwm7_bus_clk.common.hw }, + { CLK_PWM8_BUS, &pwm8_bus_clk.common.hw }, + { CLK_PWM9_BUS, &pwm9_bus_clk.common.hw }, + { CLK_PWM10_BUS, &pwm10_bus_clk.common.hw }, + { CLK_PWM11_BUS, &pwm11_bus_clk.common.hw }, + { CLK_PWM12_BUS, &pwm12_bus_clk.common.hw }, + { CLK_PWM13_BUS, &pwm13_bus_clk.common.hw }, + { CLK_PWM14_BUS, &pwm14_bus_clk.common.hw }, + { CLK_PWM15_BUS, &pwm15_bus_clk.common.hw }, + { CLK_PWM16_BUS, &pwm16_bus_clk.common.hw }, + { CLK_PWM17_BUS, &pwm17_bus_clk.common.hw }, + { CLK_PWM18_BUS, &pwm18_bus_clk.common.hw }, + { CLK_PWM19_BUS, &pwm19_bus_clk.common.hw }, + { CLK_SSP3_BUS, &ssp3_bus_clk.common.hw }, + { CLK_RTC_BUS, &rtc_bus_clk.common.hw }, + { CLK_TWSI0_BUS, &twsi0_bus_clk.common.hw }, + { CLK_TWSI1_BUS, &twsi1_bus_clk.common.hw }, + { CLK_TWSI2_BUS, &twsi2_bus_clk.common.hw }, + { CLK_TWSI4_BUS, &twsi4_bus_clk.common.hw }, + { CLK_TWSI5_BUS, &twsi5_bus_clk.common.hw }, + { CLK_TWSI6_BUS, &twsi6_bus_clk.common.hw }, + { CLK_TWSI7_BUS, &twsi7_bus_clk.common.hw }, + { CLK_TWSI8_BUS, &twsi8_bus_clk.common.hw }, + { CLK_TIMERS1_BUS, &timers1_bus_clk.common.hw }, + { CLK_TIMERS2_BUS, &timers2_bus_clk.common.hw }, + { CLK_AIB_BUS, &aib_bus_clk.common.hw }, + { CLK_ONEWIRE_BUS, &onewire_bus_clk.common.hw }, + { CLK_SSPA0_BUS, &sspa0_bus_clk.common.hw }, + { CLK_SSPA1_BUS, &sspa1_bus_clk.common.hw }, + { CLK_TSEN_BUS, &tsen_bus_clk.common.hw }, + { CLK_IPC_AP2AUD_BUS, &ipc_ap2aud_bus_clk.common.hw }, + { 0, NULL }, +}; + +static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = { + { CLK_CCI550, &cci550_clk.common.hw }, + { CLK_CPU_C0_HI, &cpu_c0_hi_clk.common.hw }, + { CLK_CPU_C0_CORE, &cpu_c0_core_clk.common.hw }, + { CLK_CPU_C0_ACE, &cpu_c0_ace_clk.common.hw }, + { CLK_CPU_C0_TCM, &cpu_c0_tcm_clk.common.hw }, + { CLK_CPU_C1_HI, &cpu_c1_hi_clk.common.hw }, + { CLK_CPU_C1_CORE, &cpu_c1_core_clk.common.hw }, + { CLK_CPU_C1_ACE, &cpu_c1_ace_clk.common.hw }, + { CLK_CCIC_4X, &ccic_4x_clk.common.hw }, + { CLK_CCIC1PHY, &ccic1phy_clk.common.hw }, + { CLK_SDH_AXI, &sdh_axi_aclk.common.hw }, + { CLK_SDH0, &sdh0_clk.common.hw }, + { CLK_SDH1, &sdh1_clk.common.hw }, + { CLK_SDH2, &sdh2_clk.common.hw }, + { CLK_USB_P1, &usb_p1_aclk.common.hw }, + { CLK_USB_AXI, &usb_axi_clk.common.hw }, + { CLK_USB30, &usb30_clk.common.hw }, + { CLK_QSPI, &qspi_clk.common.hw }, + { CLK_QSPI_BUS, &qspi_bus_clk.common.hw }, + { CLK_DMA, &dma_clk.common.hw }, + { CLK_AES, &aes_clk.common.hw }, + { CLK_VPU, &vpu_clk.common.hw }, + { CLK_GPU, &gpu_clk.common.hw }, + { CLK_EMMC, &emmc_clk.common.hw }, + { CLK_EMMC_X, &emmc_x_clk.common.hw }, + { CLK_AUDIO, &audio_clk.common.hw }, + { CLK_HDMI, &hdmi_mclk.common.hw }, + { CLK_PMUA_ACLK, &pmua_aclk.common.hw }, + { CLK_PCIE0_MASTER, &pcie0_master_clk.common.hw }, + { CLK_PCIE0_SLAVE, &pcie0_slave_clk.common.hw }, + { CLK_PCIE0_DBI, &pcie0_dbi_clk.common.hw }, + { CLK_PCIE1_MASTER, &pcie1_master_clk.common.hw }, + { CLK_PCIE1_SLAVE, &pcie1_slave_clk.common.hw }, + { CLK_PCIE1_DBI, &pcie1_dbi_clk.common.hw }, + { CLK_PCIE2_MASTER, &pcie2_master_clk.common.hw }, + { CLK_PCIE2_SLAVE, &pcie2_slave_clk.common.hw }, + { CLK_PCIE2_DBI, &pcie2_dbi_clk.common.hw }, + { CLK_EMAC0_BUS, &emac0_bus_clk.common.hw }, + { CLK_EMAC0_PTP, &emac0_ptp_clk.common.hw }, + { CLK_EMAC1_BUS, &emac1_bus_clk.common.hw }, + { CLK_EMAC1_PTP, &emac1_ptp_clk.common.hw }, + { CLK_JPG, &jpg_clk.common.hw }, + { CLK_CCIC2PHY, &ccic2phy_clk.common.hw }, + { CLK_CCIC3PHY, &ccic3phy_clk.common.hw }, + { CLK_CSI, &csi_clk.common.hw }, + { CLK_CAMM0, &camm0_clk.common.hw }, + { CLK_CAMM1, &camm1_clk.common.hw }, + { CLK_CAMM2, &camm2_clk.common.hw }, + { CLK_ISP_CPP, &isp_cpp_clk.common.hw }, + { CLK_ISP_BUS, &isp_bus_clk.common.hw }, + { CLK_ISP, &isp_clk.common.hw }, + { CLK_DPU_MCLK, &dpu_mclk.common.hw }, + { CLK_DPU_ESC, &dpu_esc_clk.common.hw }, + { CLK_DPU_BIT, &dpu_bit_clk.common.hw }, + { CLK_DPU_PXCLK, &dpu_pxclk.common.hw }, + { CLK_DPU_HCLK, &dpu_hclk.common.hw }, + { CLK_DPU_SPI, &dpu_spi_clk.common.hw }, + { CLK_DPU_SPI_HBUS, &dpu_spi_hbus_clk.common.hw }, + { CLK_DPU_SPIBUS, &dpu_spi_bus_clk.common.hw }, + { CLK_DPU_SPI_ACLK, &dpu_spi_aclk.common.hw }, + { CLK_V2D, &v2d_clk.common.hw }, + { CLK_EMMC_BUS, &emmc_bus_clk.common.hw }, + { 0, NULL }, +}; + +static int spacemit_ccu_register(struct device *dev, + struct regmap *regmap, struct regmap *lock_regmap, + const struct spacemit_ccu_clk *clks) +{ + const struct spacemit_ccu_clk *clk; + int i, ret, max_id = 0; + + for (clk = clks; clk->hw; clk++) + max_id = max(max_id, clk->id); + + struct clk_hw_onecell_data *clk_data; + + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, max_id + 1), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + for (i = 0; i <= max_id; i++) + clk_data->hws[i] = ERR_PTR(-ENOENT); + + for (clk = clks; clk->hw; clk++) { + struct ccu_common *common = hw_to_ccu_common(clk->hw); + const char *name = clk->hw->init->name; + + common->regmap = regmap; + common->lock_regmap = lock_regmap; + + ret = devm_clk_hw_register(dev, clk->hw); + if (ret) { + dev_err(dev, "Cannot register clock %d - %s\n", + i, name); + return ret; + } + + clk_data->hws[clk->id] = clk->hw; + } + + clk_data->num = max_id + 1; + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); +} + +static int k1_ccu_probe(struct platform_device *pdev) +{ + struct regmap *base_regmap, *lock_regmap = NULL; + struct device *dev = &pdev->dev; + int ret; + + base_regmap = device_node_to_regmap(dev->of_node); + if (IS_ERR(base_regmap)) + return dev_err_probe(dev, PTR_ERR(base_regmap), + "failed to get regmap\n"); + + if (of_device_is_compatible(dev->of_node, "spacemit,k1-pll")) { + struct device_node *mpmu = of_parse_phandle(dev->of_node, + "spacemit,mpmu", 0); + if (!mpmu) + return dev_err_probe(dev, -ENODEV, + "Cannot parse MPMU region\n"); + + lock_regmap = device_node_to_regmap(mpmu); + of_node_put(mpmu); + + if (IS_ERR(lock_regmap)) + return dev_err_probe(dev, PTR_ERR(lock_regmap), + "failed to get lock regmap\n"); + } + + ret = spacemit_ccu_register(dev, base_regmap, lock_regmap, + of_device_get_match_data(dev)); + if (ret) + return dev_err_probe(dev, ret, "failed to register clocks\n"); + + return 0; +} + +static const struct of_device_id of_k1_ccu_match[] = { + { + .compatible = "spacemit,k1-pll", + .data = k1_ccu_apbs_clks, + }, + { + .compatible = "spacemit,k1-syscon-mpmu", + .data = k1_ccu_mpmu_clks, + }, + { + .compatible = "spacemit,k1-syscon-apbc", + .data = k1_ccu_apbc_clks, + }, + { + .compatible = "spacemit,k1-syscon-apmu", + .data = k1_ccu_apmu_clks, + }, + { } +}; +MODULE_DEVICE_TABLE(of, of_k1_ccu_match); + +static struct platform_driver k1_ccu_driver = { + .driver = { + .name = "spacemit,k1-ccu", + .of_match_table = of_k1_ccu_match, + }, + .probe = k1_ccu_probe, +}; +module_platform_driver(k1_ccu_driver); + +MODULE_DESCRIPTION("Spacemit K1 CCU driver"); +MODULE_AUTHOR("Haylen Chu "); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_common.h new file mode 100644 index 000000000000..494cde96fe3c --- /dev/null +++ b/drivers/clk/spacemit/ccu_common.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024 Haylen Chu + */ + +#ifndef _CCU_COMMON_H_ +#define _CCU_COMMON_H_ + +#include + +struct ccu_common { + struct regmap *regmap; + struct regmap *lock_regmap; + + union { + /* For DDN and MIX */ + struct { + u32 reg_ctrl; + u32 reg_fc; + u32 fc; + }; + + /* For PLL */ + struct { + u32 reg_swcr1; + u32 reg_swcr2; + u32 reg_swcr3; + }; + }; + + struct clk_hw hw; +}; + +static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) +{ + return container_of(hw, struct ccu_common, hw); +} + +#define ccu_read(reg, c, val) regmap_read((c)->regmap, (c)->reg_##reg, val) +#define ccu_update(reg, c, mask, val) \ + regmap_update_bits((c)->regmap, (c)->reg_##reg, mask, val) +#define ccu_poll(reg, c, tmp, cond, sleep, timeout) \ + regmap_read_poll_timeout_atomic((c)->regmap, (c)->reg_##reg, \ + tmp, cond, sleep, timeout) + +#endif /* _CCU_COMMON_H_ */ diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c new file mode 100644 index 000000000000..ee187687d0c4 --- /dev/null +++ b/drivers/clk/spacemit/ccu_ddn.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Spacemit clock type ddn + * + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024 Haylen Chu + */ + +#include +#include + +#include "ccu_ddn.h" + +/* + * DDN stands for "Divider Denominator Numerator", it's M/N clock with a + * constant x2 factor. This clock hardware follows the equation below, + * + * numerator Fin + * 2 * ------------- = ------- + * denominator Fout + * + * Thus, Fout could be calculated with, + * + * Fin denominator + * Fout = ----- * ------------- + * 2 numerator + */ + +static unsigned long clk_ddn_calc_best_rate(struct ccu_ddn *ddn, + unsigned long rate, unsigned long prate, + unsigned long *num, unsigned long *den) +{ + rational_best_approximation(rate, prate / 2, + ddn->den_mask, ddn->num_mask, + den, num); + return prate / 2 * *den / *num; +} + +static long clk_ddn_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); + unsigned long num = 0, den = 0; + + return clk_ddn_calc_best_rate(ddn, rate, *prate, &num, &den); +} + +static unsigned long clk_ddn_recalc_rate(struct clk_hw *hw, unsigned long prate) +{ + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); + unsigned int val, num, den; + + ccu_read(ctrl, &ddn->common, &val); + + num = (val & ddn->num_mask) >> ddn->num_shift; + den = (val & ddn->den_mask) >> ddn->den_shift; + + return prate / 2 * den / num; +} + +static int clk_ddn_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); + unsigned long num, den; + + clk_ddn_calc_best_rate(ddn, rate, prate, &num, &den); + + ccu_update(ctrl, &ddn->common, + ddn->num_mask | ddn->den_mask, + (num << ddn->num_shift) | (den << ddn->den_shift)); + + return 0; +} + +const struct clk_ops spacemit_ccu_ddn_ops = { + .recalc_rate = clk_ddn_recalc_rate, + .round_rate = clk_ddn_round_rate, + .set_rate = clk_ddn_set_rate, +}; diff --git a/drivers/clk/spacemit/ccu_ddn.h b/drivers/clk/spacemit/ccu_ddn.h new file mode 100644 index 000000000000..3746d084e1e7 --- /dev/null +++ b/drivers/clk/spacemit/ccu_ddn.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024 Haylen Chu + */ + +#ifndef _CCU_DDN_H_ +#define _CCU_DDN_H_ + +#include + +#include "ccu_common.h" + +struct ccu_ddn { + struct ccu_common common; + unsigned int num_mask; + unsigned int num_shift; + unsigned int den_mask; + unsigned int den_shift; +}; + +#define CCU_DDN_INIT(_name, _parent, _flags) \ + CLK_HW_INIT_HW(#_name, &_parent.common.hw, &spacemit_ccu_ddn_ops, _flags) + +#define CCU_DDN_DEFINE(_name, _parent, _reg_ctrl, \ + _num_mask, _num_shift, _den_mask, _den_shift, \ + _flags) \ + struct ccu_ddn _name = { \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + .hw.init = CCU_DDN_INIT(_name, _parent, _flags), \ + }, \ + .num_mask = _num_mask, \ + .num_shift = _num_shift, \ + .den_mask = _den_mask, \ + .den_shift = _den_shift, \ + } + +static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_ddn, common); +} + +extern const struct clk_ops spacemit_ccu_ddn_ops; + +#endif diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c new file mode 100644 index 000000000000..a5c13000e062 --- /dev/null +++ b/drivers/clk/spacemit/ccu_mix.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Spacemit clock type mix(div/mux/gate/factor) + * + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024 Haylen Chu + */ + +#include + +#include "ccu_mix.h" + +#define MIX_TIMEOUT 10000 + +static void ccu_gate_disable(struct clk_hw *hw) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_common *common = &mix->common; + + ccu_update(ctrl, common, mix->gate.mask, 0); +} + +static int ccu_gate_enable(struct clk_hw *hw) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_common *common = &mix->common; + struct ccu_gate_config *gate = &mix->gate; + + ccu_update(ctrl, common, gate->mask, gate->mask); + + return 0; +} + +static int ccu_gate_is_enabled(struct clk_hw *hw) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_common *common = &mix->common; + u32 tmp; + + ccu_read(ctrl, common, &tmp); + + return !!(tmp & mix->gate.mask); +} + +static unsigned long ccu_factor_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + + return parent_rate * mix->factor.mul / mix->factor.div; +} + +static unsigned long ccu_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_common *common = &mix->common; + struct ccu_div_config *div = &mix->div; + unsigned long val; + u32 reg; + + ccu_read(ctrl, common, ®); + + val = reg >> div->shift; + val &= (1 << div->width) - 1; + + val = divider_recalc_rate(hw, parent_rate, val, NULL, 0, div->width); + + return val; +} + +static int ccu_mix_trigger_fc(struct clk_hw *hw) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_common *common = &mix->common; + unsigned int val = 0; + + ccu_update(fc, common, common->fc, common->fc); + + return ccu_poll(fc, common, val, !(val & common->fc), + 5, MIX_TIMEOUT); +} + +static long ccu_factor_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + return ccu_factor_recalc_rate(hw, *prate); +} + +static int ccu_factor_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return 0; +} + +static unsigned long +ccu_mix_calc_best_rate(struct clk_hw *hw, unsigned long rate, + struct clk_hw **best_parent, + unsigned long *best_parent_rate, + u32 *div_val) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + unsigned int parent_num = clk_hw_get_num_parents(hw); + struct ccu_div_config *div = &mix->div; + u32 div_max = 1 << div->width; + unsigned long best_rate = 0; + + for (int i = 0; i < parent_num; i++) { + struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i); + unsigned long parent_rate; + + if (!parent) + continue; + + parent_rate = clk_hw_get_rate(parent); + + for (int j = 1; j <= div_max; j++) { + unsigned long tmp = DIV_ROUND_UP_ULL(parent_rate, j); + + if (abs(tmp - rate) < abs(best_rate - rate)) { + best_rate = tmp; + + if (div_val) + *div_val = j - 1; + + if (best_parent) { + *best_parent = parent; + *best_parent_rate = parent_rate; + } + } + } + } + + return best_rate; +} + +static int ccu_mix_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + req->rate = ccu_mix_calc_best_rate(hw, req->rate, + &req->best_parent_hw, + &req->best_parent_rate, + NULL); + return 0; +} + +static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_common *common = &mix->common; + struct ccu_div_config *div = &mix->div; + int ret = 0, tmp = 0; + u32 current_div, target_div; + + ccu_mix_calc_best_rate(hw, rate, NULL, NULL, &target_div); + + ccu_read(ctrl, common, &tmp); + + current_div = tmp >> div->shift; + current_div &= (1 << div->width) - 1; + + if (current_div == target_div) + return 0; + + tmp = GENMASK(div->width + div->shift - 1, div->shift); + + ccu_update(ctrl, common, tmp, target_div << div->shift); + + if (common->reg_fc) + ret = ccu_mix_trigger_fc(hw); + + return ret; +} + +static u8 ccu_mux_get_parent(struct clk_hw *hw) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_common *common = &mix->common; + struct ccu_mux_config *mux = &mix->mux; + u32 reg; + u8 parent; + + ccu_read(ctrl, common, ®); + + parent = reg >> mux->shift; + parent &= (1 << mux->width) - 1; + + return parent; +} + +static int ccu_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_common *common = &mix->common; + struct ccu_mux_config *mux = &mix->mux; + int ret = 0; + u32 mask; + + mask = GENMASK(mux->width + mux->shift - 1, mux->shift); + + ccu_update(ctrl, common, mask, index << mux->shift); + + if (common->reg_fc) + ret = ccu_mix_trigger_fc(hw); + + return ret; +} + +const struct clk_ops spacemit_ccu_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .is_enabled = ccu_gate_is_enabled, +}; + +const struct clk_ops spacemit_ccu_factor_ops = { + .round_rate = ccu_factor_round_rate, + .recalc_rate = ccu_factor_recalc_rate, + .set_rate = ccu_factor_set_rate, +}; + +const struct clk_ops spacemit_ccu_mux_ops = { + .determine_rate = ccu_mix_determine_rate, + .get_parent = ccu_mux_get_parent, + .set_parent = ccu_mux_set_parent, +}; + +const struct clk_ops spacemit_ccu_div_ops = { + .determine_rate = ccu_mix_determine_rate, + .recalc_rate = ccu_div_recalc_rate, + .set_rate = ccu_mix_set_rate, +}; + +const struct clk_ops spacemit_ccu_gate_factor_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .is_enabled = ccu_gate_is_enabled, + + .round_rate = ccu_factor_round_rate, + .recalc_rate = ccu_factor_recalc_rate, + .set_rate = ccu_factor_set_rate, +}; + +const struct clk_ops spacemit_ccu_mux_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .is_enabled = ccu_gate_is_enabled, + + .determine_rate = ccu_mix_determine_rate, + .get_parent = ccu_mux_get_parent, + .set_parent = ccu_mux_set_parent, +}; + +const struct clk_ops spacemit_ccu_div_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .is_enabled = ccu_gate_is_enabled, + + .determine_rate = ccu_mix_determine_rate, + .recalc_rate = ccu_div_recalc_rate, + .set_rate = ccu_mix_set_rate, +}; + +const struct clk_ops spacemit_ccu_div_mux_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .is_enabled = ccu_gate_is_enabled, + + .get_parent = ccu_mux_get_parent, + .set_parent = ccu_mux_set_parent, + + .determine_rate = ccu_mix_determine_rate, + .recalc_rate = ccu_div_recalc_rate, + .set_rate = ccu_mix_set_rate, +}; + +const struct clk_ops spacemit_ccu_div_mux_ops = { + .get_parent = ccu_mux_get_parent, + .set_parent = ccu_mux_set_parent, + + .determine_rate = ccu_mix_determine_rate, + .recalc_rate = ccu_div_recalc_rate, + .set_rate = ccu_mix_set_rate, +}; diff --git a/drivers/clk/spacemit/ccu_mix.h b/drivers/clk/spacemit/ccu_mix.h new file mode 100644 index 000000000000..a3aa292d073d --- /dev/null +++ b/drivers/clk/spacemit/ccu_mix.h @@ -0,0 +1,246 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024 Haylen Chu + */ + +#ifndef _CCU_MIX_H_ +#define _CCU_MIX_H_ + +#include + +#include "ccu_common.h" + +struct ccu_gate_config { + u32 mask; +}; + +struct ccu_factor_config { + u32 div; + u32 mul; +}; + +struct ccu_mux_config { + u8 shift; + u8 width; +}; + +struct ccu_div_config { + u8 shift; + u8 width; +}; + +struct ccu_mix { + struct ccu_factor_config factor; + struct ccu_gate_config gate; + struct ccu_div_config div; + struct ccu_mux_config mux; + struct ccu_common common; +}; + +#define CCU_GATE_INIT(_mask) { .mask = _mask } +#define CCU_FACTOR_INIT(_div, _mul) { .div = _div, .mul = _mul } +#define CCU_MUX_INIT(_shift, _width) { .shift = _shift, .width = _width } +#define CCU_DIV_INIT(_shift, _width) { .shift = _shift, .width = _width } + +#define CCU_PARENT_HW(_parent) { .hw = &_parent.common.hw } +#define CCU_PARENT_NAME(_name) { .fw_name = #_name } + +#define CCU_MIX_INITHW(_name, _parent, _ops, _flags) \ + (&(struct clk_init_data) { \ + .flags = _flags, \ + .name = #_name, \ + .parent_data = (const struct clk_parent_data[]) \ + { _parent }, \ + .num_parents = 1, \ + .ops = &_ops, \ + }) + +#define CCU_MIX_INITHW_PARENTS(_name, _parents, _ops, _flags) \ + CLK_HW_INIT_PARENTS_DATA(#_name, _parents, &_ops, _flags) + +#define CCU_GATE_DEFINE(_name, _parent, _reg, _gate_mask, _flags) \ +struct ccu_mix _name = { \ + .gate = CCU_GATE_INIT(_gate_mask), \ + .common = { \ + .reg_ctrl = _reg, \ + .hw.init = CCU_MIX_INITHW(_name, _parent, \ + spacemit_ccu_gate_ops, _flags), \ + } \ +} + +#define CCU_FACTOR_DEFINE(_name, _parent, _div, _mul) \ +struct ccu_mix _name = { \ + .factor = CCU_FACTOR_INIT(_div, _mul), \ + .common = { \ + .hw.init = CCU_MIX_INITHW(_name, _parent, \ + spacemit_ccu_factor_ops, 0), \ + } \ +} + +#define CCU_MUX_DEFINE(_name, _parents, _reg, _shift, _width, _flags) \ +struct ccu_mix _name = { \ + .mux = CCU_MUX_INIT(_shift, _width), \ + .common = { \ + .reg_ctrl = _reg, \ + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ + spacemit_ccu_mux_ops, _flags),\ + } \ +} + +#define CCU_DIV_DEFINE(_name, _parent, _reg, _shift, _width, _flags) \ +struct ccu_mix _name = { \ + .div = CCU_DIV_INIT(_shift, _width), \ + .common = { \ + .reg_ctrl = _reg, \ + .hw.init = CCU_MIX_INITHW(_name, _parent, \ + spacemit_ccu_div_ops, _flags) \ + } \ +} + +#define CCU_GATE_FACTOR_DEFINE(_name, _parent, \ + _reg, \ + _gate_mask, \ + _div, _mul, \ + _flags) \ +struct ccu_mix _name = { \ + .gate = CCU_GATE_INIT(_gate_mask), \ + .factor = CCU_FACTOR_INIT(_div, _mul), \ + .common = { \ + .reg_ctrl = _reg, \ + .hw.init = CCU_MIX_INITHW(_name, _parent, \ + spacemit_ccu_gate_factor_ops, _flags) \ + } \ +} + +#define CCU_MUX_GATE_DEFINE(_name, _parents, \ + _reg, \ + _shift, _width, \ + _gate_mask, \ + _flags) \ +struct ccu_mix _name = { \ + .gate = CCU_GATE_INIT(_gate_mask), \ + .mux = CCU_MUX_INIT(_shift, _width), \ + .common = { \ + .reg_ctrl = _reg, \ + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ + spacemit_ccu_mux_gate_ops, \ + _flags), \ + } \ +} + +#define CCU_DIV_GATE_DEFINE(_name, _parent, \ + _reg, \ + _shift, _width, \ + _gate_mask, \ + _flags) \ +struct ccu_mix _name = { \ + .gate = CCU_GATE_INIT(_gate_mask), \ + .div = CCU_DIV_INIT(_shift, _width), \ + .common = { \ + .reg_ctrl = _reg, \ + .hw.init = CCU_MIX_INITHW(_name, _parent, \ + spacemit_ccu_div_gate_ops, _flags), \ + } \ +} + +#define CCU_DIV_MUX_GATE_DEFINE(_name, _parents, \ + _reg_ctrl, \ + _mshift, _mwidth, _muxshift, _muxwidth, \ + _gate_mask, \ + _flags) \ +struct ccu_mix _name = { \ + .gate = CCU_GATE_INIT(_gate_mask), \ + .div = CCU_DIV_INIT(_mshift, _mwidth), \ + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ + spacemit_ccu_div_mux_gate_ops,\ + _flags), \ + }, \ +} + +#define CCU_DIV_SPLIT_FC_MUX_GATE_DEFINE(_name, _parents, \ + _reg_ctrl, _reg_fc, \ + _mshift, _mwidth, \ + _fc, \ + _muxshift, _muxwidth, \ + _gate_mask, \ + _flags) \ +struct ccu_mix _name = { \ + .gate = CCU_GATE_INIT(_gate_mask), \ + .div = CCU_DIV_INIT(_mshift, _mwidth), \ + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + .reg_fc = _reg_fc, \ + .fc = _fc, \ + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ + spacemit_ccu_div_mux_gate_ops,\ + _flags), \ + }, \ +} + +#define CCU_DIV_FC_MUX_GATE_DEFINE(_name, _parents, \ + _reg_ctrl, \ + _mshift, _mwidth, \ + _fc, \ + _muxshift, _muxwidth, \ + _gate_mask, _flags) \ +CCU_DIV_SPLIT_FC_MUX_GATE_DEFINE(_name, _parents, _reg_ctrl, _reg_ctrl, \ + _mshift, _mwidth, _fc, _muxshift, _muxwidth, \ + _gate_mask, _flags) + +#define CCU_DIV_FC_MUX_DEFINE(_name, _parents, \ + _reg_ctrl, \ + _mshift, _mwidth, \ + _fc, \ + _muxshift, _muxwidth, \ + _flags) \ +struct ccu_mix _name = { \ + .div = CCU_DIV_INIT(_mshift, _mwidth), \ + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + .reg_fc = _reg_ctrl, \ + .fc = _fc, \ + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ + spacemit_ccu_div_mux_ops, \ + _flags), \ + }, \ +} + +#define CCU_MUX_FC_DEFINE(_name, _parents, \ + _reg_ctrl, \ + _fc, \ + _muxshift, _muxwidth, \ + _flags) \ +struct ccu_mix _name = { \ + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + .reg_fc = _reg_ctrl, \ + .fc = _fc, \ + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ + spacemit_ccu_mux_ops, _flags) \ + }, \ +} + +static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_mix, common); +} + +extern const struct clk_ops spacemit_ccu_gate_ops, spacemit_ccu_factor_ops; +extern const struct clk_ops spacemit_ccu_mux_ops, spacemit_ccu_div_ops; + +extern const struct clk_ops spacemit_ccu_gate_factor_ops; +extern const struct clk_ops spacemit_ccu_div_gate_ops; +extern const struct clk_ops spacemit_ccu_mux_gate_ops; +extern const struct clk_ops spacemit_ccu_div_mux_ops; + +extern const struct clk_ops spacemit_ccu_div_mux_gate_ops; +#endif /* _CCU_DIV_H_ */ diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c new file mode 100644 index 000000000000..9df2149f6c98 --- /dev/null +++ b/drivers/clk/spacemit/ccu_pll.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Spacemit clock type pll + * + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024 Haylen Chu + */ + +#include +#include + +#include "ccu_common.h" +#include "ccu_pll.h" + +#define PLL_DELAY_TIME 3000 + +#define PLL_SWCR3_EN BIT(31) + +static int ccu_pll_is_enabled(struct clk_hw *hw) +{ + struct ccu_pll *p = hw_to_ccu_pll(hw); + u32 tmp; + + ccu_read(swcr3, &p->common, &tmp); + + return tmp & PLL_SWCR3_EN; +} + +/* frequency unit Mhz, return pll vco freq */ +static unsigned long ccu_pll_get_vco_freq(struct clk_hw *hw) +{ + const struct ccu_pll_rate_tbl *pll_rate_table; + struct ccu_pll *p = hw_to_ccu_pll(hw); + struct ccu_common *common = &p->common; + u32 swcr1, swcr3, size; + int i; + + ccu_read(swcr1, common, &swcr1); + ccu_read(swcr3, common, &swcr3); + swcr3 &= ~PLL_SWCR3_EN; + + pll_rate_table = p->pll.rate_tbl; + size = p->pll.tbl_size; + + for (i = 0; i < size; i++) { + if (pll_rate_table[i].swcr1 == swcr1 && + pll_rate_table[i].swcr3 == swcr3) + return pll_rate_table[i].rate; + } + + WARN_ON_ONCE(1); + + return 0; +} + +static int ccu_pll_enable(struct clk_hw *hw) +{ + struct ccu_pll *p = hw_to_ccu_pll(hw); + struct ccu_common *common = &p->common; + unsigned int tmp; + int ret; + + if (ccu_pll_is_enabled(hw)) + return 0; + + ccu_update(swcr3, common, PLL_SWCR3_EN, PLL_SWCR3_EN); + + /* check lock status */ + ret = regmap_read_poll_timeout_atomic(common->lock_regmap, + p->pll.reg_lock, + tmp, + tmp & p->pll.lock_enable_bit, + 5, PLL_DELAY_TIME); + + return ret; +} + +static void ccu_pll_disable(struct clk_hw *hw) +{ + struct ccu_pll *p = hw_to_ccu_pll(hw); + struct ccu_common *common = &p->common; + + ccu_update(swcr3, common, PLL_SWCR3_EN, 0); +} + +/* + * PLLs must be gated before changing rate, which is ensured by + * flag CLK_SET_RATE_GATE. + */ +static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ccu_pll *p = hw_to_ccu_pll(hw); + struct ccu_common *common = &p->common; + struct ccu_pll_config *params = &p->pll; + const struct ccu_pll_rate_tbl *entry = NULL; + int i; + + for (i = 0; i < params->tbl_size; i++) { + if (rate == params->rate_tbl[i].rate) { + entry = ¶ms->rate_tbl[i]; + break; + } + } + + if (WARN_ON_ONCE(!entry)) + return -EINVAL; + + ccu_update(swcr1, common, entry->swcr1, entry->swcr1); + ccu_update(swcr3, common, (u32)~PLL_SWCR3_EN, entry->swcr3); + + return 0; +} + +static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return ccu_pll_get_vco_freq(hw); +} + +static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct ccu_pll *p = hw_to_ccu_pll(hw); + struct ccu_pll_config *params = &p->pll; + unsigned int i; + + for (i = 0; i < params->tbl_size; i++) { + if (params->rate_tbl[i].rate > rate) { + i--; + break; + } + } + + return rate; +} + +const struct clk_ops spacemit_ccu_pll_ops = { + .enable = ccu_pll_enable, + .disable = ccu_pll_disable, + .set_rate = ccu_pll_set_rate, + .recalc_rate = ccu_pll_recalc_rate, + .round_rate = ccu_pll_round_rate, + .is_enabled = ccu_pll_is_enabled, +}; + diff --git a/drivers/clk/spacemit/ccu_pll.h b/drivers/clk/spacemit/ccu_pll.h new file mode 100644 index 000000000000..c6a3a5cce995 --- /dev/null +++ b/drivers/clk/spacemit/ccu_pll.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024 Haylen Chu + */ + +#ifndef _CCU_PLL_H_ +#define _CCU_PLL_H_ + +#include + +#include "ccu_common.h" + +struct ccu_pll_rate_tbl { + unsigned long rate; + u32 swcr1; + u32 swcr3; +}; + +struct ccu_pll_config { + const struct ccu_pll_rate_tbl *rate_tbl; + u32 tbl_size; + u32 reg_lock; + u32 lock_enable_bit; +}; + +#define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \ + { \ + .rate = _rate, \ + .swcr1 = _swcr1, \ + .swcr3 = _swcr3, \ + } + +struct ccu_pll { + struct ccu_pll_config pll; + struct ccu_common common; +}; + +#define CCU_PLL_CONFIG(_table, _reg_lock, _lock_enable_bit) \ + { \ + .rate_tbl = _table, \ + .tbl_size = ARRAY_SIZE(_table), \ + .reg_lock = (_reg_lock), \ + .lock_enable_bit = (_lock_enable_bit), \ + } + +#define CCU_PLL_HWINIT(_name, _flags) \ + (&(struct clk_init_data) { \ + .name = #_name, \ + .ops = &spacemit_ccu_pll_ops, \ + .parent_data = &(struct clk_parent_data) { .index = 0 }, \ + .num_parents = 1, \ + .flags = _flags, \ + }) + +#define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, \ + _reg_lock, _lock_enable_bit, _flags) \ + struct ccu_pll _name = { \ + .pll = CCU_PLL_CONFIG(_table, _reg_lock, _lock_enable_bit), \ + .common = { \ + .reg_swcr1 = _reg_swcr1, \ + .reg_swcr3 = _reg_swcr3, \ + .hw.init = CCU_PLL_HWINIT(_name, _flags) \ + } \ + } + +static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_pll, common); +} + +extern const struct clk_ops spacemit_ccu_pll_ops; + +#endif From patchwork Thu Mar 6 17:57:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haylen Chu X-Patchwork-Id: 14005085 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 227B4C28B24 for ; Thu, 6 Mar 2025 18:00:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=CVpUqfYnysjm0fw6aJeiPCquNqErN0PaSFx8MaZIXC0=; b=kiA253uZBbrV9n jHeqWCvSrNdTcKNLz/rW14N7OTTOkQ50oZEEfDQCbFz2HCzy5CHX8MbATqMIe+vRgFwtEb3SIpfKs qd/ER6Y+0hjLcxrLxszvCAwQSFSIvULPF/AlwrYTz4YCn1j2CBqS8inAFWJvXroP/u/MF3TNDtiXb wbFYnCZILIGrd4sHtgTQbJHraOKk8kezCGXdjudF3Kq6lvdroc4uWFm5Qv/FdxnXMO17IHg6BU/Gr zjbf//eTygfixVTi0haERFoSdm3IvLX1FsQJbfFy6nDkbaumHQmdByLmH6kxDRRwGJxck3Soxp+01 MHVwxCvf07JPsO2G8VHA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tqFVz-0000000BltN-47N9; Thu, 06 Mar 2025 18:00:11 +0000 Received: from bayard.4d2.org ([155.254.16.17]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tqFVx-0000000BlrD-0S0R for linux-riscv@lists.infradead.org; Thu, 06 Mar 2025 18:00:10 +0000 Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1]) by bayard.4d2.org (Postfix) with ESMTP id 9530AEC59F6; Thu, 06 Mar 2025 10:00:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741284008; bh=BB4k9sCGkbf5g+pYpRa3583GKVlEvttSm9LNXnS04YI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kIMMxIC1TbcgCGUkVm86XhHmJ+cPzlaWghHeUSSBC/ZysmOVgw838PblEQ5n4LzUc PMoAm9msDybc3+WcGMGQidRwlldnVVR+nyB+1BZkbmjem+PQETYGidqT6bd3LPGgU7 hN7RsHZcPOePep4rhCIlynksokLzyn5jXX3yXgvaLsvst8mMOlyiB0U4yaM/zuetDf 6Q8oPdFyfbwEnotun/SkphYZ7HN7Ozsz7NXEVDPTew1krBI+KZI3np6cXV2TDkvHML tjqc0CHiKQqLAVLT9z23Sqz90gxRc1ZS0FG4g6fzxMDsxJJt9Qjw69CojAhr7ADjxU krcctv+Y7NBcg== X-Virus-Scanned: amavisd-new at 4d2.org Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key) header.d=4d2.org Received: from bayard.4d2.org ([127.0.0.1]) by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3YlUjIGyC8xF; Thu, 6 Mar 2025 10:00:07 -0800 (PST) Received: from localhost.localdomain (unknown [183.217.80.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) (Authenticated sender: heylenay@4d2.org) by bayard.4d2.org (Postfix) with ESMTPSA id 76327EC59F2; Thu, 06 Mar 2025 10:00:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741284007; bh=BB4k9sCGkbf5g+pYpRa3583GKVlEvttSm9LNXnS04YI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LzMTo7U+pM1z1Yty+35WwORlLc/o/yp0orzGEexss4SgJRQX/2n4gO/rJjIcWSUi/ 3ncA8ru/ERZXpFm3O+pPR4/p6StRos7wNOvFr9R8Ve/RAkwPIbHf55P4F0MJhGKGu2 tJBwG/urk21ybQf18D8xRVmiUQURSbxO/xuv0Fct+/CvoR6qIb++6aY2l6/Pch58u/ lWk6e4mg0BjPhd66yZPQKe/17v1sakRIZJ4cUsNTyfUxxGStZV3Rva1W0NGRtPJfh1 v/BRWhT2fHVgUdCA/9PEAE6eOZ+9KadmiZI39YFtIrZZrt4AszfItriESeBt9mfcdP lFliMpi7iJjnw== From: Haylen Chu To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Haylen Chu , Yixun Lan Cc: linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, spacemit@lists.linux.dev, Inochi Amaoto , Chen Wang , Jisheng Zhang , Meng Zhang , Haylen Chu Subject: [PATCH v5 4/5] clk: spacemit: k1: Add TWSI8 bus and function clocks Date: Thu, 6 Mar 2025 17:57:50 +0000 Message-ID: <20250306175750.22480-6-heylenay@4d2.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250306175750.22480-2-heylenay@4d2.org> References: <20250306175750.22480-2-heylenay@4d2.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_100009_176614_2AC24DE9 X-CRM114-Status: UNSURE ( 9.93 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org The control register for TWSI8 clocks, APBC_TWSI8_CLK_RST, contains mux selection bits, reset assertion bit and enable bits for function and bus clocks. It has a quirk that reading always results in zero. As a workaround, let's hardcode the mux value as zero to select pll1_d78_31p5 as parent and treat twsi8_clk as a gate, whose enable mask is combined from the real bus and function clocks to avoid the write-only register being shared between two clk_hws, in which case updates of one clk_hw zero the other's bits. With a 1:1 factor serving as placeholder for the bus clock, the I2C-8 controller could be brought up, which is essential for boards attaching power-management chips to it. Signed-off-by: Haylen Chu --- drivers/clk/spacemit/ccu-k1.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c index 5974a0a1b5f6..44db48ae7131 100644 --- a/drivers/clk/spacemit/ccu-k1.c +++ b/drivers/clk/spacemit/ccu-k1.c @@ -558,6 +558,10 @@ static CCU_MUX_GATE_DEFINE(twsi7_clk, twsi_parents, APBC_TWSI7_CLK_RST, 4, 3, BIT(1), 0); +static CCU_GATE_DEFINE(twsi8_clk, CCU_PARENT_HW(pll1_d78_31p5), + APBC_TWSI8_CLK_RST, + BIT(1) | BIT(0), + 0); static const struct clk_parent_data timer_parents[] = { CCU_PARENT_HW(pll1_d192_12p8), @@ -795,6 +799,8 @@ static CCU_GATE_DEFINE(twsi7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI7_CLK_RST, BIT(0), 0); +static CCU_FACTOR_DEFINE(twsi8_bus_clk, CCU_PARENT_HW(apb_clk), + 1, 1); static CCU_GATE_DEFINE(timers1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS1_CLK_RST, From patchwork Thu Mar 6 17:57:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haylen Chu X-Patchwork-Id: 14005243 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D576AC282D1 for ; Thu, 6 Mar 2025 19:04:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Sn2yvQmjC0JEl9AHTGnJY1SwIMaGFGFuKz8JHlSwZ9Y=; b=BlhQUXuOMuLDXD EMOS64XJ1KbeQ6HNQzxfXUishtDHYKVKCWBcC9S6S8nJov8zfyzA3bQI3LfZDKPbYuUoeRkWiB/BB 8GXzkCLvPEKOjCLVshDL9FjuhXUTLx+DwhTEvOy1X5AO8jOuEnTrmRu3uS+9zHAcjVNiWwN0fR7Wz L4bHJFItftNkptn59ff7D3K+54qv+Od/R0cY3Kv54q2O8kgH5XahIaHbwg5/rnyiwzEB9GobWnOXT dcVGt/vJApTVIj8oP5MquIKajImgy90xqMxx+cUqv4XM8uB0B2WgLiBLKNf2QzfNa4gtdz3VP0ex9 7ScyFk49bd/78br6XGkw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tqGVl-0000000BxcM-2YUJ; Thu, 06 Mar 2025 19:04:01 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tqFWB-0000000Bm1w-1wkA for linux-riscv@bombadil.infradead.org; Thu, 06 Mar 2025 18:00:23 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=5C9EGmMcDy7KwiuwZBgYyBMDzrztkFJ9Q41ohGJHmnk=; b=NwttOjxZ8+HBslA6dNbV8jgg1t 6ZI9u35Q5s1x9t2Nbw+C0UQLZvlX0Iit/jxmMMw6131B44OIzY6S4QS3f6JHY47hJI3itRA43T6vN jnV+RuGHcOlSHYQWfQtlcY16O/WW6o+Y4qRjYYEYNV+nqdjS5OiCEWr4cAd3P/LoWzGmSEjbCTQPc /U8Ga33Jbwfp5XXC0EevsuyIzGloH6N7k72c5e1VjflYvqS4b9hEn7m4lY3MYZU6nZbWmIZXI1H1C l6r+OFaG1jpG7bVUM8osXzA4+rIuhMZST99JQkOyf95EHbEEYXzsWtkQpKm/O/8IOKYc0CQlQQDdK hOeNQasg==; Received: from bayard.4d2.org ([155.254.16.17]) by desiato.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tqFW5-00000001Bnm-3VUD for linux-riscv@lists.infradead.org; Thu, 06 Mar 2025 18:00:22 +0000 Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1]) by bayard.4d2.org (Postfix) with ESMTP id D6BE5EC59F2; Thu, 06 Mar 2025 10:00:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741284012; bh=JPr5THma9S5EoKLt/y71Ozii0SHYauExya2FtBG0v2E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gnbmC2kMymAn7C0iu8thUpB82K7QC/5WbbLZzrKwvGPlUxc96W/0AuYeSv3O8ZSZ5 KrutYX98iNSc0bUq0hF5i8y90d6baNdPMjZ9vDjPOF7vFLZbPI1nKTDPgva2cov4qd Jo6EsSH/YMlPDTJulTHbyL9AI+vPRellq+tNbmuCOrZH5co059HxnoT+giVo6hInqy zD1Uv2VjN9SZht2EyBwm+Vl2eufM5Pj5SLT16+WUiDBvNwYKENcdQG6zUrDoW0sjgq W6y1pC24nPmQgrpjH4Noiy1XUHn+zlocctj9ugpSJAqNIL1qJFBOqBQ7hR57PCDddl 85YI7cNb7g26g== X-Virus-Scanned: amavisd-new at 4d2.org Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key) header.d=4d2.org Received: from bayard.4d2.org ([127.0.0.1]) by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kxjIPGOlARPg; Thu, 6 Mar 2025 10:00:11 -0800 (PST) Received: from localhost.localdomain (unknown [183.217.80.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) (Authenticated sender: heylenay@4d2.org) by bayard.4d2.org (Postfix) with ESMTPSA id B3236EC59F5; Thu, 06 Mar 2025 10:00:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail; t=1741284011; bh=JPr5THma9S5EoKLt/y71Ozii0SHYauExya2FtBG0v2E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iM7ureVSa/S+7YUL3tB5xtVqkBhMyJqfdx9HDE0dvLZU4RHu/Jvph1InoCn00+FoF swBVcrDvNcWdDR/1ML4rc5lCMtlXUxaTn+pdFHUr+tmtriZgHSxTVdTZdrl/V4vxYh wIoAGDF9WuaCc0kyFFUa8CdAB1OjoaA8NbBc/GQYUjNjMDm87pxeaG8k1E19NWgqaP It1BZZBizokamqsTNNlwZ37jdJGRMbLSMhb62FPRnL8vlh9aE3QAaKJIsffzsVFqkw 4dn4mImqEAaqnjdHtsEN+Dd1j6CunU0fU6djssw/H130M3VZLGURr1e+Oz52DwwSIg X/+D3MS841SPg== From: Haylen Chu To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Haylen Chu , Yixun Lan Cc: linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, spacemit@lists.linux.dev, Inochi Amaoto , Chen Wang , Jisheng Zhang , Meng Zhang , Haylen Chu Subject: [PATCH v5 5/5] riscv: dts: spacemit: Add clock tree for Spacemit K1 Date: Thu, 6 Mar 2025 17:57:51 +0000 Message-ID: <20250306175750.22480-7-heylenay@4d2.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250306175750.22480-2-heylenay@4d2.org> References: <20250306175750.22480-2-heylenay@4d2.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250306_180018_491464_93CDEF68 X-CRM114-Status: UNSURE ( 8.16 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Describe the PLL and system controllers that're capable of generating clock signals in the devicetree. Signed-off-by: Haylen Chu --- arch/riscv/boot/dts/spacemit/k1.dtsi | 79 ++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi index c670ebf8fa12..09a9100986b1 100644 --- a/arch/riscv/boot/dts/spacemit/k1.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi @@ -3,6 +3,8 @@ * Copyright (C) 2024 Yangyu Chen */ +#include + /dts-v1/; / { #address-cells = <2>; @@ -306,6 +308,40 @@ cluster1_l2_cache: l2-cache1 { }; }; + clocks { + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + + vctcxo_1m: clock-1m { + compatible = "fixed-clock"; + clock-frequency = <1000000>; + clock-output-names = "vctcxo_1m"; + #clock-cells = <0>; + }; + + vctcxo_24m: clock-24m { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "vctcxo_24m"; + #clock-cells = <0>; + }; + + vctcxo_3m: clock-3m { + compatible = "fixed-clock"; + clock-frequency = <3000000>; + clock-output-names = "vctcxo_3m"; + #clock-cells = <0>; + }; + + osc_32k: clock-32k { + compatible = "fixed-clock"; + clock-frequency = <32000>; + clock-output-names = "osc_32k"; + #clock-cells = <0>; + }; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&plic>; @@ -314,6 +350,17 @@ soc { dma-noncoherent; ranges; + syscon_apbc: system-control@d4015000 { + compatible = "spacemit,k1-syscon-apbc"; + reg = <0x0 0xd4015000 0x0 0x1000>; + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, + <&vctcxo_24m>; + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", + "vctcxo_24m"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + uart0: serial@d4017000 { compatible = "spacemit,k1-uart", "intel,xscale-uart"; reg = <0x0 0xd4017000 0x0 0x100>; @@ -409,6 +456,38 @@ pinctrl: pinctrl@d401e000 { reg = <0x0 0xd401e000 0x0 0x400>; }; + syscon_mpmu: system-controller@d4050000 { + compatible = "spacemit,k1-syscon-mpmu"; + reg = <0x0 0xd4050000 0x0 0x209c>; + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, + <&vctcxo_24m>; + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", + "vctcxo_24m"; + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; + }; + + pll: system-control@d4090000 { + compatible = "spacemit,k1-pll"; + reg = <0x0 0xd4090000 0x0 0x1000>; + clocks = <&vctcxo_24m>; + spacemit,mpmu = <&syscon_mpmu>; + #clock-cells = <1>; + }; + + syscon_apmu: system-control@d4282800 { + compatible = "spacemit,k1-syscon-apmu"; + reg = <0x0 0xd4282800 0x0 0x400>; + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, + <&vctcxo_24m>; + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", + "vctcxo_24m"; + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; + }; + plic: interrupt-controller@e0000000 { compatible = "spacemit,k1-plic", "sifive,plic-1.0.0"; reg = <0x0 0xe0000000 0x0 0x4000000>;