From b94c928277c5915602b4e60348b3fe822a6d653f Mon Sep 17 00:00:00 2001
From: Christoph Muellner
Date: Tue, 2 Apr 2019 16:50:41 +0200
Subject: 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
---
drivers/clk/rockchip/clk.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
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;
--
cgit v1.2.2-2-gfde8