diff options
author | Harvey Hunt <harvey.hunt@imgtec.com> | 2016-05-09 17:29:52 +0100 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2016-05-12 14:48:25 -0700 |
commit | 4afe2d1a6ed5cba794aeeaa816e7c97a45167b01 (patch) | |
tree | e88fd50b5e791760c7abb20f01e087c53583fe34 /drivers/clk/ingenic/cgu.c | |
parent | 5707291c6cada6db7344c90a548d02f427bf376c (diff) | |
download | linux-4afe2d1a6ed5cba794aeeaa816e7c97a45167b01.tar.bz2 |
clk: ingenic: Allow divider value to be divided
The JZ4780's MSC clock divider registers multiply the clock divider by 2.
This means that MMC devices run at half their expected speed. Add the
ability to divide the clock divider in order to solve this.
Signed-off-by: Harvey Hunt <harvey.hunt@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk/ingenic/cgu.c')
-rw-r--r-- | drivers/clk/ingenic/cgu.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 7cfb7b2a2ed6..e8248f9185f7 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -325,6 +325,7 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) div = (div_reg >> clk_info->div.shift) & GENMASK(clk_info->div.bits - 1, 0); div += 1; + div *= clk_info->div.div; rate /= div; } @@ -345,6 +346,14 @@ ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info, div = min_t(unsigned, div, 1 << clk_info->div.bits); div = max_t(unsigned, div, 1); + /* + * If the divider value itself must be divided before being written to + * the divider register, we must ensure we don't have any bits set that + * would be lost as a result of doing so. + */ + div /= clk_info->div.div; + div *= clk_info->div.div; + return div; } @@ -395,7 +404,7 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate, /* update the divide */ mask = GENMASK(clk_info->div.bits - 1, 0); reg &= ~(mask << clk_info->div.shift); - reg |= (div - 1) << clk_info->div.shift; + reg |= ((div / clk_info->div.div) - 1) << clk_info->div.shift; /* clear the stop bit */ if (clk_info->div.stop_bit != -1) |