forked from Minki/linux
clk: ti: add support for clock latching to divider clocks
Latching the clock settings is needed with certain clocks, where the setting is "cached" in HW before doing the actual re-programming of the clock source. This patch adds support for clock latching to the divider clock. Signed-off-by: Tero Kristo <t-kristo@ti.com>
This commit is contained in:
parent
e31922eda1
commit
b44a03008d
@ -22,6 +22,7 @@ struct clk_omap_divider {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
u8 flags;
|
||||
s8 latch;
|
||||
const struct clk_div_table *table;
|
||||
};
|
||||
|
||||
|
@ -263,6 +263,8 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
val |= value << divider->shift;
|
||||
ti_clk_ll_ops->clk_writel(val, ÷r->reg);
|
||||
|
||||
ti_clk_latch(÷r->reg, divider->latch);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -276,7 +278,8 @@ static struct clk *_register_divider(struct device *dev, const char *name,
|
||||
const char *parent_name,
|
||||
unsigned long flags,
|
||||
struct clk_omap_reg *reg,
|
||||
u8 shift, u8 width, u8 clk_divider_flags,
|
||||
u8 shift, u8 width, s8 latch,
|
||||
u8 clk_divider_flags,
|
||||
const struct clk_div_table *table)
|
||||
{
|
||||
struct clk_omap_divider *div;
|
||||
@ -305,6 +308,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
|
||||
memcpy(&div->reg, reg, sizeof(*reg));
|
||||
div->shift = shift;
|
||||
div->width = width;
|
||||
div->latch = latch;
|
||||
div->flags = clk_divider_flags;
|
||||
div->hw.init = &init;
|
||||
div->table = table;
|
||||
@ -420,6 +424,7 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup)
|
||||
div->table = _get_div_table_from_setup(setup, &div->width);
|
||||
|
||||
div->shift = setup->bit_shift;
|
||||
div->latch = -EINVAL;
|
||||
|
||||
return &div->hw;
|
||||
}
|
||||
@ -452,7 +457,7 @@ struct clk *ti_clk_register_divider(struct ti_clk *setup)
|
||||
|
||||
clk = _register_divider(NULL, setup->name, div->parent,
|
||||
flags, ®, div->bit_shift,
|
||||
width, div_flags, table);
|
||||
width, -EINVAL, div_flags, table);
|
||||
|
||||
if (IS_ERR(clk))
|
||||
kfree(table);
|
||||
@ -556,7 +561,7 @@ static int _get_divider_width(struct device_node *node,
|
||||
|
||||
static int __init ti_clk_divider_populate(struct device_node *node,
|
||||
struct clk_omap_reg *reg, const struct clk_div_table **table,
|
||||
u32 *flags, u8 *div_flags, u8 *width, u8 *shift)
|
||||
u32 *flags, u8 *div_flags, u8 *width, u8 *shift, s8 *latch)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
@ -570,6 +575,13 @@ static int __init ti_clk_divider_populate(struct device_node *node,
|
||||
else
|
||||
*shift = 0;
|
||||
|
||||
if (latch) {
|
||||
if (!of_property_read_u32(node, "ti,latch-bit", &val))
|
||||
*latch = val;
|
||||
else
|
||||
*latch = -EINVAL;
|
||||
}
|
||||
|
||||
*flags = 0;
|
||||
*div_flags = 0;
|
||||
|
||||
@ -606,17 +618,18 @@ static void __init of_ti_divider_clk_setup(struct device_node *node)
|
||||
u8 clk_divider_flags = 0;
|
||||
u8 width = 0;
|
||||
u8 shift = 0;
|
||||
s8 latch = -EINVAL;
|
||||
const struct clk_div_table *table = NULL;
|
||||
u32 flags = 0;
|
||||
|
||||
parent_name = of_clk_get_parent_name(node, 0);
|
||||
|
||||
if (ti_clk_divider_populate(node, ®, &table, &flags,
|
||||
&clk_divider_flags, &width, &shift))
|
||||
&clk_divider_flags, &width, &shift, &latch))
|
||||
goto cleanup;
|
||||
|
||||
clk = _register_divider(NULL, node->name, parent_name, flags, ®,
|
||||
shift, width, clk_divider_flags, table);
|
||||
shift, width, latch, clk_divider_flags, table);
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
@ -639,7 +652,8 @@ static void __init of_ti_composite_divider_clk_setup(struct device_node *node)
|
||||
return;
|
||||
|
||||
if (ti_clk_divider_populate(node, &div->reg, &div->table, &val,
|
||||
&div->flags, &div->width, &div->shift) < 0)
|
||||
&div->flags, &div->width, &div->shift,
|
||||
NULL) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER))
|
||||
|
Loading…
Reference in New Issue
Block a user