diff options
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_nkmp.c | 20 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_nkmp.h | 2 |
2 files changed, 19 insertions, 3 deletions
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index c3f6fe7be565..ebd9436d2c7c 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c | |||
| @@ -95,7 +95,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw, | |||
| 95 | unsigned long parent_rate) | 95 | unsigned long parent_rate) |
| 96 | { | 96 | { |
| 97 | struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); | 97 | struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); |
| 98 | unsigned long n, m, k, p; | 98 | unsigned long n, m, k, p, rate; |
| 99 | u32 reg; | 99 | u32 reg; |
| 100 | 100 | ||
| 101 | reg = readl(nkmp->common.base + nkmp->common.reg); | 101 | reg = readl(nkmp->common.base + nkmp->common.reg); |
| @@ -121,7 +121,11 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw, | |||
| 121 | p = reg >> nkmp->p.shift; | 121 | p = reg >> nkmp->p.shift; |
| 122 | p &= (1 << nkmp->p.width) - 1; | 122 | p &= (1 << nkmp->p.width) - 1; |
| 123 | 123 | ||
| 124 | return ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); | 124 | rate = ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); |
| 125 | if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
| 126 | rate /= nkmp->fixed_post_div; | ||
| 127 | |||
| 128 | return rate; | ||
| 125 | } | 129 | } |
| 126 | 130 | ||
| 127 | static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, | 131 | static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, |
| @@ -130,6 +134,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, | |||
| 130 | struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); | 134 | struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); |
| 131 | struct _ccu_nkmp _nkmp; | 135 | struct _ccu_nkmp _nkmp; |
| 132 | 136 | ||
| 137 | if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
| 138 | rate *= nkmp->fixed_post_div; | ||
| 139 | |||
| 133 | _nkmp.min_n = nkmp->n.min ?: 1; | 140 | _nkmp.min_n = nkmp->n.min ?: 1; |
| 134 | _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; | 141 | _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; |
| 135 | _nkmp.min_k = nkmp->k.min ?: 1; | 142 | _nkmp.min_k = nkmp->k.min ?: 1; |
| @@ -141,8 +148,12 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, | |||
| 141 | 148 | ||
| 142 | ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); | 149 | ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); |
| 143 | 150 | ||
| 144 | return ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, | 151 | rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, |
| 145 | _nkmp.m, _nkmp.p); | 152 | _nkmp.m, _nkmp.p); |
| 153 | if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
| 154 | rate = rate / nkmp->fixed_post_div; | ||
| 155 | |||
| 156 | return rate; | ||
| 146 | } | 157 | } |
| 147 | 158 | ||
| 148 | static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, | 159 | static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, |
| @@ -154,6 +165,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 154 | unsigned long flags; | 165 | unsigned long flags; |
| 155 | u32 reg; | 166 | u32 reg; |
| 156 | 167 | ||
| 168 | if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
| 169 | rate = rate * nkmp->fixed_post_div; | ||
| 170 | |||
| 157 | _nkmp.min_n = nkmp->n.min ?: 1; | 171 | _nkmp.min_n = nkmp->n.min ?: 1; |
| 158 | _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; | 172 | _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; |
| 159 | _nkmp.min_k = nkmp->k.min ?: 1; | 173 | _nkmp.min_k = nkmp->k.min ?: 1; |
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h index a82facbc6144..6940503e7fc4 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.h +++ b/drivers/clk/sunxi-ng/ccu_nkmp.h | |||
| @@ -34,6 +34,8 @@ struct ccu_nkmp { | |||
| 34 | struct ccu_div_internal m; | 34 | struct ccu_div_internal m; |
| 35 | struct ccu_div_internal p; | 35 | struct ccu_div_internal p; |
| 36 | 36 | ||
| 37 | unsigned int fixed_post_div; | ||
| 38 | |||
| 37 | struct ccu_common common; | 39 | struct ccu_common common; |
| 38 | }; | 40 | }; |
| 39 | 41 | ||
