Commit 4a5917cd authored by Tony Lindgren's avatar Tony Lindgren
Browse files

clk: ti: Improve clksel clock bit parsing for reg property



Because of legacy reasons, the TI clksel composite clocks can have
overlapping reg properties, and use a custom ti,bit-shift property.

For the clksel clocks we can start using of the standard reg property
instead of the custom ti,bit-shift property.

To do this, let's add a ti_clk_get_legacy_bit_shift() helper, and make
ti_clk_get_reg_addr() populate the clock bit offset.

This makes it possible to update the devicetree files to use the reg
property one clock at a time.

Acked-by: default avatarStephen Boyd <sboyd@kernel.org>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 35163385
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -376,14 +376,9 @@ static void __init of_omap2_apll_setup(struct device_node *node)
	}
	clk_hw->fixed_rate = val;

	if (of_property_read_u32(node, "ti,bit-shift", &val)) {
		pr_err("%pOFn missing bit-shift\n", node);
		goto cleanup;
	}

	clk_hw->enable_bit = val;
	ad->enable_mask = 0x3 << val;
	ad->autoidle_mask = 0x3 << val;
	clk_hw->enable_bit = ti_clk_get_legacy_bit_shift(node);
	ad->enable_mask = 0x3 << clk_hw->enable_bit;
	ad->autoidle_mask = 0x3 << clk_hw->enable_bit;

	if (of_property_read_u32(node, "ti,idlest-shift", &val)) {
		pr_err("%pOFn missing idlest-shift\n", node);
+50 −7
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/list.h>
#include <linux/minmax.h>
#include <linux/regmap.h>
#include <linux/string_helpers.h>
#include <linux/memblock.h>
@@ -307,8 +308,9 @@ int __init ti_clk_retry_init(struct device_node *node, void *user,
int ti_clk_get_reg_addr(struct device_node *node, int index,
			struct clk_omap_reg *reg)
{
	u32 val;
	int i;
	u32 clksel_addr, val;
	bool is_clksel = false;
	int i, err;

	for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
		if (clocks_node_ptr[i] == node->parent)
@@ -324,21 +326,62 @@ int ti_clk_get_reg_addr(struct device_node *node, int index,

	reg->index = i;

	if (of_property_read_u32_index(node, "reg", index, &val)) {
		if (of_property_read_u32_index(node->parent, "reg",
					       index, &val)) {
			pr_err("%pOFn or parent must have reg[%d]!\n",
			       node, index);
	if (of_device_is_compatible(node->parent, "ti,clksel")) {
		err = of_property_read_u32_index(node->parent, "reg", index, &clksel_addr);
		if (err) {
			pr_err("%pOFn parent clksel must have reg[%d]!\n", node, index);
			return -EINVAL;
		}
		is_clksel = true;
	}

	err = of_property_read_u32_index(node, "reg", index, &val);
	if (err && is_clksel) {
		/* Legacy clksel with no reg and a possible ti,bit-shift property */
		reg->offset = clksel_addr;
		reg->bit = ti_clk_get_legacy_bit_shift(node);
		reg->ptr = NULL;

		return 0;
	}

	/* Updated clksel clock with a proper reg property */
	if (is_clksel) {
		reg->offset = clksel_addr;
		reg->bit = val;
		reg->ptr = NULL;
		return 0;
	}

	/* Other clocks that may or may not have ti,bit-shift property  */
	reg->offset = val;
	reg->bit = ti_clk_get_legacy_bit_shift(node);
	reg->ptr = NULL;

	return 0;
}

/**
 * ti_clk_get_legacy_bit_shift - get bit shift for a clock register
 * @node: device node for the clock
 *
 * Gets the clock register bit shift using the legacy ti,bit-shift
 * property. Only needed for legacy clock, and can be eventually
 * dropped once all the composite clocks use a clksel node with a
 * proper reg property.
 */
int ti_clk_get_legacy_bit_shift(struct device_node *node)
{
	int err;
	u32 val;

	err = of_property_read_u32(node, "ti,bit-shift", &val);
	if (!err && in_range(val, 0, 32))
		return val;

	return 0;
}

void ti_clk_latch(struct clk_omap_reg *reg, s8 shift)
{
	u32 latch;
+1 −0
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,

int ti_clk_get_reg_addr(struct device_node *node, int index,
			struct clk_omap_reg *reg);
int ti_clk_get_legacy_bit_shift(struct device_node *node);
void ti_dt_clocks_register(struct ti_dt_clk *oclks);
int ti_clk_retry_init(struct device_node *node, void *user,
		      ti_of_clk_init_cb_t func);
+1 −4
Original line number Diff line number Diff line
@@ -477,10 +477,7 @@ static int __init ti_clk_divider_populate(struct device_node *node,
	if (ret)
		return ret;

	if (!of_property_read_u32(node, "ti,bit-shift", &val))
		div->shift = val;
	else
		div->shift = 0;
	div->shift = div->reg.bit;

	if (!of_property_read_u32(node, "ti,latch-bit", &val))
		div->latch = val;
+2 −7
Original line number Diff line number Diff line
@@ -132,7 +132,6 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node,
	struct clk_omap_reg reg;
	const char *name;
	u8 enable_bit = 0;
	u32 val;
	u32 flags = 0;
	u8 clk_gate_flags = 0;

@@ -140,8 +139,7 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node,
		if (ti_clk_get_reg_addr(node, 0, &reg))
			return;

		if (!of_property_read_u32(node, "ti,bit-shift", &val))
			enable_bit = val;
		enable_bit = reg.bit;
	}

	if (of_clk_get_parent_count(node) != 1) {
@@ -170,7 +168,6 @@ _of_ti_composite_gate_clk_setup(struct device_node *node,
				const struct clk_hw_omap_ops *hw_ops)
{
	struct clk_hw_omap *gate;
	u32 val = 0;

	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
	if (!gate)
@@ -179,9 +176,7 @@ _of_ti_composite_gate_clk_setup(struct device_node *node,
	if (ti_clk_get_reg_addr(node, 0, &gate->enable_reg))
		goto cleanup;

	of_property_read_u32(node, "ti,bit-shift", &val);

	gate->enable_bit = val;
	gate->enable_bit = gate->enable_reg.bit;
	gate->ops = hw_ops;

	if (!ti_clk_add_component(node, &gate->hw, CLK_COMPONENT_TYPE_GATE))
Loading