diff options
author | Peter De Schrijver | 2018-07-12 14:53:00 +0300 |
---|---|---|
committer | Stephen Boyd | 2018-07-25 13:43:34 -0700 |
commit | cb3ac5947afb3bb7e2f89c1b59f61dcf3e115fe1 (patch) | |
tree | 7111e58446fef9a299069b9104c9e32a09732a11 /drivers/clk/tegra/clk-utils.c | |
parent | 0cbb61a313979b53d6b2dc838a92f07471440708 (diff) |
clk: tegra: Refactor fractional divider calculation
Move this to a separate file so it can be used to calculate the sdmmc
clock dividers.
Signed-off-by: Peter De-Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
Acked-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/tegra/clk-utils.c')
-rw-r--r-- | drivers/clk/tegra/clk-utils.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/clk/tegra/clk-utils.c b/drivers/clk/tegra/clk-utils.c new file mode 100644 index 000000000000..1a5daae4e501 --- /dev/null +++ b/drivers/clk/tegra/clk-utils.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + */ + +#include <asm/div64.h> + +#include "clk.h" + +#define div_mask(w) ((1 << (w)) - 1) + +int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, + u8 frac_width, u8 flags) +{ + u64 divider_ux1 = parent_rate; + int mul; + + if (!rate) + return 0; + + mul = 1 << frac_width; + + if (!(flags & TEGRA_DIVIDER_INT)) + divider_ux1 *= mul; + + if (flags & TEGRA_DIVIDER_ROUND_UP) + divider_ux1 += rate - 1; + + do_div(divider_ux1, rate); + + if (flags & TEGRA_DIVIDER_INT) + divider_ux1 *= mul; + + if (divider_ux1 < mul) + return 0; + + divider_ux1 -= mul; + + if (divider_ux1 > div_mask(width)) + return div_mask(width); + + return divider_ux1; +} |