From c8f62536833eca49723b6360b3744e5110ae0ffe Mon Sep 17 00:00:00 2001 From: Ravi Patel Date: Tue, 18 Sep 2018 02:14:12 -0700 Subject: [PATCH] zynqmp: pm: Update flags in common clk divisor node Current implementation doesn't support change of div1 value if clk has 2 divisor because div1 clk is the parent of the div2 clk and div2 clk does not have SET_RATE_PARENT flag. This causes div1 value to be fixed and only value of div2 will be adjusted according to required clock rate. Example: Consider a case of nand_ref clock which has 2 divisor and 1 mux. The frequency of mux clock is 1500MHz and default value of div1 and div2 is 15 and 1 respectively. So the final clock will be of 100MHz. When driver requests 80MHz for nand_ref clock, clock framework will adjust the div2 value to 1 (setting div2 value 2 results final clock to 50MHz which is more inaccurate compare to 100Mhz) which results final clock to 100MHz. Ideally the value of div1 and div2 should be updated to 19 and 1 respectively so that final clock goes to around 78MHz. This patch fixes above problem by allowing change in div1 value. Signed-off-by: Ravi Patel Signed-off-by: Rajan Vaja Change-Id: Ibb98f6748d28653fdd1e59bf433b6a37ce9c1a58 --- plat/xilinx/zynqmp/pm_service/pm_api_clock.c | 36 ++++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c index 27966635e..f2dfbb17b 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c @@ -129,12 +129,26 @@ .div = NA_DIV, \ } -#define GENERIC_DIV(id) \ +#define GENERIC_DIV1 \ { \ - .type = TYPE_DIV##id, \ - .offset = PERIPH_DIV##id##_SHIFT, \ - .width = PERIPH_DIV##id##_WIDTH, \ + .type = TYPE_DIV1, \ + .offset = PERIPH_DIV1_SHIFT, \ + .width = PERIPH_DIV1_WIDTH, \ + .clkflags = CLK_SET_RATE_NO_REPARENT | \ + CLK_IS_BASIC, \ + .typeflags = CLK_DIVIDER_ONE_BASED | \ + CLK_DIVIDER_ALLOW_ZERO, \ + .mult = NA_MULT, \ + .div = NA_DIV, \ + } + +#define GENERIC_DIV2 \ + { \ + .type = TYPE_DIV2, \ + .offset = PERIPH_DIV2_SHIFT, \ + .width = PERIPH_DIV2_WIDTH, \ .clkflags = CLK_SET_RATE_NO_REPARENT | \ + CLK_SET_RATE_PARENT | \ CLK_IS_BASIC, \ .typeflags = CLK_DIVIDER_ONE_BASED | \ CLK_DIVIDER_ALLOW_ZERO, \ @@ -340,25 +354,25 @@ static struct pm_clock_node acpu_nodes[] = { static struct pm_clock_node generic_mux_div_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), + GENERIC_DIV1, }; static struct pm_clock_node generic_mux_div_gate_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), + GENERIC_DIV1, GENERIC_GATE, }; static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), + GENERIC_DIV1, IGNORE_UNUSED_GATE, }; static struct pm_clock_node generic_mux_div_div_gate_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), - GENERIC_DIV(2), + GENERIC_DIV1, + GENERIC_DIV2, GENERIC_GATE, }; @@ -410,8 +424,8 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = { static struct pm_clock_node usb_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), - GENERIC_DIV(2), + GENERIC_DIV1, + GENERIC_DIV2, { .type = TYPE_GATE, .offset = USB_GATE_SHIFT, -- 2.39.5