From patchwork Sun Sep 17 22:40:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Bara X-Patchwork-Id: 13388729 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 4F136CD13CF for ; Sun, 17 Sep 2023 22:41:42 +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:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ZE4agfLAapUFaTLs2jlpJ5BTREylpIFfUR/6zudu6+M=; b=T9FFrp4cLVZNJo 0j1ptFB6LT4wERxNxVnXth4VmiVfugPibWInh0BbKeVRbxZdzCaDnjrztNV3JapyaV04JOWY80jKO 3eC4CAhAKEzkM19NrgDypaR4GLHLwbgVZIHlFINvlIS61UhW3TixX5znb+mCaz/tHk8j07SrOCoCR JkHQnSm61gg9mP9R8p6mctAnrRzYHtbIOaNZhK5eltgGaMAJRG47JSjtUYKhh4Qb+NpFPd+0QVmMB G17asYpaEohqR2wNL8bZXZTuThZFZgtnTTnseHIM4Znj2O5vKv7B0LguCexMS/d/co7q899LN8Dz3 CUU5dvzsulOBIc+Sq20Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qi0S4-00E5M4-0N; Sun, 17 Sep 2023 22:41:16 +0000 Received: from mail-wm1-x32f.google.com ([2a00:1450:4864:20::32f]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qi0RW-00E50O-1J for linux-arm-kernel@lists.infradead.org; Sun, 17 Sep 2023 22:40:44 +0000 Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-402d499580dso42309955e9.1 for ; Sun, 17 Sep 2023 15:40:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694990441; x=1695595241; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=kviONp3xwBUSyMm3n9HmjGMrxjEliGN8QJc2qo9i9Gg=; b=R+nxmpqtVxEeM6PHqC02UkFXgXTClphe0jwsTTpuKPNyEdkMbQtW6/HyPb6vMIRz4K 3/UC7QKcohOuDThb86zFCZNszq41Q/FSVlyXFncSofaZJcufu5XbOUVAVUK1vNKMAkmo OkhDj+SRKzDkEnUpf369RGQdMV3hcV+szAvkSTeqabbbyZTO/z8NanP5geQMgPv3dXyY 4qa80+pKwJmdjcQVEuLrSKa7wiNpgDCzIBoRN7D3JUc2hqaXbfUFG56uJRuADCKLK+Ye BBPKn5hBY1Vw30bTrzQ/rILOaWubxkvjOltSQYAMjeAll97MZTOikbdHBVHDVDQw6Hr3 OMRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694990441; x=1695595241; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kviONp3xwBUSyMm3n9HmjGMrxjEliGN8QJc2qo9i9Gg=; b=hn+6tD8YryK9z/yYUV7M7Wyhej2PQErOkIq2iK5oeFxzoEUu4iGEfzJlJvTy9pGmRY xfQG0iL6uQ12/CGIiO7ebLM7pwWI47vBoOLzeu7FpJ/6imMpiXco8bCgcaSX+Yp96Ss6 c/aRjy1DYQINx3FqVSMEzqegSGbjB4Zt9F7Cfwfx3TMFNeEem7PQnUgVHyWHbsZKov2E fI8MaduduJXFpGI6CBxam6AwliWaRA4Wm3k+EOkxk1gwLjYC8pNyw79groBDjc/O0IcJ XM1JL6fCqoNsYX+S/qSS6DDZ9PKGrVeU4ICPzxIACLmpnkxdzmE7N9IWq3+A4TxI3PEF 9Lnw== X-Gm-Message-State: AOJu0Yz9EFIt+sO5AWlNiTC39e4y9DU/rFAa1nJ87EbPM9MG/o690yRj Z8AOhIuWv7XpE13mzqF2jzo= X-Google-Smtp-Source: AGHT+IGI9iHWZr7kzzg0eUkNH07Lgn024wjCqs9NAjnnhsL3UBw49Jv26TH9svgPt6bxfNSbTxu3XQ== X-Received: by 2002:a1c:6a01:0:b0:401:b53e:6c3b with SMTP id f1-20020a1c6a01000000b00401b53e6c3bmr6295687wmc.6.1694990441025; Sun, 17 Sep 2023 15:40:41 -0700 (PDT) Received: from [127.0.1.1] ([91.230.2.244]) by smtp.gmail.com with ESMTPSA id x14-20020a1c7c0e000000b003fe2b081661sm13642931wmc.30.2023.09.17.15.40.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Sep 2023 15:40:40 -0700 (PDT) From: Benjamin Bara Date: Mon, 18 Sep 2023 00:40:07 +0200 Subject: [PATCH 11/13] clk: imx: composite-8m: implement CLK_SET_RATE_PARENT MIME-Version: 1.0 Message-Id: <20230918-imx8mp-dtsi-v1-11-1d008b3237c0@skidata.com> References: <20230918-imx8mp-dtsi-v1-0-1d008b3237c0@skidata.com> In-Reply-To: <20230918-imx8mp-dtsi-v1-0-1d008b3237c0@skidata.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Michael Turquette , Stephen Boyd , Russell King , Abel Vesa , Peng Fan Cc: Frank Oltmanns , Maxime Ripard , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Benjamin Bara X-Mailer: b4 0.12.3 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230917_154042_450310_ADFC439C X-CRM114-Status: GOOD ( 23.40 ) 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Benjamin Bara One of the key parts to enable dynamic clock propagation on the imx8m, are the consumer-facing composites. They currently only divide, therefore the parent must be already quite good in shape to provide a close enough rate. Therefore, the parents are usually hard-assigned in the dt. To workaround that, this commit enables propagation to the parent of the composite. If a rate cannot be reached exactly by only dividing, the parent is asked (for now simply for the exact required rate - no dividers taken into account). If the parent already has a configured rate, it's the parent's job to ensure that all children are satisfied. By using a notifier, the propagation-enabled clocks listen to clock changes coming from the parent. If one is happening, it's the composites job to verify if the rate is satisfying and if it is an intended change. Otherwise, countermeasures have to be taken into account (e.g. setting the rate back or aborting the change). Signed-off-by: Benjamin Bara --- drivers/clk/imx/clk-composite-8m.c | 71 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index a121f1285110..068f61df28b1 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -119,8 +120,12 @@ static int imx8m_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_divider *divider = to_clk_divider(hw); + struct clk_hw *parent = clk_hw_get_parent(hw); int prediv_value; int div_value; + unsigned long target_rate; + struct clk_rate_request req_parent; + int ret; /* if read only, just return current value */ if (divider->flags & CLK_DIVIDER_READ_ONLY) { @@ -140,9 +145,29 @@ static int imx8m_divider_determine_rate(struct clk_hw *hw, divider->flags, prediv_value * div_value); } - return divider_determine_rate(hw, req, divider->table, - PCG_PREDIV_WIDTH + PCG_DIV_WIDTH, - divider->flags); + target_rate = req->rate; + ret = divider_determine_rate(hw, req, divider->table, + PCG_PREDIV_WIDTH + PCG_DIV_WIDTH, + divider->flags); + if (ret || req->rate == target_rate) + return ret; + + /* + * If re-configuring the parent gives a better rate, do this instead. + * Avoid re-parenting for now, which could be done first if a possible + * parent already has a satisfying rate. The implementation does not + * consider the dividers between the parent and the current clock. + */ + clk_hw_forward_rate_request(hw, req, parent, &req_parent, target_rate); + if (__clk_determine_rate(parent, &req_parent)) + return 0; + + if (abs(req_parent.rate - target_rate) < abs(req->rate - target_rate)) { + req->rate = req_parent.rate; + req->best_parent_rate = req_parent.rate; + } + + return 0; } static const struct clk_ops imx8m_clk_composite_divider_ops = { @@ -198,6 +223,33 @@ static const struct clk_ops imx8m_clk_composite_mux_ops = { .determine_rate = imx8m_clk_composite_mux_determine_rate, }; +static int imx8m_clk_composite_notifier_fn(struct notifier_block *notifier, + unsigned long code, void *data) +{ + struct clk_notifier_data *cnd = data; + struct clk_hw *hw = __clk_get_hw(cnd->clk); + + if (code != PRE_RATE_CHANGE) + return NOTIFY_OK; + + if (!__clk_is_rate_set(cnd->clk)) + return NOTIFY_OK; + + /* + * Consumer of a composite-m8 clock usually use the root clk, a gate + * connected to the composite (e.g. media_ldb and media_ldb_root). + * Therefore, evaluate the trigger's parent too. + */ + if (cnd->clk != cnd->trigger && cnd->clk != clk_get_parent(cnd->trigger)) + return notifier_from_errno(clk_hw_set_rate(hw, cnd->old_rate)); + + return NOTIFY_OK; +} + +static struct notifier_block imx8m_clk_composite_notifier = { + .notifier_call = imx8m_clk_composite_notifier_fn, +}; + struct clk_hw *__imx8m_clk_hw_composite(const char *name, const char * const *parent_names, int num_parents, void __iomem *reg, @@ -211,6 +263,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, struct clk_mux *mux = NULL; const struct clk_ops *divider_ops; const struct clk_ops *mux_ops; + int ret; mux = kzalloc(sizeof(*mux), GFP_KERNEL); if (!mux) @@ -268,6 +321,18 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, if (IS_ERR(hw)) goto fail; + /* + * register a notifier which should switch back to the configured rate + * if the rate is going to be changed unintentionally. + */ + if (flags & CLK_SET_RATE_PARENT) { + ret = clk_notifier_register(hw->clk, &imx8m_clk_composite_notifier); + if (ret) { + hw = ERR_PTR(ret); + goto fail; + } + } + return hw; fail: