diff options
Diffstat (limited to 'drivers/clk/mmp/clk-frac.c')
-rw-r--r-- | drivers/clk/mmp/clk-frac.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index 80c1dd15d15c..23a56f561812 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c | |||
@@ -40,15 +40,19 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, | |||
40 | 40 | ||
41 | for (i = 0; i < factor->ftbl_cnt; i++) { | 41 | for (i = 0; i < factor->ftbl_cnt; i++) { |
42 | prev_rate = rate; | 42 | prev_rate = rate; |
43 | rate = (((*prate / 10000) * factor->ftbl[i].num) / | 43 | rate = (((*prate / 10000) * factor->ftbl[i].den) / |
44 | (factor->ftbl[i].den * factor->masks->factor)) * 10000; | 44 | (factor->ftbl[i].num * factor->masks->factor)) * 10000; |
45 | if (rate > drate) | 45 | if (rate > drate) |
46 | break; | 46 | break; |
47 | } | 47 | } |
48 | if (i == 0) | 48 | if ((i == 0) || (i == factor->ftbl_cnt)) { |
49 | return rate; | 49 | return rate; |
50 | else | 50 | } else { |
51 | return prev_rate; | 51 | if ((drate - prev_rate) > (rate - drate)) |
52 | return rate; | ||
53 | else | ||
54 | return prev_rate; | ||
55 | } | ||
52 | } | 56 | } |
53 | 57 | ||
54 | static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, | 58 | static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, |
@@ -64,7 +68,7 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, | |||
64 | num = (val >> masks->num_shift) & masks->num_mask; | 68 | num = (val >> masks->num_shift) & masks->num_mask; |
65 | 69 | ||
66 | /* calculate denominator */ | 70 | /* calculate denominator */ |
67 | den = (val >> masks->den_shift) & masks->num_mask; | 71 | den = (val >> masks->den_shift) & masks->den_mask; |
68 | 72 | ||
69 | if (!den) | 73 | if (!den) |
70 | return 0; | 74 | return 0; |
@@ -85,8 +89,8 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, | |||
85 | 89 | ||
86 | for (i = 0; i < factor->ftbl_cnt; i++) { | 90 | for (i = 0; i < factor->ftbl_cnt; i++) { |
87 | prev_rate = rate; | 91 | prev_rate = rate; |
88 | rate = (((prate / 10000) * factor->ftbl[i].num) / | 92 | rate = (((prate / 10000) * factor->ftbl[i].den) / |
89 | (factor->ftbl[i].den * factor->masks->factor)) * 10000; | 93 | (factor->ftbl[i].num * factor->masks->factor)) * 10000; |
90 | if (rate > drate) | 94 | if (rate > drate) |
91 | break; | 95 | break; |
92 | } | 96 | } |