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 selected 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_node *node, const char *name, 122 const struct clk_parent_data *parent_data, 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_init_data init = {}; 128 struct clk_omap_mux *mux; 129 struct clk *clk; 130 131 /* allocate the mux */ 132 mux = kzalloc_obj(*mux); 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_data = parent_data; 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 = of_ti_clk_register(node, &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 struct clk_parent_data *parent_data; 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 int i; 178 179 num_parents = of_clk_get_parent_count(node); 180 if (num_parents < 2) { 181 pr_err("mux-clock %pOFn must have parents\n", node); 182 return; 183 } 184 parent_data = kzalloc_objs(*parent_data, num_parents); 185 if (!parent_data) 186 return; 187 188 for (i = 0; i < num_parents; i++) 189 parent_data[i].index = i; 190 191 if (ti_clk_get_reg_addr(node, 0, ®)) 192 goto cleanup; 193 194 shift = reg.bit; 195 196 of_property_read_u32(node, "ti,latch-bit", &latch); 197 198 if (of_property_read_bool(node, "ti,index-starts-at-one")) 199 clk_mux_flags |= CLK_MUX_INDEX_ONE; 200 201 if (of_property_read_bool(node, "ti,set-rate-parent")) 202 flags |= CLK_SET_RATE_PARENT; 203 204 /* Generate bit-mask based on parent info */ 205 mask = num_parents; 206 if (!(clk_mux_flags & CLK_MUX_INDEX_ONE)) 207 mask--; 208 209 mask = (1 << fls(mask)) - 1; 210 211 name = ti_dt_clk_name(node); 212 clk = _register_mux(node, name, parent_data, num_parents, 213 flags, ®, shift, mask, latch, clk_mux_flags, 214 NULL); 215 216 if (!IS_ERR(clk)) 217 of_clk_add_provider(node, of_clk_src_simple_get, clk); 218 219 cleanup: 220 kfree(parent_data); 221 } 222 CLK_OF_DECLARE(mux_clk, "ti,mux-clock", of_mux_clk_setup); 223 224 struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup) 225 { 226 struct clk_omap_mux *mux; 227 int num_parents; 228 229 if (!setup) 230 return NULL; 231 232 mux = kzalloc_obj(*mux); 233 if (!mux) 234 return ERR_PTR(-ENOMEM); 235 236 mux->shift = setup->bit_shift; 237 mux->latch = -EINVAL; 238 239 mux->reg.index = setup->module; 240 mux->reg.offset = setup->reg; 241 242 if (setup->flags & CLKF_INDEX_STARTS_AT_ONE) 243 mux->flags |= CLK_MUX_INDEX_ONE; 244 245 num_parents = setup->num_parents; 246 247 mux->mask = num_parents - 1; 248 mux->mask = (1 << fls(mux->mask)) - 1; 249 250 return &mux->hw; 251 } 252 253 static void __init of_ti_composite_mux_clk_setup(struct device_node *node) 254 { 255 struct clk_omap_mux *mux; 256 unsigned int num_parents; 257 258 mux = kzalloc_obj(*mux); 259 if (!mux) 260 return; 261 262 if (ti_clk_get_reg_addr(node, 0, &mux->reg)) 263 goto cleanup; 264 265 mux->shift = mux->reg.bit; 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