From nobody Wed Nov 27 18:40:51 2024 Received: from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B06216FF45; Wed, 9 Oct 2024 06:05:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.20.114.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728453929; cv=none; b=oFjaFF9P+AdImVDjM3pgdM22gQwKCnP7emCri4BzXKBhNSQCsorEIfaSnua3MEPLCEeh24Z2yuszWDwUIt04qgrtff4EEImbWUt2nvNHwtschoMzYYFQQVLp8Yw+5KVVN/NQoacVSasazZd3fuNZEM/cQhJWDc2K9dI45riSdC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728453929; c=relaxed/simple; bh=tGbR4r0mnbfbXEDlq44z0VGuJFLdhIQ2sOUhKA3wwY4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OJBUneM9nbUXbVQaHUOaPTzJ2Vrt0OM6TJAZBmLn7eHAgAo9HpY+woxI5p3ZT4DgQ/DSP2tOELIsxp0LkkcAXZccaiaIu8bZLMxBI0pr4eemeqhVtu1dK2C41yw6AgNzdM5XSp7uSltI6aYGbGvGpDJJPUNWigaCtm44XL/VOBc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com; spf=pass smtp.mailfrom=aspeedtech.com; arc=none smtp.client-ip=211.20.114.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aspeedtech.com Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 9 Oct 2024 14:05:21 +0800 Received: from twmbx02.aspeed.com (192.168.10.152) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 9 Oct 2024 14:05:21 +0800 From: Ryan Chen To: , , , , , , , , , , , , , , CC: Krzysztof Kozlowski Subject: [PATCH v5 1/3] dt-bindings: mfd: aspeed: support for AST2700 Date: Wed, 9 Oct 2024 14:05:19 +0800 Message-ID: <20241009060521.2971168-2-ryan_chen@aspeedtech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241009060521.2971168-1-ryan_chen@aspeedtech.com> References: <20241009060521.2971168-1-ryan_chen@aspeedtech.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add reset, clk dt bindings headers, and update compatible support for AST2700 clk, silicon-id in yaml. Signed-off-by: Ryan Chen Reviewed-by: Krzysztof Kozlowski --- .../bindings/mfd/aspeed,ast2x00-scu.yaml | 8 +- .../dt-bindings/clock/aspeed,ast2700-scu.h | 163 ++++++++++++++++++ .../dt-bindings/reset/aspeed,ast2700-scu.h | 124 +++++++++++++ 3 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/clock/aspeed,ast2700-scu.h create mode 100644 include/dt-bindings/reset/aspeed,ast2700-scu.h diff --git a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml = b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml index 86ee69c0f45b..c800d5e53b65 100644 --- a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml +++ b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml @@ -9,6 +9,8 @@ title: Aspeed System Control Unit description: The Aspeed System Control Unit manages the global behaviour of the SoC, configuring elements such as clocks, pinmux, and reset. + In AST2700 SOC which has two soc connection, each soc have its own scu + register control, ast2700-scu0 for soc0, ast2700-scu1 for soc1. =20 maintainers: - Joel Stanley @@ -21,6 +23,8 @@ properties: - aspeed,ast2400-scu - aspeed,ast2500-scu - aspeed,ast2600-scu + - aspeed,ast2700-scu0 + - aspeed,ast2700-scu1 - const: syscon - const: simple-mfd =20 @@ -30,7 +34,8 @@ properties: ranges: true =20 '#address-cells': - const: 1 + minimum: 1 + maximum: 2 =20 '#size-cells': const: 1 @@ -76,6 +81,7 @@ patternProperties: - aspeed,ast2400-silicon-id - aspeed,ast2500-silicon-id - aspeed,ast2600-silicon-id + - aspeed,ast2700-silicon-id - const: aspeed,silicon-id =20 reg: diff --git a/include/dt-bindings/clock/aspeed,ast2700-scu.h b/include/dt-bi= ndings/clock/aspeed,ast2700-scu.h new file mode 100644 index 000000000000..63021af3caf5 --- /dev/null +++ b/include/dt-bindings/clock/aspeed,ast2700-scu.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Device Tree binding constants for AST2700 clock controller. + * + * Copyright (c) 2024 Aspeed Technology Inc. + */ + +#ifndef __DT_BINDINGS_CLOCK_AST2700_H +#define __DT_BINDINGS_CLOCK_AST2700_H + +/* SOC0 clk */ +#define SCU0_CLKIN 0 +#define SCU0_CLK_24M 1 +#define SCU0_CLK_192M 2 +#define SCU0_CLK_UART 3 +#define SCU0_CLK_UART_DIV13 3 +#define SCU0_CLK_PSP 4 +#define SCU0_CLK_HPLL 5 +#define SCU0_CLK_HPLL_DIV2 6 +#define SCU0_CLK_HPLL_DIV4 7 +#define SCU0_CLK_HPLL_DIV_AHB 8 +#define SCU0_CLK_DPLL 9 +#define SCU0_CLK_MPLL 10 +#define SCU0_CLK_MPLL_DIV2 11 +#define SCU0_CLK_MPLL_DIV4 12 +#define SCU0_CLK_MPLL_DIV8 13 +#define SCU0_CLK_MPLL_DIV_AHB 14 +#define SCU0_CLK_D0 15 +#define SCU0_CLK_D1 16 +#define SCU0_CLK_CRT0 17 +#define SCU0_CLK_CRT1 18 +#define SCU0_CLK_MPHY 19 +#define SCU0_CLK_AXI0 20 +#define SCU0_CLK_AXI1 21 +#define SCU0_CLK_AHB 22 +#define SCU0_CLK_APB 23 +#define SCU0_CLK_UART4 24 +#define SCU0_CLK_EMMCMUX 25 +#define SCU0_CLK_EMMC 26 +#define SCU0_CLK_U2PHY_CLK12M 27 +#define SCU0_CLK_U2PHY_REFCLK 28 + +/* SOC0 clk-gate */ +#define SCU0_CLK_GATE_MCLK 29 +#define SCU0_CLK_GATE_ECLK 30 +#define SCU0_CLK_GATE_2DCLK 31 +#define SCU0_CLK_GATE_VCLK 32 +#define SCU0_CLK_GATE_BCLK 33 +#define SCU0_CLK_GATE_VGA0CLK 34 +#define SCU0_CLK_GATE_REFCLK 35 +#define SCU0_CLK_GATE_PORTBUSB2CLK 36 +#define SCU0_CLK_GATE_UHCICLK 37 +#define SCU0_CLK_GATE_VGA1CLK 38 +#define SCU0_CLK_GATE_DDRPHYCLK 39 +#define SCU0_CLK_GATE_E2M0CLK 40 +#define SCU0_CLK_GATE_HACCLK 41 +#define SCU0_CLK_GATE_PORTAUSB2CLK 42 +#define SCU0_CLK_GATE_UART4CLK 43 +#define SCU0_CLK_GATE_SLICLK 44 +#define SCU0_CLK_GATE_DACCLK 45 +#define SCU0_CLK_GATE_DP 46 +#define SCU0_CLK_GATE_E2M1CLK 47 +#define SCU0_CLK_GATE_CRT0CLK 48 +#define SCU0_CLK_GATE_CRT1CLK 49 +#define SCU0_CLK_GATE_ECDSACLK 50 +#define SCU0_CLK_GATE_RSACLK 51 +#define SCU0_CLK_GATE_RVAS0CLK 52 +#define SCU0_CLK_GATE_UFSCLK 53 +#define SCU0_CLK_GATE_EMMCCLK 54 +#define SCU0_CLK_GATE_RVAS1CLK 55 + +/* SOC1 clk */ +#define SCU1_CLKIN 0 +#define SCU1_CLK_HPLL 1 +#define SCU1_CLK_APLL 2 +#define SCU1_CLK_APLL_DIV2 3 +#define SCU1_CLK_APLL_DIV4 4 +#define SCU1_CLK_DPLL 5 +#define SCU1_CLK_UXCLK 6 +#define SCU1_CLK_HUXCLK 7 +#define SCU1_CLK_UARTX 8 +#define SCU1_CLK_HUARTX 9 +#define SCU1_CLK_AHB 10 +#define SCU1_CLK_APB 11 +#define SCU1_CLK_UART0 12 +#define SCU1_CLK_UART1 13 +#define SCU1_CLK_UART2 14 +#define SCU1_CLK_UART3 15 +#define SCU1_CLK_UART5 16 +#define SCU1_CLK_UART6 17 +#define SCU1_CLK_UART7 18 +#define SCU1_CLK_UART8 19 +#define SCU1_CLK_UART9 20 +#define SCU1_CLK_UART10 21 +#define SCU1_CLK_UART11 22 +#define SCU1_CLK_UART12 23 +#define SCU1_CLK_UART13 24 +#define SCU1_CLK_UART14 25 +#define SCU1_CLK_APLL_DIVN 26 +#define SCU1_CLK_SDMUX 27 +#define SCU1_CLK_SDCLK 28 +#define SCU1_CLK_RMII 29 +#define SCU1_CLK_RGMII 30 +#define SCU1_CLK_MACHCLK 31 +#define SCU1_CLK_MAC0RCLK 32 +#define SCU1_CLK_MAC1RCLK 33 +#define SCU1_CLK_CAN 34 + +/* SOC1 clk gate */ +#define SCU1_CLK_GATE_LCLK0 35 +#define SCU1_CLK_GATE_LCLK1 36 +#define SCU1_CLK_GATE_ESPI0CLK 37 +#define SCU1_CLK_GATE_ESPI1CLK 38 +#define SCU1_CLK_GATE_SDCLK 39 +#define SCU1_CLK_GATE_IPEREFCLK 40 +#define SCU1_CLK_GATE_REFCLK 41 +#define SCU1_CLK_GATE_LPCHCLK 42 +#define SCU1_CLK_GATE_MAC0CLK 43 +#define SCU1_CLK_GATE_MAC1CLK 44 +#define SCU1_CLK_GATE_MAC2CLK 45 +#define SCU1_CLK_GATE_UART0CLK 46 +#define SCU1_CLK_GATE_UART1CLK 47 +#define SCU1_CLK_GATE_UART2CLK 48 +#define SCU1_CLK_GATE_UART3CLK 49 +#define SCU1_CLK_GATE_I2CCLK 50 +#define SCU1_CLK_GATE_I3C0CLK 51 +#define SCU1_CLK_GATE_I3C1CLK 52 +#define SCU1_CLK_GATE_I3C2CLK 53 +#define SCU1_CLK_GATE_I3C3CLK 54 +#define SCU1_CLK_GATE_I3C4CLK 55 +#define SCU1_CLK_GATE_I3C5CLK 56 +#define SCU1_CLK_GATE_I3C6CLK 57 +#define SCU1_CLK_GATE_I3C7CLK 58 +#define SCU1_CLK_GATE_I3C8CLK 59 +#define SCU1_CLK_GATE_I3C9CLK 60 +#define SCU1_CLK_GATE_I3C10CLK 61 +#define SCU1_CLK_GATE_I3C11CLK 62 +#define SCU1_CLK_GATE_I3C12CLK 63 +#define SCU1_CLK_GATE_I3C13CLK 64 +#define SCU1_CLK_GATE_I3C14CLK 65 +#define SCU1_CLK_GATE_I3C15CLK 66 +#define SCU1_CLK_GATE_UART5CLK 67 +#define SCU1_CLK_GATE_UART6CLK 68 +#define SCU1_CLK_GATE_UART7CLK 69 +#define SCU1_CLK_GATE_UART8CLK 70 +#define SCU1_CLK_GATE_UART9CLK 71 +#define SCU1_CLK_GATE_UART10CLK 72 +#define SCU1_CLK_GATE_UART11CLK 73 +#define SCU1_CLK_GATE_UART12CLK 74 +#define SCU1_CLK_GATE_FSICLK 75 +#define SCU1_CLK_GATE_LTPIPHYCLK 76 +#define SCU1_CLK_GATE_LTPICLK 77 +#define SCU1_CLK_GATE_VGALCLK 78 +#define SCU1_CLK_GATE_UHCICLK 79 +#define SCU1_CLK_GATE_CANCLK 80 +#define SCU1_CLK_GATE_PCICLK 81 +#define SCU1_CLK_GATE_SLICLK 82 +#define SCU1_CLK_GATE_E2MCLK 83 +#define SCU1_CLK_GATE_PORTCUSB2CLK 84 +#define SCU1_CLK_GATE_PORTDUSB2CLK 85 +#define SCU1_CLK_GATE_LTPI1TXCLK 86 + +#endif diff --git a/include/dt-bindings/reset/aspeed,ast2700-scu.h b/include/dt-bi= ndings/reset/aspeed,ast2700-scu.h new file mode 100644 index 000000000000..d53c719b7a66 --- /dev/null +++ b/include/dt-bindings/reset/aspeed,ast2700-scu.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Device Tree binding constants for AST2700 reset controller. + * + * Copyright (c) 2024 Aspeed Technology Inc. + */ + +#ifndef _MACH_ASPEED_AST2700_RESET_H_ +#define _MACH_ASPEED_AST2700_RESET_H_ + +/* SOC0 */ +#define SCU0_RESET_SDRAM 0 +#define SCU0_RESET_DDRPHY 1 +#define SCU0_RESET_RSA 2 +#define SCU0_RESET_SHA3 3 +#define SCU0_RESET_HACE 4 +#define SCU0_RESET_SOC 5 +#define SCU0_RESET_VIDEO 6 +#define SCU0_RESET_2D 7 +#define SCU0_RESET_PCIS 8 +#define SCU0_RESET_RVAS0 9 +#define SCU0_RESET_RVAS1 10 +#define SCU0_RESET_SM3 11 +#define SCU0_RESET_SM4 12 +#define SCU0_RESET_CRT0 13 +#define SCU0_RESET_ECC 14 +#define SCU0_RESET_DP_PCI 15 +#define SCU0_RESET_UFS 16 +#define SCU0_RESET_EMMC 17 +#define SCU0_RESET_PCIE1RST 18 +#define SCU0_RESET_PCIE1RSTOE 19 +#define SCU0_RESET_PCIE0RST 20 +#define SCU0_RESET_PCIE0RSTOE 21 +#define SCU0_RESET_JTAG 22 +#define SCU0_RESET_MCTP0 23 +#define SCU0_RESET_MCTP1 24 +#define SCU0_RESET_XDMA0 25 +#define SCU0_RESET_XDMA1 26 +#define SCU0_RESET_H2X1 27 +#define SCU0_RESET_DP 28 +#define SCU0_RESET_DP_MCU 29 +#define SCU0_RESET_SSP 30 +#define SCU0_RESET_H2X0 31 +#define SCU0_RESET_PORTA_VHUB 32 +#define SCU0_RESET_PORTA_PHY3 33 +#define SCU0_RESET_PORTA_XHCI 34 +#define SCU0_RESET_PORTB_VHUB 35 +#define SCU0_RESET_PORTB_PHY3 36 +#define SCU0_RESET_PORTB_XHCI 37 +#define SCU0_RESET_PORTA_VHUB_EHCI 38 +#define SCU0_RESET_PORTB_VHUB_EHCI 39 +#define SCU0_RESET_UHCI 40 +#define SCU0_RESET_TSP 41 +#define SCU0_RESET_E2M0 42 +#define SCU0_RESET_E2M1 43 +#define SCU0_RESET_VLINK 44 + +/* SOC1 */ +#define SCU1_RESET_LPC0 0 +#define SCU1_RESET_LPC1 1 +#define SCU1_RESET_MII 2 +#define SCU1_RESET_PECI 3 +#define SCU1_RESET_PWM 4 +#define SCU1_RESET_MAC0 5 +#define SCU1_RESET_MAC1 6 +#define SCU1_RESET_MAC2 7 +#define SCU1_RESET_ADC 8 +#define SCU1_RESET_SD 9 +#define SCU1_RESET_ESPI0 10 +#define SCU1_RESET_ESPI1 11 +#define SCU1_RESET_JTAG1 12 +#define SCU1_RESET_SPI0 13 +#define SCU1_RESET_SPI1 14 +#define SCU1_RESET_SPI2 15 +#define SCU1_RESET_I3C0 16 +#define SCU1_RESET_I3C1 17 +#define SCU1_RESET_I3C2 18 +#define SCU1_RESET_I3C3 19 +#define SCU1_RESET_I3C4 20 +#define SCU1_RESET_I3C5 21 +#define SCU1_RESET_I3C6 22 +#define SCU1_RESET_I3C7 23 +#define SCU1_RESET_I3C8 24 +#define SCU1_RESET_I3C9 25 +#define SCU1_RESET_I3C10 26 +#define SCU1_RESET_I3C11 27 +#define SCU1_RESET_I3C12 28 +#define SCU1_RESET_I3C13 29 +#define SCU1_RESET_I3C14 30 +#define SCU1_RESET_I3C15 31 +#define SCU1_RESET_MCU0 32 +#define SCU1_RESET_MCU1 33 +#define SCU1_RESET_H2A_SPI1 34 +#define SCU1_RESET_H2A_SPI2 35 +#define SCU1_RESET_UART0 36 +#define SCU1_RESET_UART1 37 +#define SCU1_RESET_UART2 38 +#define SCU1_RESET_UART3 39 +#define SCU1_RESET_I2C_FILTER 40 +#define SCU1_RESET_CALIPTRA 41 +#define SCU1_RESET_XDMA 42 +#define SCU1_RESET_FSI 43 +#define SCU1_RESET_CAN 44 +#define SCU1_RESET_MCTP 45 +#define SCU1_RESET_I2C 46 +#define SCU1_RESET_UART6 47 +#define SCU1_RESET_UART7 48 +#define SCU1_RESET_UART8 49 +#define SCU1_RESET_UART9 50 +#define SCU1_RESET_LTPI0 51 +#define SCU1_RESET_VGAL 52 +#define SCU1_RESET_LTPI1 53 +#define SCU1_RESET_ACE 54 +#define SCU1_RESET_E2M 55 +#define SCU1_RESET_UHCI 56 +#define SCU1_RESET_PORTC_USB2UART 57 +#define SCU1_RESET_PORTC_VHUB_EHCI 58 +#define SCU1_RESET_PORTD_USB2UART 59 +#define SCU1_RESET_PORTD_VHUB_EHCI 60 +#define SCU1_RESET_H2X 61 +#define SCU1_RESET_I3CDMA 62 +#define SCU1_RESET_PCIE2RST 63 + +#endif /* _MACH_ASPEED_AST2700_RESET_H_ */ --=20 2.34.1 From nobody Wed Nov 27 18:40:51 2024 Received: from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF739176FA4; Wed, 9 Oct 2024 06:05:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.20.114.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728453931; cv=none; b=KGI3IasZfer9x1ESWDa/nUsp83XldgyKgKQLkun5c680NS45/IJpCH7ja7/RE9mXczryDaqZtZItsAHEuBRWo1ZRGn3rPsQO2jZdCe4IOTZZ+4s90EC5Mo9G7jg0BC3/6OG1eLkXB2ElOQrdcz7C/xHgAcccciOEi3Awx23qwuA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728453931; c=relaxed/simple; bh=n0rfPQbfNIy0sKSFhrTRChInbwP60zMpNBXQF3jCRyg=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jJaSFdGWmWjHv4bLjGX+pPqMrVUv8laUH1McyrnbiNJKqZLYttiT6TTcNtfvrO6/WbZTy7bZC3z15PFNqDEbL1gd3qeKlNqhNkrLrUNFyfkgdXXYWEM0IQSlxHzVWGfeEBfdwtEnYcrJY7EU12CCjQMgwDliaZy/JEMN3Y4XzUs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com; spf=pass smtp.mailfrom=aspeedtech.com; arc=none smtp.client-ip=211.20.114.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aspeedtech.com Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 9 Oct 2024 14:05:22 +0800 Received: from twmbx02.aspeed.com (192.168.10.152) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 9 Oct 2024 14:05:22 +0800 From: Ryan Chen To: , , , , , , , , , , , , , , Subject: [PATCH v5 2/3] reset: aspeed: register AST2700 reset auxiliary bus device Date: Wed, 9 Oct 2024 14:05:20 +0800 Message-ID: <20241009060521.2971168-3-ryan_chen@aspeedtech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241009060521.2971168-1-ryan_chen@aspeedtech.com> References: <20241009060521.2971168-1-ryan_chen@aspeedtech.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The AST2700 reset driver is registered as an auxiliary device due to reset and clock controller share the same register region. Signed-off-by: Ryan Chen Reviewed-by: Philipp Zabel --- drivers/reset/Kconfig | 7 + drivers/reset/Makefile | 1 + drivers/reset/reset-aspeed.c | 256 +++++++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 drivers/reset/reset-aspeed.c diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 67bce340a87e..71a3accea7cb 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -22,6 +22,13 @@ config RESET_A10SR This option enables support for the external reset functions for peripheral PHYs on the Altera Arria10 System Resource Chip. =20 +config RESET_ASPEED + tristate "ASPEED Reset Driver" + depends on ARCH_ASPEED || COMPILE_TEST + select AUXILIARY_BUS + help + This enables the reset controller driver for AST2700. + config RESET_ATH79 bool "AR71xx Reset Driver" if COMPILE_TEST default ATH79 diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 27b0bbdfcc04..97482bb56416 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -5,6 +5,7 @@ obj-y +=3D starfive/ obj-y +=3D sti/ obj-y +=3D tegra/ obj-$(CONFIG_RESET_A10SR) +=3D reset-a10sr.o +obj-$(CONFIG_RESET_ASPEED) +=3D reset-aspeed.o obj-$(CONFIG_RESET_ATH79) +=3D reset-ath79.o obj-$(CONFIG_RESET_AXS10X) +=3D reset-axs10x.o obj-$(CONFIG_RESET_BCM6345) +=3D reset-bcm6345.o diff --git a/drivers/reset/reset-aspeed.c b/drivers/reset/reset-aspeed.c new file mode 100644 index 000000000000..8a2a68ac442b --- /dev/null +++ b/drivers/reset/reset-aspeed.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2024 ASPEED Technology Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SCU0_RESET_CTRL1 0x200 +#define SCU0_RESET_CTRL2 0x220 +#define SCU1_RESET_CTRL1 0x200 +#define SCU1_RESET_CTRL2 0x220 +#define SCU1_PCIE3_CTRL 0x908 + +struct ast2700_reset_signal { + bool dedicated_clr; /* dedicated reset clr offset */ + u32 offset, bit; +}; + +struct aspeed_reset_info { + unsigned int nr_resets; + const struct ast2700_reset_signal *signal; +}; + +struct aspeed_reset { + struct reset_controller_dev rcdev; + struct aspeed_reset_info *info; + spinlock_t lock; /* Protect read-modify-write cycle */ + void __iomem *base; +}; + +static const struct ast2700_reset_signal ast2700_reset0_signals[] =3D { + [SCU0_RESET_SDRAM] =3D { true, SCU0_RESET_CTRL1, BIT(0) }, + [SCU0_RESET_DDRPHY] =3D { true, SCU0_RESET_CTRL1, BIT(1) }, + [SCU0_RESET_RSA] =3D { true, SCU0_RESET_CTRL1, BIT(2) }, + [SCU0_RESET_SHA3] =3D { true, SCU0_RESET_CTRL1, BIT(3) }, + [SCU0_RESET_HACE] =3D { true, SCU0_RESET_CTRL1, BIT(4) }, + [SCU0_RESET_SOC] =3D { true, SCU0_RESET_CTRL1, BIT(5) }, + [SCU0_RESET_VIDEO] =3D { true, SCU0_RESET_CTRL1, BIT(6) }, + [SCU0_RESET_2D] =3D { true, SCU0_RESET_CTRL1, BIT(7) }, + [SCU0_RESET_PCIS] =3D { true, SCU0_RESET_CTRL1, BIT(8) }, + [SCU0_RESET_RVAS0] =3D { true, SCU0_RESET_CTRL1, BIT(9) }, + [SCU0_RESET_RVAS1] =3D { true, SCU0_RESET_CTRL1, BIT(10) }, + [SCU0_RESET_SM3] =3D { true, SCU0_RESET_CTRL1, BIT(11) }, + [SCU0_RESET_SM4] =3D { true, SCU0_RESET_CTRL1, BIT(12) }, + [SCU0_RESET_CRT0] =3D { true, SCU0_RESET_CTRL1, BIT(13) }, + [SCU0_RESET_ECC] =3D { true, SCU0_RESET_CTRL1, BIT(14) }, + [SCU0_RESET_DP_PCI] =3D { true, SCU0_RESET_CTRL1, BIT(15) }, + [SCU0_RESET_UFS] =3D { true, SCU0_RESET_CTRL1, BIT(16) }, + [SCU0_RESET_EMMC] =3D { true, SCU0_RESET_CTRL1, BIT(17) }, + [SCU0_RESET_PCIE1RST] =3D { true, SCU0_RESET_CTRL1, BIT(18) }, + [SCU0_RESET_PCIE1RSTOE] =3D { true, SCU0_RESET_CTRL1, BIT(19) }, + [SCU0_RESET_PCIE0RST] =3D { true, SCU0_RESET_CTRL1, BIT(20) }, + [SCU0_RESET_PCIE0RSTOE] =3D { true, SCU0_RESET_CTRL1, BIT(21) }, + [SCU0_RESET_JTAG] =3D { true, SCU0_RESET_CTRL1, BIT(22) }, + [SCU0_RESET_MCTP0] =3D { true, SCU0_RESET_CTRL1, BIT(23) }, + [SCU0_RESET_MCTP1] =3D { true, SCU0_RESET_CTRL1, BIT(24) }, + [SCU0_RESET_XDMA0] =3D { true, SCU0_RESET_CTRL1, BIT(25) }, + [SCU0_RESET_XDMA1] =3D { true, SCU0_RESET_CTRL1, BIT(26) }, + [SCU0_RESET_H2X1] =3D { true, SCU0_RESET_CTRL1, BIT(27) }, + [SCU0_RESET_DP] =3D { true, SCU0_RESET_CTRL1, BIT(28) }, + [SCU0_RESET_DP_MCU] =3D { true, SCU0_RESET_CTRL1, BIT(29) }, + [SCU0_RESET_SSP] =3D { true, SCU0_RESET_CTRL1, BIT(30) }, + [SCU0_RESET_H2X0] =3D { true, SCU0_RESET_CTRL1, BIT(31) }, + [SCU0_RESET_PORTA_VHUB] =3D { true, SCU0_RESET_CTRL2, BIT(0) }, + [SCU0_RESET_PORTA_PHY3] =3D { true, SCU0_RESET_CTRL2, BIT(1) }, + [SCU0_RESET_PORTA_XHCI] =3D { true, SCU0_RESET_CTRL2, BIT(2) }, + [SCU0_RESET_PORTB_VHUB] =3D { true, SCU0_RESET_CTRL2, BIT(3) }, + [SCU0_RESET_PORTB_PHY3] =3D { true, SCU0_RESET_CTRL2, BIT(4) }, + [SCU0_RESET_PORTB_XHCI] =3D { true, SCU0_RESET_CTRL2, BIT(5) }, + [SCU0_RESET_PORTA_VHUB_EHCI] =3D { true, SCU0_RESET_CTRL2, BIT(6) }, + [SCU0_RESET_PORTB_VHUB_EHCI] =3D { true, SCU0_RESET_CTRL2, BIT(7) }, + [SCU0_RESET_UHCI] =3D { true, SCU0_RESET_CTRL2, BIT(8) }, + [SCU0_RESET_TSP] =3D { true, SCU0_RESET_CTRL2, BIT(9) }, + [SCU0_RESET_E2M0] =3D { true, SCU0_RESET_CTRL2, BIT(10) }, + [SCU0_RESET_E2M1] =3D { true, SCU0_RESET_CTRL2, BIT(11) }, + [SCU0_RESET_VLINK] =3D { true, SCU0_RESET_CTRL2, BIT(12) }, +}; + +static const struct ast2700_reset_signal ast2700_reset1_signals[] =3D { + [SCU1_RESET_LPC0] =3D { true, SCU1_RESET_CTRL1, BIT(0) }, + [SCU1_RESET_LPC1] =3D { true, SCU1_RESET_CTRL1, BIT(1) }, + [SCU1_RESET_MII] =3D { true, SCU1_RESET_CTRL1, BIT(2) }, + [SCU1_RESET_PECI] =3D { true, SCU1_RESET_CTRL1, BIT(3) }, + [SCU1_RESET_PWM] =3D { true, SCU1_RESET_CTRL1, BIT(4) }, + [SCU1_RESET_MAC0] =3D { true, SCU1_RESET_CTRL1, BIT(5) }, + [SCU1_RESET_MAC1] =3D { true, SCU1_RESET_CTRL1, BIT(6) }, + [SCU1_RESET_MAC2] =3D { true, SCU1_RESET_CTRL1, BIT(7) }, + [SCU1_RESET_ADC] =3D { true, SCU1_RESET_CTRL1, BIT(8) }, + [SCU1_RESET_SD] =3D { true, SCU1_RESET_CTRL1, BIT(9) }, + [SCU1_RESET_ESPI0] =3D { true, SCU1_RESET_CTRL1, BIT(10) }, + [SCU1_RESET_ESPI1] =3D { true, SCU1_RESET_CTRL1, BIT(11) }, + [SCU1_RESET_JTAG1] =3D { true, SCU1_RESET_CTRL1, BIT(12) }, + [SCU1_RESET_SPI0] =3D { true, SCU1_RESET_CTRL1, BIT(13) }, + [SCU1_RESET_SPI1] =3D { true, SCU1_RESET_CTRL1, BIT(14) }, + [SCU1_RESET_SPI2] =3D { true, SCU1_RESET_CTRL1, BIT(15) }, + [SCU1_RESET_I3C0] =3D { true, SCU1_RESET_CTRL1, BIT(16) }, + [SCU1_RESET_I3C1] =3D { true, SCU1_RESET_CTRL1, BIT(17) }, + [SCU1_RESET_I3C2] =3D { true, SCU1_RESET_CTRL1, BIT(18) }, + [SCU1_RESET_I3C3] =3D { true, SCU1_RESET_CTRL1, BIT(19) }, + [SCU1_RESET_I3C4] =3D { true, SCU1_RESET_CTRL1, BIT(20) }, + [SCU1_RESET_I3C5] =3D { true, SCU1_RESET_CTRL1, BIT(21) }, + [SCU1_RESET_I3C6] =3D { true, SCU1_RESET_CTRL1, BIT(22) }, + [SCU1_RESET_I3C7] =3D { true, SCU1_RESET_CTRL1, BIT(23) }, + [SCU1_RESET_I3C8] =3D { true, SCU1_RESET_CTRL1, BIT(24) }, + [SCU1_RESET_I3C9] =3D { true, SCU1_RESET_CTRL1, BIT(25) }, + [SCU1_RESET_I3C10] =3D { true, SCU1_RESET_CTRL1, BIT(26) }, + [SCU1_RESET_I3C11] =3D { true, SCU1_RESET_CTRL1, BIT(27) }, + [SCU1_RESET_I3C12] =3D { true, SCU1_RESET_CTRL1, BIT(28) }, + [SCU1_RESET_I3C13] =3D { true, SCU1_RESET_CTRL1, BIT(29) }, + [SCU1_RESET_I3C14] =3D { true, SCU1_RESET_CTRL1, BIT(30) }, + [SCU1_RESET_I3C15] =3D { true, SCU1_RESET_CTRL1, BIT(31) }, + [SCU1_RESET_MCU0] =3D { true, SCU1_RESET_CTRL2, BIT(0) }, + [SCU1_RESET_MCU1] =3D { true, SCU1_RESET_CTRL2, BIT(1) }, + [SCU1_RESET_H2A_SPI1] =3D { true, SCU1_RESET_CTRL2, BIT(2) }, + [SCU1_RESET_H2A_SPI2] =3D { true, SCU1_RESET_CTRL2, BIT(3) }, + [SCU1_RESET_UART0] =3D { true, SCU1_RESET_CTRL2, BIT(4) }, + [SCU1_RESET_UART1] =3D { true, SCU1_RESET_CTRL2, BIT(5) }, + [SCU1_RESET_UART2] =3D { true, SCU1_RESET_CTRL2, BIT(6) }, + [SCU1_RESET_UART3] =3D { true, SCU1_RESET_CTRL2, BIT(7) }, + [SCU1_RESET_I2C_FILTER] =3D { true, SCU1_RESET_CTRL2, BIT(8) }, + [SCU1_RESET_CALIPTRA] =3D { true, SCU1_RESET_CTRL2, BIT(9) }, + [SCU1_RESET_XDMA] =3D { true, SCU1_RESET_CTRL2, BIT(10) }, + [SCU1_RESET_FSI] =3D { true, SCU1_RESET_CTRL2, BIT(12) }, + [SCU1_RESET_CAN] =3D { true, SCU1_RESET_CTRL2, BIT(13) }, + [SCU1_RESET_MCTP] =3D { true, SCU1_RESET_CTRL2, BIT(14) }, + [SCU1_RESET_I2C] =3D { true, SCU1_RESET_CTRL2, BIT(15) }, + [SCU1_RESET_UART6] =3D { true, SCU1_RESET_CTRL2, BIT(16) }, + [SCU1_RESET_UART7] =3D { true, SCU1_RESET_CTRL2, BIT(17) }, + [SCU1_RESET_UART8] =3D { true, SCU1_RESET_CTRL2, BIT(18) }, + [SCU1_RESET_UART9] =3D { true, SCU1_RESET_CTRL2, BIT(19) }, + [SCU1_RESET_LTPI0] =3D { true, SCU1_RESET_CTRL2, BIT(20) }, + [SCU1_RESET_VGAL] =3D { true, SCU1_RESET_CTRL2, BIT(21) }, + [SCU1_RESET_LTPI1] =3D { true, SCU1_RESET_CTRL2, BIT(22) }, + [SCU1_RESET_ACE] =3D { true, SCU1_RESET_CTRL2, BIT(23) }, + [SCU1_RESET_E2M] =3D { true, SCU1_RESET_CTRL2, BIT(24) }, + [SCU1_RESET_UHCI] =3D { true, SCU1_RESET_CTRL2, BIT(25) }, + [SCU1_RESET_PORTC_USB2UART] =3D { true, SCU1_RESET_CTRL2, BIT(26) }, + [SCU1_RESET_PORTC_VHUB_EHCI] =3D { true, SCU1_RESET_CTRL2, BIT(27) }, + [SCU1_RESET_PORTD_USB2UART] =3D { true, SCU1_RESET_CTRL2, BIT(28) }, + [SCU1_RESET_PORTD_VHUB_EHCI] =3D { true, SCU1_RESET_CTRL2, BIT(29) }, + [SCU1_RESET_H2X] =3D { true, SCU1_RESET_CTRL2, BIT(30) }, + [SCU1_RESET_I3CDMA] =3D { true, SCU1_RESET_CTRL2, BIT(31) }, + [SCU1_RESET_PCIE2RST] =3D { false, SCU1_PCIE3_CTRL, BIT(0) }, +}; + +static inline struct aspeed_reset *to_aspeed_reset(struct reset_controller= _dev *rcdev) +{ + return container_of(rcdev, struct aspeed_reset, rcdev); +} + +static int aspeed_reset_assert(struct reset_controller_dev *rcdev, unsigne= d long id) +{ + struct aspeed_reset *rc =3D to_aspeed_reset(rcdev); + void __iomem *reg_offset =3D rc->base + rc->info->signal[id].offset; + + if (rc->info->signal[id].dedicated_clr) { + writel(rc->info->signal[id].bit, reg_offset); + } else { + guard(spinlock_irqsave)(&rc->lock); + writel(readl(reg_offset) & ~rc->info->signal[id].bit, reg_offset); + } + + return 0; +} + +static int aspeed_reset_deassert(struct reset_controller_dev *rcdev, unsig= ned long id) +{ + struct aspeed_reset *rc =3D to_aspeed_reset(rcdev); + void __iomem *reg_offset =3D rc->base + rc->info->signal[id].offset; + + if (rc->info->signal[id].dedicated_clr) { + writel(rc->info->signal[id].bit, reg_offset + 0x04); + } else { + guard(spinlock_irqsave)(&rc->lock); + writel(readl(reg_offset) | rc->info->signal[id].bit, reg_offset); + } + + return 0; +} + +static int aspeed_reset_status(struct reset_controller_dev *rcdev, unsigne= d long id) +{ + struct aspeed_reset *rc =3D to_aspeed_reset(rcdev); + void __iomem *reg_offset =3D rc->base + rc->info->signal[id].offset; + + return (readl(reg_offset) & rc->info->signal[id].bit) ? 1 : 0; +} + +static const struct reset_control_ops aspeed_reset_ops =3D { + .assert =3D aspeed_reset_assert, + .deassert =3D aspeed_reset_deassert, + .status =3D aspeed_reset_status, +}; + +static int aspeed_reset_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct aspeed_reset *reset; + struct device *dev =3D &adev->dev; + + reset =3D devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL); + if (!reset) + return -ENOMEM; + + spin_lock_init(&reset->lock); + + reset->info =3D (struct aspeed_reset_info *)id->driver_data; + reset->rcdev.owner =3D THIS_MODULE; + reset->rcdev.nr_resets =3D reset->info->nr_resets; + reset->rcdev.ops =3D &aspeed_reset_ops; + reset->rcdev.of_node =3D dev->parent->of_node; + reset->rcdev.dev =3D dev; + reset->rcdev.of_reset_n_cells =3D 1; + reset->base =3D (void __iomem *)adev->dev.platform_data; + + if (!reset->base) + return -ENOMEM; + + return devm_reset_controller_register(dev, &reset->rcdev); +} + +static const struct aspeed_reset_info ast2700_reset0_info =3D { + .nr_resets =3D ARRAY_SIZE(ast2700_reset0_signals), + .signal =3D ast2700_reset0_signals, +}; + +static const struct aspeed_reset_info ast2700_reset1_info =3D { + .nr_resets =3D ARRAY_SIZE(ast2700_reset1_signals), + .signal =3D ast2700_reset1_signals, +}; + +static const struct auxiliary_device_id aspeed_reset_ids[] =3D { + { .name =3D "clk_ast2700.reset0", .driver_data =3D (kernel_ulong_t)&ast27= 00_reset0_info }, + { .name =3D "clk_ast2700.reset1", .driver_data =3D (kernel_ulong_t)&ast27= 00_reset1_info }, + { } +}; +MODULE_DEVICE_TABLE(auxiliary, aspeed_reset_ids); + +static struct auxiliary_driver aspeed_reset_driver =3D { + .probe =3D aspeed_reset_probe, + .id_table =3D aspeed_reset_ids, +}; + +module_auxiliary_driver(aspeed_reset_driver); + +MODULE_AUTHOR("Ryan Chen "); +MODULE_DESCRIPTION("ASPEED SoC Reset Controller Driver"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Wed Nov 27 18:40:51 2024 Received: from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1444317B4FE; Wed, 9 Oct 2024 06:05:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.20.114.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728453934; cv=none; b=lFlPVrH8VUS3ShG9xYoRL5lsINPQvaVbz9VZZd/cyBHY53VHBfhrAu8L4Nbu8g9B/m6gka0lYFXHYHOg3nrJyafJXn2dQpG8jTPl1Ik2mBmZw3q1qzPj4y1UvtVLOZzuIiGFVEhrehVesSNWjIGi72cecLasoHGxhNmmTaAG2nE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728453934; c=relaxed/simple; bh=uYiltwmOFQVpjIB9I8WNdkliveFL32pV4U2gZHdpaso=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DVhqvoy1/m6iIY8V59IqKoWwn3KMmqWt3+wDnURmlRBSBUjCJJ5XInc1cr9Djk4HVuZtWMl4Nx+DZ7ReNlEbfn/7LUqOyTZQZ4QEbfJpCjSMBqnTHtIo6KUE3bMTAgOKXcUC4oL8qbwxBilcYNZ6dvD6S5AIZ0KikPjjncR0L4U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com; spf=pass smtp.mailfrom=aspeedtech.com; arc=none smtp.client-ip=211.20.114.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aspeedtech.com Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 9 Oct 2024 14:05:22 +0800 Received: from twmbx02.aspeed.com (192.168.10.152) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 9 Oct 2024 14:05:22 +0800 From: Ryan Chen To: , , , , , , , , , , , , , , Subject: [PATCH v5 3/3] clk: aspeed: add AST2700 clock driver. Date: Wed, 9 Oct 2024 14:05:21 +0800 Message-ID: <20241009060521.2971168-4-ryan_chen@aspeedtech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241009060521.2971168-1-ryan_chen@aspeedtech.com> References: <20241009060521.2971168-1-ryan_chen@aspeedtech.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add AST2700 clock controller driver and also use axiliary device framework register the reset controller driver. Due to clock and reset using the same register region. Signed-off-by: Ryan Chen --- drivers/clk/Kconfig | 8 + drivers/clk/Makefile | 1 + drivers/clk/clk-ast2700.c | 1554 +++++++++++++++++++++++++++++++++++++ 3 files changed, 1563 insertions(+) create mode 100644 drivers/clk/clk-ast2700.c diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 983ef4f36d8c..4cc35ecba1c0 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -269,6 +269,14 @@ config COMMON_CLK_ASPEED The G4 and G5 series, including the ast2400 and ast2500, are supported by this driver. =20 +config COMMON_CLK_AST2700 + bool "Clock driver for AST2700 SoC" + depends on ARCH_ASPEED || COMPILE_TEST + help + This driver provides support for clock on AST2700 SoC. + The driver is responsible for managing the various clocks required + by the peripherals and cores within the AST2700. + config COMMON_CLK_S2MPS11 tristate "Clock driver for S2MPS1X/S5M8767 MFD" depends on MFD_SEC_CORE || COMPILE_TEST diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f793a16cad40..fe95203c3138 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_COMMON_CLK_FSL_SAI) +=3D clk-fsl-sai.o obj-$(CONFIG_COMMON_CLK_GEMINI) +=3D clk-gemini.o obj-$(CONFIG_COMMON_CLK_ASPEED) +=3D clk-aspeed.o obj-$(CONFIG_MACH_ASPEED_G6) +=3D clk-ast2600.o +obj-$(CONFIG_COMMON_CLK_AST2700) +=3D clk-ast2700.o obj-$(CONFIG_ARCH_HIGHBANK) +=3D clk-highbank.o obj-$(CONFIG_CLK_HSDK) +=3D clk-hsdk-pll.o obj-$(CONFIG_COMMON_CLK_K210) +=3D clk-k210.o diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c new file mode 100644 index 000000000000..ef1f939b1c9f --- /dev/null +++ b/drivers/clk/clk-ast2700.c @@ -0,0 +1,1554 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 ASPEED Technology Inc. + * Author: Ryan Chen + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SCU_CLK_12MHZ (12 * HZ_PER_MHZ) +#define SCU_CLK_24MHZ (24 * HZ_PER_MHZ) +#define SCU_CLK_25MHZ (25 * HZ_PER_MHZ) +#define SCU_CLK_192MHZ (192 * HZ_PER_MHZ) + +/* SOC0 */ +#define SCU0_HWSTRAP1 0x010 +#define SCU0_CLK_STOP 0x240 +#define SCU0_CLK_SEL1 0x280 +#define SCU0_CLK_SEL2 0x284 +#define GET_USB_REFCLK_DIV(x) ((GENMASK(23, 20) & (x)) >> 20) +#define UART_DIV13_EN BIT(30) +#define SCU0_HPLL_PARAM 0x300 +#define SCU0_DPLL_PARAM 0x308 +#define SCU0_MPLL_PARAM 0x310 +#define SCU0_D0CLK_PARAM 0x320 +#define SCU0_D1CLK_PARAM 0x330 +#define SCU0_CRT0CLK_PARAM 0x340 +#define SCU0_CRT1CLK_PARAM 0x350 +#define SCU0_MPHYCLK_PARAM 0x360 + +/* SOC1 */ +#define SCU1_REVISION_ID 0x0 +#define REVISION_ID GENMASK(23, 16) +#define SCU1_CLK_STOP 0x240 +#define SCU1_CLK_STOP2 0x260 +#define SCU1_CLK_SEL1 0x280 +#define SCU1_CLK_SEL2 0x284 +#define UXCLK_MASK GENMASK(1, 0) +#define HUXCLK_MASK GENMASK(4, 3) +#define SCU1_HPLL_PARAM 0x300 +#define SCU1_APLL_PARAM 0x310 +#define SCU1_DPLL_PARAM 0x320 +#define SCU1_UXCLK_CTRL 0x330 +#define SCU1_HUXCLK_CTRL 0x334 +#define SCU1_MAC12_CLK_DLY 0x390 +#define SCU1_MAC12_CLK_DLY_100M 0x394 +#define SCU1_MAC12_CLK_DLY_10M 0x398 + +enum { + CLK_MUX, + CLK_PLL, + CLK_GATE, + CLK_MISC, + CLK_FIXED, + CLK_DIVIDER, + CLK_UART_PLL, + CLK_DIV_TABLE, + CLK_FIXED_FACTOR, +}; + +struct ast2700_clk_info { + const char *name; + const char * const *parent_names; + const struct clk_div_table *div_table; + unsigned long fixed_rate; + unsigned int mult; + unsigned int div; + u32 reg; + u32 flags; + u32 type; + u8 clk_idx; + u8 bit_shift; + u8 bit_width; + u8 num_parents; +}; + +struct ast2700_clk_data { + struct ast2700_clk_info const *clk_info; + unsigned int nr_clks; + const int scu; +}; + +struct ast2700_clk_ctrl { + const struct ast2700_clk_data *clk_data; + struct device *dev; + void __iomem *base; + spinlock_t lock; /* clk lock */ +}; + +static const struct clk_div_table ast2700_rgmii_div_table[] =3D { + { 0x0, 4 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + +static const struct clk_div_table ast2700_rmii_div_table[] =3D { + { 0x0, 8 }, + { 0x1, 8 }, + { 0x2, 12 }, + { 0x3, 16 }, + { 0x4, 20 }, + { 0x5, 24 }, + { 0x6, 28 }, + { 0x7, 32 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_div_table[] =3D { + { 0x0, 2 }, + { 0x1, 2 }, + { 0x2, 3 }, + { 0x3, 4 }, + { 0x4, 5 }, + { 0x5, 6 }, + { 0x6, 7 }, + { 0x7, 8 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_div_table2[] =3D { + { 0x0, 2 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_uart_div_table[] =3D { + { 0x0, 1 }, + { 0x1, 13 }, + { 0 } +}; + +static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = =3D { + [SCU0_CLKIN] =3D { + .type =3D CLK_FIXED, + .name =3D "soc0-clkin", + .fixed_rate =3D SCU_CLK_25MHZ, + }, + [SCU0_CLK_24M] =3D { + .type =3D CLK_FIXED, + .name =3D "soc0-clk24Mhz", + .fixed_rate =3D SCU_CLK_24MHZ, + }, + [SCU0_CLK_192M] =3D { + .type =3D CLK_FIXED, + .name =3D "soc0-clk192Mhz", + .fixed_rate =3D SCU_CLK_192MHZ, + }, + [SCU0_CLK_HPLL] =3D { + .type =3D CLK_PLL, + .name =3D "soc0-hpll", + .parent_names =3D (const char *[]){ "soc0-clkin", }, + .reg =3D SCU0_HPLL_PARAM, + }, + [SCU0_CLK_HPLL_DIV2] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "soc0-hpll_div2", + .parent_names =3D (const char *[]){ "soc0-hpll", }, + .mult =3D 1, + .div =3D 2, + }, + [SCU0_CLK_HPLL_DIV4] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "soc0-hpll_div4", + .parent_names =3D (const char *[]){ "soc0-hpll", }, + .mult =3D 1, + .div =3D 4, + }, + [SCU0_CLK_HPLL_DIV_AHB] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "soc0-hpll_div_ahb", + .parent_names =3D (const char *[]){ "soc0-hpll", }, + .reg =3D SCU0_HWSTRAP1, + .bit_shift =3D 5, + .bit_width =3D 2, + .div_table =3D ast2700_clk_div_table, + }, + [SCU0_CLK_DPLL] =3D { + .type =3D CLK_PLL, + .name =3D "dpll", + .parent_names =3D (const char *[]){ "soc0-clkin", }, + .reg =3D SCU0_DPLL_PARAM, + }, + [SCU0_CLK_MPLL] =3D { + .type =3D CLK_PLL, + .name =3D "soc0-mpll", + .parent_names =3D (const char *[]){ "soc0-clkin", }, + .reg =3D SCU0_MPLL_PARAM, + }, + [SCU0_CLK_MPLL_DIV2] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "soc0-mpll_div2", + .parent_names =3D (const char *[]){ "soc0-mpll", }, + .mult =3D 1, + .div =3D 2, + }, + [SCU0_CLK_MPLL_DIV4] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "soc0-mpll_div4", + .parent_names =3D (const char *[]){ "soc0-mpll", }, + .mult =3D 1, + .div =3D 4, + }, + [SCU0_CLK_MPLL_DIV8] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "soc0-mpll_div8", + .parent_names =3D (const char *[]){ "soc0-mpll", }, + .mult =3D 1, + .div =3D 8, + }, + [SCU0_CLK_MPLL_DIV_AHB] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "soc0-mpll_div_ahb", + .parent_names =3D (const char *[]){ "soc0-mpll", }, + .reg =3D SCU0_HWSTRAP1, + .bit_shift =3D 5, + .bit_width =3D 2, + .div_table =3D ast2700_clk_div_table, + }, + [SCU0_CLK_D0] =3D { + .type =3D CLK_PLL, + .name =3D "d0clk", + .parent_names =3D (const char *[]){ "soc0-clkin", }, + .reg =3D SCU0_D0CLK_PARAM, + }, + [SCU0_CLK_D1] =3D { + .type =3D CLK_PLL, + .name =3D "d1clk", + .parent_names =3D (const char *[]){ "soc0-clkin", }, + .reg =3D SCU0_D1CLK_PARAM, + }, + [SCU0_CLK_CRT0] =3D { + .type =3D CLK_PLL, + .name =3D "crt0clk", + .parent_names =3D (const char *[]){ "soc0-clkin", }, + .reg =3D SCU0_CRT0CLK_PARAM, + }, + [SCU0_CLK_CRT1] =3D { + .type =3D CLK_PLL, + .name =3D "crt1clk", + .parent_names =3D (const char *[]){ "soc0-clkin", }, + .reg =3D SCU0_CRT1CLK_PARAM, + }, + [SCU0_CLK_MPHY] =3D { + .type =3D CLK_MISC, + .name =3D "mphyclk", + .parent_names =3D (const char *[]){ "soc0-hpll", }, + .reg =3D SCU0_MPHYCLK_PARAM, + }, + [SCU0_CLK_PSP] =3D { + .type =3D CLK_MUX, + .name =3D "pspclk", + .parent_names =3D (const char *[]){"soc0-mpll", "soc0-hpll", }, + .num_parents =3D 2, + .reg =3D SCU0_HWSTRAP1, + .bit_shift =3D 4, + .bit_width =3D 1, + }, + [SCU0_CLK_AXI0] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "axi0clk", + .parent_names =3D (const char *[]){"pspclk", }, + .mult =3D 1, + .div =3D 2, + }, + [SCU0_CLK_AHB] =3D { + .type =3D CLK_MUX, + .name =3D "soc0-ahb", + .parent_names =3D (const char *[]){"soc0-mpll_div_ahb", "soc0-hspll_div_= ahb", }, + .num_parents =3D 2, + .reg =3D SCU0_HWSTRAP1, + .bit_shift =3D 7, + .bit_width =3D 1, + }, + [SCU0_CLK_AXI1] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "axi1clk", + .parent_names =3D (const char *[]){ "soc0-ahb", }, + .mult =3D 1, + .div =3D 2, + }, + [SCU0_CLK_APB] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "soc0-apb", + .parent_names =3D (const char *[]){ "axi0clk", }, + .reg =3D SCU0_CLK_SEL1, + .bit_shift =3D 23, + .bit_width =3D 3, + .div_table =3D ast2700_clk_div_table2, + }, + [SCU0_CLK_GATE_MCLK] =3D { + .type =3D CLK_GATE, + .name =3D "mclk", + .parent_names =3D (const char *[]){ "soc0-mpll", }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 0, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_ECLK] =3D { + .type =3D CLK_GATE, + .name =3D "eclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 1, + }, + [SCU0_CLK_GATE_2DCLK] =3D { + .type =3D CLK_GATE, + .name =3D "gclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 2, + }, + [SCU0_CLK_GATE_VCLK] =3D { + .type =3D CLK_GATE, + .name =3D "vclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 3, + }, + [SCU0_CLK_GATE_BCLK] =3D { + .type =3D CLK_GATE, + .name =3D "bclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 4, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_VGA0CLK] =3D { + .type =3D CLK_GATE, + .name =3D "d1clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 5, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_REFCLK] =3D { + .type =3D CLK_GATE, + .name =3D "soc0-refclk-gate", + .parent_names =3D (const char *[]){ "soc0-clkin", }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 6, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_U2PHY_REFCLK] =3D { + .type =3D CLK_MISC, + .name =3D "xhci_ref_clk", + .parent_names =3D (const char *[]){ "soc0-mpll_div8", }, + .reg =3D SCU0_CLK_SEL2, + }, + [SCU0_CLK_U2PHY_CLK12M] =3D { + .type =3D CLK_FIXED, + .name =3D "xhci_suspend_clk", + .parent_names =3D (const char *[]){ }, + .fixed_rate =3D SCU_CLK_12MHZ, + }, + [SCU0_CLK_GATE_PORTBUSB2CLK] =3D { + .type =3D CLK_GATE, + .name =3D "portb-usb2clk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 7, + }, + [SCU0_CLK_GATE_UHCICLK] =3D { + .type =3D CLK_GATE, + .name =3D "uhciclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 9, + }, + [SCU0_CLK_GATE_VGA1CLK] =3D { + .type =3D CLK_GATE, + .name =3D "d2clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 10, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_DDRPHYCLK] =3D { + .type =3D CLK_GATE, + .name =3D "ddrphy-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 11, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_E2M0CLK] =3D { + .type =3D CLK_GATE, + .name =3D "e2m0clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 12, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_HACCLK] =3D { + .type =3D CLK_GATE, + .name =3D "hac-clk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 13, + }, + [SCU0_CLK_GATE_PORTAUSB2CLK] =3D { + .type =3D CLK_GATE, + .name =3D "porta-usb2clk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 14, + }, + [SCU0_CLK_UART] =3D { + .type =3D CLK_MUX, + .name =3D "soc0-uartclk", + .parent_names =3D (const char *[]){"soc0-clk24Mhz", "soc0-clk192Mhz", }, + .num_parents =3D 2, + .reg =3D SCU0_CLK_SEL2, + .bit_shift =3D 14, + .bit_width =3D 1, + }, + [SCU0_CLK_UART4] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "uart4clk", + .parent_names =3D (const char *[]){ "soc0-uartclk", }, + .reg =3D SCU0_CLK_SEL2, + .bit_shift =3D 30, + .bit_width =3D 1, + .div_table =3D ast2700_clk_uart_div_table, + }, + [SCU0_CLK_GATE_UART4CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart4clk-gate", + .parent_names =3D (const char *[]){"uart4clk" }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 15, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_SLICLK] =3D { + .type =3D CLK_GATE, + .name =3D "soc0-sliclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 16, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_DACCLK] =3D { + .type =3D CLK_GATE, + .name =3D "dacclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 17, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_DP] =3D { + .type =3D CLK_GATE, + .name =3D "dpclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 18, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_E2M1CLK] =3D { + .type =3D CLK_GATE, + .name =3D "e2m1clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 19, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU0_CLK_GATE_CRT0CLK] =3D { + .type =3D CLK_GATE, + .name =3D "crt0clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 20, + }, + [SCU0_CLK_GATE_CRT1CLK] =3D { + .type =3D CLK_GATE, + .name =3D "crt1clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 21, + }, + [SCU0_CLK_GATE_ECDSACLK] =3D { + .type =3D CLK_GATE, + .name =3D "eccclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 23, + }, + [SCU0_CLK_GATE_RSACLK] =3D { + .type =3D CLK_GATE, + .name =3D "rsaclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 24, + }, + [SCU0_CLK_GATE_RVAS0CLK] =3D { + .type =3D CLK_GATE, + .name =3D "rvasclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 25, + }, + [SCU0_CLK_GATE_UFSCLK] =3D { + .type =3D CLK_GATE, + .name =3D "ufsclk", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 26, + }, + [SCU0_CLK_EMMCMUX] =3D { + .type =3D CLK_MUX, + .name =3D "emmcsrc-mux", + .parent_names =3D (const char *[]){"soc0-mpll_div4", "soc0-hpll_div4", }, + .num_parents =3D 2, + .reg =3D SCU0_CLK_SEL1, + .bit_shift =3D 11, + .bit_width =3D 1, + }, + [SCU0_CLK_EMMC] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "emmcclk", + .parent_names =3D (const char *[]){ "emmcsrc-mux", }, + .reg =3D SCU0_CLK_SEL1, + .bit_shift =3D 12, + .bit_width =3D 3, + .div_table =3D ast2700_clk_div_table2, + }, + [SCU0_CLK_GATE_EMMCCLK] =3D { + .type =3D CLK_GATE, + .name =3D "emmcclk-gate", + .parent_names =3D (const char *[]){ "emmcclk", }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 27, + }, + [SCU0_CLK_GATE_RVAS1CLK] =3D { + .type =3D CLK_GATE, + .name =3D "rvas2clk", + .parent_names =3D (const char *[]){ "emmcclk", }, + .reg =3D SCU0_CLK_STOP, + .clk_idx =3D 28, + }, +}; + +static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = =3D { + [SCU1_CLKIN] =3D { + .type =3D CLK_FIXED, + .name =3D "soc1-clkin", + .fixed_rate =3D SCU_CLK_25MHZ, + }, + [SCU1_CLK_HPLL] =3D { + .type =3D CLK_PLL, + .name =3D "soc1-hpll", + .parent_names =3D (const char *[]){ "soc1-clkin", }, + .reg =3D SCU1_HPLL_PARAM, + }, + [SCU1_CLK_APLL] =3D { + .type =3D CLK_PLL, + .name =3D "soc1-apll", + .parent_names =3D (const char *[]){ "soc1-clkin", }, + .reg =3D SCU1_APLL_PARAM, + }, + [SCU1_CLK_APLL_DIV2] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "soc1-apll_div2", + .parent_names =3D (const char *[]){ "soc1-apll", }, + .mult =3D 1, + .div =3D 2, + }, + [SCU1_CLK_APLL_DIV4] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "soc1-apll_div4", + .parent_names =3D (const char *[]){ "soc1-apll", }, + .mult =3D 1, + .div =3D 4, + }, + [SCU1_CLK_DPLL] =3D { + .type =3D CLK_PLL, + .name =3D "soc1-dpll", + .parent_names =3D (const char *[]){ "soc1-clkin", }, + .reg =3D SCU1_DPLL_PARAM, + }, + [SCU1_CLK_UXCLK] =3D { + .type =3D CLK_MUX, + .name =3D "uxclk", + .parent_names =3D (const char *[]){ "soc1-apll_div4", "soc1-apll_div2", + "soc1-apll", "soc1-hpll",}, + .num_parents =3D 4, + .reg =3D SCU1_CLK_SEL2, + .bit_shift =3D 0, + .bit_width =3D 2, + }, + [SCU1_CLK_UARTX] =3D { + .type =3D CLK_UART_PLL, + .name =3D "uartxclk", + .parent_names =3D (const char *[]){ "uxclk", }, + .reg =3D SCU1_UXCLK_CTRL, + }, + [SCU1_CLK_HUXCLK] =3D { + .type =3D CLK_MUX, + .name =3D "huxclk", + .parent_names =3D (const char *[]){"soc1-apll_div4", "soc1-apll_div2", + "soc1-apll", "soc1-hpll",}, + .num_parents =3D 4, + .reg =3D SCU1_CLK_SEL2, + .bit_shift =3D 3, + .bit_width =3D 2, + }, + [SCU1_CLK_HUARTX] =3D { + .type =3D CLK_UART_PLL, + .name =3D "huartxclk", + .parent_names =3D (const char *[]){ "huxclk", }, + .reg =3D SCU1_HUXCLK_CTRL, + }, + [SCU1_CLK_AHB] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "soc1-ahb", + .parent_names =3D (const char *[]){"soc1-hpll", }, + .reg =3D SCU1_CLK_SEL2, + .bit_shift =3D 20, + .bit_width =3D 3, + .div_table =3D ast2700_clk_div_table, + }, + [SCU1_CLK_APB] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "soc1-apb", + .parent_names =3D (const char *[]){"soc1-hpll", }, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 18, + .bit_width =3D 3, + .div_table =3D ast2700_clk_div_table2, + }, + [SCU1_CLK_RMII] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "rmii", + .parent_names =3D (const char *[]){"soc1-hpll", }, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 21, + .bit_width =3D 3, + .div_table =3D ast2700_rmii_div_table, + }, + [SCU1_CLK_MAC0RCLK] =3D { + .type =3D CLK_GATE, + .name =3D "mac0rclk", + .parent_names =3D (const char *[]){ "rmii", }, + .reg =3D SCU1_MAC12_CLK_DLY, + .clk_idx =3D 29, + }, + [SCU1_CLK_MAC1RCLK] =3D { + .type =3D CLK_GATE, + .name =3D "mac1rclk", + .parent_names =3D (const char *[]){ "rmii", }, + .reg =3D SCU1_MAC12_CLK_DLY, + .clk_idx =3D 30, + }, + [SCU1_CLK_RGMII] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "rgmii", + .parent_names =3D (const char *[]){"soc1-hpll", }, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 25, + .bit_width =3D 3, + .div_table =3D ast2700_rgmii_div_table, + }, + [SCU1_CLK_MACHCLK] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "machclk", + .parent_names =3D (const char *[]){"soc1-hpll", }, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 29, + .bit_width =3D 3, + .div_table =3D ast2700_clk_div_table, + }, + [SCU1_CLK_GATE_LCLK0] =3D { + .type =3D CLK_GATE, + .name =3D "lclk0-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 0, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_LCLK1] =3D { + .type =3D CLK_GATE, + .name =3D "lclk1-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 1, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_ESPI0CLK] =3D { + .type =3D CLK_GATE, + .name =3D "espi0clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 2, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_ESPI1CLK] =3D { + .type =3D CLK_GATE, + .name =3D "espi1clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 3, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_APLL_DIVN] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "soc1-apll_divn", + .parent_names =3D (const char *[]){"soc1-apll", }, + .reg =3D SCU1_CLK_SEL2, + .bit_shift =3D 8, + .bit_width =3D 3, + .div_table =3D ast2700_clk_div_table, + }, + [SCU1_CLK_SDMUX] =3D { + .type =3D CLK_MUX, + .name =3D "sdclk-mux", + .parent_names =3D (const char *[]){ "soc1-hpll", "soc1-apll", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 13, + .bit_width =3D 1, + }, + [SCU1_CLK_SDCLK] =3D { + .type =3D CLK_DIV_TABLE, + .name =3D "sdclk", + .parent_names =3D (const char *[]){"sdclk-mux", }, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 14, + .bit_width =3D 3, + .div_table =3D ast2700_clk_div_table, + }, + [SCU1_CLK_GATE_SDCLK] =3D { + .type =3D CLK_GATE, + .name =3D "sdclk-gate", + .parent_names =3D (const char *[]){"sdclk", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 4, + }, + [SCU1_CLK_GATE_IPEREFCLK] =3D { + .type =3D CLK_GATE, + .name =3D "soc1-iperefclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 5, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_REFCLK] =3D { + .type =3D CLK_GATE, + .name =3D "soc1-refclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 6, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_LPCHCLK] =3D { + .type =3D CLK_GATE, + .name =3D "lpchclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 7, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_MAC0CLK] =3D { + .type =3D CLK_GATE, + .name =3D "mac0clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 8, + }, + [SCU1_CLK_GATE_MAC1CLK] =3D { + .type =3D CLK_GATE, + .name =3D "mac1clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 9, + }, + [SCU1_CLK_GATE_MAC2CLK] =3D { + .type =3D CLK_GATE, + .name =3D "mac2clk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 10, + }, + [SCU1_CLK_UART0] =3D { + .type =3D CLK_MUX, + .name =3D "uart0clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 0, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART0CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart0clk-gate", + .parent_names =3D (const char *[]){ "uart0clk", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 11, + }, + [SCU1_CLK_UART1] =3D { + .type =3D CLK_MUX, + .name =3D "uart1clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 1, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART1CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart1clk-gate", + .parent_names =3D (const char *[]){ "uart1clk", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 12, + }, + [SCU1_CLK_UART2] =3D { + .type =3D CLK_MUX, + .name =3D "uart2clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 2, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART2CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart2clk-gate", + .parent_names =3D (const char *[]){ "uart2clk", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 13, + }, + [SCU1_CLK_UART3] =3D { + .type =3D CLK_MUX, + .name =3D "uart3clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 3, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART3CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart3clk-gate", + .parent_names =3D (const char *[]){ "uart3clk", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 14, + }, + [SCU1_CLK_GATE_I2CCLK] =3D { + .type =3D CLK_GATE, + .name =3D "i2cclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 15, + }, + [SCU1_CLK_GATE_I3C0CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c0clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 16, + }, + [SCU1_CLK_GATE_I3C1CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c1clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 17, + }, + [SCU1_CLK_GATE_I3C2CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c2clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 18, + }, + [SCU1_CLK_GATE_I3C3CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c3clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 19, + }, + [SCU1_CLK_GATE_I3C4CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c4clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 20, + }, + [SCU1_CLK_GATE_I3C5CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c5clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 21, + }, + [SCU1_CLK_GATE_I3C6CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c6clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 22, + }, + [SCU1_CLK_GATE_I3C7CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c7clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 23, + }, + [SCU1_CLK_GATE_I3C8CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c8clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 24, + }, + [SCU1_CLK_GATE_I3C9CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c9clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 25, + }, + [SCU1_CLK_GATE_I3C10CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c10clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 26, + }, + [SCU1_CLK_GATE_I3C11CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c11clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 27, + }, + [SCU1_CLK_GATE_I3C12CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c12clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 28, + }, + [SCU1_CLK_GATE_I3C13CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c13clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 29, + }, + [SCU1_CLK_GATE_I3C14CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c14clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 30, + }, + [SCU1_CLK_GATE_I3C15CLK] =3D { + .type =3D CLK_GATE, + .name =3D "i3c15clk-gate", + .parent_names =3D (const char *[]){ "soc1-ahb", }, + .reg =3D SCU1_CLK_STOP, + .clk_idx =3D 31, + }, + [SCU1_CLK_UART5] =3D { + .type =3D CLK_MUX, + .name =3D "uart5clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 5, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART5CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart5clk-gate", + .parent_names =3D (const char *[]){ "uart5clk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 0, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_UART6] =3D { + .type =3D CLK_MUX, + .name =3D "uart6clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 6, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART6CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart6clk-gate", + .parent_names =3D (const char *[]){ "uart6clk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 1, + }, + [SCU1_CLK_UART7] =3D { + .type =3D CLK_MUX, + .name =3D "uart7clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 7, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART7CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart7clk-gate", + .parent_names =3D (const char *[]){ "uart7clk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 2, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_UART8] =3D { + .type =3D CLK_MUX, + .name =3D "uart8clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 8, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART8CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart8clk-gate", + .parent_names =3D (const char *[]){ "uart8clk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 3, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_UART9] =3D { + .type =3D CLK_MUX, + .name =3D "uart9clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 9, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART9CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart9clk-gate", + .parent_names =3D (const char *[]){ "uart9clk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 4, + }, + [SCU1_CLK_UART10] =3D { + .type =3D CLK_MUX, + .name =3D "uart10clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 10, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART10CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart10clk-gate", + .parent_names =3D (const char *[]){ "uart10clk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 5, + }, + [SCU1_CLK_UART11] =3D { + .type =3D CLK_MUX, + .name =3D "uart11clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 11, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART11CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart11clk-gate", + .parent_names =3D (const char *[]){ "uart11clk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 6, + }, + [SCU1_CLK_UART12] =3D { + .type =3D CLK_MUX, + .name =3D "uart12clk", + .parent_names =3D (const char *[]){"uartxclk", "huartxclk", }, + .num_parents =3D 2, + .reg =3D SCU1_CLK_SEL1, + .bit_shift =3D 12, + .bit_width =3D 1, + }, + [SCU1_CLK_GATE_UART12CLK] =3D { + .type =3D CLK_GATE, + .name =3D "uart12clk-gate", + .parent_names =3D (const char *[]){ "uart12clk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 7, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_UART13] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "uart13clk", + .parent_names =3D (const char *[]){ "huartxclk", }, + .mult =3D 1, + .div =3D 1, + }, + [SCU1_CLK_UART14] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "uart14clk", + .parent_names =3D (const char *[]){ "huartxclk", }, + .mult =3D 1, + .div =3D 1, + }, + [SCU1_CLK_GATE_FSICLK] =3D { + .type =3D CLK_GATE, + .name =3D "fsiclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 8, + }, + [SCU1_CLK_GATE_LTPIPHYCLK] =3D { + .type =3D CLK_GATE, + .name =3D "ltpiphyclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 9, + }, + [SCU1_CLK_GATE_LTPICLK] =3D { + .type =3D CLK_GATE, + .name =3D "ltpiclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 10, + }, + [SCU1_CLK_GATE_VGALCLK] =3D { + .type =3D CLK_GATE, + .name =3D "vgalclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 11, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_UHCICLK] =3D { + .type =3D CLK_GATE, + .name =3D "usbuartclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 12, + }, + [SCU1_CLK_CAN] =3D { + .type =3D CLK_FIXED_FACTOR, + .name =3D "canclk", + .parent_names =3D (const char *[]){ "soc1-apll", }, + .mult =3D 1, + .div =3D 10, + }, + [SCU1_CLK_GATE_CANCLK] =3D { + .type =3D CLK_GATE, + .name =3D "canclk-gate", + .parent_names =3D (const char *[]){ "canclk", }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 13, + }, + [SCU1_CLK_GATE_PCICLK] =3D { + .type =3D CLK_GATE, + .name =3D "pciclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 14, + }, + [SCU1_CLK_GATE_SLICLK] =3D { + .type =3D CLK_GATE, + .name =3D "soc1-sliclk-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 15, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_E2MCLK] =3D { + .type =3D CLK_GATE, + .name =3D "soc1-e2m-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 16, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_PORTCUSB2CLK] =3D { + .type =3D CLK_GATE, + .name =3D "portcusb2-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 17, + .flags =3D CLK_IS_CRITICAL, + }, + [SCU1_CLK_GATE_PORTDUSB2CLK] =3D { + .type =3D CLK_GATE, + .name =3D "portdusb2-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 18, + }, + [SCU1_CLK_GATE_LTPI1TXCLK] =3D { + .type =3D CLK_GATE, + .name =3D "ltp1tx-gate", + .parent_names =3D (const char *[]){ }, + .reg =3D SCU1_CLK_STOP2, + .clk_idx =3D 19, + }, +}; + +static struct clk_hw *ast2700_clk_hw_register_pll(int clk_idx, void __iome= m *reg, + const struct ast2700_clk_info *clk, + struct ast2700_clk_ctrl *clk_ctrl) +{ + int scu =3D clk_ctrl->clk_data->scu; + unsigned int mult, div; + u32 val; + + if (!scu && clk_idx =3D=3D SCU0_CLK_HPLL) { + val =3D readl(clk_ctrl->base + SCU0_HWSTRAP1); + if ((val & GENMASK(3, 2)) !=3D 0) { + switch ((val & GENMASK(3, 2)) >> 2) { + case 1: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll", + NULL, 0, 1900000000); + case 2: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll", + NULL, 0, 1800000000); + case 3: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll", + NULL, 0, 1700000000); + default: + return ERR_PTR(-EINVAL); + } + } + } + + val =3D readl(reg); + + if (val & BIT(24)) { + /* Pass through mode */ + mult =3D 1; + div =3D 1; + } else { + u32 m =3D val & 0x1fff; + u32 n =3D (val >> 13) & 0x3f; + u32 p =3D (val >> 19) & 0xf; + + if (scu) { + mult =3D (m + 1) / (n + 1); + div =3D (p + 1); + } else { + if (clk_idx =3D=3D SCU0_CLK_MPLL) { + mult =3D m / (n + 1); + div =3D (p + 1); + } else { + mult =3D (m + 1) / (2 * (n + 1)); + div =3D (p + 1); + } + } + } + + return devm_clk_hw_register_fixed_factor(clk_ctrl->dev, clk->name, + clk->parent_names[0], 0, mult, div); +} + +static struct clk_hw *ast2700_clk_hw_register_uartpll(int clk_idx, void __= iomem *reg, + const struct ast2700_clk_info *clk, + struct ast2700_clk_ctrl *clk_ctrl) +{ + unsigned int mult, div; + u32 val =3D readl(reg); + u32 r =3D val & 0xff; + u32 n =3D (val >> 8) & 0x3ff; + + mult =3D r; + div =3D n * 2; + + return devm_clk_hw_register_fixed_factor(clk_ctrl->dev, clk->name, + clk->parent_names[0], 0, mult, div); +} + +static struct clk_hw *ast2700_clk_hw_register_misc(int clk_idx, void __iom= em *reg, + const struct ast2700_clk_info *clk, + struct ast2700_clk_ctrl *clk_ctrl) +{ + u32 div =3D 0; + + if (clk_idx =3D=3D SCU0_CLK_MPHY) + div =3D readl(reg) + 1; + else if (clk_idx =3D=3D SCU0_CLK_U2PHY_REFCLK) + div =3D (GET_USB_REFCLK_DIV(readl(reg)) + 1) << 1; + else + return ERR_PTR(-EINVAL); + + return devm_clk_hw_register_fixed_factor(clk_ctrl->dev, clk->name, + clk->parent_names[0], clk->flags, + 1, div); +} + +static int ast2700_clk_is_enabled(struct clk_hw *hw) +{ + struct clk_gate *gate =3D to_clk_gate(hw); + u32 clk =3D BIT(gate->bit_idx); + u32 reg; + + reg =3D readl(gate->reg); + + return !(reg & clk); +} + +static int ast2700_clk_enable(struct clk_hw *hw) +{ + struct clk_gate *gate =3D to_clk_gate(hw); + u32 clk =3D BIT(gate->bit_idx); + + if (readl(gate->reg) & clk) + writel(clk, gate->reg + 0x04); + + return 0; +} + +static void ast2700_clk_disable(struct clk_hw *hw) +{ + struct clk_gate *gate =3D to_clk_gate(hw); + u32 clk =3D BIT(gate->bit_idx); + + /* Clock is set to enable, so use write to set register */ + writel(clk, gate->reg); +} + +static const struct clk_ops ast2700_clk_gate_ops =3D { + .enable =3D ast2700_clk_enable, + .disable =3D ast2700_clk_disable, + .is_enabled =3D ast2700_clk_is_enabled, +}; + +static struct clk_hw *ast2700_clk_hw_register_gate(struct device *dev, con= st char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 clock_idx, + u8 clk_gate_flags, spinlock_t *lock) +{ + struct clk_gate *gate; + struct clk_hw *hw; + struct clk_init_data init; + int ret =3D -EINVAL; + + gate =3D kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + init.name =3D name; + init.ops =3D &ast2700_clk_gate_ops; + init.flags =3D flags; + init.parent_names =3D parent_name ? &parent_name : NULL; + init.num_parents =3D parent_name ? 1 : 0; + + gate->reg =3D reg; + gate->bit_idx =3D clock_idx; + gate->flags =3D clk_gate_flags; + gate->lock =3D lock; + gate->hw.init =3D &init; + + hw =3D &gate->hw; + ret =3D clk_hw_register(dev, hw); + if (ret) { + kfree(gate); + hw =3D ERR_PTR(ret); + } + + return hw; +} + +static void aspeed_reset_unregister_adev(void *_adev) +{ + struct auxiliary_device *adev =3D _adev; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +static void aspeed_reset_adev_release(struct device *dev) +{ + struct auxiliary_device *adev =3D to_auxiliary_dev(dev); + + kfree(adev); +} + +static int aspeed_reset_controller_register(struct device *clk_dev, + void __iomem *base, const char *adev_name) +{ + struct auxiliary_device *adev; + int ret; + + adev =3D kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + adev->name =3D adev_name; + adev->dev.parent =3D clk_dev; + adev->dev.release =3D aspeed_reset_adev_release; + adev->id =3D 666u; + + ret =3D auxiliary_device_init(adev); + if (ret) { + kfree(adev); + return ret; + } + + ret =3D auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + adev->dev.platform_data =3D (__force void *)base; + + return devm_add_action_or_reset(clk_dev, aspeed_reset_unregister_adev, ad= ev); +} + +static int ast2700_soc_clk_probe(struct platform_device *pdev) +{ + struct ast2700_clk_data *clk_data; + struct ast2700_clk_ctrl *clk_ctrl; + struct clk_hw_onecell_data *clk_hw_data; + struct device *dev =3D &pdev->dev; + void __iomem *clk_base; + struct clk_hw **hws; + char *reset_name; + int ret; + int i; + + clk_ctrl =3D devm_kzalloc(dev, sizeof(*clk_ctrl), GFP_KERNEL); + if (!clk_ctrl) + return -ENOMEM; + clk_ctrl->dev =3D dev; + dev_set_drvdata(&pdev->dev, clk_ctrl); + + spin_lock_init(&clk_ctrl->lock); + + clk_base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_base)) + return PTR_ERR(clk_base); + + clk_ctrl->base =3D clk_base; + + clk_data =3D (struct ast2700_clk_data *)of_device_get_match_data(dev); + if (!clk_data) + return devm_of_platform_populate(dev); + + clk_ctrl->clk_data =3D clk_data; + reset_name =3D devm_kasprintf(dev, GFP_KERNEL, "reset%d", clk_data->scu); + + clk_hw_data =3D devm_kzalloc(dev, struct_size(clk_hw_data, hws, clk_data-= >nr_clks), + GFP_KERNEL); + if (!clk_hw_data) + return -ENOMEM; + + clk_hw_data->num =3D clk_data->nr_clks; + hws =3D clk_hw_data->hws; + + for (i =3D 0; i < clk_data->nr_clks; i++) { + const struct ast2700_clk_info *clk =3D &clk_data->clk_info[i]; + void __iomem *reg =3D clk_ctrl->base + clk->reg; + + if (clk->type =3D=3D CLK_FIXED) { + hws[i] =3D devm_clk_hw_register_fixed_rate(dev, clk->name, NULL, + clk->flags, clk->fixed_rate); + } else if (clk->type =3D=3D CLK_FIXED_FACTOR) { + hws[i] =3D devm_clk_hw_register_fixed_factor(dev, clk->name, + clk->parent_names[0], clk->flags, + clk->mult, clk->div); + } else if (clk->type =3D=3D CLK_PLL) { + hws[i] =3D ast2700_clk_hw_register_pll(i, reg, clk, clk_ctrl); + } else if (clk->type =3D=3D CLK_UART_PLL) { + hws[i] =3D ast2700_clk_hw_register_uartpll(i, reg, clk, clk_ctrl); + } else if (clk->type =3D=3D CLK_MUX) { + hws[i] =3D devm_clk_hw_register_mux(dev, clk->name, clk->parent_names, + clk->num_parents, clk->flags, reg, + clk->bit_shift, clk->bit_width, + 0, &clk_ctrl->lock); + } else if (clk->type =3D=3D CLK_MISC) { + hws[i] =3D ast2700_clk_hw_register_misc(i, reg, clk, clk_ctrl); + } else if (clk->type =3D=3D CLK_DIVIDER) { + hws[i] =3D devm_clk_hw_register_divider(dev, clk->name, clk->parent_nam= es[0], + clk->flags, reg, clk->bit_shift, + clk->bit_width, 0, + &clk_ctrl->lock); + } else if (clk->type =3D=3D CLK_DIV_TABLE) { + hws[i] =3D clk_hw_register_divider_table(dev, clk->name, clk->parent_na= mes[0], + clk->flags, reg, clk->bit_shift, + clk->bit_width, 0, + clk->div_table, &clk_ctrl->lock); + } else { + hws[i] =3D ast2700_clk_hw_register_gate(dev, clk->name, clk->parent_nam= es[0], + clk->flags, reg, clk->clk_idx, + clk->flags, &clk_ctrl->lock); + } + + if (IS_ERR(hws[i])) + return PTR_ERR(hws[i]); + } + + ret =3D devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_da= ta); + if (ret) + return ret; + + return aspeed_reset_controller_register(dev, clk_base, reset_name); +} + +static const struct ast2700_clk_data ast2700_clk0_data =3D { + .scu =3D 0, + .nr_clks =3D ARRAY_SIZE(ast2700_scu0_clk_info), + .clk_info =3D ast2700_scu0_clk_info, +}; + +static const struct ast2700_clk_data ast2700_clk1_data =3D { + .scu =3D 1, + .nr_clks =3D ARRAY_SIZE(ast2700_scu1_clk_info), + .clk_info =3D ast2700_scu1_clk_info, +}; + +static const struct of_device_id ast2700_scu_match[] =3D { + { .compatible =3D "aspeed,ast2700-scu0", .data =3D &ast2700_clk0_data }, + { .compatible =3D "aspeed,ast2700-scu1", .data =3D &ast2700_clk1_data }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, ast2700_scu_match); + +static struct platform_driver ast2700_scu_driver =3D { + .driver =3D { + .name =3D "clk-ast2700", + .of_match_table =3D ast2700_scu_match, + }, +}; + +builtin_platform_driver_probe(ast2700_scu_driver, ast2700_soc_clk_probe); --=20 2.34.1