1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * TI Multiplexer Clock 4 * 5 * Copyright (C) 2013 Texas Instruments, Inc. 6 * 7 * Tero Kristo <t-kristo@ti.com> 8 */ 9 10 #include <linux/clk-provider.h> 11 #include <linux/slab.h> 12 #include <linux/err.h> 13 #include <linux/of.h> 14 #include <linux/of_address.h> 15 #include <linux/clk/ti.h> 16 #include "clock.h" 17 18 #undef pr_fmt 19 #define pr_fmt(fmt) "%s: " fmt, __func__ 20 21 static u8 ti_clk_mux_get_parent(struct clk_hw *hw) 22 { 23 struct clk_omap_mux *mux = to_clk_omap_mux(hw); 24 int num_parents = clk_hw_get_num_parents(hw); 25 u32 val; 26 27 /* 28 * FIXME need a mux-specific flag to determine if val is bitwise or 29 * numeric. e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges 30 * from 0x1 to 0x7 (index starts at one) 31 * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so 32 * val = 0x4 really means "bit 2, index starts at bit 0" 33 */ 34 val = ti_clk_ll_ops->clk_readl(&mux->reg) >> mux->shift; 35 val &= mux->mask; 36 37 if (mux->table) { 38 int i; 39 40 for (i = 0; i < num_parents; i++) 41 if (mux->table[i] == val) 42 return i; 43 return -EINVAL; 44 } 45 46 if (val && (mux->flags & CLK_MUX_INDEX_BIT)) 47 val = ffs(val) - 1; 48 49 if (val && (mux->flags & CLK_MUX_INDEX_ONE)) 50 val--; 51 52 if (val >= num_parents) 53 return -EINVAL; 54 55 return val; 56 } 57 58 static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index) 59 { 60 struct clk_omap_mux *mux = to_clk_omap_mux(hw); 61 u32 val; 62 63 if (mux->table) { 64 index = mux->table[index]; 65 } else { 66 if (mux->flags & CLK_MUX_INDEX_BIT) 67 index = (1 << ffs(index)); 68 69 if (mux->flags & CLK_MUX_INDEX_ONE) 70 index++; 71 } 72 73 if (mux->flags & CLK_MUX_HIWORD_MASK) { 74 val = mux->mask << (mux->shift + 16); 75 } else { 76 val = ti_clk_ll_ops->clk_readl(&mux->reg); 77 val &= ~(mux->mask << mux->shift); 78 } 79 val |= index << mux->shift; 80 ti_clk_ll_ops->clk_writel(val, &mux->reg); 81 ti_clk_latch(&mux->reg, mux->latch); 82 83 return 0; 84 } 85 86 /** 87 * clk_mux_save_context - Save the parent selcted in the mux 88 * @hw: pointer struct clk_hw 89 * 90 * Save the parent mux value. 91 */ 92 static int clk_mux_save_context(struct clk_hw *hw) 93 { 94 struct clk_omap_mux *mux = to_clk_omap_mux(hw); 95 96 mux->saved_parent = ti_clk_mux_get_parent(hw); 97 return 0; 98 } 99 100 /** 101 * clk_mux_restore_context - Restore the parent in the mux 102 * @hw: pointer struct clk_hw 103 * 104 * Restore the saved parent mux value. 105 */ 106 static void clk_mux_restore_context(struct clk_hw *hw) 107 { 108 struct clk_omap_mux *mux = to_clk_omap_mux(hw); 109 110 ti_clk_mux_set_parent(hw, mux->saved_parent); 111 } 112 113 const struct clk_ops ti_clk_mux_ops = { 114 .get_parent = ti_clk_mux_get_parent, 115 .set_parent = ti_clk_mux_set_parent, 116 .determine_rate = __clk_mux_determine_rate, 117 .save_context = clk_mux_save_context, 118 .restore_context = clk_mux_restore_context, 119 }; 120 121 static struct clk *_register_mux(struct device *dev, const char *name, 122 const char * const *parent_names, 123 u8 num_parents, unsigned long flags, 124 struct clk_omap_reg *reg, u8 shift, u32 mask, 125 s8 latch, u8 clk_mux_flags, u32 *table) 126 { 127 struct clk_omap_mux *mux; 128 struct clk *clk; 129 struct clk_init_data init; 130 131 /* allocate the mux */ 132 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 133 if (!mux) 134 return ERR_PTR(-ENOMEM); 135 136 init.name = name; 137 init.ops = &ti_clk_mux_ops; 138 init.flags = flags; 139 init.parent_names = parent_names; 140 init.num_parents = num_parents; 141 142 /* struct clk_mux assignments */ 143 memcpy(&mux->reg, reg, sizeof(*reg)); 144 mux->shift = shift; 145 mux->mask = mask; 146 mux->latch = latch; 147 mux->flags = clk_mux_flags; 148 mux->table = table; 149 mux->hw.init = &init; 150 151 clk = ti_clk_register(dev, &mux->hw, name); 152 153 if (IS_ERR(clk)) 154 kfree(mux); 155 156 return clk; 157 } 158 159 /** 160 * of_mux_clk_setup - Setup function for simple mux rate clock 161 * @node: DT node for the clock 162 * 163 * Sets up a basic clock multiplexer. 164 */ 165 static void of_mux_clk_setup(struct device_node *node) 166 { 167 struct clk *clk; 168 struct clk_omap_reg reg; 169 unsigned int num_parents; 170 const char **parent_names; 171 const char *name; 172 u8 clk_mux_flags = 0; 173 u32 mask = 0; 174 u32 shift = 0; 175 s32 latch = -EINVAL; 176 u32 flags = CLK_SET_RATE_NO_REPARENT; 177 178 num_parents = of_clk_get_parent_count(node); 179 if (num_parents < 2) { 180 pr_err("mux-clock %pOFn must have parents\n", node); 181 return; 182 } 183 parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL); 184 if (!parent_names) 185 goto cleanup; 186 187 of_clk_parent_fill(node, parent_names, num_parents); 188 189 if (ti_clk_get_reg_addr(node, 0, ®)) 190 goto cleanup; 191 192 of_property_read_u32(node, "ti,bit-shift", &shift); 193 194 of_property_read_u32(node, "ti,latch-bit", &latch); 195 196 if (of_property_read_bool(node, "ti,index-starts-at-one")) 197 clk_mux_flags |= CLK_MUX_INDEX_ONE; 198 199 if (of_property_read_bool(node, "ti,set-rate-parent")) 200 flags |= CLK_SET_RATE_PARENT; 201 202 /* Generate bit-mask based on parent info */ 203 mask = num_parents; 204 if (!(clk_mux_flags & CLK_MUX_INDEX_ONE)) 205 mask--; 206 207 mask = (1 << fls(mask)) - 1; 208 209 name = ti_dt_clk_name(node); 210 clk = _register_mux(NULL, name, parent_names, num_parents, 211 flags, ®, shift, mask, latch, clk_mux_flags, 212 NULL); 213 214 if (!IS_ERR(clk)) 215 of_clk_add_provider(node, of_clk_src_simple_get, clk); 216 217 cleanup: 218 kfree(parent_names); 219 } 220 CLK_OF_DECLARE(mux_clk, "ti,mux-clock", of_mux_clk_setup); 221 222 struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup) 223 { 224 struct clk_omap_mux *mux; 225 int num_parents; 226 227 if (!setup) 228 return NULL; 229 230 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 231 if (!mux) 232 return ERR_PTR(-ENOMEM); 233 234 mux->shift = setup->bit_shift; 235 mux->latch = -EINVAL; 236 237 mux->reg.index = setup->module; 238 mux->reg.offset = setup->reg; 239 240 if (setup->flags & CLKF_INDEX_STARTS_AT_ONE) 241 mux->flags |= CLK_MUX_INDEX_ONE; 242 243 num_parents = setup->num_parents; 244 245 mux->mask = num_parents - 1; 246 mux->mask = (1 << fls(mux->mask)) - 1; 247 248 return &mux->hw; 249 } 250 251 static void __init of_ti_composite_mux_clk_setup(struct device_node *node) 252 { 253 struct clk_omap_mux *mux; 254 unsigned int num_parents; 255 u32 val; 256 257 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 258 if (!mux) 259 return; 260 261 if (ti_clk_get_reg_addr(node, 0, &mux->reg)) 262 goto cleanup; 263 264 if (!of_property_read_u32(node, "ti,bit-shift", &val)) 265 mux->shift = val; 266 267 if (of_property_read_bool(node, "ti,index-starts-at-one")) 268 mux->flags |= CLK_MUX_INDEX_ONE; 269 270 num_parents = of_clk_get_parent_count(node); 271 272 if (num_parents < 2) { 273 pr_err("%pOFn must have parents\n", node); 274 goto cleanup; 275 } 276 277 mux->mask = num_parents - 1; 278 mux->mask = (1 << fls(mux->mask)) - 1; 279 280 if (!ti_clk_add_component(node, &mux->hw, CLK_COMPONENT_TYPE_MUX)) 281 return; 282 283 cleanup: 284 kfree(mux); 285 } 286 CLK_OF_DECLARE(ti_composite_mux_clk_setup, "ti,composite-mux-clock", 287 of_ti_composite_mux_clk_setup); 288