blob: aabf2bd613597790d9aebb81263345863ed2fb7d [file] [log] [blame]
Aneesh V095aea22011-07-21 09:10:12 -04001/*
2 * Copyright 2011 Linaro Limited
3 * Aneesh V <aneesh@ti.com>
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Aneesh V095aea22011-07-21 09:10:12 -04006 */
7#include <common.h>
8static void do_cancel_out(u32 *num, u32 *den, u32 factor)
9{
10 while (1) {
11 if (((*num)/factor*factor == (*num)) &&
12 ((*den)/factor*factor == (*den))) {
13 (*num) /= factor;
14 (*den) /= factor;
15 } else
16 break;
17 }
18}
19
20/*
21 * Cancel out the denominator and numerator of a fraction
22 * to get smaller numerator and denominator.
23 */
24void cancel_out(u32 *num, u32 *den, u32 den_limit)
25{
26 do_cancel_out(num, den, 2);
27 do_cancel_out(num, den, 3);
28 do_cancel_out(num, den, 5);
29 do_cancel_out(num, den, 7);
30 do_cancel_out(num, den, 11);
31 do_cancel_out(num, den, 13);
32 do_cancel_out(num, den, 17);
33 while ((*den) > den_limit) {
34 *num /= 2;
35 /*
36 * Round up the denominator so that the final fraction
37 * (num/den) is always <= the desired value
38 */
39 *den = (*den + 1) / 2;
40 }
41}