clk-utils.c 733 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
  4. */
  5. #include <asm/div64.h>
  6. #include "clk.h"
  7. #define div_mask(w) ((1 << (w)) - 1)
  8. int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
  9. u8 frac_width, u8 flags)
  10. {
  11. u64 divider_ux1 = parent_rate;
  12. int mul;
  13. if (!rate)
  14. return 0;
  15. mul = 1 << frac_width;
  16. if (!(flags & TEGRA_DIVIDER_INT))
  17. divider_ux1 *= mul;
  18. if (flags & TEGRA_DIVIDER_ROUND_UP)
  19. divider_ux1 += rate - 1;
  20. do_div(divider_ux1, rate);
  21. if (flags & TEGRA_DIVIDER_INT)
  22. divider_ux1 *= mul;
  23. if (divider_ux1 < mul)
  24. return 0;
  25. divider_ux1 -= mul;
  26. if (divider_ux1 > div_mask(width))
  27. return div_mask(width);
  28. return divider_ux1;
  29. }