blob: 92131f972917e5205e9da116fce20eed8777be88 [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>
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +053022#include "clk-pll.h"
Thomas Abraham721c42a2013-03-09 17:02:44 +090023
Thomas Abraham721c42a2013-03-09 17:02:44 +090024/**
Rahul Sharma976face2014-03-12 20:26:44 +053025 * struct samsung_clk_provider: information about clock provider
26 * @reg_base: virtual address for the register base.
27 * @clk_data: holds clock related data like clk* and number of clocks.
28 * @lock: maintains exclusion bwtween callbacks for a given clock-provider.
29 */
30struct samsung_clk_provider {
31 void __iomem *reg_base;
32 struct clk_onecell_data clk_data;
33 spinlock_t lock;
34};
35
36/**
Heiko Stuebner5e2e0192013-03-18 13:43:56 +090037 * struct samsung_clock_alias: information about mux clock
38 * @id: platform specific id of the clock.
39 * @dev_name: name of the device to which this clock belongs.
40 * @alias: optional clock alias name to be assigned to this clock.
41 */
42struct samsung_clock_alias {
43 unsigned int id;
44 const char *dev_name;
45 const char *alias;
46};
47
48#define ALIAS(_id, dname, a) \
49 { \
50 .id = _id, \
51 .dev_name = dname, \
52 .alias = a, \
53 }
54
Vikas Sajjand2127ac2013-06-11 15:01:16 +053055#define MHZ (1000 * 1000)
56
Heiko Stuebner5e2e0192013-03-18 13:43:56 +090057/**
Thomas Abraham721c42a2013-03-09 17:02:44 +090058 * struct samsung_fixed_rate_clock: information about fixed-rate clock
59 * @id: platform specific id of the clock.
60 * @name: name of this fixed-rate clock.
61 * @parent_name: optional parent clock name.
62 * @flags: optional fixed-rate clock flags.
63 * @fixed-rate: fixed clock rate of this clock.
64 */
65struct samsung_fixed_rate_clock {
66 unsigned int id;
67 char *name;
68 const char *parent_name;
69 unsigned long flags;
70 unsigned long fixed_rate;
71};
72
73#define FRATE(_id, cname, pname, f, frate) \
74 { \
75 .id = _id, \
76 .name = cname, \
77 .parent_name = pname, \
78 .flags = f, \
79 .fixed_rate = frate, \
80 }
81
82/*
83 * struct samsung_fixed_factor_clock: information about fixed-factor clock
84 * @id: platform specific id of the clock.
85 * @name: name of this fixed-factor clock.
86 * @parent_name: parent clock name.
87 * @mult: fixed multiplication factor.
88 * @div: fixed division factor.
89 * @flags: optional fixed-factor clock flags.
90 */
91struct samsung_fixed_factor_clock {
92 unsigned int id;
93 char *name;
94 const char *parent_name;
95 unsigned long mult;
96 unsigned long div;
97 unsigned long flags;
98};
99
100#define FFACTOR(_id, cname, pname, m, d, f) \
101 { \
102 .id = _id, \
103 .name = cname, \
104 .parent_name = pname, \
105 .mult = m, \
106 .div = d, \
107 .flags = f, \
108 }
109
110/**
111 * struct samsung_mux_clock: information about mux clock
112 * @id: platform specific id of the clock.
113 * @dev_name: name of the device to which this clock belongs.
114 * @name: name of this mux clock.
115 * @parent_names: array of pointer to parent clock names.
116 * @num_parents: number of parents listed in @parent_names.
117 * @flags: optional flags for basic clock.
118 * @offset: offset of the register for configuring the mux.
119 * @shift: starting bit location of the mux control bit-field in @reg.
120 * @width: width of the mux control bit-field in @reg.
121 * @mux_flags: flags for mux-type clock.
122 * @alias: optional clock alias name to be assigned to this clock.
123 */
124struct samsung_mux_clock {
125 unsigned int id;
126 const char *dev_name;
127 const char *name;
128 const char **parent_names;
129 u8 num_parents;
130 unsigned long flags;
131 unsigned long offset;
132 u8 shift;
133 u8 width;
134 u8 mux_flags;
135 const char *alias;
136};
137
138#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
139 { \
140 .id = _id, \
141 .dev_name = dname, \
142 .name = cname, \
143 .parent_names = pnames, \
144 .num_parents = ARRAY_SIZE(pnames), \
James Hogan819c1de2013-07-29 12:25:01 +0100145 .flags = (f) | CLK_SET_RATE_NO_REPARENT, \
Thomas Abraham721c42a2013-03-09 17:02:44 +0900146 .offset = o, \
147 .shift = s, \
148 .width = w, \
149 .mux_flags = mf, \
150 .alias = a, \
151 }
152
153#define MUX(_id, cname, pnames, o, s, w) \
154 __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
155
156#define MUX_A(_id, cname, pnames, o, s, w, a) \
157 __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
158
159#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
160 __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
161
Tushar Behera41ccf7f2013-06-20 16:17:17 +0530162#define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a) \
163 __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a)
164
Thomas Abraham721c42a2013-03-09 17:02:44 +0900165/**
166 * @id: platform specific id of the clock.
167 * struct samsung_div_clock: information about div clock
168 * @dev_name: name of the device to which this clock belongs.
169 * @name: name of this div clock.
170 * @parent_name: name of the parent clock.
171 * @flags: optional flags for basic clock.
172 * @offset: offset of the register for configuring the div.
173 * @shift: starting bit location of the div control bit-field in @reg.
174 * @div_flags: flags for div-type clock.
175 * @alias: optional clock alias name to be assigned to this clock.
176 */
177struct samsung_div_clock {
178 unsigned int id;
179 const char *dev_name;
180 const char *name;
181 const char *parent_name;
182 unsigned long flags;
183 unsigned long offset;
184 u8 shift;
185 u8 width;
186 u8 div_flags;
187 const char *alias;
Heiko Stuebner798ed612013-03-18 13:43:52 +0900188 struct clk_div_table *table;
Thomas Abraham721c42a2013-03-09 17:02:44 +0900189};
190
Heiko Stuebner798ed612013-03-18 13:43:52 +0900191#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t) \
Thomas Abraham721c42a2013-03-09 17:02:44 +0900192 { \
193 .id = _id, \
194 .dev_name = dname, \
195 .name = cname, \
196 .parent_name = pname, \
197 .flags = f, \
198 .offset = o, \
199 .shift = s, \
200 .width = w, \
201 .div_flags = df, \
202 .alias = a, \
Heiko Stuebner798ed612013-03-18 13:43:52 +0900203 .table = t, \
Thomas Abraham721c42a2013-03-09 17:02:44 +0900204 }
205
206#define DIV(_id, cname, pname, o, s, w) \
Heiko Stuebner798ed612013-03-18 13:43:52 +0900207 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL)
Thomas Abraham721c42a2013-03-09 17:02:44 +0900208
209#define DIV_A(_id, cname, pname, o, s, w, a) \
Heiko Stuebner798ed612013-03-18 13:43:52 +0900210 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL)
Thomas Abraham721c42a2013-03-09 17:02:44 +0900211
212#define DIV_F(_id, cname, pname, o, s, w, f, df) \
Heiko Stuebner798ed612013-03-18 13:43:52 +0900213 __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL)
214
215#define DIV_T(_id, cname, pname, o, s, w, t) \
216 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t)
Thomas Abraham721c42a2013-03-09 17:02:44 +0900217
218/**
219 * struct samsung_gate_clock: information about gate clock
220 * @id: platform specific id of the clock.
221 * @dev_name: name of the device to which this clock belongs.
222 * @name: name of this gate clock.
223 * @parent_name: name of the parent clock.
224 * @flags: optional flags for basic clock.
225 * @offset: offset of the register for configuring the gate.
226 * @bit_idx: bit index of the gate control bit-field in @reg.
227 * @gate_flags: flags for gate-type clock.
228 * @alias: optional clock alias name to be assigned to this clock.
229 */
230struct samsung_gate_clock {
231 unsigned int id;
232 const char *dev_name;
233 const char *name;
234 const char *parent_name;
235 unsigned long flags;
236 unsigned long offset;
237 u8 bit_idx;
238 u8 gate_flags;
239 const char *alias;
240};
241
242#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
243 { \
244 .id = _id, \
245 .dev_name = dname, \
246 .name = cname, \
247 .parent_name = pname, \
248 .flags = f, \
249 .offset = o, \
250 .bit_idx = b, \
251 .gate_flags = gf, \
252 .alias = a, \
253 }
254
255#define GATE(_id, cname, pname, o, b, f, gf) \
256 __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
257
258#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
259 __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
260
261#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
262 __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
263
264#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
265 __GATE(_id, dname, cname, pname, o, b, f, gf, a)
266
267#define PNAME(x) static const char *x[] __initdata
268
269/**
270 * struct samsung_clk_reg_dump: register dump of clock controller registers.
271 * @offset: clock register offset from the controller base address.
272 * @value: the value to be register at offset.
273 */
274struct samsung_clk_reg_dump {
275 u32 offset;
276 u32 value;
277};
278
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +0530279/**
280 * struct samsung_pll_clock: information about pll clock
281 * @id: platform specific id of the clock.
282 * @dev_name: name of the device to which this clock belongs.
283 * @name: name of this pll clock.
284 * @parent_name: name of the parent clock.
285 * @flags: optional flags for basic clock.
286 * @con_offset: offset of the register for configuring the PLL.
287 * @lock_offset: offset of the register for locking the PLL.
288 * @type: Type of PLL to be registered.
289 * @alias: optional clock alias name to be assigned to this clock.
290 */
291struct samsung_pll_clock {
292 unsigned int id;
293 const char *dev_name;
294 const char *name;
295 const char *parent_name;
296 unsigned long flags;
297 int con_offset;
298 int lock_offset;
299 enum samsung_pll_type type;
Yadwinder Singh Brar3ff6e0d2013-06-11 15:01:12 +0530300 const struct samsung_pll_rate_table *rate_table;
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +0530301 const char *alias;
302};
303
Yadwinder Singh Brar3ff6e0d2013-06-11 15:01:12 +0530304#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, \
305 _rtable, _alias) \
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +0530306 { \
307 .id = _id, \
308 .type = _typ, \
309 .dev_name = _dname, \
310 .name = _name, \
311 .parent_name = _pname, \
312 .flags = CLK_GET_RATE_NOCACHE, \
313 .con_offset = _con, \
314 .lock_offset = _lock, \
Yadwinder Singh Brar3ff6e0d2013-06-11 15:01:12 +0530315 .rate_table = _rtable, \
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +0530316 .alias = _alias, \
317 }
318
Yadwinder Singh Brar3ff6e0d2013-06-11 15:01:12 +0530319#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +0530320 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
Yadwinder Singh Brar3ff6e0d2013-06-11 15:01:12 +0530321 _lock, _con, _rtable, _name)
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +0530322
Yadwinder Singh Brar3ff6e0d2013-06-11 15:01:12 +0530323#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +0530324 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
Yadwinder Singh Brar3ff6e0d2013-06-11 15:01:12 +0530325 _lock, _con, _rtable, _alias)
Yadwinder Singh Brar07dc76f2013-06-11 15:01:07 +0530326
Rahul Sharma976face2014-03-12 20:26:44 +0530327extern struct samsung_clk_provider *__init samsung_clk_init(
328 struct device_node *np, void __iomem *base,
329 unsigned long nr_clks);
Sylwester Nawrockid5e136a2014-06-18 17:46:52 +0200330extern void __init samsung_clk_of_add_provider(struct device_node *np,
331 struct samsung_clk_provider *ctx);
Thomas Abraham721c42a2013-03-09 17:02:44 +0900332extern void __init samsung_clk_of_register_fixed_ext(
Rahul Sharma976face2014-03-12 20:26:44 +0530333 struct samsung_clk_provider *ctx,
334 struct samsung_fixed_rate_clock *fixed_rate_clk,
335 unsigned int nr_fixed_rate_clk,
336 struct of_device_id *clk_matches);
Thomas Abraham721c42a2013-03-09 17:02:44 +0900337
Rahul Sharma976face2014-03-12 20:26:44 +0530338extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
339 struct clk *clk, unsigned int id);
Thomas Abraham721c42a2013-03-09 17:02:44 +0900340
Rahul Sharma976face2014-03-12 20:26:44 +0530341extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
342 struct samsung_clock_alias *list,
343 unsigned int nr_clk);
Thomas Abraham721c42a2013-03-09 17:02:44 +0900344extern void __init samsung_clk_register_fixed_rate(
Rahul Sharma976face2014-03-12 20:26:44 +0530345 struct samsung_clk_provider *ctx,
346 struct samsung_fixed_rate_clock *clk_list,
347 unsigned int nr_clk);
Thomas Abraham721c42a2013-03-09 17:02:44 +0900348extern void __init samsung_clk_register_fixed_factor(
Rahul Sharma976face2014-03-12 20:26:44 +0530349 struct samsung_clk_provider *ctx,
350 struct samsung_fixed_factor_clock *list,
351 unsigned int nr_clk);
352extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
353 struct samsung_mux_clock *clk_list,
354 unsigned int nr_clk);
355extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
356 struct samsung_div_clock *clk_list,
357 unsigned int nr_clk);
358extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
359 struct samsung_gate_clock *clk_list,
360 unsigned int nr_clk);
361extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
362 struct samsung_pll_clock *pll_list,
363 unsigned int nr_clk, void __iomem *base);
Thomas Abraham721c42a2013-03-09 17:02:44 +0900364
365extern unsigned long _get_rate(const char *clk_name);
366
Tomasz Figa3ccefbd2014-02-14 08:16:00 +0900367extern void samsung_clk_save(void __iomem *base,
Rahul Sharma976face2014-03-12 20:26:44 +0530368 struct samsung_clk_reg_dump *rd,
369 unsigned int num_regs);
Tomasz Figa3ccefbd2014-02-14 08:16:00 +0900370extern void samsung_clk_restore(void __iomem *base,
Rahul Sharma976face2014-03-12 20:26:44 +0530371 const struct samsung_clk_reg_dump *rd,
372 unsigned int num_regs);
Tomasz Figa3ccefbd2014-02-14 08:16:00 +0900373extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
Rahul Sharma976face2014-03-12 20:26:44 +0530374 const unsigned long *rdump,
375 unsigned long nr_rdump);
Tomasz Figa3ccefbd2014-02-14 08:16:00 +0900376
Thomas Abraham721c42a2013-03-09 17:02:44 +0900377#endif /* __SAMSUNG_CLK_H */