]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
clk: zynqmp: divider: Don't allow divisor value with any remainder
authorHyun Kwon <hyun.kwon@xilinx.com>
Thu, 20 Apr 2017 04:42:33 +0000 (10:12 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Fri, 21 Apr 2017 05:55:52 +0000 (07:55 +0200)
This is an example of what happens with always-get-best-divisor approach:
- Requested frequency is 300MHz
- Divisor 1 asks its parent (Divisor 0) to generate 600MHz based on
its divisor value (= 2).
- Divisor 0 asks its parent (PLL) to generate 1800MHz based on
the divisor value (= 3).
- To meet some requirement, PLL driver rounds off the requested rate
to be 900MHz (1800Mhz / 2).
- Divisor 0 gets the closest divisor between 900MHz and 600Mhz, which is 2.
- Divisor 1 gets the cloests divisor between 450Mhz and 300MHz, which is 2.
- The resulted frequency becomes 225Mhz (vs 300Mhz).

By not allowing divisor with any remainder, divisor 0 value becomes 1,
and the divisor 1 value becomes 3, so it gets the acccurate frequency.

Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/clk/zynqmp/divider.c

index e744a097c0337132f9396d10843305780336d1e6..5e200bb7a9f22a463242da7b970e48aa8c7f98a1 100644 (file)
@@ -9,6 +9,7 @@
  * Adjustable divider clock implementation
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/clk/zynqmp.h>
 #include <linux/module.h>
@@ -93,6 +94,9 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
 
        bestdiv = divider_get_val(rate, *prate, divider->table, divider->width,
                        divider->flags);
+
+       if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
+               bestdiv = rate % *prate ? 1 : bestdiv;
        *prate = rate * bestdiv;
 
        return rate;