Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp3817022pxk; Tue, 8 Sep 2020 03:22:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwcgY1mFmFCTPmwyrZHkfzFGPoRfvnDXFAdm7WRzqCMC4S+TDdZJrT3Sp0aAXDxxZ9+geVH X-Received: by 2002:a17:906:3785:: with SMTP id n5mr26688799ejc.218.1599560523459; Tue, 08 Sep 2020 03:22:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599560523; cv=none; d=google.com; s=arc-20160816; b=wRc24h5Rqwk4iuOogkXIqTcfKNzm6BsgtFQ+xp41va54KrsBzbDuaCIxShaUK4dV/M aDTX8MvxHZ1D0FAI3mZ4HDC97oRUX0ZNIxx69NdloSffNd5Of28Cej+5SVuHmMmmpITx 4Sj1fuKnJpb0vVt/y0CtXnSieOAuzWThbtcwAWQ4ZNa5TNMLUpurb2h9sM9bJpUovngt u3hrSTTQkTK6WcmbMDbP7qJwXzxg0copRbSkTfws8OQVCHjQugLAtM4iDABafKi3Zh3K /MLFEYmBsepOmkc9Sn5ysjZhGLVJyXOMTPOhr2HlbNlqBtrIEKbhZKI1gjt+nXtYEuyS F0OA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=/gcms00Xxicy2/O0lwb7rlP4y2a2QcspxkTdndzvLjg=; b=W9TyAzIiyBl93HFXqT/Vn+x3M4CkNpK4R3MeA74YFUhIuMuoKxzvEg4CCaKxBl+mT7 1ZK0VofRIb8Vo/LPSMS4WCy+u8WM7otfVG/FjH+BJ3ttso6pWxaDcsTPxGGQUtNAxcqw HJ1uyA2Nc1P9pwEZ4ojxCZFPniO5XuplxBtyco0UIdtVk5o2FJSAKGigY33c4qH6du8i uIvW+XeLjz+JdoInMDwQokP5B08BUV8gmNGoUIx9Xn26XY6oXXbwheuCy74pjqqDP7Gw 2/UGIJ0BXDxom9659YT+EC+7TBkNDGatsNydspNYfM5AOrmvgFQzGGruepOHNuZiQsN/ a10w== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mb24si11263999ejb.583.2020.09.08.03.21.40; Tue, 08 Sep 2020 03:22:03 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729341AbgIHKTI (ORCPT + 99 others); Tue, 8 Sep 2020 06:19:08 -0400 Received: from inva021.nxp.com ([92.121.34.21]:47652 "EHLO inva021.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729285AbgIHKTB (ORCPT ); Tue, 8 Sep 2020 06:19:01 -0400 Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 8C889201599; Tue, 8 Sep 2020 12:18:59 +0200 (CEST) Received: from inva024.eu-rdc02.nxp.com (inva024.eu-rdc02.nxp.com [134.27.226.22]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 41D7620158D; Tue, 8 Sep 2020 12:18:59 +0200 (CEST) Received: from localhost (fsr-ub1664-175.ea.freescale.net [10.171.82.40]) by inva024.eu-rdc02.nxp.com (Postfix) with ESMTP id 78C302036D; Tue, 8 Sep 2020 12:18:58 +0200 (CEST) Date: Tue, 8 Sep 2020 13:18:58 +0300 From: Abel Vesa To: peng.fan@nxp.com Cc: sboyd@kernel.org, shawnguo@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com, kernel@pengutronix.de, linux-imx@nxp.com, Anson.Huang@nxp.com, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, aisheng.dong@nxp.com Subject: Re: [PATCH] clk: imx: lpcg-scu: SW workaround for errata (e10858) Message-ID: <20200908101858.kiuzcnc6rolbbyma@fsr-ub1664-175> References: <1599556487-31364-1-git-send-email-peng.fan@nxp.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1599556487-31364-1-git-send-email-peng.fan@nxp.com> User-Agent: NeoMutt/20180622 X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 20-09-08 17:14:47, peng.fan@nxp.com wrote: > From: Peng Fan > > Back-to-back LPCG writes can be ignored by the LPCG register due to > a HW bug. The writes need to be separated by at least 4 cycles of > the gated clock. > > The workaround is implemented as follows: > 1. For clocks running greater than or equal to 24MHz, a read > followed by the write will provide sufficient delay. > 2. For clocks running below 24MHz, add a delay of 4 clock cylces > after the write to the LPCG register. > > Signed-off-by: Peng Fan > --- > drivers/clk/imx/clk-lpcg-scu.c | 31 +++++++++++++++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c > index 1f0e44f921ae..6ee9d2caedf2 100644 > --- a/drivers/clk/imx/clk-lpcg-scu.c > +++ b/drivers/clk/imx/clk-lpcg-scu.c > @@ -6,6 +6,7 @@ > > #include > #include > +#include > #include > #include > #include > @@ -38,6 +39,31 @@ struct clk_lpcg_scu { > > #define to_clk_lpcg_scu(_hw) container_of(_hw, struct clk_lpcg_scu, hw) > > +/* e10858 -LPCG clock gating register synchronization errata */ > +static void do_lpcg_workaround(u32 rate, void __iomem *reg, u32 val) > +{ > + writel(val, reg); > + > + if (rate >= 24000000 || rate == 0) { > + u32 reg1; > + > + /* > + * The time taken to access the LPCG registers from the AP core > + * through the interconnect is longer than the minimum delay > + * of 4 clock cycles required by the errata. > + * Adding a readl will provide sufficient delay to prevent > + * back-to-back writes. > + */ > + reg1 = readl(reg); > + } else { > + /* > + * For clocks running below 24MHz, wait a minimum of > + * 4 clock cycles. > + */ > + ndelay(4 * (DIV_ROUND_UP(1000000000, rate))); > + } Just to make sure this is totally understood, if the lpcg consumer needs to two enables/disables in less than 4 multiplied by the clock period, the second enable/disable will be delayed. If we're fine with this, then here is my R-b. Reviewed-by: Abel Vesa > +} > + > static int clk_lpcg_scu_enable(struct clk_hw *hw) > { > struct clk_lpcg_scu *clk = to_clk_lpcg_scu(hw); > @@ -54,7 +80,8 @@ static int clk_lpcg_scu_enable(struct clk_hw *hw) > val |= CLK_GATE_SCU_LPCG_HW_SEL; > > reg |= val << clk->bit_idx; > - writel(reg, clk->reg); > + > + do_lpcg_workaround(clk_hw_get_rate(hw), clk->reg, reg); > > spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags); > > @@ -71,7 +98,7 @@ static void clk_lpcg_scu_disable(struct clk_hw *hw) > > reg = readl_relaxed(clk->reg); > reg &= ~(CLK_GATE_SCU_LPCG_MASK << clk->bit_idx); > - writel(reg, clk->reg); > + do_lpcg_workaround(clk_hw_get_rate(hw), clk->reg, reg); > > spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags); > } > -- > 2.28.0 >