mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
clk: add clk_round_rate()
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 <dariobin@libero.it> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
parent
6337d53fdf
commit
2983ad55a1
7 changed files with 109 additions and 0 deletions
|
@ -105,6 +105,15 @@ int sandbox_clk_test_get_bulk(struct udevice *dev);
|
||||||
* @return: The rate of the clock.
|
* @return: The rate of the clock.
|
||||||
*/
|
*/
|
||||||
ulong sandbox_clk_test_get_rate(struct udevice *dev, int id);
|
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
|
* sandbox_clk_test_set_rate - Ask the sandbox clock test device to set a
|
||||||
* clock's rate.
|
* clock's rate.
|
||||||
|
|
|
@ -523,6 +523,21 @@ long long clk_get_parent_rate(struct clk *clk)
|
||||||
return pclk->rate;
|
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)
|
ulong clk_set_rate(struct clk *clk, ulong rate)
|
||||||
{
|
{
|
||||||
const struct clk_ops *ops;
|
const struct clk_ops *ops;
|
||||||
|
|
|
@ -30,6 +30,22 @@ static ulong sandbox_clk_get_rate(struct clk *clk)
|
||||||
return priv->rate[clk->id];
|
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)
|
static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
|
||||||
{
|
{
|
||||||
struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
|
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 = {
|
static struct clk_ops sandbox_clk_ops = {
|
||||||
|
.round_rate = sandbox_clk_round_rate,
|
||||||
.get_rate = sandbox_clk_get_rate,
|
.get_rate = sandbox_clk_get_rate,
|
||||||
.set_rate = sandbox_clk_set_rate,
|
.set_rate = sandbox_clk_set_rate,
|
||||||
.enable = sandbox_clk_enable,
|
.enable = sandbox_clk_enable,
|
||||||
|
|
|
@ -86,6 +86,16 @@ ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
|
||||||
return clk_get_rate(sbct->clkps[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)
|
ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
|
||||||
{
|
{
|
||||||
struct sandbox_clk_test *sbct = dev_get_priv(dev);
|
struct sandbox_clk_test *sbct = dev_get_priv(dev);
|
||||||
|
|
|
@ -61,6 +61,14 @@ struct clk_ops {
|
||||||
* @return 0 if OK, or a negative error code.
|
* @return 0 if OK, or a negative error code.
|
||||||
*/
|
*/
|
||||||
int (*rfree)(struct clk *clock);
|
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.
|
* get_rate() - Get current clock rate.
|
||||||
*
|
*
|
||||||
|
|
|
@ -366,6 +366,29 @@ struct clk *clk_get_parent(struct clk *clk);
|
||||||
*/
|
*/
|
||||||
long long clk_get_parent_rate(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.
|
* clk_set_rate() - Set current clock rate.
|
||||||
*
|
*
|
||||||
|
@ -482,6 +505,11 @@ static inline long long clk_get_parent_rate(struct clk *clk)
|
||||||
return -ENOSYS;
|
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)
|
static inline ulong clk_set_rate(struct clk *clk, ulong rate)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
|
@ -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);
|
rate = sandbox_clk_test_set_rate(dev_test, SANDBOX_CLK_TEST_ID_I2C, 0);
|
||||||
ut_assert(IS_ERR_VALUE(rate));
|
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,
|
ut_asserteq(10000, sandbox_clk_test_get_rate(dev_test,
|
||||||
SANDBOX_CLK_TEST_ID_SPI));
|
SANDBOX_CLK_TEST_ID_SPI));
|
||||||
ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test,
|
ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test,
|
||||||
|
|
Loading…
Add table
Reference in a new issue