0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk-provider.h>
0011 #include <linux/slab.h>
0012 #include <linux/err.h>
0013 #include <linux/of.h>
0014 #include <linux/of_address.h>
0015 #include <linux/clk/ti.h>
0016 #include "clock.h"
0017
0018 #undef pr_fmt
0019 #define pr_fmt(fmt) "%s: " fmt, __func__
0020
0021 static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
0022 {
0023 struct clk_omap_mux *mux = to_clk_omap_mux(hw);
0024 int num_parents = clk_hw_get_num_parents(hw);
0025 u32 val;
0026
0027
0028
0029
0030
0031
0032
0033
0034 val = ti_clk_ll_ops->clk_readl(&mux->reg) >> mux->shift;
0035 val &= mux->mask;
0036
0037 if (mux->table) {
0038 int i;
0039
0040 for (i = 0; i < num_parents; i++)
0041 if (mux->table[i] == val)
0042 return i;
0043 return -EINVAL;
0044 }
0045
0046 if (val && (mux->flags & CLK_MUX_INDEX_BIT))
0047 val = ffs(val) - 1;
0048
0049 if (val && (mux->flags & CLK_MUX_INDEX_ONE))
0050 val--;
0051
0052 if (val >= num_parents)
0053 return -EINVAL;
0054
0055 return val;
0056 }
0057
0058 static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
0059 {
0060 struct clk_omap_mux *mux = to_clk_omap_mux(hw);
0061 u32 val;
0062
0063 if (mux->table) {
0064 index = mux->table[index];
0065 } else {
0066 if (mux->flags & CLK_MUX_INDEX_BIT)
0067 index = (1 << ffs(index));
0068
0069 if (mux->flags & CLK_MUX_INDEX_ONE)
0070 index++;
0071 }
0072
0073 if (mux->flags & CLK_MUX_HIWORD_MASK) {
0074 val = mux->mask << (mux->shift + 16);
0075 } else {
0076 val = ti_clk_ll_ops->clk_readl(&mux->reg);
0077 val &= ~(mux->mask << mux->shift);
0078 }
0079 val |= index << mux->shift;
0080 ti_clk_ll_ops->clk_writel(val, &mux->reg);
0081 ti_clk_latch(&mux->reg, mux->latch);
0082
0083 return 0;
0084 }
0085
0086
0087
0088
0089
0090
0091
0092 static int clk_mux_save_context(struct clk_hw *hw)
0093 {
0094 struct clk_omap_mux *mux = to_clk_omap_mux(hw);
0095
0096 mux->saved_parent = ti_clk_mux_get_parent(hw);
0097 return 0;
0098 }
0099
0100
0101
0102
0103
0104
0105
0106 static void clk_mux_restore_context(struct clk_hw *hw)
0107 {
0108 struct clk_omap_mux *mux = to_clk_omap_mux(hw);
0109
0110 ti_clk_mux_set_parent(hw, mux->saved_parent);
0111 }
0112
0113 const struct clk_ops ti_clk_mux_ops = {
0114 .get_parent = ti_clk_mux_get_parent,
0115 .set_parent = ti_clk_mux_set_parent,
0116 .determine_rate = __clk_mux_determine_rate,
0117 .save_context = clk_mux_save_context,
0118 .restore_context = clk_mux_restore_context,
0119 };
0120
0121 static struct clk *_register_mux(struct device *dev, const char *name,
0122 const char * const *parent_names,
0123 u8 num_parents, unsigned long flags,
0124 struct clk_omap_reg *reg, u8 shift, u32 mask,
0125 s8 latch, u8 clk_mux_flags, u32 *table)
0126 {
0127 struct clk_omap_mux *mux;
0128 struct clk *clk;
0129 struct clk_init_data init;
0130
0131
0132 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
0133 if (!mux)
0134 return ERR_PTR(-ENOMEM);
0135
0136 init.name = name;
0137 init.ops = &ti_clk_mux_ops;
0138 init.flags = flags;
0139 init.parent_names = parent_names;
0140 init.num_parents = num_parents;
0141
0142
0143 memcpy(&mux->reg, reg, sizeof(*reg));
0144 mux->shift = shift;
0145 mux->mask = mask;
0146 mux->latch = latch;
0147 mux->flags = clk_mux_flags;
0148 mux->table = table;
0149 mux->hw.init = &init;
0150
0151 clk = ti_clk_register(dev, &mux->hw, name);
0152
0153 if (IS_ERR(clk))
0154 kfree(mux);
0155
0156 return clk;
0157 }
0158
0159
0160
0161
0162
0163
0164
0165 static void of_mux_clk_setup(struct device_node *node)
0166 {
0167 struct clk *clk;
0168 struct clk_omap_reg reg;
0169 unsigned int num_parents;
0170 const char **parent_names;
0171 const char *name;
0172 u8 clk_mux_flags = 0;
0173 u32 mask = 0;
0174 u32 shift = 0;
0175 s32 latch = -EINVAL;
0176 u32 flags = CLK_SET_RATE_NO_REPARENT;
0177
0178 num_parents = of_clk_get_parent_count(node);
0179 if (num_parents < 2) {
0180 pr_err("mux-clock %pOFn must have parents\n", node);
0181 return;
0182 }
0183 parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL);
0184 if (!parent_names)
0185 goto cleanup;
0186
0187 of_clk_parent_fill(node, parent_names, num_parents);
0188
0189 if (ti_clk_get_reg_addr(node, 0, ®))
0190 goto cleanup;
0191
0192 of_property_read_u32(node, "ti,bit-shift", &shift);
0193
0194 of_property_read_u32(node, "ti,latch-bit", &latch);
0195
0196 if (of_property_read_bool(node, "ti,index-starts-at-one"))
0197 clk_mux_flags |= CLK_MUX_INDEX_ONE;
0198
0199 if (of_property_read_bool(node, "ti,set-rate-parent"))
0200 flags |= CLK_SET_RATE_PARENT;
0201
0202
0203 mask = num_parents;
0204 if (!(clk_mux_flags & CLK_MUX_INDEX_ONE))
0205 mask--;
0206
0207 mask = (1 << fls(mask)) - 1;
0208
0209 name = ti_dt_clk_name(node);
0210 clk = _register_mux(NULL, name, parent_names, num_parents,
0211 flags, ®, shift, mask, latch, clk_mux_flags,
0212 NULL);
0213
0214 if (!IS_ERR(clk))
0215 of_clk_add_provider(node, of_clk_src_simple_get, clk);
0216
0217 cleanup:
0218 kfree(parent_names);
0219 }
0220 CLK_OF_DECLARE(mux_clk, "ti,mux-clock", of_mux_clk_setup);
0221
0222 struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup)
0223 {
0224 struct clk_omap_mux *mux;
0225 int num_parents;
0226
0227 if (!setup)
0228 return NULL;
0229
0230 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
0231 if (!mux)
0232 return ERR_PTR(-ENOMEM);
0233
0234 mux->shift = setup->bit_shift;
0235 mux->latch = -EINVAL;
0236
0237 mux->reg.index = setup->module;
0238 mux->reg.offset = setup->reg;
0239
0240 if (setup->flags & CLKF_INDEX_STARTS_AT_ONE)
0241 mux->flags |= CLK_MUX_INDEX_ONE;
0242
0243 num_parents = setup->num_parents;
0244
0245 mux->mask = num_parents - 1;
0246 mux->mask = (1 << fls(mux->mask)) - 1;
0247
0248 return &mux->hw;
0249 }
0250
0251 static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
0252 {
0253 struct clk_omap_mux *mux;
0254 unsigned int num_parents;
0255 u32 val;
0256
0257 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
0258 if (!mux)
0259 return;
0260
0261 if (ti_clk_get_reg_addr(node, 0, &mux->reg))
0262 goto cleanup;
0263
0264 if (!of_property_read_u32(node, "ti,bit-shift", &val))
0265 mux->shift = val;
0266
0267 if (of_property_read_bool(node, "ti,index-starts-at-one"))
0268 mux->flags |= CLK_MUX_INDEX_ONE;
0269
0270 num_parents = of_clk_get_parent_count(node);
0271
0272 if (num_parents < 2) {
0273 pr_err("%pOFn must have parents\n", node);
0274 goto cleanup;
0275 }
0276
0277 mux->mask = num_parents - 1;
0278 mux->mask = (1 << fls(mux->mask)) - 1;
0279
0280 if (!ti_clk_add_component(node, &mux->hw, CLK_COMPONENT_TYPE_MUX))
0281 return;
0282
0283 cleanup:
0284 kfree(mux);
0285 }
0286 CLK_OF_DECLARE(ti_composite_mux_clk_setup, "ti,composite-mux-clock",
0287 of_ti_composite_mux_clk_setup);