From patchwork Tue Jun 19 12:34:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregory CLEMENT X-Patchwork-Id: 10474219 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0CB1F6029B for ; Tue, 19 Jun 2018 12:38:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EAA8B28B8A for ; Tue, 19 Jun 2018 12:38:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D561128B8F; Tue, 19 Jun 2018 12:38:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 77E7B28B8A for ; Tue, 19 Jun 2018 12:38:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: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=0m002zjchyeJT2swRMnrgb0+YDYg6RSF7bPJKoUUN/c=; b=ZDKg91sHpoejbomhtrvBtza49c ODXrldu6Vfa8zWKUnq5x+mmLPPcs+rp7N3HDP3TWx+r/IT2Ea3CTlX5klSxZm8jvNea70Kv0WCB9q x7lPr1J34TfnQ8S3TbxEIoHv33HvX9hfBzF9YXDw49tge5Cuj6f9dsRpomWdG9GLYU7qi0ri+5caz +Ih8x4+OOlSvTlAq53JRNzJfN9sUl2MLnpcheekk9MAnPfJZEUroH+jvtRBPhj1TohGFsiUUlQkYF VUS5bZ6g311aeY/l5iQ3cWyb/7N6v+mMQj61twUCWVmQMc2HduWoNlEI72b1A4qOKbWCaAsx21kq7 LwBtx3Nw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fVFtc-000390-Fs; Tue, 19 Jun 2018 12:38:04 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fVFrW-00023t-A2 for linux-arm-kernel@bombadil.infradead.org; Tue, 19 Jun 2018 12:35:54 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=NW270vF3IICGZPnQ4JtzoxHffJalhu3SMBF3KpeDQaA=; b=TjUI5tRuMJjvKjIowUBjVAmG3 gwtADwVOweGwpOhviO3tMnFV4AfifsJk+szDHAIlmxReOlG7NJXxaTYZQqVBZLBKee+5OSQh/RZEy tvkYSDcOQF4I9+/+A87sHNw/O+eHcOz1k8lG9xEYHs8DPz3Y7X3uXB+nOUkfmb/IP95Hua5TmjIHr Af4pv5CHtIjYpTFL04S/GHvTFTFLYJw3BkDJSSTw/VRqY+Af/bu2H97k+K41txrMcJiemDshixlbt iqVfsEUAn1YIBexlE7WG9JVZCcFPPw2SJFFGAIXQfu6lBIcSVQ31dF2yautuX39sERfAZbBrw+/nQ fUb8z9KOA==; Received: from mail.bootlin.com ([62.4.15.54]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fVFrO-0000fU-B8 for linux-arm-kernel@lists.infradead.org; Tue, 19 Jun 2018 12:35:50 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 6660A2079D; Tue, 19 Jun 2018 14:35:28 +0200 (CEST) Received: from localhost (87-231-134-186.rev.numericable.fr [87.231.134.186]) by mail.bootlin.com (Postfix) with ESMTPSA id 2A6AA2079D; Tue, 19 Jun 2018 14:35:18 +0200 (CEST) From: Gregory CLEMENT To: Stephen Boyd , Mike Turquette , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] clk: mvebu: armada-37xx-periph: Fix switching CPU rate from 300Mhz to 1.2GHz Date: Tue, 19 Jun 2018 14:34:45 +0200 Message-Id: <20180619123446.694-2-gregory.clement@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180619123446.694-1-gregory.clement@bootlin.com> References: <20180619123446.694-1-gregory.clement@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180619_083546_644706_79427325 X-CRM114-Status: GOOD ( 13.51 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Lunn , Jason Cooper , Hua Jing , Antoine Tenart , Gregory CLEMENT , stable@vger.kernel.org, Maxime Chevallier , Nadav Haklai , Ken Ma , Victor Gu , Neta Zur Hershkovits , Thomas Petazzoni , =?UTF-8?q?Miqu=C3=A8l=20Raynal?= , Marcin Wojtas , Wilson Ding , linux-arm-kernel@lists.infradead.org, Sebastian Hesselbarth MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz respectively) to L0 frequency (1.2 Ghz) requires a significant amount of time to let VDD stabilize to the appropriate voltage. This amount of time is large enough that it cannot be covered by the hardware countdown register. Due to this, the CPU might start operating at L0 before the voltage is stabilized, leading to CPU stalls. To work around this problem, we prevent switching directly from the L2/L3 frequencies to the L0 frequency, and instead switch to the L1 frequency in-between. The sequence therefore becomes: 1. First switch from L2/L3(200/300MHz) to L1(600MHZ) 2. Sleep 20ms for stabling VDD voltage 3. Then switch from L1(600MHZ) to L0(1200Mhz). It is based on the work done by Ken Ma Cc: stable@vger.kernel.org Fixes: 2089dc33ea0e ("clk: mvebu: armada-37xx-periph: add DVFS support for cpu clocks") Signed-off-by: Gregory CLEMENT --- drivers/clk/mvebu/armada-37xx-periph.c | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 6860bd5a37c5..44e4e27eddad 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -35,6 +35,7 @@ #define CLK_SEL 0x10 #define CLK_DIS 0x14 +#define ARMADA_37XX_DVFS_LOAD_1 1 #define LOAD_LEVEL_NR 4 #define ARMADA_37XX_NB_L0L1 0x18 @@ -507,6 +508,40 @@ static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate, return -EINVAL; } +/* + * Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz + * respectively) to L0 frequency (1.2 Ghz) requires a significant + * amount of time to let VDD stabilize to the appropriate + * voltage. This amount of time is large enough that it cannot be + * covered by the hardware countdown register. Due to this, the CPU + * might start operating at L0 before the voltage is stabilized, + * leading to CPU stalls. + * + * To work around this problem, we prevent switching directly from the + * L2/L3 frequencies to the L0 frequency, and instead switch to the L1 + * frequency in-between. The sequence therefore becomes: + * 1. First switch from L2/L3(200/300MHz) to L1(600MHZ) + * 2. Sleep 20ms for stabling VDD voltage + * 3. Then switch from L1(600MHZ) to L0(1200Mhz). + */ +static void clk_pm_cpu_set_rate_wa(unsigned long rate, struct regmap *base) +{ + unsigned int cur_level; + + if (rate != 1200 * 1000 * 1000) + return; + + regmap_read(base, ARMADA_37XX_NB_CPU_LOAD, &cur_level); + cur_level &= ARMADA_37XX_NB_CPU_LOAD_MASK; + if (cur_level <= ARMADA_37XX_DVFS_LOAD_1) + return; + + regmap_update_bits(base, ARMADA_37XX_NB_CPU_LOAD, + ARMADA_37XX_NB_CPU_LOAD_MASK, + ARMADA_37XX_DVFS_LOAD_1); + msleep(20); +} + static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -537,6 +572,9 @@ static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate, */ reg = ARMADA_37XX_NB_CPU_LOAD; mask = ARMADA_37XX_NB_CPU_LOAD_MASK; + + clk_pm_cpu_set_rate_wa(rate, base); + regmap_update_bits(base, reg, mask, load_level); return rate;