aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2024-02-13 12:48:52 +0200
committerTony Lindgren <tony@atomide.com>2024-02-26 13:08:45 +0200
commit4a5917cd504c7afd5e9de7166eb710687a9b026f (patch)
treeff7c9450aa2db9af0cd887820ba1157708239158 /drivers/clk
parent3516338543cafb658cbd235038c0047d2a8f3068 (diff)
downloadlinux-4a5917cd504c7afd5e9de7166eb710687a9b026f.tar.gz
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: Stephen Boyd <sboyd@kernel.org> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/ti/apll.c11
-rw-r--r--drivers/clk/ti/clk.c57
-rw-r--r--drivers/clk/ti/clock.h1
-rw-r--r--drivers/clk/ti/divider.c5
-rw-r--r--drivers/clk/ti/gate.c9
-rw-r--r--drivers/clk/ti/interface.c4
-rw-r--r--drivers/clk/ti/mux.c6
7 files changed, 60 insertions, 33 deletions
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 93183287c58db7..43514e6f3b7800 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -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);
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 53173bb250da9f..f2117fef7c7d66 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -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;
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 16a9f7c2280a57..2de7acea1ea050 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -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);
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index 5d5bb123ba9494..ade99ab6cfa9b1 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -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;
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
index 8e477d50d0fdbf..a9febd6356b826 100644
--- a/drivers/clk/ti/gate.c
+++ b/drivers/clk/ti/gate.c
@@ -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))
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index 172301c646f85a..3eb35c87c0ed5e 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -66,13 +66,11 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node,
struct clk_omap_reg reg;
u8 enable_bit = 0;
const char *name;
- u32 val;
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;
parent_name = of_clk_get_parent_name(node, 0);
if (!parent_name) {
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 1ebafa386be615..216d85d6aac6c5 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -189,7 +189,7 @@ static void of_mux_clk_setup(struct device_node *node)
if (ti_clk_get_reg_addr(node, 0, &reg))
goto cleanup;
- of_property_read_u32(node, "ti,bit-shift", &shift);
+ shift = reg.bit;
of_property_read_u32(node, "ti,latch-bit", &latch);
@@ -252,7 +252,6 @@ static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
{
struct clk_omap_mux *mux;
unsigned int num_parents;
- u32 val;
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux)
@@ -261,8 +260,7 @@ static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
if (ti_clk_get_reg_addr(node, 0, &mux->reg))
goto cleanup;
- if (!of_property_read_u32(node, "ti,bit-shift", &val))
- mux->shift = val;
+ mux->shift = mux->reg.bit;
if (of_property_read_bool(node, "ti,index-starts-at-one"))
mux->flags |= CLK_MUX_INDEX_ONE;