diff options
authorChristoph Muellner <>2019-04-02 16:50:41 +0200
committerChristoph Muellner <>2019-04-30 20:02:03 +0200
commitb94c928277c5915602b4e60348b3fe822a6d653f (patch)
parent51a75c32320b49f358def3105946c43c0cc1d223 (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 <>
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index d5e130263c05..6f96335913df 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;