From patchwork Sun Oct 25 12:34:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 1387189 X-Patchwork-Delegate: lokeshvutla@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=libero.it Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=libero.it header.i=@libero.it header.a=rsa-sha256 header.s=s2014 header.b=LOJZMkVq; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CJy9x1WFXz9sTD for ; Sun, 25 Oct 2020 23:35:49 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 132E5824A8; Sun, 25 Oct 2020 13:35:13 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=libero.it Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=libero.it header.i=@libero.it header.b="LOJZMkVq"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9109E82474; Sun, 25 Oct 2020 13:35:08 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FORGED_SPF_HELO,FREEMAIL_FROM,SPF_HELO_PASS, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from libero.it (smtp-34.italiaonline.it [213.209.10.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4CF1A8247D for ; Sun, 25 Oct 2020 13:35:04 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=libero.it Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=dariobin@libero.it Received: from passgat-Modern-14-A10M.homenet.telecomitalia.it ([79.31.32.113]) by smtp-34.iol.local with ESMTPA id WfEbkQj5cmMFTWfElkuGc1; Sun, 25 Oct 2020 13:35:04 +0100 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1603629304; bh=DViWmR5jBZWDtQzVqsyAN4Q3FJbHjVFtR0xEhItxb34=; h=From; b=LOJZMkVqR83pHzMK0tTTgKmuiNO+JcTDaCnPZ15qoujztgePVAg3J19xR1Q1YOhfK kyto9YxDA/rJyx9CEA9EJFqNvTLSysQ07GiSA98GTcZH8zXz/bm47l33P7nJ1uQl74 s+0gILmjQea2qEgZBX0SrxAGZ85MPGhmOzGNiyMOOefjqMZ8fW0e05D3WVriR0az/W K+NPA9mKgqqjuqIih8WxrRA1gJYXopa+E9Tcq8r4Abq7HSxVJpTBVRLDRZhf9VXMJ/ lzi6Bnzl0kgrF7jRgnk3Ojzf+YcstuthtZzxs/oCf/C4t8T1HUi+xs7fWoQ1n6m4zb 9GBvfIesAWS2A== X-CNFS-Analysis: v=2.4 cv=KetsDSUD c=1 sm=1 tr=0 ts=5f9570f8 a=9myQFBeCGQ66/mXSe6vdPA==:117 a=9myQFBeCGQ66/mXSe6vdPA==:17 a=cm27Pg_UAAAA:8 a=pGLkceISAAAA:8 a=IxSEBPkUA9tbEvFmOecA:9 a=xmb-EsYY8bH0VWELuYED:22 From: Dario Binacchi To: u-boot@lists.denx.de Cc: Dario Binacchi , Chunfeng Yun , Jagan Teki , Lukasz Majewski , Patrick Delaunay , Ryder Lee , Sean Anderson , Simon Glass , Stephen Warren , Walter Lozano Subject: [PATCH v5 05/27] clk: add clk_round_rate() Date: Sun, 25 Oct 2020 13:34:28 +0100 Message-Id: <20201025123451.17579-6-dariobin@libero.it> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201025123451.17579-1-dariobin@libero.it> References: <20201025123451.17579-1-dariobin@libero.it> X-CMAE-Envelope: MS4xfOE7/OVTF4Y0hEO1Hcxv3PoK18C+gi3Hgj3yeNAD0HNnv4N7Vm1JgLQfPG/+1wdqpq1oL1GdeXHmpRuLJXw3jJ/iZzJpDaDGLNcQxuwNEhdtiYB9kWz9 IIgWFQGEDQZU65pR+DfDPCXerwL4kH2e6XN/22dXXJRpPcM4Wz60izk+jHE5BkohVJQdID6oWgb9U8Ay+BQFy7GsRPZyeZVkHnEFo0KZ6nXp1kFK8n/JN3ct lUtmHMI5v2SnEsv2B2VKpj2wQNhmIZIOzH0hZTrIQlyHmN1x9hJiKLxwbSz1B3d2d9KVILJSx9g4XRhCKU0WSJDbczU8mvx6DT6oOI8xQnjU7pEA45pYVXT3 ZOzCwqBUjNj+mVfk9tDVtlbgH93EF7z5D8lRN5P0efBmB94auQS1RG60Ab4C/hY7uhvz+lcJSQNUaBB525VHEyZ/7zmIhb17d7QDQ5gdLWWAjLoGqtiCJIqx ndUXg4kMoRc++nAw6qZb5ZNOX4wpHGubwuJlLWrsropUypZ6L+mNh0EHxbxB0Bf/XxAPO4BzBMZT7gvWl3ixx/Mkm/SHaFkqG3dlbw== X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean It returns the rate which will be set if you ask clk_set_rate() to set that rate. It provides a way to query exactly what rate you'll get if you call clk_set_rate() with that same argument. So essentially, clk_round_rate() and clk_set_rate() are equivalent except the former does not modify the clock hardware in any way. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass Reviewed-by: Sean Anderson --- (no changes since v4) Changes in v4: - Update clk_round_rate description. - Add Sean Anderson review. arch/sandbox/include/asm/clk.h | 9 +++++++++ drivers/clk/clk-uclass.c | 15 +++++++++++++++ drivers/clk/clk_sandbox.c | 17 +++++++++++++++++ drivers/clk/clk_sandbox_test.c | 10 ++++++++++ include/clk-uclass.h | 8 ++++++++ include/clk.h | 28 ++++++++++++++++++++++++++++ test/dm/clk.c | 22 ++++++++++++++++++++++ 7 files changed, 109 insertions(+) diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h index c184c4bffc..0294baee27 100644 --- a/arch/sandbox/include/asm/clk.h +++ b/arch/sandbox/include/asm/clk.h @@ -105,6 +105,15 @@ int sandbox_clk_test_get_bulk(struct udevice *dev); * @return: The rate of the clock. */ ulong sandbox_clk_test_get_rate(struct udevice *dev, int id); +/** + * sandbox_clk_test_round_rate - Ask the sandbox clock test device to round a + * clock's rate. + * + * @dev: The sandbox clock test (client) device. + * @id: The test device's clock ID to configure. + * @return: The rounded rate of the clock. + */ +ulong sandbox_clk_test_round_rate(struct udevice *dev, int id, ulong rate); /** * sandbox_clk_test_set_rate - Ask the sandbox clock test device to set a * clock's rate. diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 31c5997aea..c16a8b120c 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -524,6 +524,21 @@ long long clk_get_parent_rate(struct clk *clk) return pclk->rate; } +ulong clk_round_rate(struct clk *clk, ulong rate) +{ + const struct clk_ops *ops; + + debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate); + if (!clk_valid(clk)) + return 0; + + ops = clk_dev_ops(clk->dev); + if (!ops->round_rate) + return -ENOSYS; + + return ops->round_rate(clk, rate); +} + ulong clk_set_rate(struct clk *clk, ulong rate) { const struct clk_ops *ops; diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c index 768fbb7c52..8361b930df 100644 --- a/drivers/clk/clk_sandbox.c +++ b/drivers/clk/clk_sandbox.c @@ -30,6 +30,22 @@ static ulong sandbox_clk_get_rate(struct clk *clk) return priv->rate[clk->id]; } +static ulong sandbox_clk_round_rate(struct clk *clk, ulong rate) +{ + struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); + + if (!priv->probed) + return -ENODEV; + + if (clk->id >= SANDBOX_CLK_ID_COUNT) + return -EINVAL; + + if (!rate) + return -EINVAL; + + return rate; +} + static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate) { struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); @@ -103,6 +119,7 @@ static int sandbox_clk_free(struct clk *clk) } static struct clk_ops sandbox_clk_ops = { + .round_rate = sandbox_clk_round_rate, .get_rate = sandbox_clk_get_rate, .set_rate = sandbox_clk_set_rate, .enable = sandbox_clk_enable, diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c index 873383856f..f7b77aa674 100644 --- a/drivers/clk/clk_sandbox_test.c +++ b/drivers/clk/clk_sandbox_test.c @@ -86,6 +86,16 @@ ulong sandbox_clk_test_get_rate(struct udevice *dev, int id) return clk_get_rate(sbct->clkps[id]); } +ulong sandbox_clk_test_round_rate(struct udevice *dev, int id, ulong rate) +{ + struct sandbox_clk_test *sbct = dev_get_priv(dev); + + if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT) + return -EINVAL; + + return clk_round_rate(sbct->clkps[id], rate); +} + ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate) { struct sandbox_clk_test *sbct = dev_get_priv(dev); diff --git a/include/clk-uclass.h b/include/clk-uclass.h index dac42dab36..50e8681b55 100644 --- a/include/clk-uclass.h +++ b/include/clk-uclass.h @@ -61,6 +61,14 @@ struct clk_ops { * @return 0 if OK, or a negative error code. */ int (*rfree)(struct clk *clock); + /** + * round_rate() - Adjust a rate to the exact rate a clock can provide. + * + * @clk: The clock to manipulate. + * @rate: Desidered clock rate in Hz. + * @return rounded rate in Hz, or -ve error code. + */ + ulong (*round_rate)(struct clk *clk, ulong rate); /** * get_rate() - Get current clock rate. * diff --git a/include/clk.h b/include/clk.h index a62e2efa2c..ca6b85fa6f 100644 --- a/include/clk.h +++ b/include/clk.h @@ -366,6 +366,29 @@ struct clk *clk_get_parent(struct clk *clk); */ long long clk_get_parent_rate(struct clk *clk); +/** + * clk_round_rate() - Adjust a rate to the exact rate a clock can provide + * + * This answers the question "if I were to pass @rate to clk_set_rate(), + * what clock rate would I end up with?" without changing the hardware + * in any way. In other words: + * + * rate = clk_round_rate(clk, r); + * + * and: + * + * rate = clk_set_rate(clk, r); + * + * are equivalent except the former does not modify the clock hardware + * in any way. + * + * @clk: A clock struct that was previously successfully requested by + * clk_request/get_by_*(). + * @rate: desired clock rate in Hz. + * @return rounded rate in Hz, or -ve error code. + */ +ulong clk_round_rate(struct clk *clk, ulong rate); + /** * clk_set_rate() - Set current clock rate. * @@ -482,6 +505,11 @@ static inline long long clk_get_parent_rate(struct clk *clk) return -ENOSYS; } +static inline ulong clk_round_rate(struct clk *clk, ulong rate) +{ + return -ENOSYS; +} + static inline ulong clk_set_rate(struct clk *clk, ulong rate) { return -ENOSYS; diff --git a/test/dm/clk.c b/test/dm/clk.c index edca3b49f6..21997ed892 100644 --- a/test/dm/clk.c +++ b/test/dm/clk.c @@ -112,6 +112,28 @@ static int dm_test_clk(struct unit_test_state *uts) rate = sandbox_clk_test_set_rate(dev_test, SANDBOX_CLK_TEST_ID_I2C, 0); ut_assert(IS_ERR_VALUE(rate)); + ut_asserteq(10000, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_SPI)); + ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_I2C)); + + ut_asserteq(5000, sandbox_clk_test_round_rate(dev_test, + SANDBOX_CLK_TEST_ID_SPI, + 5000)); + ut_asserteq(7000, sandbox_clk_test_round_rate(dev_test, + SANDBOX_CLK_TEST_ID_I2C, + 7000)); + + ut_asserteq(10000, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_SPI)); + ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_I2C)); + + rate = sandbox_clk_test_round_rate(dev_test, SANDBOX_CLK_TEST_ID_SPI, 0); + ut_assert(IS_ERR_VALUE(rate)); + rate = sandbox_clk_test_round_rate(dev_test, SANDBOX_CLK_TEST_ID_I2C, 0); + ut_assert(IS_ERR_VALUE(rate)); + ut_asserteq(10000, sandbox_clk_test_get_rate(dev_test, SANDBOX_CLK_TEST_ID_SPI)); ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test,