xref: /openbmc/linux/drivers/clk/ti/mux.c (revision 8e9356c6)
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