15a729246SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
288a17252STero Kristo /*
388a17252STero Kristo * OMAP clkctrl clock support
488a17252STero Kristo *
588a17252STero Kristo * Copyright (C) 2017 Texas Instruments, Inc.
688a17252STero Kristo *
788a17252STero Kristo * Tero Kristo <t-kristo@ti.com>
888a17252STero Kristo */
988a17252STero Kristo
1088a17252STero Kristo #include <linux/clk-provider.h>
1188a17252STero Kristo #include <linux/slab.h>
1288a17252STero Kristo #include <linux/of.h>
1388a17252STero Kristo #include <linux/of_address.h>
1488a17252STero Kristo #include <linux/clk/ti.h>
1588a17252STero Kristo #include <linux/delay.h>
16*bb362d0eSAndy Shevchenko #include <linux/string_helpers.h>
173d8598fbSTero Kristo #include <linux/timekeeping.h>
1888a17252STero Kristo #include "clock.h"
1988a17252STero Kristo
2022a6564fSTero Kristo #define NO_IDLEST 0
2188a17252STero Kristo
2288a17252STero Kristo #define OMAP4_MODULEMODE_MASK 0x3
2388a17252STero Kristo
2488a17252STero Kristo #define MODULEMODE_HWCTRL 0x1
2588a17252STero Kristo #define MODULEMODE_SWCTRL 0x2
2688a17252STero Kristo
2788a17252STero Kristo #define OMAP4_IDLEST_MASK (0x3 << 16)
2888a17252STero Kristo #define OMAP4_IDLEST_SHIFT 16
2988a17252STero Kristo
302209b72dSTero Kristo #define OMAP4_STBYST_MASK BIT(18)
312209b72dSTero Kristo #define OMAP4_STBYST_SHIFT 18
322209b72dSTero Kristo
3388a17252STero Kristo #define CLKCTRL_IDLEST_FUNCTIONAL 0x0
3488a17252STero Kristo #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2
3588a17252STero Kristo #define CLKCTRL_IDLEST_DISABLED 0x3
3688a17252STero Kristo
3788a17252STero Kristo /* These timeouts are in us */
3888a17252STero Kristo #define OMAP4_MAX_MODULE_READY_TIME 2000
3988a17252STero Kristo #define OMAP4_MAX_MODULE_DISABLE_TIME 5000
4088a17252STero Kristo
4188a17252STero Kristo static bool _early_timeout = true;
4288a17252STero Kristo
4388a17252STero Kristo struct omap_clkctrl_provider {
4488a17252STero Kristo void __iomem *base;
4588a17252STero Kristo struct list_head clocks;
46ddfb183eSTero Kristo char *clkdm_name;
4788a17252STero Kristo };
4888a17252STero Kristo
4988a17252STero Kristo struct omap_clkctrl_clk {
5088a17252STero Kristo struct clk_hw *clk;
5188a17252STero Kristo u16 reg_offset;
5288a17252STero Kristo int bit_offset;
5388a17252STero Kristo struct list_head node;
5488a17252STero Kristo };
5588a17252STero Kristo
5688a17252STero Kristo union omap4_timeout {
5788a17252STero Kristo u32 cycles;
5888a17252STero Kristo ktime_t start;
5988a17252STero Kristo };
6088a17252STero Kristo
6188a17252STero Kristo static const struct omap_clkctrl_data default_clkctrl_data[] __initconst = {
6288a17252STero Kristo { 0 },
6388a17252STero Kristo };
6488a17252STero Kristo
_omap4_idlest(u32 val)6588a17252STero Kristo static u32 _omap4_idlest(u32 val)
6688a17252STero Kristo {
6788a17252STero Kristo val &= OMAP4_IDLEST_MASK;
6888a17252STero Kristo val >>= OMAP4_IDLEST_SHIFT;
6988a17252STero Kristo
7088a17252STero Kristo return val;
7188a17252STero Kristo }
7288a17252STero Kristo
_omap4_is_idle(u32 val)7388a17252STero Kristo static bool _omap4_is_idle(u32 val)
7488a17252STero Kristo {
7588a17252STero Kristo val = _omap4_idlest(val);
7688a17252STero Kristo
7788a17252STero Kristo return val == CLKCTRL_IDLEST_DISABLED;
7888a17252STero Kristo }
7988a17252STero Kristo
_omap4_is_ready(u32 val)8088a17252STero Kristo static bool _omap4_is_ready(u32 val)
8188a17252STero Kristo {
8288a17252STero Kristo val = _omap4_idlest(val);
8388a17252STero Kristo
8488a17252STero Kristo return val == CLKCTRL_IDLEST_FUNCTIONAL ||
8588a17252STero Kristo val == CLKCTRL_IDLEST_INTERFACE_IDLE;
8688a17252STero Kristo }
8788a17252STero Kristo
_omap4_is_timeout(union omap4_timeout * time,u32 timeout)8888a17252STero Kristo static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
8988a17252STero Kristo {
903d8598fbSTero Kristo /*
913d8598fbSTero Kristo * There are two special cases where ktime_to_ns() can't be
923d8598fbSTero Kristo * used to track the timeouts. First one is during early boot
933d8598fbSTero Kristo * when the timers haven't been initialized yet. The second
943d8598fbSTero Kristo * one is during suspend-resume cycle while timekeeping is
953d8598fbSTero Kristo * being suspended / resumed. Clocksource for the system
963d8598fbSTero Kristo * can be from a timer that requires pm_runtime access, which
973d8598fbSTero Kristo * will eventually bring us here with timekeeping_suspended,
983d8598fbSTero Kristo * during both suspend entry and resume paths. This happens
9981a41901STony Lindgren * at least on am43xx platform. Account for flakeyness
10081a41901STony Lindgren * with udelay() by multiplying the timeout value by 2.
1013d8598fbSTero Kristo */
1023d8598fbSTero Kristo if (unlikely(_early_timeout || timekeeping_suspended)) {
10388a17252STero Kristo if (time->cycles++ < timeout) {
10481a41901STony Lindgren udelay(1 * 2);
10588a17252STero Kristo return false;
10688a17252STero Kristo }
10788a17252STero Kristo } else {
10888a17252STero Kristo if (!ktime_to_ns(time->start)) {
10988a17252STero Kristo time->start = ktime_get();
11088a17252STero Kristo return false;
11188a17252STero Kristo }
11288a17252STero Kristo
11388a17252STero Kristo if (ktime_us_delta(ktime_get(), time->start) < timeout) {
11488a17252STero Kristo cpu_relax();
11588a17252STero Kristo return false;
11688a17252STero Kristo }
11788a17252STero Kristo }
11888a17252STero Kristo
11988a17252STero Kristo return true;
12088a17252STero Kristo }
12188a17252STero Kristo
_omap4_disable_early_timeout(void)12288a17252STero Kristo static int __init _omap4_disable_early_timeout(void)
12388a17252STero Kristo {
12488a17252STero Kristo _early_timeout = false;
12588a17252STero Kristo
12688a17252STero Kristo return 0;
12788a17252STero Kristo }
12888a17252STero Kristo arch_initcall(_omap4_disable_early_timeout);
12988a17252STero Kristo
_omap4_clkctrl_clk_enable(struct clk_hw * hw)13088a17252STero Kristo static int _omap4_clkctrl_clk_enable(struct clk_hw *hw)
13188a17252STero Kristo {
13288a17252STero Kristo struct clk_hw_omap *clk = to_clk_hw_omap(hw);
13388a17252STero Kristo u32 val;
13488a17252STero Kristo int ret;
13588a17252STero Kristo union omap4_timeout timeout = { 0 };
13688a17252STero Kristo
13788a17252STero Kristo if (clk->clkdm) {
13888a17252STero Kristo ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
13988a17252STero Kristo if (ret) {
14088a17252STero Kristo WARN(1,
14188a17252STero Kristo "%s: could not enable %s's clockdomain %s: %d\n",
14288a17252STero Kristo __func__, clk_hw_get_name(hw),
14388a17252STero Kristo clk->clkdm_name, ret);
14488a17252STero Kristo return ret;
14588a17252STero Kristo }
14688a17252STero Kristo }
14788a17252STero Kristo
1481cc54078STony Lindgren if (!clk->enable_bit)
1491cc54078STony Lindgren return 0;
1501cc54078STony Lindgren
15188a17252STero Kristo val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
15288a17252STero Kristo
15388a17252STero Kristo val &= ~OMAP4_MODULEMODE_MASK;
15488a17252STero Kristo val |= clk->enable_bit;
15588a17252STero Kristo
15688a17252STero Kristo ti_clk_ll_ops->clk_writel(val, &clk->enable_reg);
15788a17252STero Kristo
15822a6564fSTero Kristo if (test_bit(NO_IDLEST, &clk->flags))
15988a17252STero Kristo return 0;
16088a17252STero Kristo
16188a17252STero Kristo /* Wait until module is enabled */
16288a17252STero Kristo while (!_omap4_is_ready(ti_clk_ll_ops->clk_readl(&clk->enable_reg))) {
16388a17252STero Kristo if (_omap4_is_timeout(&timeout, OMAP4_MAX_MODULE_READY_TIME)) {
16488a17252STero Kristo pr_err("%s: failed to enable\n", clk_hw_get_name(hw));
16588a17252STero Kristo return -EBUSY;
16688a17252STero Kristo }
16788a17252STero Kristo }
16888a17252STero Kristo
16988a17252STero Kristo return 0;
17088a17252STero Kristo }
17188a17252STero Kristo
_omap4_clkctrl_clk_disable(struct clk_hw * hw)17288a17252STero Kristo static void _omap4_clkctrl_clk_disable(struct clk_hw *hw)
17388a17252STero Kristo {
17488a17252STero Kristo struct clk_hw_omap *clk = to_clk_hw_omap(hw);
17588a17252STero Kristo u32 val;
17688a17252STero Kristo union omap4_timeout timeout = { 0 };
17788a17252STero Kristo
17888a17252STero Kristo if (!clk->enable_bit)
1791cc54078STony Lindgren goto exit;
18088a17252STero Kristo
18188a17252STero Kristo val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
18288a17252STero Kristo
18388a17252STero Kristo val &= ~OMAP4_MODULEMODE_MASK;
18488a17252STero Kristo
18588a17252STero Kristo ti_clk_ll_ops->clk_writel(val, &clk->enable_reg);
18688a17252STero Kristo
18722a6564fSTero Kristo if (test_bit(NO_IDLEST, &clk->flags))
18888a17252STero Kristo goto exit;
18988a17252STero Kristo
19088a17252STero Kristo /* Wait until module is disabled */
19188a17252STero Kristo while (!_omap4_is_idle(ti_clk_ll_ops->clk_readl(&clk->enable_reg))) {
19288a17252STero Kristo if (_omap4_is_timeout(&timeout,
19388a17252STero Kristo OMAP4_MAX_MODULE_DISABLE_TIME)) {
19488a17252STero Kristo pr_err("%s: failed to disable\n", clk_hw_get_name(hw));
19588a17252STero Kristo break;
19688a17252STero Kristo }
19788a17252STero Kristo }
19888a17252STero Kristo
19988a17252STero Kristo exit:
20088a17252STero Kristo if (clk->clkdm)
20188a17252STero Kristo ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
20288a17252STero Kristo }
20388a17252STero Kristo
_omap4_clkctrl_clk_is_enabled(struct clk_hw * hw)20488a17252STero Kristo static int _omap4_clkctrl_clk_is_enabled(struct clk_hw *hw)
20588a17252STero Kristo {
20688a17252STero Kristo struct clk_hw_omap *clk = to_clk_hw_omap(hw);
20788a17252STero Kristo u32 val;
20888a17252STero Kristo
20988a17252STero Kristo val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
21088a17252STero Kristo
21188a17252STero Kristo if (val & clk->enable_bit)
21288a17252STero Kristo return 1;
21388a17252STero Kristo
21488a17252STero Kristo return 0;
21588a17252STero Kristo }
21688a17252STero Kristo
21788a17252STero Kristo static const struct clk_ops omap4_clkctrl_clk_ops = {
21888a17252STero Kristo .enable = _omap4_clkctrl_clk_enable,
21988a17252STero Kristo .disable = _omap4_clkctrl_clk_disable,
22088a17252STero Kristo .is_enabled = _omap4_clkctrl_clk_is_enabled,
221ddfb183eSTero Kristo .init = omap2_init_clk_clkdm,
22288a17252STero Kristo };
22388a17252STero Kristo
_ti_omap4_clkctrl_xlate(struct of_phandle_args * clkspec,void * data)22488a17252STero Kristo static struct clk_hw *_ti_omap4_clkctrl_xlate(struct of_phandle_args *clkspec,
22588a17252STero Kristo void *data)
22688a17252STero Kristo {
22788a17252STero Kristo struct omap_clkctrl_provider *provider = data;
228560a3164SJakob Koschel struct omap_clkctrl_clk *entry = NULL, *iter;
22988a17252STero Kristo
23088a17252STero Kristo if (clkspec->args_count != 2)
23188a17252STero Kristo return ERR_PTR(-EINVAL);
23288a17252STero Kristo
23388a17252STero Kristo pr_debug("%s: looking for %x:%x\n", __func__,
23488a17252STero Kristo clkspec->args[0], clkspec->args[1]);
23588a17252STero Kristo
236560a3164SJakob Koschel list_for_each_entry(iter, &provider->clocks, node) {
237560a3164SJakob Koschel if (iter->reg_offset == clkspec->args[0] &&
238560a3164SJakob Koschel iter->bit_offset == clkspec->args[1]) {
239560a3164SJakob Koschel entry = iter;
24088a17252STero Kristo break;
24188a17252STero Kristo }
24241b3588dSTony Lindgren }
24388a17252STero Kristo
244560a3164SJakob Koschel if (!entry)
24588a17252STero Kristo return ERR_PTR(-EINVAL);
24688a17252STero Kristo
24788a17252STero Kristo return entry->clk;
24888a17252STero Kristo }
24988a17252STero Kristo
25085204959STero Kristo /* Get clkctrl clock base name based on clkctrl_name or dts node */
clkctrl_get_clock_name(struct device_node * np,const char * clkctrl_name,int offset,int index,bool legacy_naming)25185204959STero Kristo static const char * __init clkctrl_get_clock_name(struct device_node *np,
25285204959STero Kristo const char *clkctrl_name,
25385204959STero Kristo int offset, int index,
25485204959STero Kristo bool legacy_naming)
25585204959STero Kristo {
25685204959STero Kristo char *clock_name;
25785204959STero Kristo
25885204959STero Kristo /* l4per-clkctrl:1234:0 style naming based on clkctrl_name */
25985204959STero Kristo if (clkctrl_name && !legacy_naming) {
26085204959STero Kristo clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d",
26185204959STero Kristo clkctrl_name, offset, index);
262bd46cd0bSClaudiu Beznea if (!clock_name)
263bd46cd0bSClaudiu Beznea return NULL;
264bd46cd0bSClaudiu Beznea
26585204959STero Kristo strreplace(clock_name, '_', '-');
26685204959STero Kristo
26785204959STero Kristo return clock_name;
26885204959STero Kristo }
26985204959STero Kristo
27085204959STero Kristo /* l4per:1234:0 old style naming based on clkctrl_name */
27185204959STero Kristo if (clkctrl_name)
27285204959STero Kristo return kasprintf(GFP_KERNEL, "%s_cm:clk:%04x:%d",
27385204959STero Kristo clkctrl_name, offset, index);
27485204959STero Kristo
27585204959STero Kristo /* l4per_cm:1234:0 old style naming based on parent node name */
27685204959STero Kristo if (legacy_naming)
27785204959STero Kristo return kasprintf(GFP_KERNEL, "%pOFn:clk:%04x:%d",
27885204959STero Kristo np->parent, offset, index);
27985204959STero Kristo
28085204959STero Kristo /* l4per-clkctrl:1234:0 style naming based on node name */
28185204959STero Kristo return kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", np, offset, index);
28285204959STero Kristo }
28385204959STero Kristo
28488a17252STero Kristo static int __init
_ti_clkctrl_clk_register(struct omap_clkctrl_provider * provider,struct device_node * node,struct clk_hw * clk_hw,u16 offset,u8 bit,const char * const * parents,int num_parents,const struct clk_ops * ops,const char * clkctrl_name)28588a17252STero Kristo _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
28688a17252STero Kristo struct device_node *node, struct clk_hw *clk_hw,
28788a17252STero Kristo u16 offset, u8 bit, const char * const *parents,
28885204959STero Kristo int num_parents, const struct clk_ops *ops,
28985204959STero Kristo const char *clkctrl_name)
29088a17252STero Kristo {
29188a17252STero Kristo struct clk_init_data init = { NULL };
29288a17252STero Kristo struct clk *clk;
29388a17252STero Kristo struct omap_clkctrl_clk *clkctrl_clk;
29488a17252STero Kristo int ret = 0;
29588a17252STero Kristo
29685204959STero Kristo init.name = clkctrl_get_clock_name(node, clkctrl_name, offset, bit,
29785204959STero Kristo ti_clk_get_features()->flags &
29885204959STero Kristo TI_CLK_CLKCTRL_COMPAT);
29985204959STero Kristo
30088a17252STero Kristo clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
30188a17252STero Kristo if (!init.name || !clkctrl_clk) {
30288a17252STero Kristo ret = -ENOMEM;
30388a17252STero Kristo goto cleanup;
30488a17252STero Kristo }
30588a17252STero Kristo
30688a17252STero Kristo clk_hw->init = &init;
30788a17252STero Kristo init.parent_names = parents;
30888a17252STero Kristo init.num_parents = num_parents;
30988a17252STero Kristo init.ops = ops;
3108aa09cf3STero Kristo init.flags = 0;
31188a17252STero Kristo
3123400d546SDario Binacchi clk = of_ti_clk_register(node, clk_hw, init.name);
31388a17252STero Kristo if (IS_ERR_OR_NULL(clk)) {
31488a17252STero Kristo ret = -EINVAL;
31588a17252STero Kristo goto cleanup;
31688a17252STero Kristo }
31788a17252STero Kristo
31888a17252STero Kristo clkctrl_clk->reg_offset = offset;
31988a17252STero Kristo clkctrl_clk->bit_offset = bit;
32088a17252STero Kristo clkctrl_clk->clk = clk_hw;
32188a17252STero Kristo
32288a17252STero Kristo list_add(&clkctrl_clk->node, &provider->clocks);
32388a17252STero Kristo
32488a17252STero Kristo return 0;
32588a17252STero Kristo
32688a17252STero Kristo cleanup:
32788a17252STero Kristo kfree(init.name);
32888a17252STero Kristo kfree(clkctrl_clk);
32988a17252STero Kristo return ret;
33088a17252STero Kristo }
33188a17252STero Kristo
33288a17252STero Kristo static void __init
_ti_clkctrl_setup_gate(struct omap_clkctrl_provider * provider,struct device_node * node,u16 offset,const struct omap_clkctrl_bit_data * data,void __iomem * reg,const char * clkctrl_name)33388a17252STero Kristo _ti_clkctrl_setup_gate(struct omap_clkctrl_provider *provider,
33488a17252STero Kristo struct device_node *node, u16 offset,
33588a17252STero Kristo const struct omap_clkctrl_bit_data *data,
33685204959STero Kristo void __iomem *reg, const char *clkctrl_name)
33788a17252STero Kristo {
33888a17252STero Kristo struct clk_hw_omap *clk_hw;
33988a17252STero Kristo
34088a17252STero Kristo clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
34188a17252STero Kristo if (!clk_hw)
34288a17252STero Kristo return;
34388a17252STero Kristo
34488a17252STero Kristo clk_hw->enable_bit = data->bit;
34588a17252STero Kristo clk_hw->enable_reg.ptr = reg;
34688a17252STero Kristo
34788a17252STero Kristo if (_ti_clkctrl_clk_register(provider, node, &clk_hw->hw, offset,
34888a17252STero Kristo data->bit, data->parents, 1,
34985204959STero Kristo &omap_gate_clk_ops, clkctrl_name))
35088a17252STero Kristo kfree(clk_hw);
35188a17252STero Kristo }
35288a17252STero Kristo
35388a17252STero Kristo static void __init
_ti_clkctrl_setup_mux(struct omap_clkctrl_provider * provider,struct device_node * node,u16 offset,const struct omap_clkctrl_bit_data * data,void __iomem * reg,const char * clkctrl_name)35488a17252STero Kristo _ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider,
35588a17252STero Kristo struct device_node *node, u16 offset,
35688a17252STero Kristo const struct omap_clkctrl_bit_data *data,
35785204959STero Kristo void __iomem *reg, const char *clkctrl_name)
35888a17252STero Kristo {
35988a17252STero Kristo struct clk_omap_mux *mux;
36088a17252STero Kristo int num_parents = 0;
36188a17252STero Kristo const char * const *pname;
36288a17252STero Kristo
36388a17252STero Kristo mux = kzalloc(sizeof(*mux), GFP_KERNEL);
36488a17252STero Kristo if (!mux)
36588a17252STero Kristo return;
36688a17252STero Kristo
36788a17252STero Kristo pname = data->parents;
36888a17252STero Kristo while (*pname) {
36988a17252STero Kristo num_parents++;
37088a17252STero Kristo pname++;
37188a17252STero Kristo }
37288a17252STero Kristo
37388a17252STero Kristo mux->mask = num_parents;
37449eec6fbSTero Kristo if (!(mux->flags & CLK_MUX_INDEX_ONE))
37549eec6fbSTero Kristo mux->mask--;
37649eec6fbSTero Kristo
37788a17252STero Kristo mux->mask = (1 << fls(mux->mask)) - 1;
37888a17252STero Kristo
37988a17252STero Kristo mux->shift = data->bit;
38088a17252STero Kristo mux->reg.ptr = reg;
38188a17252STero Kristo
38288a17252STero Kristo if (_ti_clkctrl_clk_register(provider, node, &mux->hw, offset,
38388a17252STero Kristo data->bit, data->parents, num_parents,
38485204959STero Kristo &ti_clk_mux_ops, clkctrl_name))
38588a17252STero Kristo kfree(mux);
38688a17252STero Kristo }
38788a17252STero Kristo
38888a17252STero Kristo static void __init
_ti_clkctrl_setup_div(struct omap_clkctrl_provider * provider,struct device_node * node,u16 offset,const struct omap_clkctrl_bit_data * data,void __iomem * reg,const char * clkctrl_name)38988a17252STero Kristo _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider,
39088a17252STero Kristo struct device_node *node, u16 offset,
39188a17252STero Kristo const struct omap_clkctrl_bit_data *data,
39285204959STero Kristo void __iomem *reg, const char *clkctrl_name)
39388a17252STero Kristo {
39488a17252STero Kristo struct clk_omap_divider *div;
39588a17252STero Kristo const struct omap_clkctrl_div_data *div_data = data->data;
39649eec6fbSTero Kristo u8 div_flags = 0;
39788a17252STero Kristo
39888a17252STero Kristo div = kzalloc(sizeof(*div), GFP_KERNEL);
39988a17252STero Kristo if (!div)
40088a17252STero Kristo return;
40188a17252STero Kristo
40288a17252STero Kristo div->reg.ptr = reg;
40388a17252STero Kristo div->shift = data->bit;
40449eec6fbSTero Kristo div->flags = div_data->flags;
40588a17252STero Kristo
40649eec6fbSTero Kristo if (div->flags & CLK_DIVIDER_POWER_OF_TWO)
40749eec6fbSTero Kristo div_flags |= CLKF_INDEX_POWER_OF_TWO;
40849eec6fbSTero Kristo
40949eec6fbSTero Kristo if (ti_clk_parse_divider_data((int *)div_data->dividers, 0,
41049eec6fbSTero Kristo div_data->max_div, div_flags,
411a229965cSTero Kristo div)) {
412c2c296c3STero Kristo pr_err("%s: Data parsing for %pOF:%04x:%d failed\n", __func__,
413c2c296c3STero Kristo node, offset, data->bit);
41488a17252STero Kristo kfree(div);
41588a17252STero Kristo return;
41688a17252STero Kristo }
41788a17252STero Kristo
41888a17252STero Kristo if (_ti_clkctrl_clk_register(provider, node, &div->hw, offset,
41988a17252STero Kristo data->bit, data->parents, 1,
42085204959STero Kristo &ti_clk_divider_ops, clkctrl_name))
42188a17252STero Kristo kfree(div);
42288a17252STero Kristo }
42388a17252STero Kristo
42488a17252STero Kristo static void __init
_ti_clkctrl_setup_subclks(struct omap_clkctrl_provider * provider,struct device_node * node,const struct omap_clkctrl_reg_data * data,void __iomem * reg,const char * clkctrl_name)42588a17252STero Kristo _ti_clkctrl_setup_subclks(struct omap_clkctrl_provider *provider,
42688a17252STero Kristo struct device_node *node,
42788a17252STero Kristo const struct omap_clkctrl_reg_data *data,
42885204959STero Kristo void __iomem *reg, const char *clkctrl_name)
42988a17252STero Kristo {
43088a17252STero Kristo const struct omap_clkctrl_bit_data *bits = data->bit_data;
43188a17252STero Kristo
43288a17252STero Kristo if (!bits)
43388a17252STero Kristo return;
43488a17252STero Kristo
43588a17252STero Kristo while (bits->bit) {
43688a17252STero Kristo switch (bits->type) {
43788a17252STero Kristo case TI_CLK_GATE:
43888a17252STero Kristo _ti_clkctrl_setup_gate(provider, node, data->offset,
43985204959STero Kristo bits, reg, clkctrl_name);
44088a17252STero Kristo break;
44188a17252STero Kristo
44288a17252STero Kristo case TI_CLK_DIVIDER:
44388a17252STero Kristo _ti_clkctrl_setup_div(provider, node, data->offset,
44485204959STero Kristo bits, reg, clkctrl_name);
44588a17252STero Kristo break;
44688a17252STero Kristo
44788a17252STero Kristo case TI_CLK_MUX:
44888a17252STero Kristo _ti_clkctrl_setup_mux(provider, node, data->offset,
44985204959STero Kristo bits, reg, clkctrl_name);
45088a17252STero Kristo break;
45188a17252STero Kristo
45288a17252STero Kristo default:
45388a17252STero Kristo pr_err("%s: bad subclk type: %d\n", __func__,
45488a17252STero Kristo bits->type);
45588a17252STero Kristo return;
45688a17252STero Kristo }
45788a17252STero Kristo bits++;
45888a17252STero Kristo }
45988a17252STero Kristo }
46088a17252STero Kristo
_clkctrl_add_provider(void * data,struct device_node * np)461729e13bfSTero Kristo static void __init _clkctrl_add_provider(void *data,
462729e13bfSTero Kristo struct device_node *np)
463729e13bfSTero Kristo {
464729e13bfSTero Kristo of_clk_add_hw_provider(np, _ti_omap4_clkctrl_xlate, data);
465729e13bfSTero Kristo }
466729e13bfSTero Kristo
467d02747e9STony Lindgren /*
468d02747e9STony Lindgren * Get clock name based on "clock-output-names" property or the
469d02747e9STony Lindgren * compatible property for clkctrl.
470d02747e9STony Lindgren */
clkctrl_get_name(struct device_node * np)471d02747e9STony Lindgren static const char * __init clkctrl_get_name(struct device_node *np)
4726c309052STony Lindgren {
4736c309052STony Lindgren struct property *prop;
4746c309052STony Lindgren const int prefix_len = 11;
4756c309052STony Lindgren const char *compat;
476d02747e9STony Lindgren const char *output;
477*bb362d0eSAndy Shevchenko const char *end;
4786c309052STony Lindgren char *name;
4796c309052STony Lindgren
480d02747e9STony Lindgren if (!of_property_read_string_index(np, "clock-output-names", 0,
481d02747e9STony Lindgren &output)) {
482d02747e9STony Lindgren int len;
483d02747e9STony Lindgren
484d02747e9STony Lindgren len = strlen(output);
485d02747e9STony Lindgren end = strstr(output, "_clkctrl");
486d02747e9STony Lindgren if (end)
487d02747e9STony Lindgren len -= strlen(end);
488d02747e9STony Lindgren name = kstrndup(output, len, GFP_KERNEL);
489d02747e9STony Lindgren
490d02747e9STony Lindgren return name;
491d02747e9STony Lindgren }
492d02747e9STony Lindgren
4936c309052STony Lindgren of_property_for_each_string(np, "compatible", prop, compat) {
4946c309052STony Lindgren if (!strncmp("ti,clkctrl-", compat, prefix_len)) {
495*bb362d0eSAndy Shevchenko end = compat + prefix_len;
4966c309052STony Lindgren /* Two letter minimum name length for l3, l4 etc */
497*bb362d0eSAndy Shevchenko if (strnlen(end, 16) < 2)
4986c309052STony Lindgren continue;
499*bb362d0eSAndy Shevchenko name = kstrdup_and_replace(end, '-', '_', GFP_KERNEL);
5006c309052STony Lindgren if (!name)
5016c309052STony Lindgren continue;
5026c309052STony Lindgren
5036c309052STony Lindgren return name;
5046c309052STony Lindgren }
5056c309052STony Lindgren }
5066c309052STony Lindgren
5076c309052STony Lindgren return NULL;
5086c309052STony Lindgren }
5096c309052STony Lindgren
_ti_omap4_clkctrl_setup(struct device_node * node)51088a17252STero Kristo static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
51188a17252STero Kristo {
51288a17252STero Kristo struct omap_clkctrl_provider *provider;
51388a17252STero Kristo const struct omap_clkctrl_data *data = default_clkctrl_data;
51488a17252STero Kristo const struct omap_clkctrl_reg_data *reg_data;
51588a17252STero Kristo struct clk_init_data init = { NULL };
51688a17252STero Kristo struct clk_hw_omap *hw;
51788a17252STero Kristo struct clk *clk;
5186c309052STony Lindgren struct omap_clkctrl_clk *clkctrl_clk = NULL;
5196c309052STony Lindgren bool legacy_naming;
52078ab3a9aSTony Lindgren const char *clkctrl_name;
52188a17252STero Kristo u32 addr;
522729e13bfSTero Kristo int ret;
5231dc88f78STero Kristo char *c;
5242b1202d7STero Kristo u16 soc_mask = 0;
52581fe523aSRob Herring struct resource res;
52688a17252STero Kristo
52781fe523aSRob Herring of_address_to_resource(node, 0, &res);
52881fe523aSRob Herring addr = (u32)res.start;
52988a17252STero Kristo
5301c881b5aSTero Kristo #ifdef CONFIG_ARCH_OMAP4
5311c881b5aSTero Kristo if (of_machine_is_compatible("ti,omap4"))
5321c881b5aSTero Kristo data = omap4_clkctrl_data;
5331c881b5aSTero Kristo #endif
5340ad902f6STero Kristo #ifdef CONFIG_SOC_OMAP5
5350ad902f6STero Kristo if (of_machine_is_compatible("ti,omap5"))
5360ad902f6STero Kristo data = omap5_clkctrl_data;
5370ad902f6STero Kristo #endif
53824d504a3STero Kristo #ifdef CONFIG_SOC_DRA7XX
539579cdf58STony Lindgren if (of_machine_is_compatible("ti,dra7"))
54024d504a3STero Kristo data = dra7_clkctrl_data;
5412b1202d7STero Kristo if (of_machine_is_compatible("ti,dra72"))
5422b1202d7STero Kristo soc_mask = CLKF_SOC_DRA72;
5432b1202d7STero Kristo if (of_machine_is_compatible("ti,dra74"))
5442b1202d7STero Kristo soc_mask = CLKF_SOC_DRA74;
5452b1202d7STero Kristo if (of_machine_is_compatible("ti,dra76"))
5462b1202d7STero Kristo soc_mask = CLKF_SOC_DRA76;
54724d504a3STero Kristo #endif
548df54bfc5STero Kristo #ifdef CONFIG_SOC_AM33XX
5498850c3eaSTony Lindgren if (of_machine_is_compatible("ti,am33xx"))
550df54bfc5STero Kristo data = am3_clkctrl_data;
551df54bfc5STero Kristo #endif
552a3da10b7STero Kristo #ifdef CONFIG_SOC_AM43XX
553e65eb2efSTony Lindgren if (of_machine_is_compatible("ti,am4372"))
554a3da10b7STero Kristo data = am4_clkctrl_data;
55576a1049bSTero Kristo
556e65eb2efSTony Lindgren if (of_machine_is_compatible("ti,am438x"))
557a3da10b7STero Kristo data = am438x_clkctrl_data;
558a3da10b7STero Kristo #endif
55926ca2e97STero Kristo #ifdef CONFIG_SOC_TI81XX
56026ca2e97STero Kristo if (of_machine_is_compatible("ti,dm814"))
56126ca2e97STero Kristo data = dm814_clkctrl_data;
56250ef5089STero Kristo
56350ef5089STero Kristo if (of_machine_is_compatible("ti,dm816"))
56450ef5089STero Kristo data = dm816_clkctrl_data;
56526ca2e97STero Kristo #endif
5661c881b5aSTero Kristo
567869decd1STero Kristo if (ti_clk_get_features()->flags & TI_CLK_DEVICE_TYPE_GP)
568869decd1STero Kristo soc_mask |= CLKF_SOC_NONSEC;
569869decd1STero Kristo
57088a17252STero Kristo while (data->addr) {
57188a17252STero Kristo if (addr == data->addr)
57288a17252STero Kristo break;
57388a17252STero Kristo
57488a17252STero Kristo data++;
57588a17252STero Kristo }
57688a17252STero Kristo
57788a17252STero Kristo if (!data->addr) {
578c2c296c3STero Kristo pr_err("%pOF not found from clkctrl data.\n", node);
57988a17252STero Kristo return;
58088a17252STero Kristo }
58188a17252STero Kristo
58288a17252STero Kristo provider = kzalloc(sizeof(*provider), GFP_KERNEL);
58388a17252STero Kristo if (!provider)
58488a17252STero Kristo return;
58588a17252STero Kristo
58688a17252STero Kristo provider->base = of_iomap(node, 0);
58788a17252STero Kristo
5886c309052STony Lindgren legacy_naming = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT;
5896c309052STony Lindgren clkctrl_name = clkctrl_get_name(node);
5906c309052STony Lindgren if (clkctrl_name) {
5916c309052STony Lindgren provider->clkdm_name = kasprintf(GFP_KERNEL,
5926c309052STony Lindgren "%s_clkdm", clkctrl_name);
593bd46cd0bSClaudiu Beznea if (!provider->clkdm_name) {
594bd46cd0bSClaudiu Beznea kfree(provider);
595bd46cd0bSClaudiu Beznea return;
596bd46cd0bSClaudiu Beznea }
5976c309052STony Lindgren goto clkdm_found;
5986c309052STony Lindgren }
5996c309052STony Lindgren
6006c309052STony Lindgren /*
6016c309052STony Lindgren * The code below can be removed when all clkctrl nodes use domain
6026a6c2389SJulia Lawall * specific compatible property and standard clock node naming
6036c309052STony Lindgren */
6046c309052STony Lindgren if (legacy_naming) {
605e665f029SRob Herring provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFnxxx", node->parent);
606ddfb183eSTero Kristo if (!provider->clkdm_name) {
607ddfb183eSTero Kristo kfree(provider);
608ddfb183eSTero Kristo return;
609ddfb183eSTero Kristo }
610ddfb183eSTero Kristo
611ddfb183eSTero Kristo /*
61247b00dcfSTero Kristo * Create default clkdm name, replace _cm from end of parent
61347b00dcfSTero Kristo * node name with _clkdm
614ddfb183eSTero Kristo */
615d17a718dSTony Lindgren provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0;
61647b00dcfSTero Kristo } else {
617a72d7850SStephen Boyd provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFn", node);
61847b00dcfSTero Kristo if (!provider->clkdm_name) {
61947b00dcfSTero Kristo kfree(provider);
62047b00dcfSTero Kristo return;
62147b00dcfSTero Kristo }
62247b00dcfSTero Kristo
62347b00dcfSTero Kristo /*
62447b00dcfSTero Kristo * Create default clkdm name, replace _clkctrl from end of
62547b00dcfSTero Kristo * node name with _clkdm
62647b00dcfSTero Kristo */
62747b00dcfSTero Kristo provider->clkdm_name[strlen(provider->clkdm_name) - 7] = 0;
62847b00dcfSTero Kristo }
62947b00dcfSTero Kristo
630ddfb183eSTero Kristo strcat(provider->clkdm_name, "clkdm");
631ddfb183eSTero Kristo
6321dc88f78STero Kristo /* Replace any dash from the clkdm name with underscore */
6331dc88f78STero Kristo c = provider->clkdm_name;
6341dc88f78STero Kristo
6351dc88f78STero Kristo while (*c) {
6361dc88f78STero Kristo if (*c == '-')
6371dc88f78STero Kristo *c = '_';
6381dc88f78STero Kristo c++;
6391dc88f78STero Kristo }
6406c309052STony Lindgren clkdm_found:
64188a17252STero Kristo INIT_LIST_HEAD(&provider->clocks);
64288a17252STero Kristo
64388a17252STero Kristo /* Generate clocks */
64488a17252STero Kristo reg_data = data->regs;
64588a17252STero Kristo
64688a17252STero Kristo while (reg_data->parent) {
6472b1202d7STero Kristo if ((reg_data->flags & CLKF_SOC_MASK) &&
6482b1202d7STero Kristo (reg_data->flags & soc_mask) == 0) {
6492b1202d7STero Kristo reg_data++;
6502b1202d7STero Kristo continue;
6512b1202d7STero Kristo }
6522b1202d7STero Kristo
65388a17252STero Kristo hw = kzalloc(sizeof(*hw), GFP_KERNEL);
65488a17252STero Kristo if (!hw)
65588a17252STero Kristo return;
65688a17252STero Kristo
65788a17252STero Kristo hw->enable_reg.ptr = provider->base + reg_data->offset;
65888a17252STero Kristo
65988a17252STero Kristo _ti_clkctrl_setup_subclks(provider, node, reg_data,
66085204959STero Kristo hw->enable_reg.ptr, clkctrl_name);
66188a17252STero Kristo
66288a17252STero Kristo if (reg_data->flags & CLKF_SW_SUP)
66388a17252STero Kristo hw->enable_bit = MODULEMODE_SWCTRL;
66488a17252STero Kristo if (reg_data->flags & CLKF_HW_SUP)
66588a17252STero Kristo hw->enable_bit = MODULEMODE_HWCTRL;
66688a17252STero Kristo if (reg_data->flags & CLKF_NO_IDLEST)
66722a6564fSTero Kristo set_bit(NO_IDLEST, &hw->flags);
66888a17252STero Kristo
669ddfb183eSTero Kristo if (reg_data->clkdm_name)
670ddfb183eSTero Kristo hw->clkdm_name = reg_data->clkdm_name;
671ddfb183eSTero Kristo else
672ddfb183eSTero Kristo hw->clkdm_name = provider->clkdm_name;
673ddfb183eSTero Kristo
67488a17252STero Kristo init.parent_names = ®_data->parent;
67588a17252STero Kristo init.num_parents = 1;
67688a17252STero Kristo init.flags = 0;
67749159a9dSTero Kristo if (reg_data->flags & CLKF_SET_RATE_PARENT)
67849159a9dSTero Kristo init.flags |= CLK_SET_RATE_PARENT;
6796c309052STony Lindgren
6806c309052STony Lindgren init.name = clkctrl_get_clock_name(node, clkctrl_name,
6816c309052STony Lindgren reg_data->offset, 0,
6826c309052STony Lindgren legacy_naming);
6836c309052STony Lindgren if (!init.name)
6846c309052STony Lindgren goto cleanup;
6856c309052STony Lindgren
68688a17252STero Kristo clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
6876c309052STony Lindgren if (!clkctrl_clk)
68888a17252STero Kristo goto cleanup;
68988a17252STero Kristo
69088a17252STero Kristo init.ops = &omap4_clkctrl_clk_ops;
69188a17252STero Kristo hw->hw.init = &init;
69288a17252STero Kristo
6933400d546SDario Binacchi clk = of_ti_clk_register_omap_hw(node, &hw->hw, init.name);
69488a17252STero Kristo if (IS_ERR_OR_NULL(clk))
69588a17252STero Kristo goto cleanup;
69688a17252STero Kristo
69788a17252STero Kristo clkctrl_clk->reg_offset = reg_data->offset;
69888a17252STero Kristo clkctrl_clk->clk = &hw->hw;
69988a17252STero Kristo
70088a17252STero Kristo list_add(&clkctrl_clk->node, &provider->clocks);
70188a17252STero Kristo
70288a17252STero Kristo reg_data++;
70388a17252STero Kristo }
70488a17252STero Kristo
705729e13bfSTero Kristo ret = of_clk_add_hw_provider(node, _ti_omap4_clkctrl_xlate, provider);
706729e13bfSTero Kristo if (ret == -EPROBE_DEFER)
707729e13bfSTero Kristo ti_clk_retry_init(node, provider, _clkctrl_add_provider);
708729e13bfSTero Kristo
7096c309052STony Lindgren kfree(clkctrl_name);
7106c309052STony Lindgren
71188a17252STero Kristo return;
71288a17252STero Kristo
71388a17252STero Kristo cleanup:
71488a17252STero Kristo kfree(hw);
71588a17252STero Kristo kfree(init.name);
7166c309052STony Lindgren kfree(clkctrl_name);
71788a17252STero Kristo kfree(clkctrl_clk);
71888a17252STero Kristo }
71988a17252STero Kristo CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl",
72088a17252STero Kristo _ti_omap4_clkctrl_setup);
7212209b72dSTero Kristo
7222209b72dSTero Kristo /**
7232209b72dSTero Kristo * ti_clk_is_in_standby - Check if clkctrl clock is in standby or not
7242209b72dSTero Kristo * @clk: clock to check standby status for
7252209b72dSTero Kristo *
7262209b72dSTero Kristo * Finds whether the provided clock is in standby mode or not. Returns
7272209b72dSTero Kristo * true if the provided clock is a clkctrl type clock and it is in standby,
7282209b72dSTero Kristo * false otherwise.
7292209b72dSTero Kristo */
ti_clk_is_in_standby(struct clk * clk)7302209b72dSTero Kristo bool ti_clk_is_in_standby(struct clk *clk)
7312209b72dSTero Kristo {
7322209b72dSTero Kristo struct clk_hw *hw;
7332209b72dSTero Kristo struct clk_hw_omap *hwclk;
7342209b72dSTero Kristo u32 val;
7352209b72dSTero Kristo
7362209b72dSTero Kristo hw = __clk_get_hw(clk);
7372209b72dSTero Kristo
7382209b72dSTero Kristo if (!omap2_clk_is_hw_omap(hw))
7392209b72dSTero Kristo return false;
7402209b72dSTero Kristo
7412209b72dSTero Kristo hwclk = to_clk_hw_omap(hw);
7422209b72dSTero Kristo
7432209b72dSTero Kristo val = ti_clk_ll_ops->clk_readl(&hwclk->enable_reg);
7442209b72dSTero Kristo
7452209b72dSTero Kristo if (val & OMAP4_STBYST_MASK)
7462209b72dSTero Kristo return true;
7472209b72dSTero Kristo
7482209b72dSTero Kristo return false;
7492209b72dSTero Kristo }
7502209b72dSTero Kristo EXPORT_SYMBOL_GPL(ti_clk_is_in_standby);
751