2 * Copyright (c) 2014 Marvell Technology Group Ltd.
4 * Alexandre Belloni <alexandre.belloni@free-electrons.com>
5 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <linux/bitops.h>
20 #include <linux/clk-provider.h>
22 #include <linux/of_address.h>
23 #include <linux/slab.h>
24 #include <linux/spinlock.h>
26 #include "berlin2-div.h"
29 * Clock dividers in Berlin2 SoCs comprise a complex cell to select
30 * input pll and divider. The virtual structure as it is used in Marvell
31 * BSP code can be seen as:
34 * pll0 --------------->| 0 | +---+
35 * +---+ |(B)|--+--------------->| 0 | +---+
36 * pll1.0 -->| 0 | +-->| 1 | | +--------+ |(E)|----->| 0 | +---+
37 * pll1.1 -->| 1 | | +---+ +-->|(C) 1:M |-->| 1 | |(F)|-->|(G)|->
38 * ... -->|(A)|--+ | +--------+ +---+ +-->| 1 | +---+
39 * ... -->| | +-->|(D) 1:3 |----------+ +---+
40 * pll1.N -->| N | +---------
43 * (A) input pll clock mux controlled by <PllSelect[1:n]>
44 * (B) input pll bypass mux controlled by <PllSwitch>
45 * (C) programmable clock divider controlled by <Select[1:n]>
46 * (D) constant div-by-3 clock divider
47 * (E) programmable clock divider bypass controlled by <Switch>
48 * (F) constant div-by-3 clock mux controlled by <D3Switch>
49 * (G) clock gate controlled by <Enable>
51 * For whatever reason, above control signals come in two flavors:
52 * - single register dividers with all bits in one register
53 * - shared register dividers with bits spread over multiple registers
54 * (including signals for the same cell spread over consecutive registers)
56 * Also, clock gate and pll mux is not available on every div cell, so
57 * we have to deal with those, too. We reuse common clock composite driver
61 #define PLL_SELECT_MASK 0x7
62 #define DIV_SELECT_MASK 0x7
67 struct berlin2_div_map map
;
71 #define to_berlin2_div(hw) container_of(hw, struct berlin2_div, hw)
73 static u8 clk_div
[] = { 1, 2, 4, 6, 8, 12, 1, 1 };
75 static int berlin2_div_is_enabled(struct clk_hw
*hw
)
77 struct berlin2_div
*div
= to_berlin2_div(hw
);
78 struct berlin2_div_map
*map
= &div
->map
;
84 reg
= readl_relaxed(div
->base
+ map
->gate_offs
);
85 reg
>>= map
->gate_shift
;
88 spin_unlock(div
->lock
);
93 static int berlin2_div_enable(struct clk_hw
*hw
)
95 struct berlin2_div
*div
= to_berlin2_div(hw
);
96 struct berlin2_div_map
*map
= &div
->map
;
100 spin_lock(div
->lock
);
102 reg
= readl_relaxed(div
->base
+ map
->gate_offs
);
103 reg
|= BIT(map
->gate_shift
);
104 writel_relaxed(reg
, div
->base
+ map
->gate_offs
);
107 spin_unlock(div
->lock
);
112 static void berlin2_div_disable(struct clk_hw
*hw
)
114 struct berlin2_div
*div
= to_berlin2_div(hw
);
115 struct berlin2_div_map
*map
= &div
->map
;
119 spin_lock(div
->lock
);
121 reg
= readl_relaxed(div
->base
+ map
->gate_offs
);
122 reg
&= ~BIT(map
->gate_shift
);
123 writel_relaxed(reg
, div
->base
+ map
->gate_offs
);
126 spin_unlock(div
->lock
);
129 static int berlin2_div_set_parent(struct clk_hw
*hw
, u8 index
)
131 struct berlin2_div
*div
= to_berlin2_div(hw
);
132 struct berlin2_div_map
*map
= &div
->map
;
136 spin_lock(div
->lock
);
138 /* index == 0 is PLL_SWITCH */
139 reg
= readl_relaxed(div
->base
+ map
->pll_switch_offs
);
141 reg
&= ~BIT(map
->pll_switch_shift
);
143 reg
|= BIT(map
->pll_switch_shift
);
144 writel_relaxed(reg
, div
->base
+ map
->pll_switch_offs
);
146 /* index > 0 is PLL_SELECT */
148 reg
= readl_relaxed(div
->base
+ map
->pll_select_offs
);
149 reg
&= ~(PLL_SELECT_MASK
<< map
->pll_select_shift
);
150 reg
|= (index
- 1) << map
->pll_select_shift
;
151 writel_relaxed(reg
, div
->base
+ map
->pll_select_offs
);
155 spin_unlock(div
->lock
);
160 static u8
berlin2_div_get_parent(struct clk_hw
*hw
)
162 struct berlin2_div
*div
= to_berlin2_div(hw
);
163 struct berlin2_div_map
*map
= &div
->map
;
168 spin_lock(div
->lock
);
170 /* PLL_SWITCH == 0 is index 0 */
171 reg
= readl_relaxed(div
->base
+ map
->pll_switch_offs
);
172 reg
&= BIT(map
->pll_switch_shift
);
174 reg
= readl_relaxed(div
->base
+ map
->pll_select_offs
);
175 reg
>>= map
->pll_select_shift
;
176 reg
&= PLL_SELECT_MASK
;
181 spin_unlock(div
->lock
);
186 static unsigned long berlin2_div_recalc_rate(struct clk_hw
*hw
,
187 unsigned long parent_rate
)
189 struct berlin2_div
*div
= to_berlin2_div(hw
);
190 struct berlin2_div_map
*map
= &div
->map
;
191 u32 divsw
, div3sw
, divider
= 1;
194 spin_lock(div
->lock
);
196 divsw
= readl_relaxed(div
->base
+ map
->div_switch_offs
) &
197 (1 << map
->div_switch_shift
);
198 div3sw
= readl_relaxed(div
->base
+ map
->div3_switch_offs
) &
199 (1 << map
->div3_switch_shift
);
201 /* constant divide-by-3 (dominant) */
204 /* divider can be bypassed with DIV_SWITCH == 0 */
205 } else if (divsw
== 0) {
207 /* clock divider determined by DIV_SELECT */
210 reg
= readl_relaxed(div
->base
+ map
->div_select_offs
);
211 reg
>>= map
->div_select_shift
;
212 reg
&= DIV_SELECT_MASK
;
213 divider
= clk_div
[reg
];
217 spin_unlock(div
->lock
);
219 return parent_rate
/ divider
;
222 static const struct clk_ops berlin2_div_rate_ops
= {
223 .recalc_rate
= berlin2_div_recalc_rate
,
226 static const struct clk_ops berlin2_div_gate_ops
= {
227 .is_enabled
= berlin2_div_is_enabled
,
228 .enable
= berlin2_div_enable
,
229 .disable
= berlin2_div_disable
,
232 static const struct clk_ops berlin2_div_mux_ops
= {
233 .set_parent
= berlin2_div_set_parent
,
234 .get_parent
= berlin2_div_get_parent
,
238 berlin2_div_register(const struct berlin2_div_map
*map
,
239 void __iomem
*base
, const char *name
, u8 div_flags
,
240 const char **parent_names
, int num_parents
,
241 unsigned long flags
, spinlock_t
*lock
)
243 const struct clk_ops
*mux_ops
= &berlin2_div_mux_ops
;
244 const struct clk_ops
*rate_ops
= &berlin2_div_rate_ops
;
245 const struct clk_ops
*gate_ops
= &berlin2_div_gate_ops
;
246 struct berlin2_div
*div
;
248 div
= kzalloc(sizeof(*div
), GFP_KERNEL
);
250 return ERR_PTR(-ENOMEM
);
252 /* copy div_map to allow __initconst */
253 memcpy(&div
->map
, map
, sizeof(*map
));
257 if ((div_flags
& BERLIN2_DIV_HAS_GATE
) == 0)
259 if ((div_flags
& BERLIN2_DIV_HAS_MUX
) == 0)
262 return clk_register_composite(NULL
, name
, parent_names
, num_parents
,
263 &div
->hw
, mux_ops
, &div
->hw
, rate_ops
,
264 &div
->hw
, gate_ops
, flags
);