From patchwork Tue Dec 29 23:06:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 1421265 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=CbizExs7; 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) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D597g5GC6z9sVs for ; Wed, 30 Dec 2020 10:08:15 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9081F825D4; Wed, 30 Dec 2020 00:07:42 +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="CbizExs7"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 58CBC825F4; Wed, 30 Dec 2020 00:07:32 +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, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS autolearn=no autolearn_force=no version=3.4.2 Received: from libero.it (smtp-18-i2.italiaonline.it [213.209.12.18]) (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 2D0938259D for ; Wed, 30 Dec 2020 00:07:27 +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.54.115.44]) by smtp-18.iol.local with ESMTPA id uO5Akavim7QU9uO5OkzfYa; Wed, 30 Dec 2020 00:07:26 +0100 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1609283246; bh=180JE+Sps590IoXpZGypFupM0HG7gSeT9i8MDuYVQB8=; h=From; b=CbizExs7qJQvEUslNa6bq3pKuGj+K4nuNTaWhXOQI0zyB+u7EqwFd06vDScUCdGoL Hu5PK7FXtfA61REHPsrF79WHMhDlYtkN3jda6Xje+xxMhDRcHQHaCelLumaLQYY/AF GqUbeYvbIrhk0KaTrY5NS77KeRRjtWiSxi4g4oklLtd9J2RJ8vvi31eQzYdWB7g+UA H1Ps4gwL482SAXDl0N0cIuHrKCkaHuvU6Y2CSW8ZBndkX8aEitgWRvf3N7OosMoK5b 5W6G3EdRVcUIWfKl8zC33MdZk4oHKr1ia7Nx8in+2FSPkrwWDp4dUv607XpYILfWhP pxm16MLQkEIBw== X-CNFS-Analysis: v=2.4 cv=Y+c9DjSN c=1 sm=1 tr=0 ts=5febb6ae cx=a_exe a=4XFUYcG0DNokufVEFeBjWw==:117 a=4XFUYcG0DNokufVEFeBjWw==: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: Lokesh Vutla , Dario Binacchi , Chunfeng Yun , Jagan Teki , Lukasz Majewski , Patrick Delaunay , Ryder Lee , Sean Anderson , Simon Glass , Stephen Warren , Walter Lozano Subject: [PATCH v8 05/28] clk: add clk_round_rate() Date: Wed, 30 Dec 2020 00:06:31 +0100 Message-Id: <20201229230654.8609-6-dariobin@libero.it> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201229230654.8609-1-dariobin@libero.it> References: <20201229230654.8609-1-dariobin@libero.it> X-CMAE-Envelope: MS4xfLpB4LymXiPJQQN99f8s+n32gNMuh8u3FQywSIQ/r6TpqXlzO+05d0jf2bdljt3IsZthR4qx6wKZS7YhUTDJV2+51NcxRT1Xx+m5cVM/Qr0chDiV1Cyi Js0pyek84OV/4BHFWJxRV8Nos4qpE8W1JYHwhyw2j+ayVnx3qgSV4HBw2FeKuRI18N7utd/ei3G7mQZSl9fjvmDVWUuxzrft9VxViWfxLJ2sH2yq6VtRg0Ih 8Urk0JRKm1D4pDSz2I1CSj3QJr/0WIEmIfbzXH54KhxlIUxuQiJUs9lH58nLCfX6bu4T0ktpCaa478vkVce70HS8KDKoHbvkzcFR5/3eNKW6hfuvDrkpKPLX 7CdI8410Wxqpz9S5ZUKV4lMIHCFOO3pMoTC55LbP9a5tOvGrG0g7s3BTuOrbKLw9eo4sENGTVLGfoNXcrd7l3gxugt35efud2FT+brNVQzCuW/RsIgJFXsWg IHyurHLsNnqTz/bPsGE3JfLpNWLiEumrgiypvChbaE3GHRPi6os5tWI9PiZhckRbqZmB8ibEZTNn3RtUQKJ9/RT3MtFENf1/WL5SKy9ilVDqRW8ryUJ3/5Ng gus= 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 ac954a34d2..3b8e27e4a5 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -523,6 +523,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 0ff1b49633..0751e923e7 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,