blob: 2f7dba20ced8b9145f261b817be65387f3048662 [file] [log] [blame]
Thomas Abraham721c42a2013-03-09 17:02:44 +09001/*
2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3 * Copyright (c) 2013 Linaro Ltd.
4 * Author: Thomas Abraham <thomas.ab@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Common Clock Framework support for all Samsung platforms
11*/
12
13#ifndef __SAMSUNG_CLK_H
14#define __SAMSUNG_CLK_H
15
16#include <linux/clk.h>
17#include <linux/clkdev.h>
18#include <linux/io.h>
19#include <linux/clk-provider.h>
20#include <linux/of.h>
21#include <linux/of_address.h>
22
Thomas Abraham721c42a2013-03-09 17:02:44 +090023/**
Heiko Stuebner5e2e0192013-03-18 13:43:56 +090024 * struct samsung_clock_alias: information about mux clock
25 * @id: platform specific id of the clock.
26 * @dev_name: name of the device to which this clock belongs.
27 * @alias: optional clock alias name to be assigned to this clock.
28 */
29struct samsung_clock_alias {
30 unsigned int id;
31 const char *dev_name;
32 const char *alias;
33};
34
35#define ALIAS(_id, dname, a) \
36 { \
37 .id = _id, \
38 .dev_name = dname, \
39 .alias = a, \
40 }
41
42/**
Thomas Abraham721c42a2013-03-09 17:02:44 +090043 * struct samsung_fixed_rate_clock: information about fixed-rate clock
44 * @id: platform specific id of the clock.
45 * @name: name of this fixed-rate clock.
46 * @parent_name: optional parent clock name.
47 * @flags: optional fixed-rate clock flags.
48 * @fixed-rate: fixed clock rate of this clock.
49 */
50struct samsung_fixed_rate_clock {
51 unsigned int id;
52 char *name;
53 const char *parent_name;
54 unsigned long flags;
55 unsigned long fixed_rate;
56};
57
58#define FRATE(_id, cname, pname, f, frate) \
59 { \
60 .id = _id, \
61 .name = cname, \
62 .parent_name = pname, \
63 .flags = f, \
64 .fixed_rate = frate, \
65 }
66
67/*
68 * struct samsung_fixed_factor_clock: information about fixed-factor clock
69 * @id: platform specific id of the clock.
70 * @name: name of this fixed-factor clock.
71 * @parent_name: parent clock name.
72 * @mult: fixed multiplication factor.
73 * @div: fixed division factor.
74 * @flags: optional fixed-factor clock flags.
75 */
76struct samsung_fixed_factor_clock {
77 unsigned int id;
78 char *name;
79 const char *parent_name;
80 unsigned long mult;
81 unsigned long div;
82 unsigned long flags;
83};
84
85#define FFACTOR(_id, cname, pname, m, d, f) \
86 { \
87 .id = _id, \
88 .name = cname, \
89 .parent_name = pname, \
90 .mult = m, \
91 .div = d, \
92 .flags = f, \
93 }
94
95/**
96 * struct samsung_mux_clock: information about mux clock
97 * @id: platform specific id of the clock.
98 * @dev_name: name of the device to which this clock belongs.
99 * @name: name of this mux clock.
100 * @parent_names: array of pointer to parent clock names.
101 * @num_parents: number of parents listed in @parent_names.
102 * @flags: optional flags for basic clock.
103 * @offset: offset of the register for configuring the mux.
104 * @shift: starting bit location of the mux control bit-field in @reg.
105 * @width: width of the mux control bit-field in @reg.
106 * @mux_flags: flags for mux-type clock.
107 * @alias: optional clock alias name to be assigned to this clock.
108 */
109struct samsung_mux_clock {
110 unsigned int id;
111 const char *dev_name;
112 const char *name;
113 const char **parent_names;
114 u8 num_parents;
115 unsigned long flags;
116 unsigned long offset;
117 u8 shift;
118 u8 width;
119 u8 mux_flags;
120 const char *alias;
121};
122
123#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
124 { \
125 .id = _id, \
126 .dev_name = dname, \
127 .name = cname, \
128 .parent_names = pnames, \
129 .num_parents = ARRAY_SIZE(pnames), \
130 .flags = f, \
131 .offset = o, \
132 .shift = s, \
133 .width = w, \
134 .mux_flags = mf, \
135 .alias = a, \
136 }
137
138#define MUX(_id, cname, pnames, o, s, w) \
139 __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
140
141#define MUX_A(_id, cname, pnames, o, s, w, a) \
142 __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
143
144#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
145 __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
146
Tushar Behera41ccf7f2013-06-20 16:17:17 +0530147#define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a) \
148 __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a)
149
Thomas Abraham721c42a2013-03-09 17:02:44 +0900150/**
151 * @id: platform specific id of the clock.
152 * struct samsung_div_clock: information about div clock
153 * @dev_name: name of the device to which this clock belongs.
154 * @name: name of this div clock.
155 * @parent_name: name of the parent clock.
156 * @flags: optional flags for basic clock.
157 * @offset: offset of the register for configuring the div.
158 * @shift: starting bit location of the div control bit-field in @reg.
159 * @div_flags: flags for div-type clock.
160 * @alias: optional clock alias name to be assigned to this clock.
161 */
162struct samsung_div_clock {
163 unsigned int id;
164 const char *dev_name;
165 const char *name;
166 const char *parent_name;
167 unsigned long flags;
168 unsigned long offset;
169 u8 shift;
170 u8 width;
171 u8 div_flags;
172 const char *alias;
Heiko Stuebner798ed612013-03-18 13:43:52 +0900173 struct clk_div_table *table;
Thomas Abraham721c42a2013-03-09 17:02:44 +0900174};
175
Heiko Stuebner798ed612013-03-18 13:43:52 +0900176#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t) \
Thomas Abraham721c42a2013-03-09 17:02:44 +0900177 { \
178 .id = _id, \
179 .dev_name = dname, \
180 .name = cname, \
181 .parent_name = pname, \
182 .flags = f, \
183 .offset = o, \
184 .shift = s, \
185 .width = w, \
186 .div_flags = df, \
187 .alias = a, \
Heiko Stuebner798ed612013-03-18 13:43:52 +0900188 .table = t, \
Thomas Abraham721c42a2013-03-09 17:02:44 +0900189 }
190
191#define DIV(_id, cname, pname, o, s, w) \
Heiko Stuebner798ed612013-03-18 13:43:52 +0900192 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL)
Thomas Abraham721c42a2013-03-09 17:02:44 +0900193
194#define DIV_A(_id, cname, pname, o, s, w, a) \
Heiko Stuebner798ed612013-03-18 13:43:52 +0900195 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL)
Thomas Abraham721c42a2013-03-09 17:02:44 +0900196
197#define DIV_F(_id, cname, pname, o, s, w, f, df) \
Heiko Stuebner798ed612013-03-18 13:43:52 +0900198 __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL)
199
200#define DIV_T(_id, cname, pname, o, s, w, t) \
201 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t)
Thomas Abraham721c42a2013-03-09 17:02:44 +0900202
203/**
204 * struct samsung_gate_clock: information about gate clock
205 * @id: platform specific id of the clock.
206 * @dev_name: name of the device to which this clock belongs.
207 * @name: name of this gate clock.
208 * @parent_name: name of the parent clock.
209 * @flags: optional flags for basic clock.
210 * @offset: offset of the register for configuring the gate.
211 * @bit_idx: bit index of the gate control bit-field in @reg.
212 * @gate_flags: flags for gate-type clock.
213 * @alias: optional clock alias name to be assigned to this clock.
214 */
215struct samsung_gate_clock {
216 unsigned int id;
217 const char *dev_name;
218 const char *name;
219 const char *parent_name;
220 unsigned long flags;
221 unsigned long offset;
222 u8 bit_idx;
223 u8 gate_flags;
224 const char *alias;
225};
226
227#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
228 { \
229 .id = _id, \
230 .dev_name = dname, \
231 .name = cname, \
232 .parent_name = pname, \
233 .flags = f, \
234 .offset = o, \
235 .bit_idx = b, \
236 .gate_flags = gf, \
237 .alias = a, \
238 }
239
240#define GATE(_id, cname, pname, o, b, f, gf) \
241 __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
242
243#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
244 __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
245
246#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
247 __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
248
249#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
250 __GATE(_id, dname, cname, pname, o, b, f, gf, a)
251
252#define PNAME(x) static const char *x[] __initdata
253
254/**
255 * struct samsung_clk_reg_dump: register dump of clock controller registers.
256 * @offset: clock register offset from the controller base address.
257 * @value: the value to be register at offset.
258 */
259struct samsung_clk_reg_dump {
260 u32 offset;
261 u32 value;
262};
263
264extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
265 unsigned long nr_clks, unsigned long *rdump,
Tomasz Figa6b5756e2013-04-04 13:35:35 +0900266 unsigned long nr_rdump, unsigned long *soc_rdump,
267 unsigned long nr_soc_rdump);
Thomas Abraham721c42a2013-03-09 17:02:44 +0900268extern void __init samsung_clk_of_register_fixed_ext(
269 struct samsung_fixed_rate_clock *fixed_rate_clk,
270 unsigned int nr_fixed_rate_clk,
271 struct of_device_id *clk_matches);
272
273extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id);
274
Heiko Stuebner5e2e0192013-03-18 13:43:56 +0900275extern void samsung_clk_register_alias(struct samsung_clock_alias *list,
276 unsigned int nr_clk);
Thomas Abraham721c42a2013-03-09 17:02:44 +0900277extern void __init samsung_clk_register_fixed_rate(
278 struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk);
279extern void __init samsung_clk_register_fixed_factor(
280 struct samsung_fixed_factor_clock *list, unsigned int nr_clk);
281extern void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list,
282 unsigned int nr_clk);
283extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
284 unsigned int nr_clk);
285extern void __init samsung_clk_register_gate(
286 struct samsung_gate_clock *clk_list, unsigned int nr_clk);
287
288extern unsigned long _get_rate(const char *clk_name);
289
290#endif /* __SAMSUNG_CLK_H */