From patchwork Tue Dec 3 07:45:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SmFtZXMgVGFpIFvmiLTlv5fls7Bd?= X-Patchwork-Id: 11270739 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 046CF6C1 for ; Tue, 3 Dec 2019 07:46:54 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BAB802053B for ; Tue, 3 Dec 2019 07:46:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="StSsLIz2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BAB802053B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=realtek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=LEKXIEfSlxxxr3hJTI8HKpKtueuxgcTU+xH6vnHUBI8=; b=StSsLIz2Fs0v01RPndoqRDaxW SGNHY3BKViwmKQmR3ZPxB1Cqx5ZsLofYRlwgI433QXPgY+FV5cwUKRQtzhpMf3uvQy+Kz8eF+VCQN dDC4kvFVAxNNQIgJjHJ3FCIv0+7ovDWT093++jvsImMUtbq3QGrUNYdzF6D/tgJcC+Fnv9Xdw8Kw3 xAMDxudsjJC28B29okuJxeuapZbDtfcnpr93uWxbQvLmMlY7Fq2Bvs+Gn9SvKQxslTNM5YbHtcKhk mOZsrVf1ZfFdMvnqPfzNBtwXuyDXFYpXnIUSIRGVTqXJl9S0s+w4NcMZe91SdKWMNOU5cxNLSNOVV /JOfqE65A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2tW-0000QW-Le; Tue, 03 Dec 2019 07:46:50 +0000 Received: from rtits2.realtek.com ([211.75.126.72] helo=rtits2.realtek.com.tw) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2sF-0007a1-LY; Tue, 03 Dec 2019 07:45:33 +0000 Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.62 with qID xB37jKtg016012, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (RTITCASV01.realtek.com.tw[172.21.6.18]) by rtits2.realtek.com.tw (8.15.2/2.57/5.78) with ESMTPS id xB37jKtg016012 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 3 Dec 2019 15:45:21 +0800 Received: from james-BS01.localdomain (172.21.190.33) by RTITCASV01.realtek.com.tw (172.21.6.18) with Microsoft SMTP Server id 14.3.468.0; Tue, 3 Dec 2019 15:45:19 +0800 From: James Tai To: =?utf-8?q?Andreas_F=C3=A4rber?= Subject: [PATCH 1/6] dt-bindings: clock: add bindings for RTD1619 clocks Date: Tue, 3 Dec 2019 15:45:08 +0800 Message-ID: <20191203074513.9416-2-james.tai@realtek.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191203074513.9416-1-james.tai@realtek.com> References: <20191203074513.9416-1-james.tai@realtek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191202_234531_895397_79CEB749 X-CRM114-Status: UNSURE ( 8.82 ) X-CRM114-Notice: Please train this message. X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [211.75.126.72 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , devicetree@vger.kernel.org, cylee12 , linux-realtek-soc@lists.infradead.org, Palmer Dabbelt , linux-kernel@vger.kernel.org, Rob Herring , linux-mediatek@lists.infradead.org, Paul Walmsley , Matthias Brugger , linux-riscv@lists.infradead.org, linux-arm-kernel@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org From: cylee12 Add devicetree binding for Realtek RTD1619 clocks. Signed-off-by: Cheng-Yu Lee Signed-off-by: James Tai --- include/dt-bindings/clock/rtk,clock-rtd1619.h | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 include/dt-bindings/clock/rtk,clock-rtd1619.h diff --git a/include/dt-bindings/clock/rtk,clock-rtd1619.h b/include/dt-bindings/clock/rtk,clock-rtd1619.h new file mode 100644 index 000000000000..497f9b914857 --- /dev/null +++ b/include/dt-bindings/clock/rtk,clock-rtd1619.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __DT_BINDINGS_RTK_CLOCK_RTD1619_H +#define __DT_BINDINGS_RTK_CLOCK_RTD1619_H + +#define CC_PLL_SCPU 0 +#define CC_PLL_BUS 2 +#define CC_CLK_SYS 3 +#define CC_CLK_SYS_SB2 4 +#define CC_PLL_DCSB 5 +#define CC_CLK_SYSH 6 +#define CC_PLL_DDSA 7 +#define CC_PLL_DDSB 8 +#define CC_PLL_GPU 9 +#define CC_CLK_GPU 10 +#define CC_PLL_VE1 11 +#define CC_PLL_VE2 12 +#define CC_CLK_VE1 13 +#define CC_CLK_VE2 14 +#define CC_CLK_VE3 15 +#define CC_CLK_VE2_BPU 16 +#define CC_PLL_DIF 17 +#define CC_PLL_PSAUD1A 18 +#define CC_PLL_PSAUD2A 19 + +#define CC_CKE_MISC 33 +#define CC_CKE_PCIE0 34 +#define CC_CKE_GSPI 35 +#define CC_CKE_SDS 36 +#define CC_CKE_HDMI 37 +#define CC_CKE_LSADC 38 +#define CC_CKE_SE 39 +#define CC_CKE_CP 40 +#define CC_CKE_MD 41 +#define CC_CKE_TP 42 +#define CC_CKE_RSA 43 +#define CC_CKE_NF 44 +#define CC_CKE_EMMC 45 +#define CC_CKE_SD 46 +#define CC_CKE_SDIO_IP 47 +#define CC_CKE_MIPI 48 +#define CC_CKE_EMMC_IP 49 +#define CC_CKE_SDIO 50 +#define CC_CKE_SD_IP 51 +#define CC_CKE_CABLERX 52 +#define CC_CKE_TPB 53 +#define CC_CKE_SC1 54 +#define CC_CKE_I2C3 55 +#define CC_CKE_JPEG 56 +#define CC_CKE_SC0 57 +#define CC_CKE_HDMIRX 58 +#define CC_CKE_HSE 59 +#define CC_CKE_UR2 60 +#define CC_CKE_UR1 61 +#define CC_CKE_FAN 62 +#define CC_CKE_SATA_WRAP_SYS 63 +#define CC_CKE_SATA_WRAP_SYSH 64 +#define CC_CKE_SATA_MAC_SYSH 65 +#define CC_CKE_R2RDSC 66 +#define CC_CKE_PCIE1 67 +#define CC_CKE_I2C4 68 +#define CC_CKE_I2C5 69 +#define CC_CKE_EDP 70 +#define CC_CKE_TSIO_TRX 71 +#define CC_CKE_TVE 72 +#define CC_CKE_VO 73 + +#define CC_CLK_MAX 74 + + +#define IC_CKE_CEC0 2 +#define IC_CKE_CBUSRX_SYS 3 +#define IC_CKE_CBUSTX_SYS 4 +#define IC_CKE_CBUS_SYS 5 +#define IC_CKE_CBUS_OSC 6 +#define IC_CKE_IR 7 +#define IC_CKE_UR0 8 +#define IC_CKE_I2C0 9 +#define IC_CKE_I2C1 10 +#define IC_CKE_ETN_250M 11 +#define IC_CKE_ETN_SYS 12 +#define IC_CKE_USB_DRD 13 +#define IC_CKE_USB_HOST 14 +#define IC_CKE_USB_U3_HOST 15 +#define IC_CKE_USB 16 +#define IC_CLK_MAX 17 + +#endif /* __DT_BINDINGS_RTK_CLOCK_RTD1619_H */ + From patchwork Tue Dec 3 07:45:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SmFtZXMgVGFpIFvmiLTlv5fls7Bd?= X-Patchwork-Id: 11270749 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 759C66C1 for ; Tue, 3 Dec 2019 07:47:58 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 378AC2053B for ; Tue, 3 Dec 2019 07:47:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="W4MoLWgp" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 378AC2053B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=realtek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=x00OjYK/z/iLlGY2ASADbsBsxWmk0jVRTFz5Vyk/tss=; b=W4MoLWgpjHNH8WOQgK891D3kU ltjnjWai/k4smp5oqagcFTLKVI740hRZaPtsUCv4mwFfAxHcvMTT8DgAlzoinZScjEMlipiXn7Xi/ V4KvpJv3X7w1T5FoJP2wvUAfkPcPfWB+gT3I+OfkptaZA8yZtt6eXZ8agv6w5KXDoER13c4X8cr+Q rJSE1L/UtUqqD1OV2P8ur0jFnwvoiA0TJXGftakMtmzV/ZGSKtaRq4Ck32THh+Hkr1eLIzzPECVTP HWn5WzaVbHg9jY1GblmahvK7W7+7jflGFLWjprXplJBog3ZdWU+YNahhMfWy74m8wS4+D6ZkN1FrW loLQI2FTw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2ua-0001JE-Gy; Tue, 03 Dec 2019 07:47:56 +0000 Received: from rtits2.realtek.com ([211.75.126.72] helo=rtits2.realtek.com.tw) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2sF-0007aX-Lv; Tue, 03 Dec 2019 07:45:33 +0000 Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.62 with qID xB37jMhk016017, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (RTITCASV01.realtek.com.tw[172.21.6.18]) by rtits2.realtek.com.tw (8.15.2/2.57/5.78) with ESMTPS id xB37jMhk016017 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 3 Dec 2019 15:45:22 +0800 Received: from james-BS01.localdomain (172.21.190.33) by RTITCASV01.realtek.com.tw (172.21.6.18) with Microsoft SMTP Server id 14.3.468.0; Tue, 3 Dec 2019 15:45:21 +0800 From: James Tai To: =?utf-8?q?Andreas_F=C3=A4rber?= Subject: [PATCH 2/6] dt-bindings: reset: add bindings for rtd1619 reset controls Date: Tue, 3 Dec 2019 15:45:09 +0800 Message-ID: <20191203074513.9416-3-james.tai@realtek.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191203074513.9416-1-james.tai@realtek.com> References: <20191203074513.9416-1-james.tai@realtek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191202_234532_042703_7C4ADC5E X-CRM114-Status: UNSURE ( 8.66 ) X-CRM114-Notice: Please train this message. X-Spam-Score: 0.8 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.8 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [211.75.126.72 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.8 UPPERCASE_50_75 message body is 50-75% uppercase X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , devicetree@vger.kernel.org, cylee12 , linux-realtek-soc@lists.infradead.org, Palmer Dabbelt , linux-kernel@vger.kernel.org, Rob Herring , linux-mediatek@lists.infradead.org, Philipp Zabel , Paul Walmsley , Matthias Brugger , linux-riscv@lists.infradead.org, linux-arm-kernel@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org From: cylee12 Add devicetree binding for Realtek RTD1619 SoC reset controls. Signed-off-by: Cheng-Yu Lee Signed-off-by: James Tai --- include/dt-bindings/reset/rtk,reset-rtd1619.h | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 include/dt-bindings/reset/rtk,reset-rtd1619.h diff --git a/include/dt-bindings/reset/rtk,reset-rtd1619.h b/include/dt-bindings/reset/rtk,reset-rtd1619.h new file mode 100644 index 000000000000..f6fa6359ec1c --- /dev/null +++ b/include/dt-bindings/reset/rtk,reset-rtd1619.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __DT_BINDINGS_RTK_RESET_RTD1619_H +#define __DT_BINDINGS_RTK_RESET_RTD1619_H + +#define CC_RSTN_REG_BANK_1 (0x0000) +#define CC_RSTN_REG_BANK_2 (0x0100) +#define CC_RSTN_REG_BANK_3 (0x0200) +#define CC_RSTN_REG_BANK_4 (0x0300) +#define CC_RSTN_REG_BANK_6 (0x0400) +#define CC_RSTN_REG_BANK_7 (0x0500) + +#define CC_RSTN_MISC (CC_RSTN_REG_BANK_1 | 0x00) +#define CC_RSTN_DIP (CC_RSTN_REG_BANK_1 | 0x02) +#define CC_RSTN_GSPI (CC_RSTN_REG_BANK_1 | 0x04) +#define CC_RSTN_SDS (CC_RSTN_REG_BANK_1 | 0x06) +#define CC_RSTN_SDS_REG (CC_RSTN_REG_BANK_1 | 0x08) +#define CC_RSTN_SDS_PHY (CC_RSTN_REG_BANK_1 | 0x0a) +#define CC_RSTN_VE1 (CC_RSTN_REG_BANK_1 | 0x0c) +#define CC_RSTN_VE2 (CC_RSTN_REG_BANK_1 | 0x0e) +#define CC_RSTN_R2RDSC_A00 (CC_RSTN_REG_BANK_1 | 0x10) +#define CC_RSTN_RSA (CC_RSTN_REG_BANK_1 | 0x12) +#define CC_RSTN_GPU (CC_RSTN_REG_BANK_1 | 0x14) +#define CC_RSTN_DC_PHY (CC_RSTN_REG_BANK_1 | 0x16) +#define CC_RSTN_DCPHY_CRT (CC_RSTN_REG_BANK_1 | 0x18) +#define CC_RSTN_LSADC (CC_RSTN_REG_BANK_1 | 0x1a) +#define CC_RSTN_SE (CC_RSTN_REG_BANK_1 | 0x1c) +#define CC_RSTN_HSE_A00 (CC_RSTN_REG_BANK_1 | 0x1e) + +#define CC_RSTN_JPEG (CC_RSTN_REG_BANK_2 | 0x00) +#define CC_RSTN_SD (CC_RSTN_REG_BANK_2 | 0x02) +#define CC_RSTN_EMMC_A00 (CC_RSTN_REG_BANK_2 | 0x04) +#define CC_RSTN_SDIO (CC_RSTN_REG_BANK_2 | 0x06) +#define CC_RSTN_PCR_CNT (CC_RSTN_REG_BANK_2 | 0x08) +#define CC_RSTN_PCIE0_STITCH (CC_RSTN_REG_BANK_2 | 0x0a) +#define CC_RSTN_PCIE0_PHY (CC_RSTN_REG_BANK_2 | 0x0c) +#define CC_RSTN_PCIE0 (CC_RSTN_REG_BANK_2 | 0x0e) +#define CC_RSTN_PCIE0_CORE (CC_RSTN_REG_BANK_2 | 0x10) +#define CC_RSTN_PCIE0_POWER (CC_RSTN_REG_BANK_2 | 0x12) +#define CC_RSTN_PCIE0_NONSTITCH (CC_RSTN_REG_BANK_2 | 0x14) +#define CC_RSTN_PCIE0_PHY_MDIO (CC_RSTN_REG_BANK_2 | 0x16) +#define CC_RSTN_PCIE0_SGMII_MDIO (CC_RSTN_REG_BANK_2 | 0x18) +#define CC_RSTN_UR2 (CC_RSTN_REG_BANK_2 | 0x1a) +#define CC_RSTN_UR1 (CC_RSTN_REG_BANK_2 | 0x1c) +#define CC_RSTN_MISC_SC0 (CC_RSTN_REG_BANK_2 | 0x1e) + +#define CC_RSTN_AE (CC_RSTN_REG_BANK_3 | 0x00) +#define CC_RSTN_CABLERX (CC_RSTN_REG_BANK_3 | 0x02) +#define CC_RSTN_MD_A00 (CC_RSTN_REG_BANK_3 | 0x04) +#define CC_RSTN_TP_A00 (CC_RSTN_REG_BANK_3 | 0x06) +#define CC_RSTN_NF_A00 (CC_RSTN_REG_BANK_3 | 0x08) +#define CC_RSTN_MISC_SC1 (CC_RSTN_REG_BANK_3 | 0x0a) +#define CC_RSTN_I2C_3 (CC_RSTN_REG_BANK_3 | 0x0c) +#define CC_RSTN_FAN (CC_RSTN_REG_BANK_3 | 0x0e) +#define CC_RSTN_TVE (CC_RSTN_REG_BANK_3 | 0x10) +#define CC_RSTN_AIO (CC_RSTN_REG_BANK_3 | 0x12) +#define CC_RSTN_VO (CC_RSTN_REG_BANK_3 | 0x14) +#define CC_RSTN_MIPI_A00 (CC_RSTN_REG_BANK_3 | 0x16) +#define CC_RSTN_HDMIRX (CC_RSTN_REG_BANK_3 | 0x18) +#define CC_RSTN_HDMIRX_WRAP (CC_RSTN_REG_BANK_3 | 0x1a) +#define CC_RSTN_HDMI (CC_RSTN_REG_BANK_3 | 0x1c) +#define CC_RSTN_DISP (CC_RSTN_REG_BANK_3 | 0x1e) + +#define CC_RSTN_SATA_PHY_POW1 (CC_RSTN_REG_BANK_4 | 0x00) +#define CC_RSTN_SATA_PHY_POW0 (CC_RSTN_REG_BANK_4 | 0x02) +#define CC_RSTN_SATA_MDIO1 (CC_RSTN_REG_BANK_4 | 0x04) +#define CC_RSTN_SATA_MDIO0 (CC_RSTN_REG_BANK_4 | 0x06) +#define CC_RSTN_SATA_WRAP (CC_RSTN_REG_BANK_4 | 0x08) +#define CC_RSTN_SATA_MAC_P1 (CC_RSTN_REG_BANK_4 | 0x0a) +#define CC_RSTN_SATA_MAC_P0 (CC_RSTN_REG_BANK_4 | 0x0c) +#define CC_RSTN_SATA_MAC_COM (CC_RSTN_REG_BANK_4 | 0x0e) +#define CC_RSTN_PCIE1_STITCH (CC_RSTN_REG_BANK_4 | 0x10) +#define CC_RSTN_PCIE1_PHY (CC_RSTN_REG_BANK_4 | 0x12) +#define CC_RSTN_PCIE1 (CC_RSTN_REG_BANK_4 | 0x14) +#define CC_RSTN_PCIE1_CORE (CC_RSTN_REG_BANK_4 | 0x16) +#define CC_RSTN_PCIE1_POWER (CC_RSTN_REG_BANK_4 | 0x18) +#define CC_RSTN_PCIE1_NONSTITCH (CC_RSTN_REG_BANK_4 | 0x1a) +#define CC_RSTN_PCIE1_PHY_MDIO (CC_RSTN_REG_BANK_4 | 0x1c) +#define CC_RSTN_HDMITOP (CC_RSTN_REG_BANK_4 | 0x1e) + +#define CC_RSTN_HSE (CC_RSTN_REG_BANK_6 | 0x06) +#define CC_RSTN_R2RDSC (CC_RSTN_REG_BANK_6 | 0x08) +#define CC_RSTN_EMMC (CC_RSTN_REG_BANK_6 | 0x0a) +#define CC_RSTN_NF (CC_RSTN_REG_BANK_6 | 0x0c) +#define CC_RSTN_MD (CC_RSTN_REG_BANK_6 | 0x0e) +#define CC_RSTN_TPB (CC_RSTN_REG_BANK_6 | 0x18) +#define CC_RSTN_TP (CC_RSTN_REG_BANK_6 | 0x1a) +#define CC_RSTN_MIPI (CC_RSTN_REG_BANK_6 | 0x1c) + +#define CC_RSTN_TPB_A00 (CC_RSTN_REG_BANK_7 | 0x00) +#define CC_RSTN_I2C_4 (CC_RSTN_REG_BANK_7 | 0x02) +#define CC_RSTN_I2C_5 (CC_RSTN_REG_BANK_7 | 0x04) +#define CC_RSTN_TSIO (CC_RSTN_REG_BANK_7 | 0x06) +#define CC_RSTN_VE3 (CC_RSTN_REG_BANK_7 | 0x08) +#define CC_RSTN_EDP (CC_RSTN_REG_BANK_7 | 0x0a) + +/* 0x98007088 */ +#define IC_RSTN_VFD 0x0000 +#define IC_RSTN_IR 0x0001 +#define IC_RSTN_CEC0 0x0002 +#define IC_RSTN_CEC1 0x0003 +#define IC_RSTN_DP 0x0004 +#define IC_RSTN_CBUSTX 0x0005 +#define IC_RSTN_CBUSRX 0x0006 +#define IC_RSTN_EFUSE 0x0007 +#define IC_RSTN_UR0 0x0008 +#define IC_RSTN_GMAC 0x0009 +#define IC_RSTN_GPHY 0x000a +#define IC_RSTN_I2C_0 0x000b +#define IC_RSTN_I2C_1 0x000c +#define IC_RSTN_CBUS 0x000d +#define IC_RSTN_USB_DRD 0x000e +#define IC_RSTN_USB_HOST 0x000f +#define IC_RSTN_USB_PHY_0 0x0010 +#define IC_RSTN_USB_PHY_1 0x0011 +#define IC_RSTN_USB_PHY_2 0x0012 +#define IC_RSTN_USB 0x0013 +#define IC_RSTN_TYPE_C 0x0014 +#define IC_RSTN_USB_U3_HOST 0x0015 +#define IC_RSTN_USB3_PHY0_POW 0x0016 +#define IC_RSTN_USB3_P0_MDIO 0x0017 +#define IC_RSTN_USB3_PHY1_POW 0x0018 +#define IC_RSTN_USB3_P1_MDIO 0x0019 + +#endif From patchwork Tue Dec 3 07:45:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SmFtZXMgVGFpIFvmiLTlv5fls7Bd?= X-Patchwork-Id: 11270745 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3483C6C1 for ; Tue, 3 Dec 2019 07:47:29 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CF65D20637 for ; Tue, 3 Dec 2019 07:47:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="B3//4W21" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CF65D20637 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=realtek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Hejh/gpnvKAhJcUKPAU47bAA+atdZrycT0i1D9ZIcuI=; b=B3//4W21BhIg1toscVJHN2Ko1 lA13OOjN7XR3AZcz48hzCdlRBoJ7596XC89O7Kup+9Srtn4APueBl+tZApYZWfOTEZb4nkFWA9K6C IYwJ6mMMQQ0Bw3QOwCXMEWDTXhSUrv1S8aDE5n5nOdthNFFKPcYfZiSk8oTSfiqqSP+o/B+Pp0yR3 U6ZSvtuSpTimn3mcr1eOTjRCBzBkICPVcynCObCl5mCbJUx1pTsaRfXLNxAV5MwhqqSQHJBotidLO YIfSK0PuLWw9sKpfc0Z/sC6Ch09ds6y4A0Qvm3m/PDexWFLoT+sjFJ2vBeKdQQeq3uIQDEeru4jz7 Hznf5xutg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2u7-0000wL-9Q; Tue, 03 Dec 2019 07:47:27 +0000 Received: from rtits2.realtek.com ([211.75.126.72] helo=rtits2.realtek.com.tw) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2sG-0007bx-VJ; Tue, 03 Dec 2019 07:45:38 +0000 Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.62 with qID xB37jObJ016023, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (RTITCASV01.realtek.com.tw[172.21.6.18]) by rtits2.realtek.com.tw (8.15.2/2.57/5.78) with ESMTPS id xB37jObJ016023 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 3 Dec 2019 15:45:24 +0800 Received: from james-BS01.localdomain (172.21.190.33) by RTITCASV01.realtek.com.tw (172.21.6.18) with Microsoft SMTP Server id 14.3.468.0; Tue, 3 Dec 2019 15:45:23 +0800 From: James Tai To: =?utf-8?q?Andreas_F=C3=A4rber?= Subject: [PATCH 3/6] clk: realtek: add common clock support for Realtek SoCs Date: Tue, 3 Dec 2019 15:45:10 +0800 Message-ID: <20191203074513.9416-4-james.tai@realtek.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191203074513.9416-1-james.tai@realtek.com> References: <20191203074513.9416-1-james.tai@realtek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191202_234533_470870_6F4B5E7E X-CRM114-Status: GOOD ( 15.73 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [211.75.126.72 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: cylee12 , linux-realtek-soc@lists.infradead.org, Stephen Boyd , Michael Turquette , Palmer Dabbelt , linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, Paul Walmsley , Matthias Brugger , linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org From: cylee12 This patch adds common clock support for Realtek SoCs, including PLLs, Mux clocks and Gate clocks. Signed-off-by: Cheng-Yu Lee Signed-off-by: James Tai --- drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/realtek/Kconfig | 10 + drivers/clk/realtek/Makefile | 9 + drivers/clk/realtek/clk-pll-dif.c | 81 ++++++ drivers/clk/realtek/clk-pll-psaud.c | 120 ++++++++ drivers/clk/realtek/clk-pll.c | 400 ++++++++++++++++++++++++++ drivers/clk/realtek/clk-pll.h | 151 ++++++++++ drivers/clk/realtek/clk-regmap-gate.c | 89 ++++++ drivers/clk/realtek/clk-regmap-gate.h | 26 ++ drivers/clk/realtek/clk-regmap-mux.c | 63 ++++ drivers/clk/realtek/clk-regmap-mux.h | 26 ++ drivers/clk/realtek/common.c | 320 +++++++++++++++++++++ drivers/clk/realtek/common.h | 123 ++++++++ 14 files changed, 1420 insertions(+) create mode 100644 drivers/clk/realtek/Kconfig create mode 100644 drivers/clk/realtek/Makefile create mode 100644 drivers/clk/realtek/clk-pll-dif.c create mode 100644 drivers/clk/realtek/clk-pll-psaud.c create mode 100644 drivers/clk/realtek/clk-pll.c create mode 100644 drivers/clk/realtek/clk-pll.h create mode 100644 drivers/clk/realtek/clk-regmap-gate.c create mode 100644 drivers/clk/realtek/clk-regmap-gate.h create mode 100644 drivers/clk/realtek/clk-regmap-mux.c create mode 100644 drivers/clk/realtek/clk-regmap-mux.h create mode 100644 drivers/clk/realtek/common.c create mode 100644 drivers/clk/realtek/common.h diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c44247d0b83e..8e06487440ce 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -317,6 +317,7 @@ source "drivers/clk/mediatek/Kconfig" source "drivers/clk/meson/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/qcom/Kconfig" +source "drivers/clk/realtek/Kconfig" source "drivers/clk/renesas/Kconfig" source "drivers/clk/samsung/Kconfig" source "drivers/clk/sifive/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 0138fb14e6f8..71ea17f97f7d 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -95,6 +95,7 @@ obj-$(CONFIG_COMMON_CLK_NXP) += nxp/ obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ +obj-$(CONFIG_COMMON_CLK_REALTEK) += realtek/ obj-y += renesas/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig new file mode 100644 index 000000000000..5bca757dddfa --- /dev/null +++ b/drivers/clk/realtek/Kconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-only +config COMMON_CLK_REALTEK + bool "Clock driver for realtek" + select MFD_SYSCON + +config CLK_PLL_PSAUD + bool + +config CLK_PLL_DIF + bool diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile new file mode 100644 index 000000000000..050d450db067 --- /dev/null +++ b/drivers/clk/realtek/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_COMMON_CLK_REALTEK) += clk-rtk.o + +clk-rtk-y += common.o +clk-rtk-y += clk-regmap-mux.o +clk-rtk-y += clk-regmap-gate.o +clk-rtk-y += clk-pll.o +clk-rtk-$(CONFIG_CLK_PLL_PSAUD) += clk-pll-psaud.o +clk-rtk-$(CONFIG_CLK_PLL_DIF) += clk-pll-dif.o diff --git a/drivers/clk/realtek/clk-pll-dif.c b/drivers/clk/realtek/clk-pll-dif.c new file mode 100644 index 000000000000..d19efef2626e --- /dev/null +++ b/drivers/clk/realtek/clk-pll-dif.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#include +#include +#include +#include +#include "common.h" +#include "clk-pll.h" + +static int clk_pll_dif_enable(struct clk_hw *hw) +{ + struct clk_pll_dif *pll = to_clk_pll_dif(hw); + + pr_debug("%pC: %s\n", hw->clk, __func__); + + clk_regmap_write(&pll->clkr, pll->pll_ofs + 0x0C, 0x00000048); + clk_regmap_write(&pll->clkr, pll->pll_ofs + 0x08, 0x00020c00); + clk_regmap_write(&pll->clkr, pll->pll_ofs + 0x04, 0x204004ca); + clk_regmap_write(&pll->clkr, pll->pll_ofs + 0x00, 0x8000a000); + udelay(100); + + clk_regmap_write(&pll->clkr, pll->pll_ofs + 0x08, 0x00420c00); + udelay(50); + + clk_regmap_write(&pll->clkr, pll->pll_ofs + 0x08, 0x00420c03); + udelay(200); + + clk_regmap_write(&pll->clkr, pll->pll_ofs + 0x0C, 0x00000078); + udelay(100); + + clk_regmap_write(&pll->clkr, pll->pll_ofs + 0x04, 0x204084ca); + + /* ssc control */ + clk_regmap_write(&pll->clkr, pll->ssc_ofs + 0x00, 0x00000004); + clk_regmap_write(&pll->clkr, pll->ssc_ofs + 0x04, 0x00006800); + clk_regmap_write(&pll->clkr, pll->ssc_ofs + 0x0C, 0x00000000); + clk_regmap_write(&pll->clkr, pll->ssc_ofs + 0x10, 0x00000000); + clk_regmap_write(&pll->clkr, pll->ssc_ofs + 0x08, 0x001e1f98); + clk_regmap_write(&pll->clkr, pll->ssc_ofs + 0x00, 0x00000005); + pll->status = 1; + + return 0; +} + +static void clk_pll_dif_disable(struct clk_hw *hw) +{ + struct clk_pll_dif *pll = to_clk_pll_dif(hw); + + pr_debug("%pC: %s\n", hw->clk, __func__); + clk_regmap_update(&pll->clkr, pll->pll_ofs + 0x04, 0x00080000, 0x0); + clk_regmap_update(&pll->clkr, pll->pll_ofs + 0x08, 0x00400C03, 0x0); + clk_regmap_update(&pll->clkr, pll->pll_ofs + 0x0C, 0x00000038, 0x0); + + clk_regmap_write(&pll->clkr, pll->ssc_ofs + 0x00, 0x00000004); + pll->status = 0; +} + +static int clk_pll_dif_is_enabled(struct clk_hw *hw) +{ + struct clk_pll_dif *pll = to_clk_pll_dif(hw); + + return pll->status; +} + +static void clk_pll_dif_disable_unused(struct clk_hw *hw) +{ + pr_info("%pC: %s\n", hw->clk, __func__); + clk_pll_dif_disable(hw); +} + +const struct clk_ops clk_pll_dif_ops = { + .enable = clk_pll_dif_enable, + .disable = clk_pll_dif_disable, + .disable_unused = clk_pll_dif_disable_unused, + .is_enabled = clk_pll_dif_is_enabled, +}; + diff --git a/drivers/clk/realtek/clk-pll-psaud.c b/drivers/clk/realtek/clk-pll-psaud.c new file mode 100644 index 000000000000..757a3320ebb7 --- /dev/null +++ b/drivers/clk/realtek/clk-pll-psaud.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * clk-pll-psaud.c - PLL_PSAUDXA + * + * Copyright (c) 2019 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#include +#include "common.h" +#include "clk-pll.h" + +static int clk_pll_psaud_enable(struct clk_hw *hw) +{ + struct clk_pll_psaud *pll = to_clk_pll_psaud(hw); + u32 mask = 0, val = 0; + + if (pll->id == CLK_PLL_PSAUD1A) { + mask = 0x3; + val = 0x1; + } else { + mask = 0xc; + val = 0x4; + } + clk_regmap_update(&pll->clkr, pll->reg + 4, mask, val); + return 0; +} + +static void clk_pll_psaud_disable(struct clk_hw *hw) +{ + struct clk_pll_psaud *pll = to_clk_pll_psaud(hw); + u32 mask = 0, val = 0; + + if (pll->id == CLK_PLL_PSAUD1A) { + mask = 0x3; + val = 0x3; + } else { + mask = 0xc; + val = 0xc; + } + clk_regmap_update(&pll->clkr, pll->reg + 4, mask, val); +} + +static void clk_pll_psaud_disable_unused(struct clk_hw *hw) +{ + pr_info("%pC: %s\n", hw->clk, __func__); + clk_pll_psaud_disable(hw); +} + +static int clk_pll_psaud_is_enabled(struct clk_hw *hw) +{ + struct clk_pll_psaud *pll = to_clk_pll_psaud(hw); + u32 val; + + val = clk_regmap_read(&pll->clkr, pll->reg + 4); + if (pll->id == CLK_PLL_PSAUD1A) + val &= 0x3; + else + val >>= 2; + return val == 0x1; +} + +static long clk_pll_psaud_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *parent_rate) +{ + return 49192000; +} + +static int clk_pll_psaud_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pll_psaud *pll = to_clk_pll_psaud(hw); + u32 rsel = 0; + u32 mask = 0, val = 0; + + if (WARN_ON_ONCE(rate != 45158400 && rate != 49192000)) + return -EINVAL; + + if (rate == 45158400) + rsel = 1; + if (pll->id == CLK_PLL_PSAUD1A) { + val = 0x6a0 | (rsel << 8); + mask = 0x7e0; + } else { + val = 0x19 | (rsel << 2); + mask = 0x1f; + } + clk_regmap_update(&pll->clkr, pll->reg, mask, val); + return 0; +} + +static unsigned long clk_pll_psaud_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll_psaud *pll = to_clk_pll_psaud(hw); + u32 val; + u32 rsel = 0; + + val = clk_regmap_read(&pll->clkr, pll->reg); + + if (pll->id == CLK_PLL_PSAUD1A) + rsel = !!(val & BIT(8)); + else + rsel = !!(val & BIT(2)); + + return rsel ? 45158400 : 49192000; +} + +const struct clk_ops clk_pll_psaud_ops = { + .enable = clk_pll_psaud_enable, + .disable = clk_pll_psaud_disable, + .disable_unused = clk_pll_psaud_disable_unused, + .is_enabled = clk_pll_psaud_is_enabled, + .set_rate = clk_pll_psaud_set_rate, + .round_rate = clk_pll_psaud_round_rate, + .recalc_rate = clk_pll_psaud_recalc_rate, +}; + diff --git a/drivers/clk/realtek/clk-pll.c b/drivers/clk/realtek/clk-pll.c new file mode 100644 index 000000000000..dd90bfc011ec --- /dev/null +++ b/drivers/clk/realtek/clk-pll.c @@ -0,0 +1,400 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2017-2018 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "clk-pll.h" + +static int clk_pll_debug_rate_u64_set(void *data, u64 val) +{ + struct clk_hw *hw = data; + + clk_set_rate(hw->clk, (unsigned long)(val)); + return 0; +} + +static int clk_pll_debug_rate_u64_get(void *data, u64 *val) +{ + struct clk_hw *hw = data; + + *val = (u64)clk_get_rate(hw->clk); + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(clk_pll_debut_rate_op, clk_pll_debug_rate_u64_get, + clk_pll_debug_rate_u64_set, "%llu\n"); + +static void clk_pll_debug_init(struct clk_hw *hw, struct dentry *d) +{ + debugfs_create_file("debug_rate", 0644, d, hw, &clk_pll_debut_rate_op); +} + +static const struct freq_table *ftbl_find_by_rate(const struct freq_table *ftbl, + unsigned long rate) +{ + unsigned long best_rate = 0; + const struct freq_table *best = NULL; + + for ( ; !IS_FREQ_TABLE_END(ftbl); ftbl++) { + if (ftbl->rate == rate) + return ftbl; + + if (ftbl->rate > rate) + continue; + + if ((rate - best_rate) > (rate - ftbl->rate)) { + best_rate = ftbl->rate; + best = ftbl; + } + } + + return best; +} + +static const struct freq_table *ftbl_find_by_val(const struct freq_table *ftbl, + uint32_t value) +{ + while (!IS_FREQ_TABLE_END(ftbl)) { + if (ftbl->val == (value)) + return ftbl; + ftbl++; + } + return NULL; +}; + +static const struct div_table *dtbl_find_by_rate(const struct div_table *dtbl, + unsigned long rate) +{ + while (!IS_DIV_TABLE_END(dtbl)) { + if (rate >= dtbl->rate) + return dtbl; + dtbl++; + } + return NULL; +} + +static const struct div_table *dtbl_find_by_val(const struct div_table *dtbl, + uint32_t val) +{ + while (!IS_DIV_TABLE_END(dtbl)) { + if (val == dtbl->val) + return dtbl; + dtbl++; + } + return NULL; +} + +static void __clk_pll_set_pow_reg(struct clk_pll *clkp, int on) +{ + uint32_t pow = (clkp->pow_loc == CLK_PLL_CONF_POW_LOC_CTL3) ? 0x8 : 0x4; + + if (on) { + clk_regmap_update(&clkp->clkr, clkp->pll_ofs + pow, 0x7, 0x3); + if (clkp->freq_loc == CLK_PLL_CONF_FREQ_LOC_SSC1) { + uint32_t val; + + val = clk_regmap_read(&clkp->clkr, clkp->ssc_ofs + 0x0); + + /* + * For those PLL with SCC used only the default + * freq, the oc_en would nerver to be set. + * Help to set it here. + */ + if ((val & 0x7) != 0x5) + clk_regmap_update(&clkp->clkr, + clkp->ssc_ofs + 0x0, 0x7, 0x5); + } + udelay(200); + } else { + clk_regmap_update(&clkp->clkr, clkp->pll_ofs + pow, 0x7, 0x4); + } +} + +static int clk_pll_enable(struct clk_hw *hw) +{ + struct clk_pll *clkp = to_clk_pll(hw); + + if (clk_pll_has_pow(clkp)) + __clk_pll_set_pow_reg(clkp, 1); + return 0; +} + +static void clk_pll_disable(struct clk_hw *hw) +{ + struct clk_pll *clkp = to_clk_pll(hw); + + if (clk_pll_has_pow(clkp)) + __clk_pll_set_pow_reg(clkp, 0); +} + +static void clk_pll_disable_unused(struct clk_hw *hw) +{ + pr_info("%pC: %s\n", hw->clk, __func__); + clk_pll_disable(hw); +} + +static int clk_pll_is_enabled(struct clk_hw *hw) +{ + struct clk_pll *clkp = to_clk_pll(hw); + uint32_t pow; + uint32_t val; + + if (!clk_pll_has_pow(clkp)) + return -EINVAL; + + pow = (clkp->pow_loc == CLK_PLL_CONF_POW_LOC_CTL3) ? 0x8 : 0x4; + val = clk_regmap_read(&clkp->clkr, clkp->pll_ofs + pow); + return !!(val & 0x1); +} + +static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct clk_pll *clkp = to_clk_pll(hw); + const struct freq_table *ftblv = NULL; + + ftblv = ftbl_find_by_rate(clkp->freq_tbl, rate); + return ftblv ? ftblv->rate : 0; +} + +static uint32_t __clk_pll_freq_get(struct clk_pll *clkp) +{ + uint32_t val = 0; + + switch (clkp->freq_loc) { + case CLK_PLL_CONF_FREQ_LOC_CTL1: + val = clk_regmap_read(&clkp->clkr, clkp->pll_ofs + 0x0); + break; + + case CLK_PLL_CONF_FREQ_LOC_CTL2: + val = clk_regmap_read(&clkp->clkr, clkp->pll_ofs + 0x4); + break; + + case CLK_PLL_CONF_FREQ_LOC_SSC1: + val = clk_regmap_read(&clkp->clkr, clkp->ssc_ofs + 0x4); + break; + + default: + break; + } + return val & clkp->freq_mask; +} + +static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll *clkp = to_clk_pll(hw); + unsigned long flags = 0; + const struct freq_table *fv; + uint32_t val; + + flags = clk_pll_lock(clkp); + val = __clk_pll_freq_get(clkp); + clk_pll_unlock(clkp, flags); + + fv = ftbl_find_by_val(clkp->freq_tbl, val); + return fv ? fv->rate : 0; +} + +static inline int __clk_pll_freq_set(struct clk_pll *clkp, uint32_t val) +{ + struct clk_hw *hw = &clkp->clkr.hw; + int ret = 0; + uint32_t mask = clkp->freq_mask; + uint32_t pollval; + + switch (clkp->freq_loc) { + case CLK_PLL_CONF_FREQ_LOC_CTL1: + clk_regmap_update(&clkp->clkr, clkp->pll_ofs, mask, val); + break; + + case CLK_PLL_CONF_FREQ_LOC_CTL2: + clk_regmap_update(&clkp->clkr, clkp->pll_ofs + 0x4, mask, val); + clk_regmap_update(&clkp->clkr, clkp->pll_ofs + 0x8, 0x1, 0x0); + clk_regmap_update(&clkp->clkr, clkp->pll_ofs + 0x8, 0x1, 0x1); + break; + + case CLK_PLL_CONF_FREQ_LOC_SSC1: + clk_regmap_update(&clkp->clkr, clkp->ssc_ofs + 0x0, 0x7, 0x4); + clk_regmap_update(&clkp->clkr, clkp->ssc_ofs + 0x4, mask, val); + clk_regmap_update(&clkp->clkr, clkp->ssc_ofs + 0x0, 0x7, 0x5); + + if (clk_pll_has_pow(clkp) && !clk_pll_is_enabled(hw)) + return 0; + + ret = regmap_read_poll_timeout(clkp->clkr.regmap, + clkp->ssc_ofs + 0x1c, + pollval, pollval & BIT(20), + 0, 2000); + break; + + default: + ret = -EINVAL; + break; + } + return ret; +} + +static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pll *clkp = to_clk_pll(hw); + unsigned long flags = 0; + const struct freq_table *fv; + int ret = 0; + + fv = ftbl_find_by_rate(clkp->freq_tbl, rate); + if (!fv) + return -EINVAL; + + pr_debug("%pC: %s: rate=%ld, val=0x%08x\n", hw->clk, __func__, + fv->rate, fv->val); + + flags = clk_pll_lock(clkp); + ret = __clk_pll_freq_set(clkp, fv->val); + clk_pll_unlock(clkp, flags); + if (ret) + pr_warn("%pC %s: failed to set freq: %d\n", hw->clk, __func__, + ret); + return ret; +} + +static void __clk_pll_div_set(struct clk_pll_div *clkpd, uint32_t val) +{ + uint32_t m = (BIT(clkpd->div_width) - 1) << clkpd->div_shift; + uint32_t s = clkpd->div_shift; + + clk_regmap_update(&clkpd->clkp.clkr, clkpd->div_ofs, m, val << s); +} + +static uint32_t __clk_pll_div_get(struct clk_pll_div *clkpd) +{ + uint32_t m = (BIT(clkpd->div_width) - 1) << clkpd->div_shift; + uint32_t s = clkpd->div_shift; + + return (clk_regmap_read(&clkpd->clkp.clkr, clkpd->div_ofs) & m) >> s; +} + +static long clk_pll_div_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct clk_pll_div *clkpd = to_clk_pll_div(hw); + const struct div_table *dv; + + /* lookup div in dtbl */ + dv = dtbl_find_by_rate(clkpd->div_tbl, rate); + if (!dv) + return 0; + + rate *= dv->div; + rate = clk_pll_round_rate(hw, rate, parent_rate); + return rate / dv->div; +} + +static unsigned long clk_pll_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll_div *clkpd = to_clk_pll_div(hw); + unsigned long rate; + const struct div_table *dv; + uint32_t val; + + rate = clk_pll_recalc_rate(hw, parent_rate); + + val = __clk_pll_div_get(clkpd); + dv = dtbl_find_by_val(clkpd->div_tbl, val); + if (!dv) + return 0; + + rate /= dv->div; + pr_debug("%pC: %s: current rate=%lu, div=%d, reg_val=0x%x\n", + hw->clk, __func__, rate, dv->div, val); + + return rate; +} + +static int clk_pll_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk *clk = hw->clk; + struct clk_pll_div *clkpd = to_clk_pll_div(hw); + unsigned long flags; + const struct div_table *ndv, *cdv; + unsigned long target; + uint32_t cur_d; + int ret; + + /* find next in the dtbl */ + ndv = dtbl_find_by_rate(clkpd->div_tbl, rate); + if (!ndv) + return -EINVAL; + + target = rate * ndv->div; + + /* find current in the dtbl */ + cur_d = __clk_pll_div_get(clkpd); + cdv = dtbl_find_by_val(clkpd->div_tbl, cur_d); + if (!cdv) + return -EINVAL; + + pr_debug("%pC: rate=%lu, cdv={%d,0x%x}, ndv={%d,0x%x}\n", + clk, rate, cdv->div, cdv->val, ndv->div, ndv->val); + + flags = clk_pll_div_lock(clkpd); + + /* workaround to prevent glitch */ +#ifdef CONFIG_COMMON_CLK_RTD129X + if ((&clkpd->clkp.flags & CLK_PLL_DIV_WORKAROUND) && + ndv->val != cdv->val && (ndv->val == 1 || cdv->val == 1)) { + + pr_debug("%pC: apply rate=%u\n", clk, 1000000000); + clk_pll_set_rate(hw, 1000000000, parent_rate); + + pr_debug("%pC: apply dv={%d, 0x%x}\n", clk, ndv->div, ndv->val); + __clk_pll_div_set(clkpd, ndv->val); + cdv = ndv; + } +#endif + + if (ndv->div > cdv->div) + __clk_pll_div_set(clkpd, ndv->val); + ret = clk_pll_set_rate(hw, target, parent_rate); + if (ndv->div < cdv->div) + __clk_pll_div_set(clkpd, ndv->val); + + clk_pll_div_unlock(clkpd, flags); + + return ret; +} + +const struct clk_ops clk_pll_ops = { + .debug_init = clk_pll_debug_init, + .round_rate = clk_pll_round_rate, + .recalc_rate = clk_pll_recalc_rate, + .set_rate = clk_pll_set_rate, + .enable = clk_pll_enable, + .disable = clk_pll_disable, + .disable_unused = clk_pll_disable_unused, + .is_enabled = clk_pll_is_enabled, +}; + +const struct clk_ops clk_pll_div_ops = { + .debug_init = clk_pll_debug_init, + .round_rate = clk_pll_div_round_rate, + .recalc_rate = clk_pll_div_recalc_rate, + .set_rate = clk_pll_div_set_rate, + .enable = clk_pll_enable, + .disable = clk_pll_disable, + .disable_unused = clk_pll_disable_unused, + .is_enabled = clk_pll_is_enabled, +}; + diff --git a/drivers/clk/realtek/clk-pll.h b/drivers/clk/realtek/clk-pll.h new file mode 100644 index 000000000000..03b4d0391c31 --- /dev/null +++ b/drivers/clk/realtek/clk-pll.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2017-2019 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#ifndef __CLK_REALTEK_CLK_PLL_H +#define __CLK_REALTEK_CLK_PLL_H + +#include "common.h" + +struct freq_table { + uint32_t val; + unsigned long rate; +}; + +#define FREQ_TABLE_END { .rate = 0 } +#define IS_FREQ_TABLE_END(_f) ((_f)->rate == 0) + +struct div_table { + unsigned long rate; + uint32_t div; + uint32_t val; +}; + +#define DIV_TABLE_END { .rate = 0 } +#define IS_DIV_TABLE_END(_d) ((_d)->rate == 0) + +struct clk_pll { + struct clk_regmap clkr; + + + int pll_ofs; + int ssc_ofs; + + const struct freq_table *freq_tbl; + uint32_t freq_mask; + uint32_t freq_loc; +#define CLK_PLL_CONF_FREQ_LOC_CTL1 1 +#define CLK_PLL_CONF_FREQ_LOC_CTL2 2 +#define CLK_PLL_CONF_FREQ_LOC_SSC1 3 + + uint32_t pow_loc; +#define CLK_PLL_CONF_NO_POW 0 +#define CLK_PLL_CONF_POW_LOC_CTL2 1 +#define CLK_PLL_CONF_POW_LOC_CTL3 2 + + spinlock_t *lock; + + uint32_t flags; +}; + +#define to_clk_pll(_hw) container_of(to_clk_regmap(_hw), struct clk_pll, clkr) +#define __clk_pll_hw(_ptr) __clk_regmap_hw(&(_ptr)->clkr) + +/* clk_pll flags */ +#define CLK_PLL_DIV_WORKAROUND BIT(2) + + +static inline bool clk_pll_has_pow(struct clk_pll *pll) +{ + if (pll->pow_loc != CLK_PLL_CONF_NO_POW) + return true; + return false; +} + +static inline unsigned long clk_pll_lock(struct clk_pll *pll) +{ + unsigned long flags = 0; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + return flags; +} + +static inline void clk_pll_unlock(struct clk_pll *pll, unsigned long flags) +{ + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); +} + +struct clk_pll_div { + struct clk_pll clkp; + int div_ofs; + int div_shift; + int div_width; + const struct div_table *div_tbl; + spinlock_t *lock; +}; + +#define to_clk_pll_div(_hw) \ + container_of(to_clk_pll(_hw), struct clk_pll_div, clkp) +#define __clk_pll_div_hw(_ptr) __clk_pll_hw(&(_ptr)->clkp) + +/* clk_pll_div helper functions */ +static inline unsigned long clk_pll_div_lock(struct clk_pll_div *plld) +{ + unsigned long flags = 0; + + if (plld->lock) + spin_lock_irqsave(plld->lock, flags); + return flags; +} + +static inline void clk_pll_div_unlock(struct clk_pll_div *plld, + unsigned long flags) +{ + if (plld->lock) + spin_unlock_irqrestore(plld->lock, flags); +} + +extern const struct clk_ops clk_pll_ops; +extern const struct clk_ops clk_pll_div_ops; + +#ifdef CONFIG_CLK_PLL_PSAUD + +struct clk_pll_psaud { + struct clk_regmap clkr; + int id; + int reg; + spinlock_t *lock; +}; + +#define to_clk_pll_psaud(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_pll_psaud, clkr) +#define __clk_pll_psaud_hw(_ptr) __clk_regmap_hw(&(_ptr)->clkr) +extern const struct clk_ops clk_pll_psaud_ops; + +#define CLK_PLL_PSAUD1A (0x1) +#define CLK_PLL_PSAUD2A (0x2) + +#endif /* CONFIG_CLK_PLL_PSAUD */ + +#ifdef CONFIG_CLK_PLL_DIF + +struct clk_pll_dif { + struct clk_regmap clkr; + int pll_ofs; + int ssc_ofs; + uint32_t status; + spinlock_t *lock; +}; +#define to_clk_pll_dif(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_pll_dif, clkr) +#define __clk_pll_dif_hw(_ptr) __clk_regmap_hw(&(_ptr)->clkr) + +extern const struct clk_ops clk_pll_dif_ops; +#endif /* CONFIG_CLK_PLL_DIF */ + + +#endif /* __CLK_REALTEK_CLK_PLL_H */ diff --git a/drivers/clk/realtek/clk-regmap-gate.c b/drivers/clk/realtek/clk-regmap-gate.c new file mode 100644 index 000000000000..5f4a6a98da94 --- /dev/null +++ b/drivers/clk/realtek/clk-regmap-gate.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2017 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#include +#include +#include "clk-regmap-gate.h" + +static int clk_regmap_gate_enable(struct clk_hw *hw) +{ + struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw); + unsigned long flags = 0; + unsigned int mask; + unsigned int val; + + if (clkg->lock) + spin_lock_irqsave(clkg->lock, flags); + + mask = BIT(clkg->bit_idx); + val = BIT(clkg->bit_idx); + + if (clkg->write_en) { + mask |= BIT(clkg->bit_idx + 1); + val |= BIT(clkg->bit_idx + 1); + } + + clk_regmap_update(&clkg->clkr, clkg->gate_ofs, mask, val); + + if (clkg->lock) + spin_unlock_irqrestore(clkg->lock, flags); + + return 0; +} + +static void clk_regmap_gate_disable(struct clk_hw *hw) +{ + struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw); + unsigned long flags = 0; + unsigned int mask; + unsigned int val; + + if (clkg->lock) + spin_lock_irqsave(clkg->lock, flags); + + mask = BIT(clkg->bit_idx); + val = 0; + + if (clkg->write_en) { + mask |= BIT(clkg->bit_idx + 1); + val |= BIT(clkg->bit_idx + 1); + } + + clk_regmap_update(&clkg->clkr, clkg->gate_ofs, mask, val); + + if (clkg->lock) + spin_unlock_irqrestore(clkg->lock, flags); +} + +static void clk_regmap_gate_disable_unused(struct clk_hw *hw) +{ + pr_info("%pC: %s\n", hw->clk, __func__); + clk_regmap_gate_disable(hw); +} + +static int clk_regmap_gate_is_enabled(struct clk_hw *hw) +{ + struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw); + int ret; + unsigned long flags = 0; + + if (clkg->lock) + spin_lock_irqsave(clkg->lock, flags); + + ret = clk_regmap_read(&clkg->clkr, clkg->gate_ofs) & BIT(clkg->bit_idx); + + if (clkg->lock) + spin_unlock_irqrestore(clkg->lock, flags); + + return !!ret; +} + +const struct clk_ops clk_regmap_gate_ops = { + .enable = clk_regmap_gate_enable, + .disable = clk_regmap_gate_disable, + .disable_unused = clk_regmap_gate_disable_unused, + .is_enabled = clk_regmap_gate_is_enabled, +}; diff --git a/drivers/clk/realtek/clk-regmap-gate.h b/drivers/clk/realtek/clk-regmap-gate.h new file mode 100644 index 000000000000..7643e0193177 --- /dev/null +++ b/drivers/clk/realtek/clk-regmap-gate.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2017 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#ifndef __CLK_REALTEK_CLK_MMIO_GATE_H +#define __CLK_REALTEK_CLK_MMIO_GATE_H + +#include "common.h" + +struct clk_regmap_gate { + struct clk_regmap clkr; + int gate_ofs; + uint8_t bit_idx; + spinlock_t *lock; + int write_en:1; +}; + +#define to_clk_regmap_gate(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_regmap_gate, clkr) +#define __clk_regmap_gate_hw(_p) __clk_regmap_hw(&(_p)->clkr) + +extern const struct clk_ops clk_regmap_gate_ops; + +#endif diff --git a/drivers/clk/realtek/clk-regmap-mux.c b/drivers/clk/realtek/clk-regmap-mux.c new file mode 100644 index 000000000000..bd7eb706e12a --- /dev/null +++ b/drivers/clk/realtek/clk-regmap-mux.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2017 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#include +#include +#include +#include +#include +#include +#include "clk-regmap-mux.h" + +static u8 clk_regmap_mux_get_parent(struct clk_hw *hw) +{ + struct clk_regmap_mux *clkm = to_clk_regmap_mux(hw); + int num_parents = clk_hw_get_num_parents(hw); + u32 val; + unsigned long flags = 0; + + if (clkm->lock) + spin_lock_irqsave(clkm->lock, flags); + + val = clk_regmap_read(&clkm->clkr, clkm->mux_ofs) >> clkm->shift; + if (clkm->lock) + spin_unlock_irqrestore(clkm->lock, flags); + + val &= clkm->mask; + if (val >= num_parents) + return -EINVAL; + + return val; +} + +static int clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_regmap_mux *clkm = to_clk_regmap_mux(hw); + unsigned long flags = 0; + + if (clkm->lock) + spin_lock_irqsave(clkm->lock, flags); + + clk_regmap_update(&clkm->clkr, clkm->mux_ofs, clkm->mask << clkm->shift, + index << clkm->shift); + + if (clkm->lock) + spin_unlock_irqrestore(clkm->lock, flags); + return 0; +} + +const struct clk_ops clk_regmap_mux_ops = { + .get_parent = clk_regmap_mux_get_parent, + .set_parent = clk_regmap_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, +}; +EXPORT_SYMBOL_GPL(clk_regmap_mux_ops); + +const struct clk_ops clk_regmap_mux_ro_ops = { + .get_parent = clk_regmap_mux_get_parent, +}; +EXPORT_SYMBOL_GPL(clk_regmap_mux_ro_ops); + diff --git a/drivers/clk/realtek/clk-regmap-mux.h b/drivers/clk/realtek/clk-regmap-mux.h new file mode 100644 index 000000000000..36895f03c0f4 --- /dev/null +++ b/drivers/clk/realtek/clk-regmap-mux.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2017 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#ifndef __CLK_REALTEK_CLK_MMIO_MUX_H +#define __CLK_REALTEK_CLK_MMIO_MUX_H + +#include "common.h" + +struct clk_regmap_mux { + struct clk_regmap clkr; + int mux_ofs; + unsigned int mask; + unsigned int shift; + spinlock_t *lock; +}; + +#define to_clk_regmap_mux(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_regmap_mux, clkr) +#define __clk_regmap_mux_hw(_p) __clk_regmap_hw(&(_p)->clkr) + +extern const struct clk_ops clk_regmap_mux_ops; + +#endif diff --git a/drivers/clk/realtek/common.c b/drivers/clk/realtek/common.c new file mode 100644 index 000000000000..0c5dc5ce4682 --- /dev/null +++ b/drivers/clk/realtek/common.c @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2019 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "clk-pll.h" +#include "clk-regmap-gate.h" +#include "clk-regmap-mux.h" + +static int rtk_clk_suspend(struct device *dev) +{ + struct rtk_clk_data *data = dev_get_drvdata(dev); + int i; + + for (i = 0; i < data->pm_data_num; i++) { + struct clk_pm_data *pm_data = &data->pm_data[i]; + + regmap_read(data->regmap, pm_data->ofs, &pm_data->val); + } + return 0; +} + +static int rtk_clk_resume(struct device *dev) +{ + struct rtk_clk_data *data = dev_get_drvdata(dev); + int i; + + for (i = data->pm_data_num - 1; i >= 0; i--) { + struct clk_pm_data *pm_data = &data->pm_data[i]; + uint32_t val = pm_data->val; + uint32_t mask = ~0x0; + + if (pm_data->write_en_bits) + val |= pm_data->write_en_bits; + if (pm_data->ignore_bits) + mask &= ~pm_data->ignore_bits; + dev_info(dev, "resuming: ofs=%03x, vs=%08x vr=%08x m=%08x\n", + pm_data->ofs, pm_data->val, val, mask); + regmap_update_bits(data->regmap, pm_data->ofs, mask, val); + } + return 0; +} + +const struct dev_pm_ops rtk_clk_pm_ops = { + .suspend = rtk_clk_suspend, + .resume = rtk_clk_resume, +}; + +struct rtk_clk_data *alloc_rtk_clk_data(int clk_num) +{ + struct rtk_clk_data *data; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return NULL; + + data->clk_num = clk_num; + data->clk_data.clk_num = clk_num; + data->clk_data.clks = kcalloc(clk_num, sizeof(*data->clk_data.clks), + GFP_KERNEL); + if (!data->clk_data.clks) + goto free_data; + return data; + +free_data: + kfree(data->clk_data.clks); + kfree(data); + return NULL; +} + +void free_rtk_clk_data(struct rtk_clk_data *data) +{ + kfree(data->clk_data.clks); + kfree(data); +} + +static inline +int __cell_clk_add(struct clk_onecell_data *clk_data, int i, struct clk *clk) +{ + if (clk_data->clks[i]) { + pr_err("%s: failed to add %pC, cell%d is used by %pC\n", + __func__, clk, i, clk_data->clks[i]); + return -EINVAL; + } + clk_data->clks[i] = clk; + return 0; +} + +#define CLK_TYPE_DEFAULT (0x0) +#define CLK_TYPE_REGMAP (0x8) +#define CLK_TYPE_REGMAP_PLL (0x1 | CLK_TYPE_REGMAP) +#define CLK_TYPE_REGMAP_MUX (0x2 | CLK_TYPE_REGMAP) +#define CLK_TYPE_REGMAP_GATE (0x3 | CLK_TYPE_REGMAP) + +static inline int __hw_to_type(struct clk_hw *hw) +{ + const struct clk_ops *ops = hw->init->ops; + + if (ops == &clk_pll_ops || ops == &clk_pll_div_ops) + return CLK_TYPE_REGMAP_PLL; + if (ops == &clk_regmap_mux_ops) + return CLK_TYPE_REGMAP_MUX; + if (ops == &clk_regmap_gate_ops) + return CLK_TYPE_REGMAP_GATE; +#ifdef CONFIG_CLK_PLL_DIF + /* + * clk_pll_dif is not based struct clk_pll, so + * return as CLK_TYPE_REGMAP to setup internal + * clk_reg + */ + if (ops == &clk_pll_dif_ops) + return CLK_TYPE_REGMAP; +#endif +#ifdef CONFIG_CLK_PLL_PSAUD + /* + * clk_pll_psaud is not based struct clk_pll, so + * return as CLK_TYPE_REGMAP to setup internal + * clk_reg + */ + if (ops == &clk_pll_psaud_ops) + return CLK_TYPE_REGMAP; +#endif + + return CLK_TYPE_DEFAULT; +} + +static +struct clk *rtk_clk_register_hw(struct device *dev, struct regmap *regmap, + struct clk_hw *hw) +{ + int type; + + type = __hw_to_type(hw); + if (type & CLK_TYPE_REGMAP) { + struct clk_regmap *clkr = to_clk_regmap(hw); + + clkr->regmap = regmap; + } + + return clk_register(dev, hw); +} + +int rtk_clk_add_hws(struct device *dev, struct rtk_clk_data *data, + struct clk_hw **hws, int num) +{ + struct clk_onecell_data *clk_data = &data->clk_data; + struct regmap *regmap = data->regmap; + int i; + + for (i = 0; i < num; i++) { + struct clk_hw *hw = hws[i]; + const char *name; + struct clk *clk; + + if (IS_ERR(hw)) + __cell_clk_add(clk_data, i, ERR_CAST(hw)); + if (IS_ERR_OR_NULL(hw)) + continue; + + name = hw->init->name; + clk = rtk_clk_register_hw(dev, regmap, hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to add hw%d(%s): %ld\n", __func__, + i, name, PTR_ERR(clk)); + continue; + } + + clk_register_clkdev(clk, name, NULL); + __cell_clk_add(clk_data, i, clk); + } + return 0; +} + +static +struct clk *rtk_clk_register_composite(struct device *dev, + struct regmap *regmap, + struct clk_composite_data *comp) +{ + struct clk_regmap_mux *clkm = NULL; + const struct clk_ops *mux_op = NULL; + struct clk_hw *mux_hw = NULL; + struct clk_regmap_gate *clkg = NULL; + const struct clk_ops *gate_op = NULL; + struct clk_hw *gate_hw = NULL; + struct clk *clk; + + if (comp->mux_ofs != CLK_OFS_INVALID) { + clkm = kzalloc(sizeof(*clkm), GFP_KERNEL); + if (!clkm) { + clk = ERR_PTR(-ENOMEM); + goto check_err; + } + + clkm->mux_ofs = comp->mux_ofs; + clkm->mask = BIT(comp->mux_width) - 1; + clkm->shift = comp->mux_shift; + clkm->clkr.regmap = regmap; + + mux_op = &clk_regmap_mux_ops; + mux_hw = &__clk_regmap_mux_hw(clkm); + } + + if (comp->gate_ofs != CLK_OFS_INVALID) { + clkg = kzalloc(sizeof(*clkg), GFP_KERNEL); + if (!clkg) { + clk = ERR_PTR(-ENOMEM); + goto check_err; + } + + clkg->gate_ofs = comp->gate_ofs; + clkg->bit_idx = comp->gate_shift; + clkg->write_en = comp->gate_write_en; + clkg->clkr.regmap = regmap; + + gate_op = &clk_regmap_gate_ops; + gate_hw = &__clk_regmap_gate_hw(clkg); + } + + clk = clk_register_composite(NULL, comp->name, comp->parent_names, + comp->num_parents, mux_hw, mux_op, + NULL, NULL, gate_hw, gate_op, comp->flags); +check_err: + if (IS_ERR(clk)) { + kfree(clkm); + kfree(clkg); + } + return clk; +} + +int rtk_clk_add_composites(struct device *dev, struct rtk_clk_data *data, + struct clk_composite_data *comps, int num) +{ + struct clk_onecell_data *clk_data = &data->clk_data; + struct regmap *regmap = data->regmap; + int i; + + for (i = 0; i < num; i++) { + struct clk_composite_data *comp = &comps[i]; + const char *name = comp->name; + struct clk *clk; + + clk = rtk_clk_register_composite(dev, regmap, comp); + if (IS_ERR(clk)) { + pr_err("%s: failed to add composite%d(%s): %ld\n", + __func__, i, name, PTR_ERR(clk)); + continue; + } + + clk_register_clkdev(clk, name, NULL); + __cell_clk_add(clk_data, comp->id, clk); + } + + return 0; +} + +static +struct clk *rtk_clk_register_gate(struct device *dev, struct regmap *regmap, + struct clk_gate_data *gate) +{ + struct clk_regmap_gate *clkg; + struct clk_init_data init = { 0 }; + struct clk_hw *hw; + + clkg = kzalloc(sizeof(*clkg), GFP_KERNEL); + if (!clkg) + return ERR_PTR(-ENOMEM); + + clkg->gate_ofs = gate->gate_ofs; + clkg->bit_idx = gate->gate_shift; + clkg->write_en = gate->gate_write_en; + clkg->clkr.regmap = regmap; + + init.name = gate->name; + init.ops = &clk_regmap_gate_ops; + init.flags = gate->flags; + if (gate->parent) { + init.parent_names = &gate->parent; + init.num_parents = 1; + } + + hw = &__clk_regmap_gate_hw(clkg); + hw->init = &init; + return clk_register(dev, hw); +} + +int rtk_clk_add_gates(struct device *dev, struct rtk_clk_data *data, + struct clk_gate_data *gates, int num) +{ + struct clk_onecell_data *clk_data = &data->clk_data; + struct regmap *regmap = data->regmap; + int i; + + for (i = 0; i < num; i++) { + struct clk_gate_data *gate = &gates[i]; + const char *name = gate->name; + struct clk *clk; + + clk = rtk_clk_register_gate(dev, regmap, gate); + if (IS_ERR(clk)) { + pr_err("%s: failed to add gate%d(%s): %ld\n", __func__, + i, name, PTR_ERR(clk)); + continue; + } + + clk_register_clkdev(clk, name, NULL); + __cell_clk_add(clk_data, gate->id, clk); + } + + return 0; +} + diff --git a/drivers/clk/realtek/common.h b/drivers/clk/realtek/common.h new file mode 100644 index 000000000000..c736b254852f --- /dev/null +++ b/drivers/clk/realtek/common.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2016-2019 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#ifndef __CLK_REALTEK_COMMON_H +#define __CLK_REALTEK_COMMON_H + +#include +#include +#include +#include +#include +#include + +struct device; +struct platform_device; + +struct clk_regmap { + struct clk_hw hw; + struct regmap *regmap; +}; + +#define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw) +#define __clk_regmap_hw(_p) ((_p)->hw) + +static inline +void clk_regmap_write(struct clk_regmap *clkr, uint32_t ofs, uint32_t val) +{ + pr_debug("%s: ofs=%03x, val=%08x\n", __func__, ofs, val); + regmap_write(clkr->regmap, ofs, val); +} + +static inline +uint32_t clk_regmap_read(struct clk_regmap *clkr, uint32_t ofs) +{ + uint32_t val = 0; + + regmap_read(clkr->regmap, ofs, &val); + pr_debug("%s: ofs=%03x, val=%08x\n", __func__, ofs, val); + return val; +} + +static inline void clk_regmap_update(struct clk_regmap *clkr, uint32_t ofs, + uint32_t mask, uint32_t val) +{ + pr_debug("%s: ofs=%03x, mask=%08x, val=%08x\n", __func__, ofs, + mask, val); + regmap_update_bits(clkr->regmap, ofs, mask, val); +} + +/* ofs check */ +#define CLK_OFS_INVALID (-1) +#define CLK_OFS_IS_VALID(_ofs) ((_ofs) != CLK_OFS_INVALID) + +struct clk_composite_data { + int id; + const char *name; + unsigned long flags; + struct clk *clk; + + int gate_ofs; + int gate_shift; + int gate_write_en; + + int mux_ofs; + int mux_width; + int mux_shift; + const char * const *parent_names; + int num_parents; +}; + +struct clk_gate_data { + int id; + const char *name; + const char *parent; + unsigned long flags; + struct clk *clk; + + int gate_ofs; + int gate_shift; + int gate_write_en; +}; + +#define CLK_GATE_DATA(_id, _name, _parent, _flags, _ofs, _shift, _write_en) \ +{ \ + .id = _id, \ + .name = _name, \ + .parent = _parent, \ + .flags = _flags, \ + .gate_ofs = _ofs, \ + .gate_shift = _shift, \ + .gate_write_en = _write_en, \ +} + +struct clk_pm_data { + int ofs; + uint32_t ignore_bits; + uint32_t write_en_bits; + uint32_t val; +}; + +struct rtk_clk_data { + int clk_num; + struct regmap *regmap; + struct clk_onecell_data clk_data; + struct clk_pm_data *pm_data; + int pm_data_num; +}; + +struct rtk_clk_data *alloc_rtk_clk_data(int clk_num); +void free_rtk_clk_data(struct rtk_clk_data *data); +int rtk_clk_add_hws(struct device *dev, struct rtk_clk_data *data, + struct clk_hw **hws, int num); +int rtk_clk_add_composites(struct device *dev, struct rtk_clk_data *data, + struct clk_composite_data *comps, int num); +int rtk_clk_add_gates(struct device *dev, struct rtk_clk_data *data, + struct clk_gate_data *gates, int num); +extern const struct dev_pm_ops rtk_clk_pm_ops; + +#endif /* __CLK_REALTEK_COMMON_H */ + From patchwork Tue Dec 3 07:45:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SmFtZXMgVGFpIFvmiLTlv5fls7Bd?= X-Patchwork-Id: 11270751 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA6006C1 for ; Tue, 3 Dec 2019 07:48:01 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B6F7E2053B for ; Tue, 3 Dec 2019 07:48:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="nTMRbSxk" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B6F7E2053B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=realtek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=VA0ogPox2smcR7squSELHyqglh4XFX0+uZRfiNQYs+M=; b=nTMRbSxkvc9Fn12ODzvSxeunq R80u9yNN8O8PZxnyOfdNmBIttgTkFzvZ+EFMLqKtKb7KR4yBAXBIWf+CodsGZ8MFEA8vNk1fSWBlQ 3tbTGu56bypyyNNhacPpl6Qrg7Rt6kwxanYEx+QL8/Ihp6kdUWawK+tsYDH8IL69XEpEy5zeFi3Qk iZS8PjVgfE7q6uQJWrNzV5tAczdJRZAVXyAqsuNf6uiDbmifk4Zd/04QMKu63jDPvJViZbywGMwTD zjv0OfLhY31Ce2wTPIDILi4hsQh1ytIPHcanvMpoEax8zk5vuckG8PolRxR+rUj2+G8i5m0b7VeOn pLOIca0IA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2uf-0001OA-08; Tue, 03 Dec 2019 07:48:01 +0000 Received: from rtits2.realtek.com ([211.75.126.72] helo=rtits2.realtek.com.tw) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2sI-0007e1-AN; Tue, 03 Dec 2019 07:45:37 +0000 Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.62 with qID xB37jQU0016032, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (RTITCASV01.realtek.com.tw[172.21.6.18]) by rtits2.realtek.com.tw (8.15.2/2.57/5.78) with ESMTPS id xB37jQU0016032 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 3 Dec 2019 15:45:26 +0800 Received: from james-BS01.localdomain (172.21.190.33) by RTITCASV01.realtek.com.tw (172.21.6.18) with Microsoft SMTP Server id 14.3.468.0; Tue, 3 Dec 2019 15:45:25 +0800 From: James Tai To: =?utf-8?q?Andreas_F=C3=A4rber?= Subject: [PATCH 4/6] clk: realtek: add reset controller support for Realtek SoCs Date: Tue, 3 Dec 2019 15:45:11 +0800 Message-ID: <20191203074513.9416-5-james.tai@realtek.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191203074513.9416-1-james.tai@realtek.com> References: <20191203074513.9416-1-james.tai@realtek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191202_234534_681332_7A15CBBF X-CRM114-Status: GOOD ( 13.04 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [211.75.126.72 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: cylee12 , linux-realtek-soc@lists.infradead.org, Stephen Boyd , Michael Turquette , Palmer Dabbelt , linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, Paul Walmsley , Matthias Brugger , linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org From: cylee12 This patch add reset control support for Realtek SoCs. Signed-off-by: Cheng-Yu Lee Signed-off-by: James Tai --- drivers/clk/realtek/Kconfig | 1 + drivers/clk/realtek/Makefile | 1 + drivers/clk/realtek/reset.c | 107 +++++++++++++++++++++++++++++++++++ drivers/clk/realtek/reset.h | 37 ++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 drivers/clk/realtek/reset.c create mode 100644 drivers/clk/realtek/reset.h diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig index 5bca757dddfa..8e7e7edf64dd 100644 --- a/drivers/clk/realtek/Kconfig +++ b/drivers/clk/realtek/Kconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config COMMON_CLK_REALTEK bool "Clock driver for realtek" + select RESET_CONTROLLER select MFD_SYSCON config CLK_PLL_PSAUD diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile index 050d450db067..43f8bd71c0c8 100644 --- a/drivers/clk/realtek/Makefile +++ b/drivers/clk/realtek/Makefile @@ -7,3 +7,4 @@ clk-rtk-y += clk-regmap-gate.o clk-rtk-y += clk-pll.o clk-rtk-$(CONFIG_CLK_PLL_PSAUD) += clk-pll-psaud.o clk-rtk-$(CONFIG_CLK_PLL_DIF) += clk-pll-dif.o +clk-rtk-y += reset.o diff --git a/drivers/clk/realtek/reset.c b/drivers/clk/realtek/reset.c new file mode 100644 index 000000000000..3f4d1a723b2a --- /dev/null +++ b/drivers/clk/realtek/reset.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2019 Realtek Semiconductor Corporation + */ + +#include +#include +#include +#include +#include +#include "reset.h" + +static int rtk_reset_assert(struct reset_controller_dev *rcdev, + unsigned long idx) +{ + struct rtk_reset_data *data = to_rtk_reset_controller(rcdev); + struct rtk_reset_bank *bank = &data->banks[idx >> 8]; + uint32_t id = idx & 0xff; + uint32_t mask = bank->write_en ? (0x3 << id) : BIT(id); + uint32_t val = bank->write_en ? (0x2 << id) : 0; + + return regmap_update_bits(data->regmap, bank->ofs, mask, val); +} + +static int rtk_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long idx) +{ + struct rtk_reset_data *data = to_rtk_reset_controller(rcdev); + struct rtk_reset_bank *bank = &data->banks[idx >> 8]; + uint32_t id = idx & 0xff; + uint32_t mask = bank->write_en ? (0x3 << id) : BIT(id); + uint32_t val = mask; + + return regmap_update_bits(data->regmap, bank->ofs, mask, val); +} + +static int rtk_reset_reset(struct reset_controller_dev *rcdev, + unsigned long idx) +{ + int ret; + + ret = rtk_reset_assert(rcdev, idx); + if (ret) + return ret; + + return rtk_reset_deassert(rcdev, idx); +} + +static int rtk_reset_status(struct reset_controller_dev *rcdev, + unsigned long idx) +{ + struct rtk_reset_data *data = to_rtk_reset_controller(rcdev); + struct rtk_reset_bank *bank = &data->banks[idx >> 8]; + uint32_t id = idx & 0xff; + uint32_t val; + + regmap_read(data->regmap, bank->ofs, &val); + return !((val >> id) & 1); +} + +static struct reset_control_ops rtk_reset_ops = { + .assert = rtk_reset_assert, + .deassert = rtk_reset_deassert, + .reset = rtk_reset_reset, + .status = rtk_reset_status, +}; + +static int rtk_of_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + struct rtk_reset_data *data = to_rtk_reset_controller(rcdev); + int val; + + val = reset_spec->args[0]; + if (val >= rcdev->nr_resets) + return -EINVAL; + + if (data->id_xlate) + return data->id_xlate(val); + return val; +} + + +int rtk_reset_controller_add(struct device *dev, struct regmap *regmap, + struct rtk_reset_initdata *initdata) +{ + struct rtk_reset_data *data; + struct device_node *np = dev->of_node; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + data->regmap = regmap; + data->num_banks = initdata->num_banks; + data->banks = initdata->banks; + data->id_xlate = initdata->id_xlate; + + data->rcdev.owner = THIS_MODULE; + data->rcdev.ops = &rtk_reset_ops; + data->rcdev.of_node = np; + data->rcdev.nr_resets = initdata->num_banks * 0x100; + data->rcdev.of_xlate = rtk_of_reset_xlate; + data->rcdev.of_reset_n_cells = 1; + + return reset_controller_register(&data->rcdev); +} + diff --git a/drivers/clk/realtek/reset.h b/drivers/clk/realtek/reset.h new file mode 100644 index 000000000000..f0cc7b1045ee --- /dev/null +++ b/drivers/clk/realtek/reset.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2019 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#ifndef __CLK_REALTEK_RESET_H +#define __CLK_REALTEK_RESET_H + +#include + +struct rtk_reset_bank { + uint32_t ofs; + uint32_t write_en; +}; + +struct rtk_reset_data { + struct reset_controller_dev rcdev; + struct rtk_reset_bank *banks; + uint32_t num_banks; + struct regmap *regmap; + unsigned long (*id_xlate)(unsigned long id); +}; + +#define to_rtk_reset_controller(r) \ + container_of(r, struct rtk_reset_data, rcdev) + +struct rtk_reset_initdata { + struct rtk_reset_bank *banks; + uint32_t num_banks; + unsigned long (*id_xlate)(unsigned long id); +}; + +int rtk_reset_controller_add(struct device *dev, struct regmap *regmap, + struct rtk_reset_initdata *initdata); + +#endif /* __CLK_REALTEK_RESET_H */ From patchwork Tue Dec 3 07:45:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SmFtZXMgVGFpIFvmiLTlv5fls7Bd?= X-Patchwork-Id: 11270753 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4B5986C1 for ; Tue, 3 Dec 2019 07:48:06 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0ACE02053B for ; Tue, 3 Dec 2019 07:48:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="rsAbQN4O" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0ACE02053B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=realtek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=qOx4kclQovun5S4wjy7Gnp+5YlKoRoPWN6l1RYBjKHM=; b=rsAbQN4O8mm3Moxyv0gtoZEH4 NmLTFEKfCQ27GLvIt0GXLhRW6U+LfCeNizm5ZVbvodAM9KYpEJIap4z+pE/YcGV5H6aVG/KrWX+7y L3vaPu+itDvWGnT4bnApCIpk+/yEuzI0ybUv3cL8SVTej4fGaJDOS/XRQMjDZ3fkGJjD+jlPSC0E1 0BnUDJVYj5K2+Jkf+rRZsgibnS2v2TS4KsPF8te/tNcSmq1pI6LTQILM+GcyrQb/siYLHhuHszhcn gwbsWbEdl+UwOxmcLDhjDYTu9TL9VRF/vqDOpgR+NQcUZTDdQUzgGLrynEDmBQFYHkfx00rK7j8VF xZ6dPVmQg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2ui-0001R6-Jy; Tue, 03 Dec 2019 07:48:04 +0000 Received: from rtits2.realtek.com ([211.75.126.72] helo=rtits2.realtek.com.tw) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2sK-0007gD-Ld; Tue, 03 Dec 2019 07:45:40 +0000 Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.62 with qID xB37jSG1016043, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (RTITCASV01.realtek.com.tw[172.21.6.18]) by rtits2.realtek.com.tw (8.15.2/2.57/5.78) with ESMTPS id xB37jSG1016043 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 3 Dec 2019 15:45:28 +0800 Received: from james-BS01.localdomain (172.21.190.33) by RTITCASV01.realtek.com.tw (172.21.6.18) with Microsoft SMTP Server id 14.3.468.0; Tue, 3 Dec 2019 15:45:27 +0800 From: James Tai To: =?utf-8?q?Andreas_F=C3=A4rber?= Subject: [PATCH 5/6] clk: realtek: add rtd1619 controllers Date: Tue, 3 Dec 2019 15:45:12 +0800 Message-ID: <20191203074513.9416-6-james.tai@realtek.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191203074513.9416-1-james.tai@realtek.com> References: <20191203074513.9416-1-james.tai@realtek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191202_234537_270891_A19578DC X-CRM114-Status: GOOD ( 11.97 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [211.75.126.72 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: cylee12 , linux-realtek-soc@lists.infradead.org, Stephen Boyd , Michael Turquette , Palmer Dabbelt , linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, Paul Walmsley , Matthias Brugger , linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org From: cylee12 This patch adds CRT controller and ISO controller for RTD1619 SoC. Signed-off-by: Cheng-Yu Lee Signed-off-by: James Tai --- drivers/clk/realtek/Kconfig | 10 + drivers/clk/realtek/Makefile | 2 + drivers/clk/realtek/clk-rtd1619-cc.c | 553 +++++++++++++++++++++++++++ drivers/clk/realtek/clk-rtd1619-ic.c | 112 ++++++ 4 files changed, 677 insertions(+) create mode 100644 drivers/clk/realtek/clk-rtd1619-cc.c create mode 100644 drivers/clk/realtek/clk-rtd1619-ic.c diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig index 8e7e7edf64dd..43c55be25eba 100644 --- a/drivers/clk/realtek/Kconfig +++ b/drivers/clk/realtek/Kconfig @@ -9,3 +9,13 @@ config CLK_PLL_PSAUD config CLK_PLL_DIF bool + +config COMMON_CLK_RTD1619 + bool "RTD1619 Clock Controller" + depends on ARCH_REALTEK || COMPILE_TEST + select COMMON_CLK_REALTEK + select CLK_PLL_PSAUD + select CLK_PLL_DIF + default ARCH_REALTEK + ---help--- + Support for the clock controller on RTD1619 diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile index 43f8bd71c0c8..24af3dbe2006 100644 --- a/drivers/clk/realtek/Makefile +++ b/drivers/clk/realtek/Makefile @@ -8,3 +8,5 @@ clk-rtk-y += clk-pll.o clk-rtk-$(CONFIG_CLK_PLL_PSAUD) += clk-pll-psaud.o clk-rtk-$(CONFIG_CLK_PLL_DIF) += clk-pll-dif.o clk-rtk-y += reset.o +clk-rtk-$(CONFIG_COMMON_CLK_RTD1619) += clk-rtd1619-cc.o +clk-rtk-$(CONFIG_COMMON_CLK_RTD1619) += clk-rtd1619-ic.o diff --git a/drivers/clk/realtek/clk-rtd1619-cc.c b/drivers/clk/realtek/clk-rtd1619-cc.c new file mode 100644 index 000000000000..c799ffd4cc7a --- /dev/null +++ b/drivers/clk/realtek/clk-rtd1619-cc.c @@ -0,0 +1,553 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2018-2019 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "clk-pll.h" +#include "clk-regmap-gate.h" +#include "clk-regmap-mux.h" +#include "reset.h" +#include +#include + +#define DIV_DV(_r, _d, _v) { .rate = _r, .div = _d, .val = _v, } +#define FREQ_NF_MASK (0x7FFFF) +#define FREQ_NF(_r, _n, _f) { .rate = _r, .val = ((_n) << 11) | (_f), } +#define FREQ_MNO_MASK (0x63FF0) +#define FREQ_MNO(_r, _m, _n, _o) \ + { .rate = _r, .val = ((_m) << 4) | ((_n) << 12) | ((_o) << 17), } + +static const char * const default_parent[] = { "osc27m" }; + +static const struct div_table scpu_div_tbl[] = { + DIV_DV(1000000000, 1, 0), + DIV_DV(500000000, 2, 0x88), + DIV_DV(350000000, 3, 0x8C), + DIV_DV(250000000, 4, 0x90), + DIV_DV(200000000, 8, 0xA0), + DIV_DV(100000000, 10, 0xA8), + DIV_TABLE_END +}; + +static const struct freq_table scpu_tbl[] = { + FREQ_NF(1000000000, 34, 75), + FREQ_NF(1100000000, 37, 1517), + FREQ_NF(1200000000, 41, 910), + FREQ_NF(1300000000, 45, 303), + FREQ_NF(1400000000, 48, 1745), + FREQ_NF(1500000000, 52, 1137), + FREQ_NF(1600000000, 56, 530), + FREQ_NF(1700000000, 59, 1972), + FREQ_NF(1800000000, 63, 1365), + FREQ_NF(1900000000, 67, 758), + FREQ_NF(2000000000, 71, 151), + /* init-value mapping */ + FREQ_NF(1000000000, 35, 0), + FREQ_NF(1200000000, 41, 0), + FREQ_NF(1800000000, 65, 0), + FREQ_NF(1800000000, 64, 0), + FREQ_TABLE_END +}; + +static struct clk_pll_div pll_scpu = { + .div_ofs = 0x030, + .div_shift = 6, + .div_width = 8, + .div_tbl = scpu_div_tbl, + .clkp = { + .ssc_ofs = 0x500, + .pll_ofs = CLK_OFS_INVALID, + .freq_loc = CLK_PLL_CONF_FREQ_LOC_SSC1, + .freq_tbl = scpu_tbl, + .freq_mask = FREQ_NF_MASK, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_scpu", + .ops = &clk_pll_div_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_IGNORE_UNUSED | + CLK_GET_RATE_NOCACHE, + }, + }, +}; + +static const struct div_table bus_div_tbl[] = { + DIV_DV(257000000, 1, 0), + DIV_DV(129000000, 2, 2), + DIV_DV(65000000, 4, 3), + DIV_TABLE_END +}; + +static const struct freq_table bus_tbl[] = { + FREQ_NF(513000000, 35, 0), + FREQ_NF(400000000, 26, 1289), + FREQ_TABLE_END +}; + +static struct clk_pll_div pll_bus = { + .div_ofs = 0x030, + .div_shift = 0, + .div_width = 2, + .div_tbl = bus_div_tbl, + .clkp = { + .ssc_ofs = 0x520, + .pll_ofs = CLK_OFS_INVALID, + .freq_loc = CLK_PLL_CONF_FREQ_LOC_SSC1, + .freq_tbl = bus_tbl, + .freq_mask = FREQ_NF_MASK, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_bus", + .ops = &clk_pll_div_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_IGNORE_UNUSED | + CLK_GET_RATE_NOCACHE, + }, + }, +}; + +static struct clk_fixed_factor clk_sys = { + .div = 1, + .mult = 1, + .hw.init = &(struct clk_init_data) { + .name = "clk_sys", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "pll_bus" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct div_table dcsb_div_tbl[] = { + DIV_DV(550000000, 1, 0), + DIV_DV(275000000, 2, 2), + DIV_DV(1, 4, 3), + DIV_TABLE_END +}; + +static const struct freq_table dcsb_tbl[] = { + FREQ_NF(550000000, 38, 0), + FREQ_NF(550000000, 37, 1517), + FREQ_TABLE_END +}; + +static struct clk_pll_div pll_dcsb = { + .div_ofs = 0x030, + .div_shift = 2, + .div_width = 2, + .div_tbl = dcsb_div_tbl, + .clkp = { + .ssc_ofs = 0x540, + .pll_ofs = CLK_OFS_INVALID, + .freq_loc = CLK_PLL_CONF_FREQ_LOC_SSC1, + .freq_tbl = dcsb_tbl, + .freq_mask = FREQ_NF_MASK, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_dcsb", + .ops = &clk_pll_div_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_IGNORE_UNUSED | + CLK_GET_RATE_NOCACHE, + }, + }, +}; + +static struct clk_fixed_factor clk_sysh = { + .div = 1, + .mult = 1, + .hw.init = &(struct clk_init_data) { + .name = "clk_sysh", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "pll_dcsb" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_table ddsx_tbl[] = { + FREQ_NF(432000000, 13, 0), + FREQ_TABLE_END +}; + +static struct clk_pll pll_ddsa = { + .ssc_ofs = 0x560, + .pll_ofs = 0x120, + .pow_loc = CLK_PLL_CONF_POW_LOC_CTL3, + .freq_loc = CLK_PLL_CONF_FREQ_LOC_SSC1, + .freq_tbl = ddsx_tbl, + .freq_mask = FREQ_NF_MASK, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_ddsa", + .ops = &clk_pll_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, + }, +}; + +static const struct freq_table gpu_tbl[] = { + FREQ_NF(300000000, 19, 455), + FREQ_NF(400000000, 26, 1289), + FREQ_NF(500000000, 34, 75), + FREQ_NF(600000000, 41, 910), + FREQ_NF(650000000, 45, 303), + FREQ_NF(700000000, 48, 1745), + FREQ_NF(750000000, 52, 1137), + FREQ_NF(800000000, 56, 530), + FREQ_NF(850000000, 59, 1971), + FREQ_TABLE_END +}; + +static struct clk_pll pll_gpu = { + .ssc_ofs = 0x5A0, + .pll_ofs = 0x1C0, + .pow_loc = CLK_PLL_CONF_POW_LOC_CTL2, + .freq_loc = CLK_PLL_CONF_FREQ_LOC_SSC1, + .freq_tbl = gpu_tbl, + .freq_mask = FREQ_NF_MASK, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_gpu", + .ops = &clk_pll_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static const struct freq_table ve_tbl[] = { + FREQ_MNO(189000000, 12, 0, 1), + FREQ_MNO(270000000, 18, 0, 1), + FREQ_MNO(405000000, 13, 0, 0), + FREQ_MNO(432000000, 14, 0, 0), + FREQ_MNO(459000000, 15, 0, 0), + FREQ_MNO(486000000, 16, 0, 0), + FREQ_MNO(513000000, 17, 0, 0), + FREQ_MNO(540000000, 18, 0, 0), + FREQ_MNO(550000000, 59, 2, 0), + FREQ_MNO(567000000, 19, 0, 0), + FREQ_MNO(594000000, 20, 0, 0), + FREQ_MNO(648000000, 22, 0, 0), + FREQ_MNO(675000000, 23, 0, 0), + FREQ_MNO(702000000, 24, 0, 0), + FREQ_MNO(715000000, 51, 1, 0), + FREQ_TABLE_END +}; + +static struct clk_pll pll_ve1 = { + .ssc_ofs = CLK_OFS_INVALID, + .pll_ofs = 0x114, + .pow_loc = CLK_PLL_CONF_POW_LOC_CTL2, + .freq_loc = CLK_PLL_CONF_FREQ_LOC_CTL1, + .freq_tbl = ve_tbl, + .freq_mask = FREQ_MNO_MASK, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_ve1", + .ops = &clk_pll_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_pll pll_ve2 = { + .ssc_ofs = CLK_OFS_INVALID, + .pll_ofs = 0x1D0, + .pow_loc = CLK_PLL_CONF_POW_LOC_CTL2, + .freq_loc = CLK_PLL_CONF_FREQ_LOC_CTL1, + .freq_tbl = ve_tbl, + .freq_mask = FREQ_MNO_MASK, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_ve2", + .ops = &clk_pll_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_pll_dif pll_dif = { + .ssc_ofs = 0x634, + .pll_ofs = 0x624, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_dif", + .ops = &clk_pll_dif_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_pll_psaud pll_psaud1a = { + .reg = 0x130, + .id = CLK_PLL_PSAUD1A, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_psaud1a", + .ops = &clk_pll_psaud_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_IGNORE_UNUSED | CLK_SET_RATE_UNGATE, + }, +}; + +static struct clk_pll_psaud pll_psaud2a = { + .reg = 0x130, + .id = CLK_PLL_PSAUD2A, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pll_psaud2a", + .ops = &clk_pll_psaud_ops, + .parent_names = default_parent, + .num_parents = 1, + .flags = CLK_IGNORE_UNUSED | CLK_SET_RATE_UNGATE, + }, +}; + +static struct clk_hw *cc_hws[] = { + [CC_PLL_SCPU] = &__clk_pll_div_hw(&pll_scpu), + [CC_PLL_BUS] = &__clk_pll_div_hw(&pll_bus), + [CC_PLL_DCSB] = &__clk_pll_div_hw(&pll_dcsb), + [CC_PLL_DDSA] = &__clk_pll_hw(&pll_ddsa), + [CC_PLL_GPU] = &__clk_pll_hw(&pll_gpu), + [CC_PLL_VE1] = &__clk_pll_hw(&pll_ve1), + [CC_PLL_VE2] = &__clk_pll_hw(&pll_ve2), + [CC_PLL_DIF] = &__clk_pll_dif_hw(&pll_dif), + [CC_CLK_SYS] = &clk_sys.hw, + [CC_CLK_SYSH] = &clk_sysh.hw, + [CC_PLL_PSAUD1A] = &__clk_pll_psaud_hw(&pll_psaud1a), + [CC_PLL_PSAUD2A] = &__clk_pll_psaud_hw(&pll_psaud2a), +}; + +static const char * const ve_parents[] = { + "clk_sys", + "clk_sysh", + "pll_ve1", + "pll_ve2", +}; + +static struct clk_composite_data cc_composites[] = { + { + .id = CC_CLK_GPU, + .mux_ofs = CLK_OFS_INVALID, + .gate_ofs = 0x050, + .gate_shift = 18, + .gate_write_en = 1, + .parent_names = (const char *[]){ "pll_gpu" }, + .num_parents = 1, + .name = "clk_gpu", + .flags = CLK_SET_RATE_PARENT, + }, + { + .id = CC_CLK_VE1, + .gate_ofs = 0x050, + .gate_shift = 20, + .gate_write_en = 1, + .mux_ofs = 0x04C, + .mux_width = 3, + .mux_shift = 0, + .parent_names = ve_parents, + .num_parents = ARRAY_SIZE(ve_parents), + .name = "clk_ve1", + .flags = CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, + }, + { + .id = CC_CLK_VE2, + .gate_ofs = 0x050, + .gate_shift = 22, + .gate_write_en = 1, + .mux_ofs = 0x04C, + .mux_width = 3, + .mux_shift = 3, + .parent_names = ve_parents, + .num_parents = ARRAY_SIZE(ve_parents), + .name = "clk_ve2", + .flags = CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, + }, + { + .id = CC_CLK_VE3, + .gate_ofs = 0x05C, + .gate_shift = 26, + .gate_write_en = 1, + .mux_ofs = 0x04C, + .mux_width = 3, + .mux_shift = 6, + .parent_names = ve_parents, + .num_parents = ARRAY_SIZE(ve_parents), + .name = "clk_ve3", + .flags = CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, + }, + { + .id = CC_CLK_VE2_BPU, + .gate_ofs = CLK_OFS_INVALID, + .mux_ofs = 0x04C, + .mux_width = 3, + .mux_shift = 9, + .parent_names = ve_parents, + .num_parents = ARRAY_SIZE(ve_parents), + .name = "clk_ve2_bpu", + .flags = CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, + }, +}; + +#define GATE(_id, _name, _parent, _ofs, _shift) \ + CLK_GATE_DATA(_id, _name, _parent, 0, _ofs, _shift, 1) +#define GATE_IGNORE(_id, _name, _parent, _ofs, _shift) \ + CLK_GATE_DATA(_id, _name, _parent, CLK_IGNORE_UNUSED, _ofs, _shift, 1) + +static struct clk_gate_data cc_gates[] = { + GATE_IGNORE(CC_CKE_MISC, "misc", NULL, 0x50, 0), + GATE(CC_CKE_PCIE0, "pcie0", NULL, 0x50, 2), + GATE(CC_CKE_GSPI, "gspi", "misc", 0x50, 6), + GATE(CC_CKE_SDS, "sds", NULL, 0x50, 12), + GATE_IGNORE(CC_CKE_HDMI, "hdmi", NULL, 0x50, 14), + GATE_IGNORE(CC_CKE_TVE, "tve", NULL, 0x50, 24), + GATE_IGNORE(CC_CKE_VO, "vo", NULL, 0x50, 26), + GATE_IGNORE(CC_CKE_LSADC, "lsadc", NULL, 0x50, 28), + GATE(CC_CKE_SE, "se", NULL, 0x50, 30), + GATE_IGNORE(CC_CKE_CP, "cp", NULL, 0x54, 2), + GATE_IGNORE(CC_CKE_MD, "md", NULL, 0x54, 4), + GATE_IGNORE(CC_CKE_TP, "tp", NULL, 0x54, 6), + GATE(CC_CKE_RSA, "rsa", NULL, 0x54, 8), + GATE(CC_CKE_NF, "nf", NULL, 0x54, 10), + GATE(CC_CKE_EMMC, "emmc", NULL, 0x54, 12), + GATE(CC_CKE_SD, "sd", NULL, 0x54, 14), + GATE(CC_CKE_SDIO_IP, "sdio_ip", NULL, 0x54, 16), + GATE(CC_CKE_MIPI, "mipi", NULL, 0x54, 18), + GATE(CC_CKE_EMMC_IP, "emmc_ip", NULL, 0x54, 20), + GATE(CC_CKE_SDIO, "sdio", NULL, 0x54, 22), + GATE(CC_CKE_SD_IP, "sd_ip", NULL, 0x54, 24), + GATE(CC_CKE_CABLERX, "cablerx", NULL, 0x54, 26), + GATE(CC_CKE_TPB, "tpb", NULL, 0x54, 28), + GATE(CC_CKE_SC1, "sc1", "misc", 0x54, 30), + GATE(CC_CKE_I2C3, "i2c3", "misc", 0x58, 0), + GATE(CC_CKE_JPEG, "jpeg", NULL, 0x58, 4), + GATE(CC_CKE_SC0, "sc0", "misc", 0x58, 10), + GATE(CC_CKE_HDMIRX, "hdmirx", NULL, 0x58, 26), + GATE(CC_CKE_HSE, "hse", NULL, 0x58, 28), + GATE(CC_CKE_UR2, "ur2", "misc", 0x58, 30), + GATE(CC_CKE_UR1, "ur1", "misc", 0x5C, 0), + GATE(CC_CKE_FAN, "fan", "misc", 0x5C, 2), + GATE(CC_CKE_SATA_WRAP_SYS, "sata_wrap_sys", NULL, 0x5C, 8), + GATE(CC_CKE_SATA_WRAP_SYSH, "sata_wrap_sysh", NULL, 0x5C, 10), + GATE(CC_CKE_SATA_MAC_SYSH, "sata_mac_sysh", NULL, 0x5C, 12), + GATE(CC_CKE_R2RDSC, "r2rdsc", NULL, 0x5C, 14), + GATE(CC_CKE_PCIE1, "pcie1", NULL, 0x5C, 18), + GATE(CC_CKE_I2C4, "i2c4", "misc", 0x5C, 20), + GATE(CC_CKE_I2C5, "i2c5", "misc", 0x5C, 22), + GATE(CC_CKE_EDP, "edp", NULL, 0x5C, 28), + GATE_IGNORE(CC_CKE_TSIO_TRX, "tsio_trx", NULL, 0x5C, 30), +}; + +static struct rtk_reset_bank cc_reset_banks[] = { + { .ofs = 0x00, .write_en = 1, }, + { .ofs = 0x04, .write_en = 1, }, + { .ofs = 0x08, .write_en = 1, }, + { .ofs = 0x0c, .write_en = 1, }, + { .ofs = 0x14, .write_en = 1, }, + { .ofs = 0x68, .write_en = 1, }, +}; + +static struct rtk_reset_initdata cc_reset_initdata = { + .banks = cc_reset_banks, + .num_banks = ARRAY_SIZE(cc_reset_banks), +}; + +static struct clk_pm_data cc_pm_data[] = { + /* SOFT_RESET */ + { .ofs = 0x00, .write_en_bits = 0xAAAAAAAA, }, + { .ofs = 0x04, .write_en_bits = 0xAAAAAAAA, }, + { .ofs = 0x08, .write_en_bits = 0x0A80AAAA, }, + { .ofs = 0x0C, .write_en_bits = 0x2AAAAAAA, }, + { .ofs = 0x14, .write_en_bits = 0xAA82AA82, }, + { .ofs = 0x68, .write_en_bits = 0xAAAAAAAA, }, + /* CLK_EN */ + { .ofs = 0x50, .write_en_bits = 0xA0A8288A, }, + { .ofs = 0x54, .write_en_bits = 0xAAAAAAA8, }, + { .ofs = 0x58, .write_en_bits = 0xA800082A, }, + { .ofs = 0x5C, .write_en_bits = 0xAAAAAA0A, }, + /* PLL_GPU */ + { .ofs = 0x1C4, }, + { .ofs = 0x5A4, .ignore_bits = ~(0x7FFFF), }, + /* PLL_VE1 */ + { .ofs = 0x118, }, + { .ofs = 0x114, .ignore_bits = ~(0x63FF0), }, + /* PLL_VE2 */ + { .ofs = 0x1D4, }, + { .ofs = 0x1D0, .ignore_bits = ~(0x63FF0), }, +}; + +static int rtd1619_cc_probe(struct platform_device *pdev) +{ + struct device *parent; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct rtk_clk_data *data; + struct regmap *regmap; + int ret; + + parent = dev->parent; + if (!parent) { + dev_err(dev, "no parent crt controller\n"); + return -ENODEV; + } + + regmap = syscon_node_to_regmap(parent->of_node); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(dev, "failed to get regmap form %s: %d\n", np->name, + ret); + return ret; + } + + data = alloc_rtk_clk_data(CC_CLK_MAX); + if (!data) + return -ENOMEM; + + platform_set_drvdata(pdev, data); + data->regmap = regmap; + data->pm_data = cc_pm_data; + data->pm_data_num = ARRAY_SIZE(cc_pm_data); + + rtk_clk_add_hws(dev, data, cc_hws, ARRAY_SIZE(cc_hws)); + rtk_clk_add_composites(dev, data, cc_composites, + ARRAY_SIZE(cc_composites)); + rtk_clk_add_gates(dev, data, cc_gates, ARRAY_SIZE(cc_gates)); + + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &data->clk_data); + if (ret) + dev_err(dev, "failed to add clk provider: %d\n", ret); + + rtk_reset_controller_add(dev, regmap, &cc_reset_initdata); + + return 0; +} + +static const struct of_device_id rtd1619_cc_match[] = { + { .compatible = "realtek,rtd1619-cc", }, + { /* sentinel */ } +}; + +static struct platform_driver rtd1619_cc_driver = { + .probe = rtd1619_cc_probe, + .driver = { + .name = "rtk-rtd1619-cc", + .of_match_table = rtd1619_cc_match, + .pm = &rtk_clk_pm_ops, + }, +}; + +static int __init rtd1619_cc_init(void) +{ + return platform_driver_register(&rtd1619_cc_driver); +} +core_initcall(rtd1619_cc_init); diff --git a/drivers/clk/realtek/clk-rtd1619-ic.c b/drivers/clk/realtek/clk-rtd1619-ic.c new file mode 100644 index 000000000000..9651c9aca26d --- /dev/null +++ b/drivers/clk/realtek/clk-rtd1619-ic.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2019 Realtek Semiconductor Corporation + * Author: Cheng-Yu Lee + */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "reset.h" +#include + +#define GATE(_id, _name, _parent, _ofs, _shift) \ + CLK_GATE_DATA(_id, _name, _parent, 0, _ofs, _shift, 0) + +static struct clk_gate_data ic_gates[] = { + GATE(IC_CKE_CEC0, "cec0", NULL, 0x8c, 2), + GATE(IC_CKE_CBUSRX_SYS, "cbusrx_sys", NULL, 0x8c, 3), + GATE(IC_CKE_CBUSTX_SYS, "cbustx_sys", NULL, 0x8c, 4), + GATE(IC_CKE_CBUS_SYS, "cbus_sys", NULL, 0x8c, 5), + GATE(IC_CKE_CBUS_OSC, "cbus_osc", NULL, 0x8c, 6), + GATE(IC_CKE_IR, "ir", NULL, 0x8c, 7), + GATE(IC_CKE_UR0, "ur0", NULL, 0x8c, 8), + GATE(IC_CKE_I2C0, "i2c0", NULL, 0x8c, 9), + GATE(IC_CKE_I2C1, "i2c1", NULL, 0x8c, 10), + GATE(IC_CKE_ETN_250M, "etn_250m", NULL, 0x8c, 11), + GATE(IC_CKE_ETN_SYS, "etn_sys", NULL, 0x8c, 12), + GATE(IC_CKE_USB_DRD, "usb_drd", NULL, 0x8c, 13), + GATE(IC_CKE_USB_HOST, "usb_host", NULL, 0x8c, 14), + GATE(IC_CKE_USB_U3_HOST, "usb_u3_host", NULL, 0x8c, 15), + GATE(IC_CKE_USB, "usb", NULL, 0x8c, 16), +}; + +static struct rtk_reset_bank ic_reset_banks[] = { + { .ofs = 0x88, }, +}; + +static struct rtk_reset_initdata ic_reset_initdata = { + .banks = ic_reset_banks, + .num_banks = ARRAY_SIZE(ic_reset_banks), +}; + +static struct clk_pm_data ic_pm_data[] = { + { .ofs = 0x88, }, + { .ofs = 0x8C, }, +}; + +static int rtd1619_ic_probe(struct platform_device *pdev) +{ + struct device *parent; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct rtk_clk_data *data; + struct regmap *regmap; + int ret; + + parent = dev->parent; + if (!parent) { + dev_err(dev, "no parent crt controller\n"); + return -ENODEV; + } + + regmap = syscon_node_to_regmap(parent->of_node); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(dev, "failed to get regmap form %s: %d\n", np->name, + ret); + return ret; + } + + data = alloc_rtk_clk_data(IC_CLK_MAX); + if (!data) + return -ENOMEM; + + platform_set_drvdata(pdev, data); + data->regmap = regmap; + data->pm_data = ic_pm_data; + data->pm_data_num = ARRAY_SIZE(ic_pm_data); + + rtk_clk_add_gates(dev, data, ic_gates, ARRAY_SIZE(ic_gates)); + + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &data->clk_data); + if (ret) + dev_err(dev, "failed to add clk provider: %d\n", ret); + + rtk_reset_controller_add(dev, regmap, &ic_reset_initdata); + + return 0; +} + +static const struct of_device_id rtd1619_ic_match[] = { + { .compatible = "realtek,rtd1619-ic", }, + { /* sentinel */ } +}; + +static struct platform_driver rtd1619_ic_driver = { + .probe = rtd1619_ic_probe, + .driver = { + .name = "rtk-rtd1619-ic", + .of_match_table = rtd1619_ic_match, + .pm = &rtk_clk_pm_ops, + }, +}; + +static int __init rtd1619_ic_init(void) +{ + return platform_driver_register(&rtd1619_ic_driver); +} +core_initcall(rtd1619_ic_init); From patchwork Tue Dec 3 07:45:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SmFtZXMgVGFpIFvmiLTlv5fls7Bd?= X-Patchwork-Id: 11270755 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 980686C1 for ; Tue, 3 Dec 2019 07:48:10 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F86E2053B for ; Tue, 3 Dec 2019 07:48:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="XlmDDUxR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F86E2053B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=realtek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=cR+gYDz2rc9M/7zI9qNzXJbqu3SgqrIGq3xnD26oZeM=; b=XlmDDUxRvfa/N8DGOFOXmfY5m XdX9KZonNaVYNPw5UlfLuRUBIoWBScth/ulXfNDbCi2J2Yv08EWKBP+q/jUH8wkvcoRafPz5NKi02 /dmjCzU+8c9EdaNiTLhXPcOTb81GNRyoo9LNqe8qj/hWNWtVIkoQai/yaLmCUIZZ5hp+qmpsPVSQ0 GQdJKhAaespwsg1TSi48yjZn/b99c5TBerzv4HVgDeG1fYEZ5uIRblMyE2iI/0Kt2lhEliGqWxGtQ dyRYAMPrhwozvUcckJivqOw8+tcL1MvA6dcnkz49ZwNVAHEhnb3g6PtxWNoaZb9jc0i49MuUk3cZV KJltQElWA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2un-0001Us-EL; Tue, 03 Dec 2019 07:48:09 +0000 Received: from rtits2.realtek.com ([211.75.126.72] helo=rtits2.realtek.com.tw) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ic2sP-0007ky-Pf; Tue, 03 Dec 2019 07:45:44 +0000 Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.62 with qID xB37jTZl016051, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (RTITCASV01.realtek.com.tw[172.21.6.18]) by rtits2.realtek.com.tw (8.15.2/2.57/5.78) with ESMTPS id xB37jTZl016051 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 3 Dec 2019 15:45:29 +0800 Received: from james-BS01.localdomain (172.21.190.33) by RTITCASV01.realtek.com.tw (172.21.6.18) with Microsoft SMTP Server id 14.3.468.0; Tue, 3 Dec 2019 15:45:28 +0800 From: James Tai To: =?utf-8?q?Andreas_F=C3=A4rber?= Subject: [PATCH 6/6] dt-bindings: clk: realtek: add rtd1619 clock controller bindings Date: Tue, 3 Dec 2019 15:45:13 +0800 Message-ID: <20191203074513.9416-7-james.tai@realtek.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191203074513.9416-1-james.tai@realtek.com> References: <20191203074513.9416-1-james.tai@realtek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191202_234542_048569_973CC2DC X-CRM114-Status: UNSURE ( 9.21 ) X-CRM114-Notice: Please train this message. X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [211.75.126.72 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , devicetree@vger.kernel.org, cylee12 , linux-realtek-soc@lists.infradead.org, Stephen Boyd , Michael Turquette , Palmer Dabbelt , linux-kernel@vger.kernel.org, Rob Herring , linux-mediatek@lists.infradead.org, Paul Walmsley , Matthias Brugger , linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org From: cylee12 Signed-off-by: Cheng-Yu Lee Signed-off-by: James Tai --- .../bindings/clock/realtek,clocks.txt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/realtek,clocks.txt diff --git a/Documentation/devicetree/bindings/clock/realtek,clocks.txt b/Documentation/devicetree/bindings/clock/realtek,clocks.txt new file mode 100644 index 000000000000..db101508ac6a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/realtek,clocks.txt @@ -0,0 +1,38 @@ +Realtek Clock/Reset Controller +============================== + +Realtek CRT/ISO controller device-tree binding for Realtek Platforms. + +This binding uses the common clock binding[1]. + +The controller node should be the child of a syscon node with the required +propertise: + +- compatible : + should contain only one of the following: + "realtek,rtd1619-cc" for RTD1619 CRT clock controller, + "realtek,rtd1619-ic" for RTD1619 ISO clock controller, + +- #clock-cells : should be 1. + +- #reset-cells : should be 1. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Example: + + crt@98000000 { + compatible = "realtek,rtd1619-crt", "simple-mfd", "syscon"; + reg = <0x98000000 0x1000>; + + cc: cc@98000000 { + compatible = "realtek,rtd1619-cc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + }; + + consumer { + clocks = <&cc CC_CKE_GSPI>; + }; +