drivers: soc: cal-if: create new macro to handle NULL return
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / drivers / soc / samsung / cal-if / cmucal.h
1 #ifndef __CMUCAL_H__
2 #define __CMUCAL_H__
3
4 #include <linux/types.h>
5 #include <linux/kernel.h>
6 #include "vclk.h"
7
8 struct dentry;
9
10 #ifndef abs
11 #define abs(x) ({ \
12 long ret; \
13 if (sizeof(x) == sizeof(long)) { \
14 long __x = (x); \
15 ret = (__x < 0) ? -__x : __x; \
16 } else { \
17 int __x = (x); \
18 ret = (__x < 0) ? -__x : __x; \
19 } \
20 ret; \
21 })
22 #endif
23
24 #ifndef do_div
25 #define do_div(a, b) (a /= b)
26 #endif
27
28 #define EVCLKPERM 1
29 #define EVCLKNOENT 2
30 #define EVCLKAGAIN 11
31 #define EVCLKNOMEM 12
32 #define EVCLKFAULT 14 /* Bad address */
33 #define EVCLKBUSY 16
34 #define EVCLKINVAL 22
35 #define EVCLKTIMEOUT 110
36
37 #define MASK_OF_TYPE 0x0F000000
38 #define MASK_OF_SUBTYPE 0x00FF0000
39 #define MASK_OF_ID 0x0000FFFF
40 #define FIXED_RATE_TYPE 0x01000000
41 #define FIXED_FACTOR_TYPE 0x02000000
42 #define PLL_TYPE 0x03000000
43 #define MUX_TYPE 0x04000000
44 #define USER_MUX_TYPE 0x04010000
45 #define CONST_MUX_TYPE 0x04020000
46 #define DIV_TYPE 0x05000000
47 #define CONST_DIV_TYPE 0x05020000
48 #define GATE_TYPE 0x06000000
49 #define GATE_ROOT_TYPE 0x06010000
50 #define QCH_TYPE 0x07000000
51 #define SFR_BLOCK_TYPE 0x08000000
52 #define SFR_TYPE 0x09000000
53 #define SFR_ACCESS_TYPE 0x0A000000
54 #define VCLK_TYPE 0x0B000000
55 #define COMMON_VCLK_TYPE 0x0B010000
56 #define DFS_VCLK_TYPE 0x0B020000
57 #define GATE_VCLK_TYPE 0x0B030000
58 #define ACPM_VCLK_TYPE 0x0B040000
59 #define OPTION_TYPE 0x0C000000
60 #define CLKOUT_TYPE 0x0D000000
61 #define INVALID_CLK_ID MASK_OF_ID
62 #define EMPTY_CLK_ID MASK_OF_ID
63 #define EMPTY_CAL_ID MASK_OF_ID
64
65 /**
66 * struct vclk_lut - Virtual clock Look-Up-Table
67 * @rate: virtual clock rate
68 * @params: clks setting parameters, number of params is num_clks
69 */
70 struct vclk_lut {
71 unsigned int rate;
72 unsigned int *params;
73 };
74
75 /**
76 * struct vclk_seq - Virtual clock sequence
77 * @idx: index of struct vclk_clks
78 * @opt: option : TRANS_HIGH, TRANS_LOW, TRANS_FORCE
79 */
80 struct vclk_seq {
81 unsigned int idx;
82 unsigned int opt;
83 };
84
85 /**
86 * struct vclk_switch - switching lut info
87 * @switch_rate: switch_rate
88 * @mux_value: mux value about source
89 * @div_value: div value about mout
90 */
91 struct switch_lut {
92 unsigned int rate;
93 unsigned int mux_value;
94 unsigned int div_value;
95 };
96
97 /**
98 * struct vclk_switch - Virtual clock switching PLL info
99 * @switch_mux: switching MUX id
100 * @src_mux: switching PLL source MUX id
101 * @src_div: switching PLL source Divider id
102 * @lut: switch PLL Look-Up-Table pointer
103 */
104 struct vclk_switch {
105 unsigned int switch_mux;
106 unsigned int src_mux;
107 unsigned int src_div;
108 unsigned int src_gate;
109 unsigned int src_umux;
110 struct switch_lut *lut;
111 unsigned int num_switches;
112 };
113
114 /**
115 * struct vclk - Virtual clock
116 * @id: vclk id
117 * @name: vclk name
118 * @vrate: vclk virtual clock frequency
119 * @lut: Look-Up-Table pointer
120 * @seq: clock setting sequnce pointer
121 * @clk_list: clock list pointer
122 * @num_rates: number of lut rates
123 * @num_clks: number of clks and seq
124 */
125 struct vclk {
126 unsigned int id;
127 char *name;
128 unsigned int vrate;
129 struct vclk_lut *lut;
130 unsigned int *list;
131 struct vclk_seq *seq;
132 unsigned int num_rates;
133 unsigned int num_list;
134 unsigned int max_freq;
135 unsigned int min_freq;
136 unsigned int boot_freq;
137 unsigned int resume_freq;
138 int margin_id;
139 struct vclk_switch *switch_info;
140 struct vclk_trans_ops *ops;
141 #ifdef CONFIG_DEBUG_FS
142 struct dentry *dentry;
143 #endif
144 };
145
146 enum clk_pll_type {
147 PLL_1416X = 14160,
148 PLL_1417X = 14170,
149 PLL_1418X = 14180,
150 PLL_1419X = 14190,
151 PLL_1431X = 14310,
152 PLL_1450X = 14500,
153 PLL_1451X = 14510,
154 PLL_1452X = 14520,
155 PLL_1460X = 14600,
156
157 PLL_1050X = 10500,
158 PLL_1051X = 10510,
159 PLL_1052X = 10520,
160 PLL_1054X = 10540,
161 PLL_1061X = 10610,
162
163 PLL_1016X = 10160,
164 PLL_1017X = 10170,
165 PLL_1018X = 10180,
166 PLL_1019X = 10190,
167 PLL_1031X = 10310,
168 };
169
170 enum margin_id {
171 MARGIN_MIF,
172 MARGIN_INT,
173 MARGIN_BIG,
174 MARGIN_LIT,
175 MARGIN_G3D,
176 MARGIN_INTCAM,
177 MARGIN_CAM,
178 MARGIN_DISP,
179 MARGIN_G3DM,
180 MARGIN_CP,
181 MARGIN_FSYS0,
182 MARGIN_AUD,
183 MARGIN_IVA,
184 MARGIN_SCORE,
185 MAX_MARGIN_ID,
186 };
187
188 #define IS_FIXED_RATE(_id) ((_id & MASK_OF_TYPE) == FIXED_RATE_TYPE)
189 #define IS_FIXED_FACTOR(_id) ((_id & MASK_OF_TYPE) == FIXED_FACTOR_TYPE)
190 #define IS_PLL(_id) ((_id & MASK_OF_TYPE) == PLL_TYPE)
191 #define IS_MUX(_id) ((_id & MASK_OF_TYPE) == MUX_TYPE)
192 #define IS_USER_MUX(_id) ((_id & (MASK_OF_TYPE | MASK_OF_SUBTYPE)) == USER_MUX_TYPE)
193 #define IS_CONST_MUX(_id) ((_id & (MASK_OF_TYPE | MASK_OF_SUBTYPE)) == CONST_MUX_TYPE)
194 #define IS_DIV(_id) ((_id & MASK_OF_TYPE) == DIV_TYPE)
195 #define IS_CONST_DIV(_id) ((_id & MASK_OF_TYPE | MASK_OF_SUBTYPE) == CONST_DIV_TYPE)
196 #define IS_GATE(_id) ((_id & MASK_OF_TYPE) == GATE_TYPE)
197 #define IS_QCH(_id) ((_id & MASK_OF_TYPE) == QCH_TYPE)
198 #define IS_OPTION(_id) ((_id & MASK_OF_TYPE) == OPTION_TYPE)
199
200 #define IS_VCLK(_id) ((_id & MASK_OF_TYPE) == VCLK_TYPE)
201 #define IS_DFS_VCLK(_id) ((_id & (MASK_OF_TYPE | MASK_OF_SUBTYPE)) == DFS_VCLK_TYPE)
202 #define IS_COMMON_VCLK(_id) ((_id & (MASK_OF_TYPE | MASK_OF_SUBTYPE)) == COMMON_VCLK_TYPE)
203 #define IS_GATE_VCLK(_id) ((_id & (MASK_OF_TYPE | MASK_OF_SUBTYPE)) == GATE_VCLK_TYPE)
204 #define IS_ACPM_VCLK(_id) ((_id & (MASK_OF_TYPE | MASK_OF_SUBTYPE)) == ACPM_VCLK_TYPE)
205
206 #define GET_TYPE(_id) (_id & MASK_OF_TYPE)
207 #define GET_IDX(_id) (_id & MASK_OF_ID)
208 /*
209 * struct sfr_block - SFR block
210 * @id: id of sfr_block
211 * @name: name of sfr_block
212 * @pa: physical address
213 * @va: virtual address
214 * @size: sfr block size, 2 ^ n
215 */
216 struct sfr_block {
217 unsigned int id;
218 char *name;
219 phys_addr_t pa;
220 void __iomem *va;
221 unsigned int size;
222 };
223
224 /*
225 * struct sfr - SFR
226 * @id: id of sfr
227 * @name: sfr name
228 * @offset: offset from block
229 * @block: index of block
230 */
231 struct sfr {
232 unsigned int id;
233 char *name;
234 unsigned int offset;
235 unsigned int block;
236 };
237
238 /*
239 * struct sfr_access - SFR field
240 * @id: id of sfr
241 * @name: sfr field name
242 * @shift: shift value of field
243 * @width: width value of field
244 * @sfr: index of sfr
245 */
246 struct sfr_access {
247 unsigned int id;
248 char *name;
249 unsigned char shift;
250 unsigned char width;
251 unsigned int sfr;
252 };
253
254 /*
255 * struct cmucal_clk - CMUCAL Clock node
256 * @id: id of clock node
257 * @paddr: physical addr of clock node
258 * @pid: parent id of clock node
259 * @name: name of clock node
260 * @offset_idx: index of offset
261 * @status_idx: index of status
262 * @enable_idx: index of enable
263 * @offset: offset address
264 * @status: status address, or lock_offset of pll
265 * @enable: enable address
266 * @shift: shift of offset
267 * @width: width of offset
268 * @s_shift: shift of status
269 * @s_width: width of status
270 * @e_shift: shift of enable
271 * @e_width: width of enable
272 */
273 struct cmucal_clk {
274 unsigned int id;
275 unsigned int paddr;
276 unsigned int pid;
277 char *name;
278 union {
279 void __iomem *offset;
280 void __iomem *lock;
281 unsigned long offset_idx;
282 };
283 union {
284 void __iomem *enable;
285 void __iomem *pll_con0;
286 unsigned long enable_idx;
287 };
288 union {
289 void __iomem *status;
290 void __iomem *pll_con1;
291 unsigned long status_idx;
292 };
293 unsigned char shift;
294 unsigned char width;
295 unsigned char s_shift;
296 unsigned char s_width;
297 unsigned char e_shift;
298 unsigned char e_width;
299 };
300
301 /*
302 * struct pll_spec
303 * @p,m,s,k min/max value
304 * @fref, fvco, fout min/max value
305 */
306 struct pll_spec {
307 unsigned int pdiv_min;
308 unsigned int pdiv_max;
309 unsigned int mdiv_min;
310 unsigned int mdiv_max;
311 unsigned int sdiv_min;
312 unsigned int sdiv_max;
313 signed short kdiv_min;
314 signed short kdiv_max;
315 unsigned long long fref_min;
316 unsigned long long fref_max;
317 unsigned long long fvco_min;
318 unsigned long long fvco_max;
319 unsigned long long fout_min;
320 unsigned long long fout_max;
321 unsigned int lock_time;
322 unsigned int flock_time;
323 };
324
325 /*
326 * struct cmucal_pll_table
327 * @rate: pll rate
328 * @pdiv, @mdiv, @sdiv, @kdiv: for rate
329 */
330 struct cmucal_pll_table {
331 unsigned int rate;
332 unsigned short pdiv;
333 unsigned short mdiv;
334 unsigned short sdiv;
335 signed short kdiv;
336 };
337
338 /*
339 * struct cmucal_pll
340 * @clk: cmucal_rate structure
341 * @type: pll type
342 * @rate_table: rate table
343 * @rate_count: number of rate_table
344 * @lock_time: integer PLL locktime
345 * @flock_time: fractional PLL locktime
346 */
347 struct cmucal_pll {
348 struct cmucal_clk clk;
349 unsigned int umux;
350 unsigned int type;
351 struct cmucal_pll_table *rate_table;
352 unsigned int rate_count;
353 unsigned int lock_time;
354 unsigned int flock_time;
355 unsigned int p_idx, m_idx, s_idx, k_idx;
356 unsigned char p_shift, m_shift, s_shift, k_shift;
357 unsigned char p_width, m_width, s_width, k_width;
358 };
359
360 struct cmucal_clk_fixed_rate {
361 struct cmucal_clk clk;
362 unsigned int fixed_rate;
363 };
364
365 struct cmucal_clk_fixed_factor {
366 struct cmucal_clk clk;
367 unsigned short ratio;
368 };
369
370 struct cmucal_mux {
371 struct cmucal_clk clk;
372 unsigned int *pid;
373 unsigned char num_parents;
374 };
375
376 struct cmucal_div {
377 struct cmucal_clk clk;
378 };
379
380 struct cmucal_gate {
381 struct cmucal_clk clk;
382 };
383
384 struct cmucal_qch {
385 struct cmucal_clk clk;
386 union {
387 void __iomem *ignore;
388 unsigned long ignore_idx;
389 };
390 unsigned char ig_shift;
391 unsigned char ig_width;
392 };
393
394 struct cmucal_option {
395 struct cmucal_clk clk;
396 };
397
398 struct cmucal_clkout {
399 struct cmucal_clk clk;
400 unsigned int sel;
401 unsigned int en;
402 };
403
404 #define CMUCAL_VCLK(_id, _lut, _list, _seq, _switch) \
405 [_id & MASK_OF_ID] = { \
406 .id = _id, \
407 .name = #_id, \
408 .lut = _lut, \
409 .list = _list, \
410 .seq = _seq, \
411 .num_rates = (sizeof(_lut) / sizeof((_lut)[0])), \
412 .num_list = (sizeof(_list) / sizeof((_list)[0])), \
413 .switch_info = _switch, \
414 .ops = NULL, \
415 }
416
417 #define CMUCAL_VCLK_NULL(_id, _lut, _list, _seq, _switch) \
418 [_id & MASK_OF_ID] = { \
419 .id = _id, \
420 .name = #_id, \
421 .lut = _lut, \
422 .list = _list, \
423 .seq = _seq, \
424 .num_rates = 0, \
425 .num_list = (sizeof(_list) / sizeof((_list)[0])), \
426 .switch_info = _switch, \
427 .ops = NULL, \
428 }
429
430 #define CMUCAL_ACPM_VCLK(_id, _lut, _list, _seq, _switch, _margin_id) \
431 [_id & MASK_OF_ID] = { \
432 .id = _id, \
433 .name = #_id, \
434 .lut = _lut, \
435 .list = _list, \
436 .seq = _seq, \
437 .num_rates = 0, \
438 .num_list = 0, \
439 .switch_info = _switch, \
440 .ops = NULL, \
441 .margin_id = _margin_id, \
442 }
443
444 #define SFR_BLOCK(_id, _pa, _size) \
445 [_id & MASK_OF_ID] = { \
446 .id = _id, \
447 .pa = _pa, \
448 .size = _size, \
449 }
450
451 #define SFR(_id, _offset, _block) \
452 [_id & MASK_OF_ID] = { \
453 .id = _id, \
454 .offset = _offset, \
455 .block = _block, \
456 }
457
458 #define SFR_ACCESS(_id, _shift, _width, _sfr) \
459 [_id & MASK_OF_ID] = { \
460 .id = _id, \
461 .shift = _shift, \
462 .width = _width, \
463 .sfr = _sfr, \
464 }
465
466 #define CLK_PLL(_typ, _id, _pid, _lock, _enable, _stable, \
467 _p, _m, _s, _k, \
468 _rtable, _time, _ftime) \
469 [_id & MASK_OF_ID] = { \
470 .clk.id = _id, \
471 .clk.pid = EMPTY_CLK_ID, \
472 .clk.name = #_id, \
473 .clk.offset_idx = _lock, \
474 .clk.enable_idx = _enable, \
475 .clk.status_idx = _stable, \
476 .p_idx = _p, \
477 .m_idx = _m, \
478 .s_idx = _s, \
479 .k_idx = _k, \
480 .type = _typ, \
481 .umux = _pid, \
482 .rate_table = _rtable, \
483 .rate_count = (sizeof(_rtable) / sizeof((_rtable)[0])), \
484 .lock_time = _time, \
485 .flock_time = _ftime, \
486 }
487
488 #define CLK_MUX(_id, _pids, _o, _so, _eo) \
489 [_id & MASK_OF_ID] = { \
490 .clk.id = _id, \
491 .clk.name = #_id, \
492 .clk.offset_idx = _o, \
493 .clk.status_idx = _so, \
494 .clk.enable_idx = _eo, \
495 .pid = _pids, \
496 .num_parents = (sizeof(_pids) / sizeof((_pids)[0])), \
497 }
498
499 #define CLK_MUX_NULL(_id, _pids, _o, _so, _eo) \
500 [_id & MASK_OF_ID] = { \
501 .clk.id = _id, \
502 .clk.name = #_id, \
503 .clk.offset_idx = _o, \
504 .clk.status_idx = _so, \
505 .clk.enable_idx = _eo, \
506 .pid = _pids, \
507 .num_parents = 0, \
508 }
509
510 #define CLK_DIV(_id, _pid, _o, _so, _eo) \
511 [_id & MASK_OF_ID] = { \
512 .clk.id = _id, \
513 .clk.name = #_id, \
514 .clk.pid = _pid, \
515 .clk.offset_idx = _o, \
516 .clk.status_idx = _so, \
517 .clk.enable_idx = _eo, \
518 }
519
520 #define CLK_GATE(_id, _pid, _o, _so, _eo) \
521 [_id & MASK_OF_ID] = { \
522 .clk.id = _id, \
523 .clk.name = #_id, \
524 .clk.pid = _pid, \
525 .clk.offset_idx = _o, \
526 .clk.status_idx = _so, \
527 .clk.enable_idx = _eo, \
528 }
529 #ifdef CONFIG_CMUCAL_QCH_IGNORE_SUPPORT
530 #define CLK_QCH(_id, _o, _so, _eo, _ig) \
531 [_id & MASK_OF_ID] = { \
532 .clk.id = _id, \
533 .clk.name = #_id, \
534 .clk.pid = EMPTY_CLK_ID, \
535 .clk.offset_idx = _o, \
536 .clk.status_idx = _so, \
537 .clk.enable_idx = _eo, \
538 .ignore_idx = _ig, \
539 }
540 #else
541 #define CLK_QCH(_id, _o, _so, _eo) \
542 [_id & MASK_OF_ID] = { \
543 .clk.id = _id, \
544 .clk.name = #_id, \
545 .clk.pid = EMPTY_CLK_ID, \
546 .clk.offset_idx = _o, \
547 .clk.status_idx = _so, \
548 .clk.enable_idx = _eo, \
549 }
550 #endif
551 #define CLK_OPTION(_id, _o, _eo) \
552 [_id & MASK_OF_ID] = { \
553 .clk.id = _id, \
554 .clk.name = #_id, \
555 .clk.pid = EMPTY_CLK_ID, \
556 .clk.offset_idx = _o, \
557 .clk.enable_idx = _eo, \
558 }
559
560 #define FIXEDRATE(_id, _frate, _eo) \
561 [_id & MASK_OF_ID] = { \
562 .clk.id = _id, \
563 .clk.pid = EMPTY_CLK_ID, \
564 .clk.name = #_id, \
565 .clk.enable_idx = _eo, \
566 .fixed_rate = _frate, \
567 }
568
569 #define FIXEDFACTOR(_id, _pid, _ratio, _eo) \
570 [_id & MASK_OF_ID] = { \
571 .clk.id = _id, \
572 .clk.pid = _pid, \
573 .clk.name = #_id, \
574 .clk.enable_idx = _eo, \
575 .ratio = _ratio, \
576 }
577
578 #define CLKOUT(_id, _o, _s, _w, _sel, _es, _ew, _en) \
579 [_id & MASK_OF_ID] = { \
580 .clk.id = _id, \
581 .clk.name = #_id, \
582 .clk.offset_idx = _o, \
583 .clk.shift = _s, \
584 .clk.width = _w, \
585 .clk.e_shift = _es, \
586 .clk.e_width = _ew, \
587 .sel = _sel, \
588 .en = _en, \
589 }
590
591 #define PLL_RATE_MPS(_rate, _m, _p, _s) \
592 { \
593 .rate = (_rate), \
594 .mdiv = (_m), \
595 .pdiv = (_p), \
596 .sdiv = (_s), \
597 .kdiv = (0), \
598 }
599
600 #define PLL_RATE_MPSK(_rate, _m, _p, _s, _k) \
601 { \
602 .rate = (_rate), \
603 .mdiv = (_m), \
604 .pdiv = (_p), \
605 .sdiv = (_s), \
606 .kdiv = (_k), \
607 }
608
609 #define to_fixed_rate_clk(_clk) container_of(_clk, struct cmucal_clk_fixed_rate, clk)
610 #define to_fixed_factor_clk(_clk) container_of(_clk, struct cmucal_clk_fixed_factor, clk)
611 #define to_pll_clk(_clk) container_of(_clk, struct cmucal_pll, clk)
612 #define to_mux_clk(_clk) container_of(_clk, struct cmucal_mux, clk)
613 #define to_div_clk(_clk) container_of(_clk, struct cmucal_div, clk)
614 #define to_gate_clk(_clk) container_of(_clk, struct cmucal_gate, clk)
615 #define to_clkout(_clk) container_of(_clk, struct cmucal_clkout, clk)
616 #define to_qch(_clk) container_of(_clk, struct cmucal_qch, clk)
617
618 extern unsigned int cmucal_get_list_size(unsigned int type);
619 extern void *cmucal_get_node(unsigned int id);
620 extern void *cmucal_get_sfr_node(unsigned int id);
621 extern unsigned int cmucal_get_id(char *name);
622 extern unsigned int cmucal_get_id_by_addr(unsigned int addr);
623 extern void (*cal_data_init)(void);
624 #endif