From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 0C1A2ECAAD5 for ; Fri, 2 Sep 2022 18:36:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=qpY0c9XZjw0nYFvVNvee4Qr8YoGov6hKvFWouHpQctM=; b=b7IFCqav329YxV oWVCDfVjp346kF6DG0cjPWyL7FIj/EbiYO/g1I1i7JsNZfBTDhF94IrUS04rBvHTSviBe/voJlLgF CK0hFQG+FfkXgvI4R10fg2BABbFVYoZWFXvnZavWu4kEHsTjesir6eMPrtRmR5Tysa+pY5eRseg21 ESaF6o9sC31ml8nRr++IqslfP1Dr6UjafIztf80ookrRUX8rouoe4YGd+rFZHCYHFbRPZcy7rC8tN HphCJwE0YItkodm5ADC9W7uvG5Dnw3IxvU9XMtEYVyLS90J/dgqV/Ld5Yqeod3+5UCKJIoPjyDP5N 3e/Hu1NRqKJ0sCO3kH2w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oUBVz-009XIT-K0; Fri, 02 Sep 2022 18:35:40 +0000 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oUBVw-009XDt-45 for linux-arm-kernel@lists.infradead.org; Fri, 02 Sep 2022 18:35:38 +0000 Received: by mail-wm1-x32d.google.com with SMTP id k6-20020a05600c1c8600b003a54ecc62f6so1900674wms.5 for ; Fri, 02 Sep 2022 11:35:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date; bh=niZAHKVh64gtpmzwpJTHnkg94O+WeGO3E9/49vCP0mA=; b=KGaF25aS6brzj8URuVZeFP9rO1UyJxrpOFwN9UA4rbWoaVH9qCwhIHdYWTZJW0oAIp xJBxiV2BIwxtaqraqmsYxbM26W3V0QZMaCfcl6tndme3rRpBW4CfQvCyM9L00UGZlAXb EE7ntVWHkhQ5AFTLs2OY6Wmf7Hkzgn6+IZBwamDWRojcHvRAmSpecNr0IR9SQeizodRd zEF0N8l+Eq2SX4pBHKxAuQHL/JCoNnCRIzavlId59NPkFXEuJ7dji93J4qJr8XvHuT2R H0nquuF4spF/wwUlUA94bSY/jkvplhwtI4Sg4jfLLyclQGqkhHBOSq86K91DqTHKNbYj uz/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date; bh=niZAHKVh64gtpmzwpJTHnkg94O+WeGO3E9/49vCP0mA=; b=Ick+XsMe1P3drfD36BI+F/2PltCJ1y1VfwrYkYokBDB+XFRw86x2mcOVZBexXemGQ+ Y+OOdrU9Oo1Dn47y4vlFjtsUEVkW4Ojw2pesrzodusAyL5oaytsRZFqfoDVZ9nSq94zO BY6CRsHwnPASm9lO3konb3CodmDaveEzqfTBAk6/ZD7MznZqmEavbzYnsZcOLwFmmZdV 4p8A+JeU8yyir9pvJQrkR0WBe3Y6bole8g44PcBGAnigZyRvD7FWT5Kv6EpUqhnGuRbZ m56A9+PHCAbBGIUBd1gLzhWOXv4vuOangRh2jj+iPwZRB0/sckkeKR2pRCG8kqejcm0a DFPA== X-Gm-Message-State: ACgBeo3tI49Svr5usGiI4oun9vhI2kwk4zOdjH4lnEdmPxdlPecIplUD DHRVPfQXTbujHgFwU6lbZpUugg== X-Google-Smtp-Source: AA6agR49lqN/61WJGMQqgdnr+8m4C2M0Bm2h9QER8PqOK2QKNltoy1SikmTcmNCAFPtPvWhSme52Zw== X-Received: by 2002:a05:600c:3d05:b0:3a5:dd21:e201 with SMTP id bh5-20020a05600c3d0500b003a5dd21e201mr3773404wmb.132.1662143733350; Fri, 02 Sep 2022 11:35:33 -0700 (PDT) Received: from linaro.org ([94.52.112.99]) by smtp.gmail.com with ESMTPSA id m14-20020a5d56ce000000b00226d238be98sm2021494wrw.82.2022.09.02.11.35.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Sep 2022 11:35:32 -0700 (PDT) Date: Fri, 2 Sep 2022 21:35:28 +0300 From: Abel Vesa To: "Peng Fan (OSS)" Cc: abelvesa@kernel.org, mturquette@baylibre.com, sboyd@kernel.org, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Peng Fan , Ye Li , Jacky Bai Subject: Re: [PATCH V3 5/8] clk: imx: add i.MX93 clk gate Message-ID: References: <20220830033137.4149542-1-peng.fan@oss.nxp.com> <20220830033137.4149542-6-peng.fan@oss.nxp.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20220830033137.4149542-6-peng.fan@oss.nxp.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220902_113536_201566_D3A4DE8D X-CRM114-Status: GOOD ( 30.17 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On 22-08-30 11:31:34, Peng Fan (OSS) wrote: > From: Peng Fan > > i.MX93 LPCG is different from i.MX8M CCGR. Although imx_clk_hw_gate4_flags > is used here, it not strictly match i.MX93. i.MX93 has such design: > - LPCG_DIRECT use BIT0 as on/off gate when LPCG_AUTHEN CPU_LPM is 0 > - LPCG_LPM_CUR use BIT[2:0] as on/off gate when LPCG_AUTHEN CPU_LPM is 1 > > The current implementation suppose CPU_LPM is 0, and use LPCG_DIRECT > BIT[1:0] as on/off gate. Although BIT1 is touched, actually BIT1 is > reserved. > > And imx_clk_hw_gate4_flags use mask 0x3 to determine whether the clk > is enabled or not, but i.MX93 LPCG only use BIT0 to control when CPU_LPM > is 0. So clk disabled unused during kernel boot not able to gate off > the unused clocks. > > To match i.MX93 LPCG, introduce imx93_clk_gate. > > Signed-off-by: Peng Fan > Reviewed-by: Ye Li > Reviewed-by: Jacky Bai I'm OK with it. Reviewed-by: Abel Vesa > --- > drivers/clk/imx/Makefile | 2 +- > drivers/clk/imx/clk-gate-93.c | 199 ++++++++++++++++++++++++++++++++++ > drivers/clk/imx/clk.h | 4 + > 3 files changed, 204 insertions(+), 1 deletion(-) > create mode 100644 drivers/clk/imx/clk-gate-93.c > > diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile > index 88b9b9285d22..89fe72327788 100644 > --- a/drivers/clk/imx/Makefile > +++ b/drivers/clk/imx/Makefile > @@ -28,7 +28,7 @@ obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o > obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o > obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o > > -obj-$(CONFIG_CLK_IMX93) += clk-imx93.o > +obj-$(CONFIG_CLK_IMX93) += clk-imx93.o clk-gate-93.o > > obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o > clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \ > diff --git a/drivers/clk/imx/clk-gate-93.c b/drivers/clk/imx/clk-gate-93.c > new file mode 100644 > index 000000000000..ceb56b290394 > --- /dev/null > +++ b/drivers/clk/imx/clk-gate-93.c > @@ -0,0 +1,199 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright 2022 NXP > + * > + * Peng Fan > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "clk.h" > + > +#define DIRECT_OFFSET 0x0 > + > +/* > + * 0b000 - LPCG will be OFF in any CPU mode. > + * 0b100 - LPCG will be ON in any CPU mode. > + */ > +#define LPM_SETTING_OFF 0x0 > +#define LPM_SETTING_ON 0x4 > + > +#define LPM_CUR_OFFSET 0x1c > + > +#define AUTHEN_OFFSET 0x30 > +#define CPULPM_EN BIT(2) > +#define TZ_NS_SHIFT 9 > +#define TZ_NS_MASK BIT(9) > + > +#define WHITE_LIST_SHIFT 16 > + > +struct imx93_clk_gate { > + struct clk_hw hw; > + void __iomem *reg; > + u32 bit_idx; > + u32 val; > + u32 mask; > + spinlock_t *lock; > + unsigned int *share_count; > +}; > + > +#define to_imx93_clk_gate(_hw) container_of(_hw, struct imx93_clk_gate, hw) > + > +static void imx93_clk_gate_do_hardware(struct clk_hw *hw, bool enable) > +{ > + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); > + u32 val; > + > + val = readl(gate->reg + AUTHEN_OFFSET); > + if (val & CPULPM_EN) { > + val = enable ? LPM_SETTING_ON : LPM_SETTING_OFF; > + writel(val, gate->reg + LPM_CUR_OFFSET); > + } else { > + val = readl(gate->reg + DIRECT_OFFSET); > + val &= ~(gate->mask << gate->bit_idx); > + if (enable) > + val |= (gate->val & gate->mask) << gate->bit_idx; > + writel(val, gate->reg + DIRECT_OFFSET); > + } > +} > + > +static int imx93_clk_gate_enable(struct clk_hw *hw) > +{ > + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); > + unsigned long flags; > + > + spin_lock_irqsave(gate->lock, flags); > + > + if (gate->share_count && (*gate->share_count)++ > 0) > + goto out; > + > + imx93_clk_gate_do_hardware(hw, true); > +out: > + spin_unlock_irqrestore(gate->lock, flags); > + > + return 0; > +} > + > +static void imx93_clk_gate_disable(struct clk_hw *hw) > +{ > + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); > + unsigned long flags; > + > + spin_lock_irqsave(gate->lock, flags); > + > + if (gate->share_count) { > + if (WARN_ON(*gate->share_count == 0)) > + goto out; > + else if (--(*gate->share_count) > 0) > + goto out; > + } > + > + imx93_clk_gate_do_hardware(hw, false); > +out: > + spin_unlock_irqrestore(gate->lock, flags); > +} > + > +static int imx93_clk_gate_reg_is_enabled(struct imx93_clk_gate *gate) > +{ > + u32 val = readl(gate->reg + AUTHEN_OFFSET); > + > + if (val & CPULPM_EN) { > + val = readl(gate->reg + LPM_CUR_OFFSET); > + if (val == LPM_SETTING_ON) > + return 1; > + } else { > + val = readl(gate->reg); > + if (((val >> gate->bit_idx) & gate->mask) == gate->val) > + return 1; > + } > + > + return 0; > +} > + > +static int imx93_clk_gate_is_enabled(struct clk_hw *hw) > +{ > + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); > + unsigned long flags; > + int ret; > + > + spin_lock_irqsave(gate->lock, flags); > + > + ret = imx93_clk_gate_reg_is_enabled(gate); > + > + spin_unlock_irqrestore(gate->lock, flags); > + > + return ret; > +} > + > +static void imx93_clk_gate_disable_unused(struct clk_hw *hw) > +{ > + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); > + unsigned long flags; > + > + spin_lock_irqsave(gate->lock, flags); > + > + if (!gate->share_count || *gate->share_count == 0) > + imx93_clk_gate_do_hardware(hw, false); > + > + spin_unlock_irqrestore(gate->lock, flags); > +} > + > +static const struct clk_ops imx93_clk_gate_ops = { > + .enable = imx93_clk_gate_enable, > + .disable = imx93_clk_gate_disable, > + .disable_unused = imx93_clk_gate_disable_unused, > + .is_enabled = imx93_clk_gate_is_enabled, > +}; > + > +static const struct clk_ops imx93_clk_gate_ro_ops = { > + .is_enabled = imx93_clk_gate_is_enabled, > +}; > + > +struct clk_hw *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name, > + unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val, > + u32 mask, u32 domain_id, unsigned int *share_count) > +{ > + struct imx93_clk_gate *gate; > + struct clk_hw *hw; > + struct clk_init_data init; > + int ret; > + u32 authen; > + > + gate = kzalloc(sizeof(struct imx93_clk_gate), GFP_KERNEL); > + if (!gate) > + return ERR_PTR(-ENOMEM); > + > + gate->reg = reg; > + gate->lock = &imx_ccm_lock; > + gate->bit_idx = bit_idx; > + gate->val = val; > + gate->mask = mask; > + gate->share_count = share_count; > + > + init.name = name; > + init.ops = &imx93_clk_gate_ops; > + init.flags = flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE; > + init.parent_names = parent_name ? &parent_name : NULL; > + init.num_parents = parent_name ? 1 : 0; > + > + gate->hw.init = &init; > + hw = &gate->hw; > + > + authen = readl(reg + AUTHEN_OFFSET); > + if (!(authen & TZ_NS_MASK) || !(authen & BIT(WHITE_LIST_SHIFT + domain_id))) > + init.ops = &imx93_clk_gate_ro_ops; > + > + ret = clk_hw_register(dev, hw); > + if (ret) { > + kfree(gate); > + return ERR_PTR(ret); > + } > + > + return hw; > +} > +EXPORT_SYMBOL_GPL(imx93_clk_gate); > diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h > index 396a5ea75083..dd49f90110e8 100644 > --- a/drivers/clk/imx/clk.h > +++ b/drivers/clk/imx/clk.h > @@ -451,6 +451,10 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, > imx93_clk_composite_flags(name, parent_names, num_parents, reg, domain_id \ > CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) > > +struct clk_hw *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name, > + unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val, > + u32 mask, u32 domain_id, unsigned int *share_count); > + > struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name, > unsigned long flags, void __iomem *reg, u8 shift, u8 width, > u8 clk_divider_flags, const struct clk_div_table *table, > -- > 2.37.1 > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel