From patchwork Sun Oct 11 12:13:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 1380321 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=85.214.62.61; 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=Qiz0OPrv; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (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 4C8LQ904t1z9sS8 for ; Sun, 11 Oct 2020 23:16:32 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 76C1A823EA; Sun, 11 Oct 2020 14:15:41 +0200 (CEST) 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="Qiz0OPrv"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id BA612823E6; Sun, 11 Oct 2020 14:15:37 +0200 (CEST) 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, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from libero.it (smtp-34-i2.italiaonline.it [213.209.12.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 535A7823E5 for ; Sun, 11 Oct 2020 14:15:32 +0200 (CEST) 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 RaF7kmOccmMFTRaG6kXUuc; Sun, 11 Oct 2020 14:15:26 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1602418526; bh=Vf2GWlUdk2N5uSRsDIDoEfZ3VmTrxt1p6t8XW6K1YXg=; h=From; b=Qiz0OPrvmwJSuHla21+HR1zFCQxyghtd17OWFWQBh8NGeSTon6Zt6GJcsHtBtokKQ vT8GihOb/q6jjQqB9xCLiRn1YOgrGt3LOWXbI/76W840zwmeGrmkAX4G69t255HCr1 1/SQQwYSc/pxXxYwvTTwSRWeYaRCH2bUd4HH0khRGvt6JrhkufCRfWbqXsMblYiP8H Xxe5Jela5px2xEINIjfJGjmX5VLJOfhPSh8iRyzDoTkC02OFLPpjtBNuRh9oeLtDPW zc0LKiu+/wR/IWOycQ11GhMoOuoO88gNspaAl9qdUnR0g1vkU5EZRSPiolcUCB2HSh alAvoZWgwtwjg== X-CNFS-Analysis: v=2.4 cv=KetsDSUD c=1 sm=1 tr=0 ts=5f82f75e a=9myQFBeCGQ66/mXSe6vdPA==:117 a=9myQFBeCGQ66/mXSe6vdPA==:17 a=cm27Pg_UAAAA:8 a=IxSEBPkUA9tbEvFmOecA:9 a=xmb-EsYY8bH0VWELuYED:22 From: Dario Binacchi To: u-boot@lists.denx.de Cc: Dario Binacchi , Chunfeng Yun , Jagan Teki , Jean-Jacques Hiblot , Lukasz Majewski , Patrick Delaunay , Sean Anderson , Simon Glass , Stephen Warren , Walter Lozano Subject: [PATCH v3 05/27] clk: add clk_round_rate() Date: Sun, 11 Oct 2020 14:13:18 +0200 Message-Id: <20201011121340.21660-6-dariobin@libero.it> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201011121340.21660-1-dariobin@libero.it> References: <20201011121340.21660-1-dariobin@libero.it> X-CMAE-Envelope: MS4xfJd7q4EjnK34bXYbzeC+TnCDpuWP8KhH09UXy4s+sqfFPn+aTajgWblUYZ+yazPOyS9VyaCCB62n7Lnqr+astby0oMmsUFFcLVbNzmlFldm83o3oFfQq 0/SBkEo3IRUqXH4dsU6N42Skj0hKOX7pr/Fj16/0PLYlqYEd+6ZpHyFjT5q0qiN46krRB0DpSEEemTkb6j7xIu/4itVTiLGZwo0XnocnpO8jRO8v5pbdoTQz uVxM5NyEwrxZH6FKVCbk1N3Bmb824KgSvohXPg0F0MQhKCw0we6c2594YqP60HeVjuf2rQk/jwIvQAym0/jO71t8C6Gk/MxiN0A7pAB4gmtnTcnBOvL4JzZK sFlW+Myihn9AGQqFdYXMpjKIHgOv4mTcX3KH0NzDyC7L0WraECeu1+WGjCuXsTf2TmjCnbO2H9eN44S+eXhGon4yl9YaWQ7gV6M1p8D4D+ynnEp11A9CTWoi xn8roHO6cjxp5fS8fWTou1Yhjt3Qx6k62cPXexPjoFGR8seJ6l610iNXH68tVNG8vWmG/qLJplGkmx4D 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 v1) 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 | 29 +++++++++++++++++++++++++++++ test/dm/clk.c | 22 ++++++++++++++++++++++ 7 files changed, 110 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..cce763b05b 100644 --- a/include/clk.h +++ b/include/clk.h @@ -366,6 +366,30 @@ 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: + * + * clk_set_rate(clk, r); + * rate = clk_get_rate(clk); + * + * 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 +506,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,