From patchwork Tue Dec 9 07:58:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anson Huang X-Patchwork-Id: 5460751 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id AA6619F1CD for ; Tue, 9 Dec 2014 08:05:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6D74D2015A for ; Tue, 9 Dec 2014 08:05:18 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E36312010F for ; Tue, 9 Dec 2014 08:05:16 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XyFkl-0003x1-Sv; Tue, 09 Dec 2014 08:02:39 +0000 Received: from mail-bn1bon0118.outbound.protection.outlook.com ([157.56.111.118] helo=na01-bn1-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XyFki-0003sf-U4 for linux-arm-kernel@lists.infradead.org; Tue, 09 Dec 2014 08:02:38 +0000 Received: from CH1PR03CA002.namprd03.prod.outlook.com (10.255.156.147) by BN1PR0301MB0625.namprd03.prod.outlook.com (25.160.170.28) with Microsoft SMTP Server (TLS) id 15.1.31.17; Tue, 9 Dec 2014 08:02:12 +0000 Received: from BN1AFFO11FD052.protection.gbl (10.255.156.132) by CH1PR03CA002.outlook.office365.com (10.255.156.147) with Microsoft SMTP Server (TLS) id 15.1.31.17 via Frontend Transport; Tue, 9 Dec 2014 08:02:11 +0000 Received: from tx30smr01.am.freescale.net (192.88.168.50) by BN1AFFO11FD052.mail.protection.outlook.com (10.58.53.67) with Microsoft SMTP Server (TLS) id 15.1.26.17 via Frontend Transport; Tue, 9 Dec 2014 08:02:12 +0000 Received: from ubuntu.ap.freescale.net (ubuntu-010192242118.ap.freescale.net [10.192.242.118]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id sB9826eS020383; Tue, 9 Dec 2014 01:02:08 -0700 From: Anson Huang To: , , Subject: [PATCH] arm: imx: correct the hardware clock gate setting for shared nodes Date: Tue, 9 Dec 2014 15:58:05 +0800 Message-ID: <1418111885-3623-1-git-send-email-b20788@freescale.com> X-Mailer: git-send-email 1.7.9.5 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:192.88.168.50; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(189002)(199003)(92566001)(89996001)(77096005)(84676001)(105606002)(50226001)(4396001)(68736005)(6806004)(46102003)(31966008)(19580405001)(2201001)(87936001)(106466001)(50986999)(48376002)(99396003)(229853001)(64706001)(50466002)(107886001)(97736003)(21056001)(47776003)(33646002)(104016003)(20776003)(36756003)(19580395003)(107046002)(77156002)(120916001)(62966003)(42262002); DIR:OUT; SFP:1102; SCL:1; SRVR:BN1PR0301MB0625; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; MLV:sfv; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Antispam: UriScan:; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;SRVR:BN1PR0301MB0625; X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(602002); SRVR:BN1PR0301MB0625; X-Forefront-PRVS: 0420213CCD Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=Anson.Huang@freescale.com; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:; SRVR:BN1PR0301MB0625; X-OriginatorOrg: freescale.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141209_000237_213015_9F5B8F2F X-CRM114-Status: UNSURE ( 8.80 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -0.0 (/) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP For those clk gates which hold share count, since its is_enabled callback is only checking the share count rather than reading the hardware register setting, in the late phase of kernel bootup, the clk_disable_unused action will NOT handle the scenario of share_count is 0 but the hardware setting is enabled, actually, uboot normally enables all clk gates, then those shared clk gates will be always enabled until they are used by some modules. So the problem would be: when kernel boot up, the usecount cat from clk tree is 0, but the clk gates actually is enabled in hardware register, it will confuse user and bring unnecessary power consumption, take i.MX6SX for example, the ESAI clk info is as below, the use count is 0, but the hardware register read from CCM_CCGR1_CG8 is ungated. cat /sys/kernel/debug/clk/clk_summary | grep esai esai_sel 0 0 393216000 0 0 esai_pred 0 0 196608000 0 0 esai_podf 0 0 24576000 0 0 esai_extal 0 0 24576000 0 0 esai_mem 0 0 132000000 0 0 esai_ipg 0 0 132000000 0 0 Read CCM_CCGR1: 0x020C406C: F33FFF00 This patch disables all those clk gates which hold share count before registering them, then the hardware status will match the clk tree info. Signed-off-by: Anson Huang --- arch/arm/mach-imx/clk-imx6q.c | 6 ++++++ arch/arm/mach-imx/clk-imx6sl.c | 2 ++ arch/arm/mach-imx/clk-imx6sx.c | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 5951660..fe53473 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -369,6 +369,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) /* name parent_name reg shift */ clk[IMX6QDL_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); + /* make sure the initial clock gate setting of share_count is off */ + writel_relaxed(readl_relaxed(base + 0x68) & (~(0x3 << 6)), base + 0x68); clk[IMX6QDL_CLK_ASRC] = imx_clk_gate2_shared("asrc", "asrc_podf", base + 0x68, 6, &share_count_asrc); clk[IMX6QDL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); clk[IMX6QDL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); @@ -385,6 +387,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) else clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10); + /* make sure the initial clock gate setting of share_count is off */ + writel_relaxed(readl_relaxed(base + 0x6c) & (~(0x3 << 16)), base + 0x6c); clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ipg", base + 0x6c, 16, &share_count_esai); clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); @@ -443,6 +447,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); + /* make sure the initial clock gate setting of share_count is off */ + writel_relaxed(readl_relaxed(base + 0x7c) & (~(0x3f << 18)), base + 0x7c); clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index e982ebe..6af14a8 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -396,6 +396,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6); clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14); + /* make sure the initial clock gate setting of share_count is off */ + writel_relaxed(readl_relaxed(base + 0x7c) & (~(0x3f << 18)), base + 0x7c); clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c index 17354a1..e42052e 100644 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ b/arch/arm/mach-imx/clk-imx6sx.c @@ -379,6 +379,8 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); + /* make sure the initial clock gate setting of share_count is off */ + writel_relaxed(readl_relaxed(base + 0x68) & (~(0x3 << 6)), base + 0x68); clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); clks[IMX6SX_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8); @@ -400,6 +402,8 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_podf", base + 0x6c, 8); clks[IMX6SX_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12); clks[IMX6SX_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14); + /* make sure the initial clock gate setting of share_count is off */ + writel_relaxed(readl_relaxed(base + 0x6c) & (~(0x3 << 16)), base + 0x6c); clks[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); clks[IMX6SX_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); clks[IMX6SX_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); @@ -455,6 +459,8 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); + /* make sure the initial clock gate setting of share_count is off */ + writel_relaxed(readl_relaxed(base + 0x7c) & (~(0x3 << 14)) & (~(0x3f << 18)), base + 0x7c); clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);