summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Muellner <christoph.muellner@theobroma-systems.com>2019-04-02 16:50:41 +0200
committerChristoph Muellner <christoph.muellner@theobroma-systems.com>2019-04-02 19:16:02 +0200
commit1ecaf2cd676f3d57cb27f0d895cfa6a4c9bce917 (patch)
tree67f4824dd6bdf74aaaf83b4352988edb63fce415
parentc47938872e53f30b0150911681ae095de98a96bb (diff)
rk: clk: Allow clk_i2s0_frac to violate precision restriction.
The fraction approximation code for rockchip frac dividers impose the following requirement (as noted in a driver comment): fractional divider must set that denominator is 20 times larger than numerator to generate precise clock frequency. Additionally the frac driver limits the maximum input frequency to 600 MHz. This limitation can be achieved by using the integer divider (limiting to e.g. 400 MHz). Note, that both restrictions are not stated in the RK3399 TRM. The implication of these restrictions are, that the range of possible output frequencies is reduced quite drastically. This results in the problem, that clk_i2s0_frac cannot generate a clock of 24.56 MHz and thus audio on RK3399-Q7 is broken. Therefore this patch whitelists clk_i2s0_frac from the first restriction, similar to the exception for UART (in the same function). Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
-rw-r--r--drivers/clk/rockchip/clk.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index a2cf1d39e450..cce3d8da918d 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -207,7 +207,14 @@ static void rockchip_fractional_approximation(struct clk_hw *hw,
}
}
- if (*parent_rate < rate * 20) {
+ /*
+ * Check again if parent rate < rate x 20.
+ * Note that this is needed, because we might have changed
+ * the parent rate above.
+ */
+ if (*parent_rate < rate * 20 &&
+ /* Whitelist clocks, where we can accept imprecisions. */
+ !strstr(clk_hw_get_name(hw), "clk_i2s0_frac")) {
pr_warn("%s p_rate(%ld) is low than rate(%ld)*20, use integer or half-div\n",
clk_hw_get_name(hw), *parent_rate, rate);
*m = 0;