Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp3648201pxf; Mon, 29 Mar 2021 07:51:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw5TubZ6gtCkzJzpJO7xwVi0M6FBeNm8xu/c6Kuj7eEjZYupeG/YutvTLBtNHWYGk1K5XOJ X-Received: by 2002:a05:6402:4a:: with SMTP id f10mr3784084edu.85.1617029479715; Mon, 29 Mar 2021 07:51:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617029479; cv=none; d=google.com; s=arc-20160816; b=Pl8m3oIPOBzhrcwehqnbQWvq8c16fIMRDsv37G4X2G4jCW8t46Gy6UhncsnD1NOIDc YoIBwNI28gVlpAUKphr52E3jM14bwC12fAx01pjuzQbAc0cKDsmMw6fLqlrVO4jcCkkj JeXSWWGkg21zBEJfwCIS5QwBnAJ+IcGYNtflPQ/fUhPtDkD+qnBn0MikUxsog7fU7u6v /LTx2Dszm+fO8FPHm1utLhlmDwCb4JJxMKKzk/0ky/a94+ZI0SvSh915pn8Sklt85Pig M66cfzO+ZL0p7BJzoGTCEdOZdFD/JRRNSVyeFx8yiZ99QMXyK5CxaaDnCB49llS+bPm6 u6lQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:references:in-reply-to:subject:cc:to:from; bh=8p0F9yDtqI9yZcK96GV50+YBMpz9MSehDiwa+pbrL08=; b=ZKQo1T4Dx8Hha94ovZ24HWvUCUUMZx+LCKNF9YV55VfkCDouAjRbYPc3SIbDeCmkCv 6cv/ZAPb3d2M9XFxDK5pDj2tgjPb+mDe7BkhRib1jkalh5KYXc0OUJ0YEzbqrZT58+gG SqtRSM0GznUPXfX0Mc0rosTEOYyl6HGaskDYNFVrzp8mIoWrkS2W8AkA61rIqfgZZ26j ii0WJOQ350Y6z1arTN7Co2M8S/SpEU2l2repCrCM7umnPFZ2L908VEZf82iCp1wWTUkL dc0eh0FiN0Dktj5O95PUDiporsDv1BG2xHAKwLhjXz+IjrvGT/ZjGA335aS3QfUQbrdw iHSA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x21si14035818ejb.180.2021.03.29.07.50.56; Mon, 29 Mar 2021 07:51:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231388AbhC2Ota convert rfc822-to-8bit (ORCPT + 99 others); Mon, 29 Mar 2021 10:49:30 -0400 Received: from relay10.mail.gandi.net ([217.70.178.230]:52497 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231314AbhC2OtM (ORCPT ); Mon, 29 Mar 2021 10:49:12 -0400 Received: from localhost (91-175-115-186.subs.proxad.net [91.175.115.186]) (Authenticated sender: gregory.clement@bootlin.com) by relay10.mail.gandi.net (Postfix) with ESMTPSA id C086324000F; Mon, 29 Mar 2021 14:49:08 +0000 (UTC) From: Gregory CLEMENT To: Pali =?utf-8?Q?Roh=C3=A1r?= , Andrew Lunn , Michael Turquette , Stephen Boyd , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org Cc: Marek =?utf-8?Q?Beh=C3=BAn?= , Miquel Raynal , Tomasz Maciej Nowak , Luka Perkov , Andre Heider , Vladimir Vid , Russell King , =?utf-8?Q?G=C3=A9rald?= Kerma , Konstantin Porotchkin Subject: Re: [PATCH mvebu v3 06/10] clk: mvebu: armada-37xx-periph: Fix workaround for switching from L1 to L0 In-Reply-To: <20210222194158.12342-7-pali@kernel.org> References: <20210114124032.12765-1-pali@kernel.org> <20210222194158.12342-1-pali@kernel.org> <20210222194158.12342-7-pali@kernel.org> Date: Mon, 29 Mar 2021 16:49:08 +0200 Message-ID: <87v99adnh7.fsf@BL-laptop> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Pali Rohár writes: > When CPU frequency is at 250 MHz and set_rate() is called with 500 MHz (L1) > quickly followed by a call with 1 GHz (L0), the CPU does not necessarily > stay in L1 for at least 20ms as is required by Marvell errata. > > This situation happens frequently with the ondemand cpufreq governor and > can be also reproduced with userspace governor. In most cases it causes CPU > to crash. > > This change fixes the above issue and ensures that the CPU always stays in > L1 for at least 20ms when switching from any state to L0. > > Signed-off-by: Marek Behún > Signed-off-by: Pali Rohár > Acked-by: Stephen Boyd > Tested-by: Tomasz Maciej Nowak > Tested-by: Anders Trier Olesen > Tested-by: Philip Soares > Fixes: 61c40f35f5cd ("clk: mvebu: armada-37xx-periph: Fix switching CPU rate from 300Mhz to 1.2GHz") > Cc: stable@vger.kernel.org Acked-by: Gregory CLEMENT Thanks, Gregory > --- > drivers/clk/mvebu/armada-37xx-periph.c | 45 ++++++++++++++++++++++---- > 1 file changed, 39 insertions(+), 6 deletions(-) > > diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c > index b15e177bea7e..32ac6b6b7530 100644 > --- a/drivers/clk/mvebu/armada-37xx-periph.c > +++ b/drivers/clk/mvebu/armada-37xx-periph.c > @@ -84,6 +84,7 @@ struct clk_pm_cpu { > void __iomem *reg_div; > u8 shift_div; > struct regmap *nb_pm_base; > + unsigned long l1_expiration; > }; > > #define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw) > @@ -504,22 +505,52 @@ static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate, > * 2. Sleep 20ms for stabling VDD voltage > * 3. Then switch from L1 (500/600 MHz) to L0 (1000/1200 MHz). > */ > -static void clk_pm_cpu_set_rate_wa(unsigned long rate, struct regmap *base) > +static void clk_pm_cpu_set_rate_wa(struct clk_pm_cpu *pm_cpu, > + unsigned int new_level, unsigned long rate, > + struct regmap *base) > { > unsigned int cur_level; > > - if (rate < 1000 * 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) > + > + if (cur_level == new_level) > + return; > + > + /* > + * System wants to go to L1 on its own. If we are going from L2/L3, > + * remember when 20ms will expire. If from L0, set the value so that > + * next switch to L0 won't have to wait. > + */ > + if (new_level == ARMADA_37XX_DVFS_LOAD_1) { > + if (cur_level == ARMADA_37XX_DVFS_LOAD_0) > + pm_cpu->l1_expiration = jiffies; > + else > + pm_cpu->l1_expiration = jiffies + msecs_to_jiffies(20); > return; > + } > + > + /* > + * If we are setting to L2/L3, just invalidate L1 expiration time, > + * sleeping is not needed. > + */ > + if (rate < 1000*1000*1000) > + goto invalidate_l1_exp; > + > + /* > + * We are going to L0 with rate >= 1GHz. Check whether we have been at > + * L1 for long enough time. If not, go to L1 for 20ms. > + */ > + if (pm_cpu->l1_expiration && jiffies >= pm_cpu->l1_expiration) > + goto invalidate_l1_exp; > > regmap_update_bits(base, ARMADA_37XX_NB_CPU_LOAD, > ARMADA_37XX_NB_CPU_LOAD_MASK, > ARMADA_37XX_DVFS_LOAD_1); > msleep(20); > + > +invalidate_l1_exp: > + pm_cpu->l1_expiration = 0; > } > > static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate, > @@ -553,7 +584,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); > + /* Apply workaround when base CPU frequency is 1000 or 1200 MHz */ > + if (parent_rate >= 1000*1000*1000) > + clk_pm_cpu_set_rate_wa(pm_cpu, load_level, rate, base); > > regmap_update_bits(base, reg, mask, load_level); > > -- > 2.20.1 > -- Gregory Clement, Bootlin Embedded Linux and Kernel engineering http://bootlin.com