15a729246SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
224582b34STero Kristo /*
324582b34STero Kristo * OMAP interface clock support
424582b34STero Kristo *
524582b34STero Kristo * Copyright (C) 2013 Texas Instruments, Inc.
624582b34STero Kristo *
724582b34STero Kristo * Tero Kristo <t-kristo@ti.com>
824582b34STero Kristo */
924582b34STero Kristo
1024582b34STero Kristo #include <linux/clk-provider.h>
1124582b34STero Kristo #include <linux/slab.h>
1224582b34STero Kristo #include <linux/of.h>
1324582b34STero Kristo #include <linux/of_address.h>
1424582b34STero Kristo #include <linux/clk/ti.h>
1506524fa4STero Kristo #include "clock.h"
1624582b34STero Kristo
1724582b34STero Kristo #undef pr_fmt
1824582b34STero Kristo #define pr_fmt(fmt) "%s: " fmt, __func__
1924582b34STero Kristo
2024582b34STero Kristo static const struct clk_ops ti_interface_clk_ops = {
2124582b34STero Kristo .init = &omap2_init_clk_clkdm,
2224582b34STero Kristo .enable = &omap2_dflt_clk_enable,
2324582b34STero Kristo .disable = &omap2_dflt_clk_disable,
2424582b34STero Kristo .is_enabled = &omap2_dflt_clk_is_enabled,
2524582b34STero Kristo };
2624582b34STero Kristo
_register_interface(struct device_node * node,const char * name,const char * parent_name,struct clk_omap_reg * reg,u8 bit_idx,const struct clk_hw_omap_ops * ops)27*3400d546SDario Binacchi static struct clk *_register_interface(struct device_node *node,
28*3400d546SDario Binacchi const char *name,
2906524fa4STero Kristo const char *parent_name,
306c0afb50STero Kristo struct clk_omap_reg *reg, u8 bit_idx,
3124582b34STero Kristo const struct clk_hw_omap_ops *ops)
3224582b34STero Kristo {
3324582b34STero Kristo struct clk_init_data init = { NULL };
3424582b34STero Kristo struct clk_hw_omap *clk_hw;
3506524fa4STero Kristo struct clk *clk;
3624582b34STero Kristo
3724582b34STero Kristo clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
3824582b34STero Kristo if (!clk_hw)
3906524fa4STero Kristo return ERR_PTR(-ENOMEM);
4024582b34STero Kristo
4124582b34STero Kristo clk_hw->hw.init = &init;
4224582b34STero Kristo clk_hw->ops = ops;
436c0afb50STero Kristo memcpy(&clk_hw->enable_reg, reg, sizeof(*reg));
4406524fa4STero Kristo clk_hw->enable_bit = bit_idx;
4524582b34STero Kristo
4606524fa4STero Kristo init.name = name;
4724582b34STero Kristo init.ops = &ti_interface_clk_ops;
4824582b34STero Kristo init.flags = 0;
4924582b34STero Kristo
5024582b34STero Kristo init.num_parents = 1;
5124582b34STero Kristo init.parent_names = &parent_name;
5224582b34STero Kristo
53*3400d546SDario Binacchi clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
5424582b34STero Kristo
5506524fa4STero Kristo if (IS_ERR(clk))
5606524fa4STero Kristo kfree(clk_hw);
5706524fa4STero Kristo
5806524fa4STero Kristo return clk;
5906524fa4STero Kristo }
6006524fa4STero Kristo
_of_ti_interface_clk_setup(struct device_node * node,const struct clk_hw_omap_ops * ops)6106524fa4STero Kristo static void __init _of_ti_interface_clk_setup(struct device_node *node,
6206524fa4STero Kristo const struct clk_hw_omap_ops *ops)
6306524fa4STero Kristo {
6406524fa4STero Kristo struct clk *clk;
6506524fa4STero Kristo const char *parent_name;
666c0afb50STero Kristo struct clk_omap_reg reg;
6706524fa4STero Kristo u8 enable_bit = 0;
68ed06099cSTony Lindgren const char *name;
6906524fa4STero Kristo u32 val;
7006524fa4STero Kristo
716c0afb50STero Kristo if (ti_clk_get_reg_addr(node, 0, ®))
7206524fa4STero Kristo return;
7306524fa4STero Kristo
7406524fa4STero Kristo if (!of_property_read_u32(node, "ti,bit-shift", &val))
7506524fa4STero Kristo enable_bit = val;
7606524fa4STero Kristo
7706524fa4STero Kristo parent_name = of_clk_get_parent_name(node, 0);
7806524fa4STero Kristo if (!parent_name) {
79e665f029SRob Herring pr_err("%pOFn must have a parent\n", node);
8024582b34STero Kristo return;
8124582b34STero Kristo }
8224582b34STero Kristo
83ed06099cSTony Lindgren name = ti_dt_clk_name(node);
84*3400d546SDario Binacchi clk = _register_interface(node, name, parent_name, ®,
8506524fa4STero Kristo enable_bit, ops);
8606524fa4STero Kristo
8706524fa4STero Kristo if (!IS_ERR(clk))
8806524fa4STero Kristo of_clk_add_provider(node, of_clk_src_simple_get, clk);
8924582b34STero Kristo }
9024582b34STero Kristo
of_ti_interface_clk_setup(struct device_node * node)9124582b34STero Kristo static void __init of_ti_interface_clk_setup(struct device_node *node)
9224582b34STero Kristo {
9324582b34STero Kristo _of_ti_interface_clk_setup(node, &clkhwops_iclk_wait);
9424582b34STero Kristo }
9524582b34STero Kristo CLK_OF_DECLARE(ti_interface_clk, "ti,omap3-interface-clock",
9624582b34STero Kristo of_ti_interface_clk_setup);
9724582b34STero Kristo
of_ti_no_wait_interface_clk_setup(struct device_node * node)9824582b34STero Kristo static void __init of_ti_no_wait_interface_clk_setup(struct device_node *node)
9924582b34STero Kristo {
10024582b34STero Kristo _of_ti_interface_clk_setup(node, &clkhwops_iclk);
10124582b34STero Kristo }
10224582b34STero Kristo CLK_OF_DECLARE(ti_no_wait_interface_clk, "ti,omap3-no-wait-interface-clock",
10324582b34STero Kristo of_ti_no_wait_interface_clk_setup);
10424582b34STero Kristo
105de742570STero Kristo #ifdef CONFIG_ARCH_OMAP3
of_ti_hsotgusb_interface_clk_setup(struct device_node * node)10624582b34STero Kristo static void __init of_ti_hsotgusb_interface_clk_setup(struct device_node *node)
10724582b34STero Kristo {
10824582b34STero Kristo _of_ti_interface_clk_setup(node,
10924582b34STero Kristo &clkhwops_omap3430es2_iclk_hsotgusb_wait);
11024582b34STero Kristo }
11124582b34STero Kristo CLK_OF_DECLARE(ti_hsotgusb_interface_clk, "ti,omap3-hsotgusb-interface-clock",
11224582b34STero Kristo of_ti_hsotgusb_interface_clk_setup);
11324582b34STero Kristo
of_ti_dss_interface_clk_setup(struct device_node * node)11424582b34STero Kristo static void __init of_ti_dss_interface_clk_setup(struct device_node *node)
11524582b34STero Kristo {
11624582b34STero Kristo _of_ti_interface_clk_setup(node,
11724582b34STero Kristo &clkhwops_omap3430es2_iclk_dss_usbhost_wait);
11824582b34STero Kristo }
11924582b34STero Kristo CLK_OF_DECLARE(ti_dss_interface_clk, "ti,omap3-dss-interface-clock",
12024582b34STero Kristo of_ti_dss_interface_clk_setup);
12124582b34STero Kristo
of_ti_ssi_interface_clk_setup(struct device_node * node)12224582b34STero Kristo static void __init of_ti_ssi_interface_clk_setup(struct device_node *node)
12324582b34STero Kristo {
12424582b34STero Kristo _of_ti_interface_clk_setup(node, &clkhwops_omap3430es2_iclk_ssi_wait);
12524582b34STero Kristo }
12624582b34STero Kristo CLK_OF_DECLARE(ti_ssi_interface_clk, "ti,omap3-ssi-interface-clock",
12724582b34STero Kristo of_ti_ssi_interface_clk_setup);
12824582b34STero Kristo
of_ti_am35xx_interface_clk_setup(struct device_node * node)12924582b34STero Kristo static void __init of_ti_am35xx_interface_clk_setup(struct device_node *node)
13024582b34STero Kristo {
13124582b34STero Kristo _of_ti_interface_clk_setup(node, &clkhwops_am35xx_ipss_wait);
13224582b34STero Kristo }
13324582b34STero Kristo CLK_OF_DECLARE(ti_am35xx_interface_clk, "ti,am35xx-interface-clock",
13424582b34STero Kristo of_ti_am35xx_interface_clk_setup);
135de742570STero Kristo #endif
136de742570STero Kristo
137de742570STero Kristo #ifdef CONFIG_SOC_OMAP2430
of_ti_omap2430_interface_clk_setup(struct device_node * node)138de742570STero Kristo static void __init of_ti_omap2430_interface_clk_setup(struct device_node *node)
139de742570STero Kristo {
140de742570STero Kristo _of_ti_interface_clk_setup(node, &clkhwops_omap2430_i2chs_wait);
141de742570STero Kristo }
142de742570STero Kristo CLK_OF_DECLARE(ti_omap2430_interface_clk, "ti,omap2430-interface-clock",
143de742570STero Kristo of_ti_omap2430_interface_clk_setup);
144de742570STero Kristo #endif
145