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
CommitLineData
32760332
JJ
1#ifndef __CMUCAL_H__
2#define __CMUCAL_H__
3
4#include <linux/types.h>
5#include <linux/kernel.h>
6#include "vclk.h"
7
8struct 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 */
70struct 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 */
80struct 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 */
91struct 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 */
104struct 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 */
125struct 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
146enum 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
170enum 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 */
216struct 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 */
231struct 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 */
246struct 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 */
273struct 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 */
306struct 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 */
330struct 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 */
347struct 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
360struct cmucal_clk_fixed_rate {
361 struct cmucal_clk clk;
362 unsigned int fixed_rate;
363};
364
365struct cmucal_clk_fixed_factor {
366 struct cmucal_clk clk;
367 unsigned short ratio;
368};
369
370struct cmucal_mux {
371 struct cmucal_clk clk;
372 unsigned int *pid;
373 unsigned char num_parents;
374};
375
376struct cmucal_div {
377 struct cmucal_clk clk;
378};
379
380struct cmucal_gate {
381 struct cmucal_clk clk;
382};
383
384struct 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
394struct cmucal_option {
395 struct cmucal_clk clk;
396};
397
398struct 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
36b28160 417#define CMUCAL_VCLK_NULL(_id, _lut, _list, _seq, _switch) \
32760332
JJ
418[_id & MASK_OF_ID] = { \
419 .id = _id, \
420 .name = #_id, \
421 .lut = _lut, \
422 .list = _list, \
423 .seq = _seq, \
36b28160 424 .num_rates = 0, \
32760332
JJ
425 .num_list = (sizeof(_list) / sizeof((_list)[0])), \
426 .switch_info = _switch, \
427 .ops = NULL, \
36b28160
MB
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, \
32760332
JJ
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
36b28160
MB
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
32760332
JJ
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
618extern unsigned int cmucal_get_list_size(unsigned int type);
619extern void *cmucal_get_node(unsigned int id);
620extern void *cmucal_get_sfr_node(unsigned int id);
621extern unsigned int cmucal_get_id(char *name);
622extern unsigned int cmucal_get_id_by_addr(unsigned int addr);
623extern void (*cal_data_init)(void);
624#endif