clk: zynqmp: fix check for fractional clock

The firmware sets BIT(13) in clkflag to mark a divider as fractional
divider. The clock driver copies the clkflag straight to the flags of
the common clock framework. In the common clk framework flags, BIT(13)
is defined as CLK_DUTY_CYCLE_PARENT.

Add a new field to the zynqmp_clk_divider to specify if a divider is a
fractional devider. Set this field based on the clkflag when registering
a divider.

At the same time, unset BIT(13) from clkflag when copying the flags to
the common clk framework flags.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
Michael Tretter 2019-03-19 11:01:46 +01:00 committed by Stephen Boyd
parent e91158f1be
commit c06e64407e

View File

@ -31,12 +31,14 @@
* struct zynqmp_clk_divider - adjustable divider clock * struct zynqmp_clk_divider - adjustable divider clock
* @hw: handle between common and hardware-specific interfaces * @hw: handle between common and hardware-specific interfaces
* @flags: Hardware specific flags * @flags: Hardware specific flags
* @is_frac: The divider is a fractional divider
* @clk_id: Id of clock * @clk_id: Id of clock
* @div_type: divisor type (TYPE_DIV1 or TYPE_DIV2) * @div_type: divisor type (TYPE_DIV1 or TYPE_DIV2)
*/ */
struct zynqmp_clk_divider { struct zynqmp_clk_divider {
struct clk_hw hw; struct clk_hw hw;
u8 flags; u8 flags;
bool is_frac;
u32 clk_id; u32 clk_id;
u32 div_type; u32 div_type;
}; };
@ -123,8 +125,7 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
bestdiv = zynqmp_divider_get_val(*prate, rate); bestdiv = zynqmp_divider_get_val(*prate, rate);
if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
(divider->flags & CLK_FRAC))
bestdiv = rate % *prate ? 1 : bestdiv; bestdiv = rate % *prate ? 1 : bestdiv;
*prate = rate * bestdiv; *prate = rate * bestdiv;
@ -202,11 +203,13 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
init.name = name; init.name = name;
init.ops = &zynqmp_clk_divider_ops; init.ops = &zynqmp_clk_divider_ops;
init.flags = nodes->flag; /* CLK_FRAC is not defined in the common clk framework */
init.flags = nodes->flag & ~CLK_FRAC;
init.parent_names = parents; init.parent_names = parents;
init.num_parents = 1; init.num_parents = 1;
/* struct clk_divider assignments */ /* struct clk_divider assignments */
div->is_frac = !!(nodes->flag & CLK_FRAC);
div->flags = nodes->type_flag; div->flags = nodes->type_flag;
div->hw.init = &init; div->hw.init = &init;
div->clk_id = clk_id; div->clk_id = clk_id;