1 /* 2 * TI Multiplexer Clock 3 * 4 * Copyright (C) 2013 Texas Instruments, Inc. 5 * 6 * Tero Kristo <t-kristo@ti.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 13 * kind, whether express or implied; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 */ 17 18 #include <linux/clk-provider.h> 19 #include <linux/slab.h> 20 #include <linux/err.h> 21 #include <linux/of.h> 22 #include <linux/of_address.h> 23 #include <linux/clk/ti.h> 24 25 #undef pr_fmt 26 #define pr_fmt(fmt) "%s: " fmt, __func__ 27 28 #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) 29 30 static u8 ti_clk_mux_get_parent(struct clk_hw *hw) 31 { 32 struct clk_mux *mux = to_clk_mux(hw); 33 int num_parents = __clk_get_num_parents(hw->clk); 34 u32 val; 35 36 /* 37 * FIXME need a mux-specific flag to determine if val is bitwise or 38 * numeric. e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges 39 * from 0x1 to 0x7 (index starts at one) 40 * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so 41 * val = 0x4 really means "bit 2, index starts at bit 0" 42 */ 43 val = ti_clk_ll_ops->clk_readl(mux->reg) >> mux->shift; 44 val &= mux->mask; 45 46 if (mux->table) { 47 int i; 48 49 for (i = 0; i < num_parents; i++) 50 if (mux->table[i] == val) 51 return i; 52 return -EINVAL; 53 } 54 55 if (val && (mux->flags & CLK_MUX_INDEX_BIT)) 56 val = ffs(val) - 1; 57 58 if (val && (mux->flags & CLK_MUX_INDEX_ONE)) 59 val--; 60 61 if (val >= num_parents) 62 return -EINVAL; 63 64 return val; 65 } 66 67 static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index) 68 { 69 struct clk_mux *mux = to_clk_mux(hw); 70 u32 val; 71 unsigned long flags = 0; 72 73 if (mux->table) { 74 index = mux->table[index]; 75 } else { 76 if (mux->flags & CLK_MUX_INDEX_BIT) 77 index = (1 << ffs(index)); 78 79 if (mux->flags & CLK_MUX_INDEX_ONE) 80 index++; 81 } 82 83 if (mux->lock) 84 spin_lock_irqsave(mux->lock, flags); 85 86 if (mux->flags & CLK_MUX_HIWORD_MASK) { 87 val = mux->mask << (mux->shift + 16); 88 } else { 89 val = ti_clk_ll_ops->clk_readl(mux->reg); 90 val &= ~(mux->mask << mux->shift); 91 } 92 val |= index << mux->shift; 93 ti_clk_ll_ops->clk_writel(val, mux->reg); 94 95 if (mux->lock) 96 spin_unlock_irqrestore(mux->lock, flags); 97 98 return 0; 99 } 100 101 const struct clk_ops ti_clk_mux_ops = { 102 .get_parent = ti_clk_mux_get_parent, 103 .set_parent = ti_clk_mux_set_parent, 104 .determine_rate = __clk_mux_determine_rate, 105 }; 106 107 static struct clk *_register_mux(struct device *dev, const char *name, 108 const char **parent_names, u8 num_parents, 109 unsigned long flags, void __iomem *reg, 110 u8 shift, u32 mask, u8 clk_mux_flags, 111 u32 *table, spinlock_t *lock) 112 { 113 struct clk_mux *mux; 114 struct clk *clk; 115 struct clk_init_data init; 116 117 /* allocate the mux */ 118 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 119 if (!mux) { 120 pr_err("%s: could not allocate mux clk\n", __func__); 121 return ERR_PTR(-ENOMEM); 122 } 123 124 init.name = name; 125 init.ops = &ti_clk_mux_ops; 126 init.flags = flags | CLK_IS_BASIC; 127 init.parent_names = parent_names; 128 init.num_parents = num_parents; 129 130 /* struct clk_mux assignments */ 131 mux->reg = reg; 132 mux->shift = shift; 133 mux->mask = mask; 134 mux->flags = clk_mux_flags; 135 mux->lock = lock; 136 mux->table = table; 137 mux->hw.init = &init; 138 139 clk = clk_register(dev, &mux->hw); 140 141 if (IS_ERR(clk)) 142 kfree(mux); 143 144 return clk; 145 } 146 147 /** 148 * of_mux_clk_setup - Setup function for simple mux rate clock 149 * @node: DT node for the clock 150 * 151 * Sets up a basic clock multiplexer. 152 */ 153 static void of_mux_clk_setup(struct device_node *node) 154 { 155 struct clk *clk; 156 void __iomem *reg; 157 int num_parents; 158 const char **parent_names; 159 int i; 160 u8 clk_mux_flags = 0; 161 u32 mask = 0; 162 u32 shift = 0; 163 u32 flags = 0; 164 165 num_parents = of_clk_get_parent_count(node); 166 if (num_parents < 2) { 167 pr_err("mux-clock %s must have parents\n", node->name); 168 return; 169 } 170 parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL); 171 if (!parent_names) 172 goto cleanup; 173 174 for (i = 0; i < num_parents; i++) 175 parent_names[i] = of_clk_get_parent_name(node, i); 176 177 reg = ti_clk_get_reg_addr(node, 0); 178 179 if (!reg) 180 goto cleanup; 181 182 of_property_read_u32(node, "ti,bit-shift", &shift); 183 184 if (of_property_read_bool(node, "ti,index-starts-at-one")) 185 clk_mux_flags |= CLK_MUX_INDEX_ONE; 186 187 if (of_property_read_bool(node, "ti,set-rate-parent")) 188 flags |= CLK_SET_RATE_PARENT; 189 190 /* Generate bit-mask based on parent info */ 191 mask = num_parents; 192 if (!(clk_mux_flags & CLK_MUX_INDEX_ONE)) 193 mask--; 194 195 mask = (1 << fls(mask)) - 1; 196 197 clk = _register_mux(NULL, node->name, parent_names, num_parents, flags, 198 reg, shift, mask, clk_mux_flags, NULL, NULL); 199 200 if (!IS_ERR(clk)) 201 of_clk_add_provider(node, of_clk_src_simple_get, clk); 202 203 cleanup: 204 kfree(parent_names); 205 } 206 CLK_OF_DECLARE(mux_clk, "ti,mux-clock", of_mux_clk_setup); 207 208 static void __init of_ti_composite_mux_clk_setup(struct device_node *node) 209 { 210 struct clk_mux *mux; 211 int num_parents; 212 u32 val; 213 214 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 215 if (!mux) 216 return; 217 218 mux->reg = ti_clk_get_reg_addr(node, 0); 219 220 if (!mux->reg) 221 goto cleanup; 222 223 if (!of_property_read_u32(node, "ti,bit-shift", &val)) 224 mux->shift = val; 225 226 if (of_property_read_bool(node, "ti,index-starts-at-one")) 227 mux->flags |= CLK_MUX_INDEX_ONE; 228 229 num_parents = of_clk_get_parent_count(node); 230 231 if (num_parents < 2) { 232 pr_err("%s must have parents\n", node->name); 233 goto cleanup; 234 } 235 236 mux->mask = num_parents - 1; 237 mux->mask = (1 << fls(mux->mask)) - 1; 238 239 if (!ti_clk_add_component(node, &mux->hw, CLK_COMPONENT_TYPE_MUX)) 240 return; 241 242 cleanup: 243 kfree(mux); 244 } 245 CLK_OF_DECLARE(ti_composite_mux_clk_setup, "ti,composite-mux-clock", 246 of_ti_composite_mux_clk_setup); 247