0001
0002
0003
0004
0005
0006 #include <asm/div64.h>
0007
0008 #include "clk.h"
0009
0010 #define div_mask(w) ((1 << (w)) - 1)
0011
0012 int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
0013 u8 frac_width, u8 flags)
0014 {
0015 u64 divider_ux1 = parent_rate;
0016 int mul;
0017
0018 if (!rate)
0019 return 0;
0020
0021 mul = 1 << frac_width;
0022
0023 if (!(flags & TEGRA_DIVIDER_INT))
0024 divider_ux1 *= mul;
0025
0026 if (flags & TEGRA_DIVIDER_ROUND_UP)
0027 divider_ux1 += rate - 1;
0028
0029 do_div(divider_ux1, rate);
0030
0031 if (flags & TEGRA_DIVIDER_INT)
0032 divider_ux1 *= mul;
0033
0034 if (divider_ux1 < mul)
0035 return 0;
0036
0037 divider_ux1 -= mul;
0038
0039 if (divider_ux1 > div_mask(width))
0040 return div_mask(width);
0041
0042 return divider_ux1;
0043 }