Merge tag 'v3.10.55' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / mt_clkmgr.c
1 #define __MT_CLKMGR_C__
2
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/types.h>
6 #include <linux/delay.h>
7 #include <linux/list.h>
8 #include <linux/slab.h>
9 #include <linux/spinlock.h>
10 #include <linux/proc_fs.h>
11
12 #include <asm/uaccess.h>
13
14 #include <linux/device.h>
15 #include <linux/platform_device.h>
16
17 #include <mach/mt_typedefs.h>
18 #include <mach/sync_write.h>
19 #include <mach/mt_clkmgr.h>
20 #include <mach/mt_dcm.h>
21 #include <mach/mt_spm.h>
22 #include <mach/mt_spm_mtcmos.h>
23 #include <mach/mt_spm_sleep.h>
24 #include <mach/mt_freqhopping.h>
25 #include <mach/mt_gpufreq.h>
26 #include <linux/earlysuspend.h>
27
28
29 #define DISABLE_BUG_ON_CNT 0
30 #define WORKAROUND_DPI0_MUX 1
31 #define WORKAROUND_DAPC 1
32
33 #if CLKMGR_8127
34 #include <linux/fs.h>
35 #include <linux/seq_file.h>
36 #endif /* CLKMGR_8127 */
37
38 /* #define CONFIG_CLKMGR_BRINGUP */
39
40 /* #define CLK_LOG_TOP */
41 /* #define CLK_LOG */
42 /* #define SYS_LOG */
43 /* #define MUX_LOG_TOP */
44 #define MUX_LOG
45 /* #define PLL_LOG_TOP */
46 #define PLL_LOG
47
48 /************************************************
49 ********** log debug **********
50 ************************************************/
51
52 #define USING_XLOG
53
54 #ifdef USING_XLOG
55 #include <linux/xlog.h>
56
57 #define TAG "Power/clkmgr"
58
59 #define clk_err(fmt, args...) \
60 xlog_printk(ANDROID_LOG_ERROR, TAG, fmt, ##args)
61 #define clk_warn(fmt, args...) \
62 xlog_printk(ANDROID_LOG_WARN, TAG, fmt, ##args)
63 #define clk_info(fmt, args...) \
64 xlog_printk(ANDROID_LOG_INFO, TAG, fmt, ##args)
65 #define clk_dbg(fmt, args...) \
66 xlog_printk(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
67 #define clk_ver(fmt, args...) \
68 xlog_printk(ANDROID_LOG_VERBOSE, TAG, fmt, ##args)
69
70 #else
71
72 #define TAG "[Power/clkmgr] "
73
74 #define clk_err(fmt, args...) \
75 pr_err(TAG fmt, ##args)
76 #define clk_warn(fmt, args...) \
77 pr_warn(TAG fmt, ##args)
78 #define clk_info(fmt, args...) \
79 pr_notice(TAG fmt, ##args)
80 #define clk_dbg(fmt, args...) \
81 pr_info(TAG fmt, ##args)
82 #define clk_ver(fmt, args...) \
83 pr_debug(TAG fmt, ##args)
84
85 #endif
86
87
88
89 /************************************************
90 ********** macro / functions **********
91 ************************************************/
92
93 #define BITS(_bits_, _val_) ((BIT((1 ? _bits_) + 1) - BIT((0 ? _bits_))) & (_val_ << (0 ? _bits_)))
94 #define BITMASK(_bits_) (BIT((1 ? _bits_) + 1) - BIT((0 ? _bits_)))
95 #define ABS_DIFF(a, b) ((a) > (b) ? (a) - (b) : (b) - (a))
96
97
98 /************************************************
99 ********** register access **********
100 ************************************************/
101
102 #define clk_readl(addr) \
103 DRV_Reg32(addr)
104
105 #define clk_writel(addr, val) \
106 mt65xx_reg_sync_writel(val, addr)
107
108 #define clk_setl(addr, val) \
109 mt65xx_reg_sync_writel(clk_readl(addr) | (val), addr)
110
111 #define clk_clrl(addr, val) \
112 mt65xx_reg_sync_writel(clk_readl(addr) & ~(val), addr)
113
114 #define clk_writel_mask(addr, mask, val) \
115 clk_writel(addr, (clk_readl(addr) & ~(mask)) | (val))
116
117
118
119 /************************************************
120 ********** struct definition **********
121 ************************************************/
122
123 /* #define CONFIG_CLKMGR_STAT */
124
125 struct pll;
126 struct pll_ops {
127 int (*get_state)(struct pll *pll);
128 void (*enable)(struct pll *pll);
129 void (*disable)(struct pll *pll);
130 void (*fsel)(struct pll *pll, unsigned int value);
131 int (*dump_regs)(struct pll *pll, unsigned int *ptr);
132 unsigned int (*vco_calc)(struct pll *pll);
133 int (*hp_enable)(struct pll *pll);
134 int (*hp_disable)(struct pll *pll);
135 #if CLKMGR_8127
136 unsigned int (*get_postdiv)(struct pll *pll);
137 void (*set_postdiv)(struct pll *pll, unsigned int postdiv);
138 unsigned int (*get_pcw)(struct pll *pll);
139 void (*set_pcw)(struct pll *pll, unsigned int pcw);
140 int (*set_freq)(struct pll *pll, unsigned int freq);
141 #endif /* CLKMGR_8127 */
142 };
143
144 struct pll {
145 const char *name;
146 int type;
147 int mode;
148 int feat;
149 int state;
150 unsigned int cnt;
151 unsigned int en_mask;
152 unsigned int base_addr;
153 unsigned int pwr_addr;
154 struct pll_ops *ops;
155 unsigned int hp_id;
156 int hp_switch;
157 #ifdef CONFIG_CLKMGR_STAT
158 struct list_head head;
159 #endif
160 };
161
162
163 struct subsys;
164 struct subsys_ops {
165 int (*enable)(struct subsys *sys);
166 int (*disable)(struct subsys *sys);
167 int (*get_state)(struct subsys *sys);
168 int (*dump_regs)(struct subsys *sys, unsigned int *ptr);
169 };
170
171 struct subsys {
172 const char *name;
173 int type;
174 int force_on;
175 unsigned int cnt;
176 unsigned int state;
177 unsigned int default_sta;
178 unsigned int sta_mask; /* mask in PWR_STATUS */
179 unsigned int ctl_addr;
180 struct subsys_ops *ops;
181 struct cg_grp *start;
182 unsigned int nr_grps;
183 struct clkmux *mux;
184 #ifdef CONFIG_CLKMGR_STAT
185 struct list_head head;
186 #endif
187 };
188
189
190 struct clkmux;
191 struct clkmux_ops {
192 void (*sel)(struct clkmux *mux, unsigned int clksrc);
193 void (*enable)(struct clkmux *mux);
194 void (*disable)(struct clkmux *mux);
195 };
196
197 struct clkmux {
198 const char *name;
199 unsigned int cnt;
200 unsigned int base_addr;
201 unsigned int sel_mask;
202 unsigned int pdn_mask;
203 unsigned int offset;
204 unsigned int nr_inputs;
205 struct clkmux_ops *ops;
206 struct clkmux *parent;
207 struct clkmux *siblings;
208 struct pll *pll;
209 #ifdef CONFIG_CLKMGR_STAT
210 struct list_head head;
211 #endif
212 };
213
214
215 struct cg_grp;
216 struct cg_grp_ops {
217 int (*prepare)(struct cg_grp *grp);
218 int (*finished)(struct cg_grp *grp);
219 unsigned int (*get_state)(struct cg_grp *grp);
220 int (*dump_regs)(struct cg_grp *grp, unsigned int *ptr);
221 };
222
223 struct cg_grp {
224 const char *name;
225 unsigned int set_addr;
226 unsigned int clr_addr;
227 unsigned int sta_addr;
228 unsigned int mask;
229 unsigned int state;
230 struct cg_grp_ops *ops;
231 struct subsys *sys;
232 };
233
234
235 struct cg_clk;
236 struct cg_clk_ops {
237 int (*get_state)(struct cg_clk *clk);
238 int (*check_validity)(struct cg_clk *clk); /* 1: valid, 0: invalid */
239 int (*enable)(struct cg_clk *clk);
240 int (*disable)(struct cg_clk *clk);
241 };
242
243 struct cg_clk {
244 int cnt;
245 unsigned int state;
246 unsigned int mask;
247 int force_on;
248 struct cg_clk_ops *ops;
249 struct cg_grp *grp;
250 struct clkmux *mux;
251 struct cg_clk *parent;
252 #if CLKMGR_8127
253 const char *name;
254 #endif /* CLKMGR_8127 */
255 #ifdef CONFIG_CLKMGR_STAT
256 struct list_head head;
257 #endif
258 };
259
260
261 #ifdef CONFIG_CLKMGR_STAT
262 struct stat_node {
263 struct list_head link;
264 unsigned int cnt_on;
265 unsigned int cnt_off;
266 char name[0];
267 };
268 #endif
269
270
271
272 /************************************************
273 ********** global variablies **********
274 ************************************************/
275
276 #define PWR_DOWN 0
277 #define PWR_ON 1
278
279 static int initialized;
280
281 static struct pll plls[NR_PLLS];
282 static struct subsys syss[NR_SYSS];
283 static struct clkmux muxs[NR_MUXS];
284 static struct cg_grp grps[NR_GRPS];
285 static struct cg_clk clks[NR_CLKS];
286
287
288
289 /************************************************
290 ********** spin lock protect **********
291 ************************************************/
292
293 static DEFINE_SPINLOCK(clock_lock);
294
295 #define clkmgr_lock(flags) \
296 spin_lock_irqsave(&clock_lock, flags)
297
298 #define clkmgr_unlock(flags) \
299 spin_unlock_irqrestore(&clock_lock, flags)
300
301 #define clkmgr_locked() \
302 spin_is_locked(&clock_lock)
303
304
305 #if !CLKMGR_8127
306
307 int clkmgr_is_locked(void)
308 {
309 return clkmgr_locked();
310 }
311 EXPORT_SYMBOL(clkmgr_is_locked);
312
313 #endif /* !CLKMGR_8127 */
314
315
316
317 /************************************************
318 ********** clkmgr stat debug **********
319 ************************************************/
320
321 #ifdef CONFIG_CLKMGR_STAT
322 void update_stat_locked(struct list_head *head, char *name, int op)
323 {
324 struct list_head *pos = NULL;
325 struct stat_node *node = NULL;
326 int len = strlen(name);
327 int new_node = 1;
328
329 list_for_each(pos, head) {
330 node = list_entry(pos, struct stat_node, link);
331 if (!strncmp(node->name, name, len)) {
332 new_node = 0;
333 break;
334 }
335 }
336
337 if (new_node) {
338 node = NULL;
339 node = kzalloc(sizeof(*node) + len + 1, GFP_ATOMIC);
340 if (!node) {
341 clk_err("[%s]: malloc stat node for %s fail\n", __func__, name);
342 return;
343 } else {
344 memcpy(node->name, name, len);
345 list_add_tail(&node->link, head);
346 }
347 }
348
349 if (op)
350 node->cnt_on++;
351 else
352 node->cnt_off++;
353 }
354 #endif
355
356
357
358 /************************************************
359 ********** function declaration **********
360 ************************************************/
361
362 static int pll_enable_locked(struct pll *pll);
363 static int pll_disable_locked(struct pll *pll);
364
365 static int sys_enable_locked(struct subsys *sys);
366 static int sys_disable_locked(struct subsys *sys, int force_off);
367
368 static void mux_enable_locked(struct clkmux *mux);
369 static void mux_disable_locked(struct clkmux *mux);
370
371 static int clk_enable_locked(struct cg_clk *clk);
372 static int clk_disable_locked(struct cg_clk *clk);
373
374
375 static inline int pll_enable_internal(struct pll *pll, char *name)
376 {
377 int err;
378 err = pll_enable_locked(pll);
379 #ifdef CONFIG_CLKMGR_STAT
380 update_stat_locked(&pll->head, name, 1);
381 #endif
382 return err;
383 }
384
385 static inline int pll_disable_internal(struct pll *pll, char *name)
386 {
387 int err;
388 err = pll_disable_locked(pll);
389 #ifdef CONFIG_CLKMGR_STAT
390 update_stat_locked(&pll->head, name, 0);
391 #endif
392 return err;
393 }
394
395
396 static inline int subsys_enable_internal(struct subsys *sys, char *name)
397 {
398 int err;
399 err = sys_enable_locked(sys);
400 #ifdef CONFIG_CLKMGR_STAT
401 update_stat_locked(&sys->head, name, 1);
402 #endif
403 return err;
404 }
405
406 static inline int subsys_disable_internal(struct subsys *sys, int force_off, char *name)
407 {
408 int err;
409 err = sys_disable_locked(sys, force_off);
410 #ifdef CONFIG_CLKMGR_STAT
411 update_stat_locked(&sys->head, name, 0);
412 #endif
413 return err;
414 }
415
416
417 static inline void mux_enable_internal(struct clkmux *mux, char *name)
418 {
419 mux_enable_locked(mux);
420 #ifdef CONFIG_CLKMGR_STAT
421 update_stat_locked(&mux->head, name, 1);
422 #endif
423 }
424
425 static inline void mux_disable_internal(struct clkmux *mux, char *name)
426 {
427 mux_disable_locked(mux);
428 #ifdef CONFIG_CLKMGR_STAT
429 update_stat_locked(&mux->head, name, 0);
430 #endif
431 }
432
433
434 static inline int clk_enable_internal(struct cg_clk *clk, char *name)
435 {
436 int err;
437 err = clk_enable_locked(clk);
438 #ifdef CONFIG_CLKMGR_STAT
439 update_stat_locked(&clk->head, name, 1);
440 #endif
441 return err;
442 }
443
444 static inline int clk_disable_internal(struct cg_clk *clk, char *name)
445 {
446 int err;
447 err = clk_disable_locked(clk);
448 #ifdef CONFIG_CLKMGR_STAT
449 update_stat_locked(&clk->head, name, 0);
450 #endif
451 return err;
452 }
453
454
455
456 /************************************************
457 ********** pll part **********
458 ************************************************/
459
460 #define PLL_TYPE_SDM 0
461 #define PLL_TYPE_LC 1
462
463 #define HAVE_RST_BAR (0x1 << 0)
464 #define HAVE_PLL_HP (0x1 << 1)
465 #define HAVE_FIX_FRQ (0x1 << 2)
466 #define Others (0x1 << 3)
467
468 #define RST_BAR_MASK 0x1000000
469
470 static struct pll_ops arm_pll_ops;
471 static struct pll_ops sdm_pll_ops;
472
473 #if CLKMGR_8127
474 static struct pll_ops aud_pll_ops;
475 #endif /* CLKMGR_8127 */
476
477 static struct pll plls[NR_PLLS] = {
478 [ARMPLL] = {
479 .name = __stringify(ARMPLL),
480 .type = PLL_TYPE_SDM,
481 .feat = HAVE_PLL_HP,
482 .en_mask = 0x00000001,
483 .base_addr = ARMPLL_CON0,
484 .pwr_addr = ARMPLL_PWR_CON0,
485 .ops = &arm_pll_ops,
486 .hp_id = MT658X_FH_ARM_PLL,
487 .hp_switch = 1,
488 },
489 [MAINPLL] = {
490 .name = __stringify(MAINPLL),
491 .type = PLL_TYPE_SDM,
492 .feat = HAVE_PLL_HP | HAVE_RST_BAR,
493 .en_mask = 0x78000001,
494 .base_addr = MAINPLL_CON0,
495 .pwr_addr = MAINPLL_PWR_CON0,
496 .ops = &sdm_pll_ops,
497 .hp_id = MT658X_FH_MAIN_PLL,
498 .hp_switch = 1,
499 },
500 [MSDCPLL] = {
501 .name = __stringify(MSDCPLL),
502 .type = PLL_TYPE_SDM,
503 .feat = HAVE_PLL_HP,
504 .en_mask = 0x00000001,
505 .base_addr = MSDCPLL_CON0,
506 .pwr_addr = MSDCPLL_PWR_CON0,
507 .ops = &sdm_pll_ops,
508 .hp_id = MT658X_FH_MSDC_PLL,
509 .hp_switch = 1,
510 },
511 [UNIVPLL] = {
512 .name = __stringify(UNIVPLL),
513 .type = PLL_TYPE_SDM,
514 .feat = HAVE_RST_BAR | HAVE_FIX_FRQ,
515 .en_mask = 0xFC000001,
516 .base_addr = UNIVPLL_CON0,
517 .pwr_addr = UNIVPLL_PWR_CON0,
518 .ops = &sdm_pll_ops,
519 },
520 [MMPLL] = {
521 .name = __stringify(MMPLL),
522 .type = PLL_TYPE_SDM,
523 .feat = HAVE_PLL_HP,
524 .en_mask = 0x00000001,
525 .base_addr = MMPLL_CON0,
526 .pwr_addr = MMPLL_PWR_CON0,
527 .ops = &sdm_pll_ops,
528 .hp_id = MT658X_FH_MM_PLL,
529 .hp_switch = 1,
530 },
531 [VENCPLL] = {
532 .name = __stringify(VENCPLL),
533 .type = PLL_TYPE_SDM,
534 .feat = HAVE_PLL_HP,
535 .en_mask = 0x00000001,
536 .base_addr = VENCPLL_CON0,
537 .pwr_addr = VENCPLL_PWR_CON0,
538 .ops = &sdm_pll_ops,
539 .hp_id = MT658X_FH_VENC_PLL,
540 .hp_switch = 1,
541 },
542 [TVDPLL] = {
543 .name = __stringify(TVDPLL),
544 .type = PLL_TYPE_SDM,
545 .feat = HAVE_PLL_HP,
546 .en_mask = 0x00000001,
547 .base_addr = TVDPLL_CON0,
548 .pwr_addr = TVDPLL_PWR_CON0,
549 .ops = &sdm_pll_ops,
550 .hp_id = MT658X_FH_TVD_PLL,
551 .hp_switch = 1,
552 },
553 [LVDSPLL] = {
554 .name = __stringify(LVDSPLL),
555 .type = PLL_TYPE_SDM,
556 .feat = HAVE_PLL_HP,
557 .en_mask = 0x00000001,
558 .base_addr = LVDSPLL_CON0,
559 .pwr_addr = LVDSPLL_PWR_CON0,
560 .ops = &sdm_pll_ops,
561 .hp_id = MT658X_FH_LVDS_PLL,
562 .hp_switch = 1,
563 },
564 [AUDPLL] = {
565 .name = __stringify(AUDPLL),
566 .type = PLL_TYPE_SDM,
567 .feat = 0x0,
568 .en_mask = 0x00000001,
569 .base_addr = AUDPLL_CON0,
570 .pwr_addr = AUDPLL_PWR_CON0,
571 .ops = &aud_pll_ops,
572 }
573 };
574
575 static struct pll *id_to_pll(unsigned int id)
576 {
577 return id < NR_PLLS ? plls + id : NULL;
578 }
579
580 #define PLL_PWR_ON (0x1 << 0)
581 #define PLL_ISO_EN (0x1 << 1)
582
583 #define SDM_PLL_N_INFO_MASK 0x001FFFFF
584 #define UNIV_SDM_PLL_N_INFO_MASK 0x001fc000
585 #define AUD_SDM_PLL_N_INFO_MASK 0x7FFFFFFF
586 #define SDM_PLL_N_INFO_CHG 0x80000000
587 #define ARMPLL_POSDIV_MASK 0x07000000
588
589 #define PLL_FBKDIV_MASK 0x00007F00
590 #define PLL_FBKDIV_OFFSET 0x8
591
592
593 static int pll_get_state_op(struct pll *pll)
594 {
595 return clk_readl(pll->base_addr) & 0x1;
596 }
597
598 static void sdm_pll_enable_op(struct pll *pll)
599 {
600 #ifdef PLL_LOG
601 clk_dbg("[%s]: pll->name=%s\n", __func__, pll->name);
602 #endif
603
604 clk_setl(pll->pwr_addr, PLL_PWR_ON);
605 udelay(2);
606 clk_clrl(pll->pwr_addr, PLL_ISO_EN);
607
608 clk_setl(pll->base_addr, pll->en_mask);
609 udelay(20);
610
611 if (pll->feat & HAVE_RST_BAR)
612 clk_setl(pll->base_addr, RST_BAR_MASK);
613 }
614
615 static void sdm_pll_disable_op(struct pll *pll)
616 {
617 #ifdef PLL_LOG
618 clk_dbg("[%s]: pll->name=%s\n", __func__, pll->name);
619 #endif
620
621 if (pll->feat & HAVE_RST_BAR)
622 clk_clrl(pll->base_addr, RST_BAR_MASK);
623
624 clk_clrl(pll->base_addr, 0x1);
625
626 clk_setl(pll->pwr_addr, PLL_ISO_EN);
627 clk_clrl(pll->pwr_addr, PLL_PWR_ON);
628 }
629
630 static void sdm_pll_fsel_op(struct pll *pll, unsigned int value)
631 {
632 unsigned int ctrl_value;
633
634 ctrl_value = clk_readl(pll->base_addr + 4);
635 if (pll->base_addr == UNIVPLL_CON0) {
636 ctrl_value &= ~UNIV_SDM_PLL_N_INFO_MASK;
637 ctrl_value |= value & UNIV_SDM_PLL_N_INFO_MASK;
638 } else if (pll->base_addr == AUDPLL_CON0) {
639 ctrl_value &= ~AUD_SDM_PLL_N_INFO_MASK;
640 ctrl_value |= value & AUD_SDM_PLL_N_INFO_MASK;
641 } else {
642 ctrl_value &= ~SDM_PLL_N_INFO_MASK;
643 ctrl_value |= value & SDM_PLL_N_INFO_MASK;
644 }
645
646 ctrl_value |= SDM_PLL_N_INFO_CHG;
647
648 clk_writel(pll->base_addr + 4, ctrl_value);
649 udelay(20);
650 }
651
652 static int sdm_pll_dump_regs_op(struct pll *pll, unsigned int *ptr)
653 {
654 *(ptr) = clk_readl(pll->base_addr);
655 *(++ptr) = clk_readl(pll->base_addr + 4);
656 *(++ptr) = clk_readl(pll->pwr_addr);
657
658 return 3;
659 }
660
661
662 static const unsigned int pll_posdiv_map[8] = {1, 2, 4, 8, 16, 16, 16, 16};
663
664
665 static unsigned int sdm_pll_get_postdiv_op(struct pll *pll)
666 {
667 unsigned int con0 = clk_readl(pll->base_addr); /* PLL_CON0 */
668 unsigned int posdiv = (con0 & BITMASK(6 : 4)) >> 4; /* bit[6:4] */
669
670 return posdiv;
671 }
672
673
674 static void sdm_pll_set_postdiv_op(struct pll *pll, unsigned int postdiv)
675 {
676 unsigned con0_addr = pll->base_addr;
677 unsigned int con0_value = clk_readl(con0_addr); /* PLL_CON0 */
678
679 clk_writel(con0_addr, (con0_value & ~BITMASK(6 : 4)) | BITS(6 : 4, postdiv)); /* bit[8:6] */
680 }
681
682
683 static unsigned int sdm_pll_get_pcw_op(struct pll *pll)
684 {
685 unsigned int con1_addr = pll->base_addr + 4;
686 unsigned int reg_value;
687
688 reg_value = clk_readl(con1_addr); /* PLL_CON1 */
689 reg_value &= SDM_PLL_N_INFO_MASK; /* bit[20:0] */
690
691 return reg_value;
692 }
693
694
695 static void sdm_pll_set_pcw_op(struct pll *pll, unsigned int pcw)
696 {
697 unsigned int con1_addr = pll->base_addr + 4;
698 unsigned int reg_value;
699 unsigned int pll_en;
700
701 pll_en = clk_readl(pll->base_addr) & BIT(0); /* PLL_CON0[0] */
702
703 reg_value = clk_readl(con1_addr);
704 reg_value &= ~SDM_PLL_N_INFO_MASK;
705 reg_value |= pcw & SDM_PLL_N_INFO_MASK; /* PLL_CON1[20:0] = pcw */
706
707 if (pll_en)
708 reg_value |= SDM_PLL_N_INFO_CHG; /* PLL_CON1[31] = 1 */
709
710 clk_writel(con1_addr, reg_value);
711
712 if (pll_en)
713 udelay(20);
714 }
715
716
717 static unsigned int calc_pll_vco_freq(
718 unsigned int fin,
719 unsigned int pcw,
720 unsigned int vcodivsel,
721 unsigned int prediv,
722 unsigned int pcw_f_bits)
723 {
724 /* vco = (fin * pcw * vcodivsel / prediv) >> pcw_f_bits; */
725 uint64_t vco = fin;
726 vco = vco * pcw * vcodivsel;
727 if (prediv > 1)
728 do_div(vco, prediv);
729 vco >>= pcw_f_bits;
730 return (unsigned int)vco;
731 }
732
733
734 static unsigned int sdm_pll_vco_calc_op(struct pll *pll)
735 {
736 unsigned int con1 = clk_readl(pll->base_addr + 4);
737
738 unsigned int vcodivsel = 1;
739 unsigned int prediv = 1;
740 unsigned int pcw = con1 & BITMASK(20 : 0); /* bit[20:0] */
741
742 return calc_pll_vco_freq(26000, pcw, vcodivsel, prediv, 14); /* 26M = 26000K Hz */
743 }
744
745
746 static int general_pll_calc_freq(unsigned int *pcw, int *postdiv_idx, unsigned int freq, int pcwfbits)
747 {
748 const uint64_t freq_max = 2000 * 1000 * 1000; /* 2000 MHz */
749 const uint64_t freq_min = 1000 * 1000 * 1000; /* 1000 MHz */
750 const uint32_t fin = 26 * 1000 * 1000; /* 26 MHz */
751 static const uint64_t postdiv[] = {1, 2, 4, 8, 16};
752 uint64_t n_info;
753 int idx;
754
755 /* search suitable postdiv */
756 for (idx = 0; idx < ARRAY_SIZE(postdiv) && postdiv[idx] * freq <= freq_min; idx++)
757 ;
758
759 if (idx >= ARRAY_SIZE(postdiv))
760 return -2; /* freq is out of range (too low) */
761 else if (postdiv[idx] * freq > freq_max)
762 return -3; /* freq is out of range (too high) */
763
764 n_info = (postdiv[idx] * freq) << pcwfbits; /* n_info = freq * postdiv / 26MHz * 2^pcwfbits */
765 do_div(n_info, fin);
766
767 *postdiv_idx = idx;
768 *pcw = (unsigned int)n_info;
769
770 return 0;
771 }
772
773
774 static int general_pll_set_freq_op(struct pll *pll, unsigned int freq, int pcwfbits)
775 {
776 int r;
777 unsigned int pcw = 0;
778 int postdiv_idx = 0;
779
780 r = general_pll_calc_freq(&pcw, &postdiv_idx, freq, pcwfbits);
781
782 if (r == 0) {
783 pll->ops->set_postdiv(pll, postdiv_idx);
784 pll->ops->set_pcw(pll, pcw);
785 }
786
787 return r;
788 }
789
790
791 static int sdm_pll_set_freq_op(struct pll *pll, unsigned int freq)
792 {
793 return general_pll_set_freq_op(pll, freq, 14);
794 }
795
796
797 static int sdm_pll_hp_enable_op(struct pll *pll)
798 {
799 int err;
800 unsigned int vco = 0;
801
802 if (!pll->hp_switch || (pll->state == PWR_DOWN))
803 return 0;
804
805 err = freqhopping_config(pll->hp_id, vco, 1);
806
807 return err;
808 }
809
810 static int sdm_pll_hp_disable_op(struct pll *pll)
811 {
812 int err;
813 unsigned int vco = 0;
814
815 if (!pll->hp_switch || (pll->state == PWR_ON))
816 return 0;
817
818 err = freqhopping_config(pll->hp_id, vco, 0);
819
820 return err;
821 }
822
823 static struct pll_ops sdm_pll_ops = {
824 .get_state = pll_get_state_op,
825 .enable = sdm_pll_enable_op,
826 .disable = sdm_pll_disable_op,
827 .fsel = sdm_pll_fsel_op,
828 .dump_regs = sdm_pll_dump_regs_op,
829 .vco_calc = sdm_pll_vco_calc_op,
830 .hp_enable = sdm_pll_hp_enable_op,
831 .hp_disable = sdm_pll_hp_disable_op,
832 #if CLKMGR_8127
833 .get_postdiv = sdm_pll_get_postdiv_op,
834 .set_postdiv = sdm_pll_set_postdiv_op,
835 .get_pcw = sdm_pll_get_pcw_op,
836 .set_pcw = sdm_pll_set_pcw_op,
837 .set_freq = sdm_pll_set_freq_op,
838 #endif /* CLKMGR_8127 */
839 };
840
841
842 #if CLKMGR_8127
843
844
845 static unsigned int aud_pll_get_pcw_op(struct pll *pll)
846 {
847 unsigned int con1_addr = pll->base_addr + 4;
848 unsigned int reg_value = clk_readl(con1_addr); /* PLL_CON1; */
849
850 reg_value &= BITMASK(30 : 0); /* bit[30:0] */
851 return reg_value;
852 }
853
854
855 static void aud_pll_set_pcw_op(struct pll *pll, unsigned int pcw)
856 {
857 unsigned int con1_addr = pll->base_addr + 4;
858 unsigned int con3_addr = pll->base_addr + 0x01B8;
859 unsigned int reg_value;
860 unsigned int pll_en;
861
862 pll_en = clk_readl(pll->base_addr) & BIT(0);
863 reg_value = clk_readl(con1_addr); /* AUDPLL_CON1[30:0] (PLL_SDM_PCW) = pcw */
864 reg_value = (reg_value & ~BITMASK(30 : 0)) | BITS(30 : 0, pcw);
865
866 if (pll_en) /* AUDPLL_CON1[31] (AUDPLL_SDM_PCW_CHG) = 1 "and" */
867 reg_value |= SDM_PLL_N_INFO_CHG; /* AUDPLL_CON3[31] (AUDPLL_TUNER_EN) = 1 */
868
869 clk_writel(con3_addr, reg_value + 1); /* AUDPLL_CON3[30:0] (AUDPLL_TUNER_N_INFO) = (pcw + 1) */
870 clk_writel(con1_addr, reg_value); /* AUDPLL_CON1 */
871
872 if (pll_en)
873 udelay(20);
874 }
875
876
877 static unsigned int aud_pll_vco_calc_op(struct pll *pll)
878 {
879 unsigned int con1 = clk_readl(pll->base_addr + 4);
880
881 unsigned int vcodivsel = 1;
882 unsigned int prediv = 1;
883 unsigned int pcw = con1 & BITMASK(30 : 0); /* bit[30:0] */
884
885 return calc_pll_vco_freq(26000, pcw, vcodivsel, prediv, 24); /* 26M = 26000K Hz */
886 }
887
888
889 static int aud_pll_set_freq_op(struct pll *pll, unsigned int freq)
890 {
891 return general_pll_set_freq_op(pll, freq, 24);
892 }
893
894
895 static struct pll_ops aud_pll_ops = {
896 .get_state = pll_get_state_op,
897 .enable = sdm_pll_enable_op,
898 .disable = sdm_pll_disable_op,
899 .fsel = sdm_pll_fsel_op,
900 .dump_regs = sdm_pll_dump_regs_op,
901 .vco_calc = aud_pll_vco_calc_op,
902 .hp_enable = sdm_pll_hp_enable_op,
903 .hp_disable = sdm_pll_hp_disable_op,
904 .get_postdiv = sdm_pll_get_postdiv_op,
905 .set_postdiv = sdm_pll_set_postdiv_op,
906 .get_pcw = aud_pll_get_pcw_op,
907 .set_pcw = aud_pll_set_pcw_op,
908 .set_freq = aud_pll_set_freq_op,
909 };
910
911
912 #endif /* CLKMGR_8127 */
913
914
915 static void arm_pll_fsel_op(struct pll *pll, unsigned int value)
916 {
917 unsigned int ctrl_value;
918
919 ctrl_value = clk_readl(pll->base_addr + 4);
920 ctrl_value &= ~(SDM_PLL_N_INFO_MASK | ARMPLL_POSDIV_MASK);
921 ctrl_value |= value & (SDM_PLL_N_INFO_MASK | ARMPLL_POSDIV_MASK);
922 ctrl_value |= SDM_PLL_N_INFO_CHG;
923
924 clk_writel(pll->base_addr + 4, ctrl_value);
925 udelay(20);
926 }
927
928
929 #if CLKMGR_8127
930
931
932 static unsigned int arm_pll_get_postdiv_op(struct pll *pll)
933 {
934 unsigned int con1 = clk_readl(pll->base_addr + 4); /* PLL_CON1 */
935 unsigned int posdiv = (con1 & BITMASK(26 : 24)) >> 24; /* bit[26:24] */
936
937 return posdiv;
938 }
939
940
941 static void arm_pll_set_postdiv_op(struct pll *pll, unsigned int postdiv)
942 {
943 unsigned con1_addr = pll->base_addr + 4;
944 unsigned int con1_value = clk_readl(con1_addr); /* PLL_CON1 */
945
946 clk_writel(con1_addr, (con1_value & ~BITMASK(26 : 24)) | BITS(26 : 24, postdiv)); /* bit[26:24] */
947 }
948
949
950 static int arm_pll_set_freq_op(struct pll *pll, unsigned int freq)
951 {
952 const int pcwfbits = 14;
953 int r;
954 unsigned int pcw = 0;
955 int postdiv_idx = 0;
956
957 r = general_pll_calc_freq(&pcw, &postdiv_idx, freq, pcwfbits);
958
959 if (r == 0) {
960 unsigned int reg_val = BITS(26 : 24, postdiv_idx) | BITS(20 : 0, pcw);
961 arm_pll_fsel_op(pll, reg_val);
962 }
963
964 return r;
965 }
966
967
968 #endif /* CLKMGR_8127 */
969
970
971 static struct pll_ops arm_pll_ops = {
972 .get_state = pll_get_state_op,
973 .enable = sdm_pll_enable_op,
974 .disable = sdm_pll_disable_op,
975 .fsel = arm_pll_fsel_op,
976 .dump_regs = sdm_pll_dump_regs_op,
977 .vco_calc = sdm_pll_vco_calc_op,
978 .hp_enable = sdm_pll_hp_enable_op,
979 .hp_disable = sdm_pll_hp_disable_op,
980 #if CLKMGR_8127
981 .get_postdiv = arm_pll_get_postdiv_op,
982 .set_postdiv = arm_pll_set_postdiv_op,
983 .get_pcw = sdm_pll_get_pcw_op,
984 .set_pcw = sdm_pll_set_pcw_op,
985 .set_freq = arm_pll_set_freq_op,
986 #endif /* CLKMGR_8127 */
987 };
988
989
990 #if CLKMGR_8127
991
992
993 static unsigned int pll_freq_calc_op(struct pll *pll)
994 {
995 return pll->ops->vco_calc(pll) / pll_posdiv_map[pll->ops->get_postdiv(pll)];
996 }
997
998
999 unsigned int pll_get_freq(int id)
1000 {
1001 unsigned int r;
1002 unsigned long flags;
1003 struct pll *pll = id_to_pll(id);
1004 BUG_ON(!pll);
1005
1006 clkmgr_lock(flags);
1007 r = pll_freq_calc_op(pll);
1008 clkmgr_unlock(flags);
1009
1010 return r;
1011 }
1012 EXPORT_SYMBOL(pll_get_freq);
1013
1014
1015 unsigned int pll_set_freq(int id, unsigned int freq_khz)
1016 {
1017 unsigned int r;
1018 unsigned long flags;
1019 struct pll *pll = id_to_pll(id);
1020 BUG_ON(!pll);
1021
1022 clkmgr_lock(flags);
1023 r = pll->ops->set_freq(pll, freq_khz * 1000);
1024 clkmgr_unlock(flags);
1025
1026 return r;
1027 }
1028 EXPORT_SYMBOL(pll_set_freq);
1029
1030
1031 #endif /* CLKMGR_8127 */
1032
1033
1034 static int get_pll_state_locked(struct pll *pll)
1035 {
1036 if (likely(initialized))
1037 return pll->state;
1038 else
1039 return pll->ops->get_state(pll);
1040 }
1041
1042 static int pll_enable_locked(struct pll *pll)
1043 {
1044 #ifdef PLL_LOG_TOP
1045 clk_info("[%s]: Start. pll->name=%s, pll->cnt=%d, pll->state=%d\n", __func__, pll->name, pll->cnt, pll->state);
1046 #endif
1047
1048 pll->cnt++;
1049
1050 if (pll->cnt > 1)
1051 return 0;
1052
1053 if (pll->state == PWR_DOWN) {
1054 pll->ops->enable(pll);
1055 pll->state = PWR_ON;
1056 }
1057
1058 if (pll->ops->hp_enable)
1059 pll->ops->hp_enable(pll);
1060
1061 #ifdef PLL_LOG_TOP
1062 clk_info("[%s]: End. pll->name=%s, pll->cnt=%d, pll->state=%d\n", __func__, pll->name, pll->cnt, pll->state);
1063 #endif
1064 return 0;
1065 }
1066
1067 static int pll_disable_locked(struct pll *pll)
1068 {
1069 #ifdef PLL_LOG_TOP
1070 clk_info("[%s]: Start. pll->name=%s, pll->cnt=%d, pll->state=%d\n", __func__, pll->name, pll->cnt, pll->state);
1071 #endif
1072
1073 #if DISABLE_BUG_ON_CNT
1074 WARN_ON(!pll->cnt);
1075 if (!pll->cnt)
1076 return 0;
1077 #else /* !DISABLE_BUG_ON_CNT */
1078 BUG_ON(!pll->cnt);
1079 #endif /* DISABLE_BUG_ON_CNT */
1080
1081 pll->cnt--;
1082
1083 if (pll->cnt > 0)
1084 return 0;
1085
1086 if (pll->state == PWR_ON) {
1087 pll->ops->disable(pll);
1088 pll->state = PWR_DOWN;
1089 }
1090
1091 if (pll->ops->hp_disable)
1092 pll->ops->hp_disable(pll);
1093
1094 #ifdef PLL_LOG_TOP
1095 clk_info("[%s]: End. pll->name=%s, pll->cnt=%d, pll->state=%d\n", __func__, pll->name, pll->cnt, pll->state);
1096 #endif
1097 return 0;
1098 }
1099
1100
1101 static int pll_fsel_locked(struct pll *pll, unsigned int value)
1102 {
1103 pll->ops->fsel(pll, value);
1104 if (pll->ops->hp_enable)
1105 pll->ops->hp_enable(pll);
1106
1107 return 0;
1108 }
1109
1110 int pll_is_on(int id)
1111 {
1112 int state;
1113 unsigned long flags;
1114 struct pll *pll = id_to_pll(id);
1115
1116 #if defined(CONFIG_CLKMGR_BRINGUP)
1117 return 1;
1118 #endif
1119
1120 BUG_ON(!pll);
1121
1122 clkmgr_lock(flags);
1123 state = get_pll_state_locked(pll);
1124 clkmgr_unlock(flags);
1125
1126 return state;
1127 }
1128 EXPORT_SYMBOL(pll_is_on);
1129
1130 int enable_pll(int id, char *name)
1131 {
1132 int err;
1133 unsigned long flags;
1134 struct pll *pll = id_to_pll(id);
1135
1136 #if defined(CONFIG_CLKMGR_BRINGUP)
1137 return 0;
1138 #endif
1139
1140 BUG_ON(!initialized);
1141 BUG_ON(!pll);
1142 BUG_ON(!name);
1143 #ifdef PLL_LOG_TOP
1144 clk_info("[%s]: id=%d, name=%s\n", __func__, id, name);
1145 #endif
1146 clkmgr_lock(flags);
1147 err = pll_enable_internal(pll, name);
1148 clkmgr_unlock(flags);
1149
1150 return err;
1151 }
1152 EXPORT_SYMBOL(enable_pll);
1153
1154 int disable_pll(int id, char *name)
1155 {
1156 int err;
1157 unsigned long flags;
1158 struct pll *pll = id_to_pll(id);
1159
1160 #if defined(CONFIG_CLKMGR_BRINGUP)
1161 return 0;
1162 #endif
1163
1164 BUG_ON(!initialized);
1165 BUG_ON(!pll);
1166 BUG_ON(!name);
1167 #ifdef PLL_LOG_TOP
1168 clk_info("[%s]: id=%d, name=%s\n", __func__, id, name);
1169 #endif
1170 clkmgr_lock(flags);
1171 err = pll_disable_internal(pll, name);
1172 clkmgr_unlock(flags);
1173
1174 return err;
1175 }
1176 EXPORT_SYMBOL(disable_pll);
1177
1178
1179 #if !CLKMGR_8127
1180
1181
1182 int enable_pll_spec(int id, char *name)
1183 {
1184 int err;
1185 unsigned long flags;
1186 struct pll *pll = id_to_pll(id);
1187
1188 #if defined(CONFIG_CLKMGR_BRINGUP)
1189 return 0;
1190 #endif
1191
1192 BUG_ON(!initialized);
1193 BUG_ON(!pll);
1194 BUG_ON(!name);
1195 #ifdef PLL_LOG_TOP
1196 clk_info("[%s]: id=%d, name=%s\n", __func__, id, name);
1197 #endif
1198 clkmgr_lock(flags);
1199 err = pll_enable_internal(pll, name);
1200 clkmgr_unlock(flags);
1201
1202 return err;
1203 }
1204 EXPORT_SYMBOL(enable_pll_spec);
1205
1206 int disable_pll_spec(int id, char *name)
1207 {
1208 int err;
1209 unsigned long flags;
1210 struct pll *pll = id_to_pll(id);
1211
1212 #if defined(CONFIG_CLKMGR_BRINGUP)
1213 return 0;
1214 #endif
1215
1216 BUG_ON(!initialized);
1217 BUG_ON(!pll);
1218 BUG_ON(!name);
1219 #ifdef PLL_LOG_TOP
1220 clk_info("[%s]: id=%d, name=%s\n", __func__, id, name);
1221 #endif
1222 clkmgr_lock(flags);
1223 err = pll_disable_internal(pll, name);
1224 clkmgr_unlock(flags);
1225
1226 return err;
1227 }
1228 EXPORT_SYMBOL(disable_pll_spec);
1229
1230
1231 #endif /* !CLKMGR_8127 */
1232
1233
1234 int pll_fsel(int id, unsigned int value)
1235 {
1236 int err;
1237 unsigned long flags;
1238 struct pll *pll = id_to_pll(id);
1239
1240 #if defined(CONFIG_CLKMGR_BRINGUP)
1241 return 0;
1242 #endif
1243
1244 BUG_ON(!initialized);
1245 BUG_ON(!pll);
1246
1247 clkmgr_lock(flags);
1248 err = pll_fsel_locked(pll, value);
1249 clkmgr_unlock(flags);
1250
1251 return err;
1252 }
1253 EXPORT_SYMBOL(pll_fsel);
1254
1255
1256 int pll_hp_switch_on(int id, int hp_on)
1257 {
1258 int err = 0;
1259 unsigned long flags;
1260 int old_value;
1261 struct pll *pll = id_to_pll(id);
1262
1263 #if defined(CONFIG_CLKMGR_BRINGUP)
1264 return 0;
1265 #endif
1266
1267 BUG_ON(!initialized);
1268 BUG_ON(!pll);
1269
1270 if (pll->type != PLL_TYPE_SDM) {
1271 err = -EINVAL;
1272 goto out;
1273 }
1274
1275 clkmgr_lock(flags);
1276 old_value = pll->hp_switch;
1277 if (old_value == 0) {
1278 pll->hp_switch = 1;
1279 if (hp_on)
1280 err = pll->ops->hp_enable(pll);
1281 }
1282 clkmgr_unlock(flags);
1283
1284 out:
1285 return err;
1286 }
1287 EXPORT_SYMBOL(pll_hp_switch_on);
1288
1289 int pll_hp_switch_off(int id, int hp_off)
1290 {
1291 int err = 0;
1292 unsigned long flags;
1293 int old_value;
1294 struct pll *pll = id_to_pll(id);
1295
1296 #if defined(CONFIG_CLKMGR_BRINGUP)
1297 return 0;
1298 #endif
1299
1300 BUG_ON(!initialized);
1301 BUG_ON(!pll);
1302
1303 if (pll->type != PLL_TYPE_SDM) {
1304 err = -EINVAL;
1305 goto out;
1306 }
1307
1308 clkmgr_lock(flags);
1309 old_value = pll->hp_switch;
1310 if (old_value == 1) {
1311 if (hp_off)
1312 err = pll->ops->hp_disable(pll);
1313 pll->hp_switch = 0;
1314 }
1315 clkmgr_unlock(flags);
1316
1317 out:
1318 return err;
1319 }
1320 EXPORT_SYMBOL(pll_hp_switch_off);
1321
1322
1323 int pll_dump_regs(int id, unsigned int *ptr)
1324 {
1325 struct pll *pll = id_to_pll(id);
1326
1327 BUG_ON(!initialized);
1328 BUG_ON(!pll);
1329
1330 return pll->ops->dump_regs(pll, ptr);
1331 }
1332 EXPORT_SYMBOL(pll_dump_regs);
1333
1334 const char *pll_get_name(int id)
1335 {
1336 struct pll *pll = id_to_pll(id);
1337
1338 BUG_ON(!initialized);
1339 BUG_ON(!pll);
1340
1341 return pll->name;
1342 }
1343
1344
1345 #if !CLKMGR_8127
1346
1347
1348 void enable_clksq1(void)
1349 {
1350 unsigned long flags;
1351
1352 return;
1353
1354 clkmgr_lock(flags);
1355 clk_setl(AP_PLL_CON0, 0x1 << 0);
1356 udelay(200);
1357 clk_setl(AP_PLL_CON0, 0x1 << 1);
1358 clkmgr_unlock(flags);
1359 }
1360 EXPORT_SYMBOL(enable_clksq1);
1361
1362 void disable_clksq1(void)
1363 {
1364 unsigned long flags;
1365
1366 return;
1367
1368 clkmgr_lock(flags);
1369 clk_clrl(AP_PLL_CON0, 0x3 << 0);
1370 clkmgr_unlock(flags);
1371 }
1372 EXPORT_SYMBOL(disable_clksq1);
1373
1374 void clksq1_sw2hw(void)
1375 {
1376 unsigned long flags;
1377
1378 return;
1379
1380 clkmgr_lock(flags);
1381 clk_clrl(AP_PLL_CON1, 0x3 << 0);
1382 clkmgr_unlock(flags);
1383 }
1384 EXPORT_SYMBOL(clksq1_sw2hw);
1385
1386 void clksq1_hw2sw(void)
1387 {
1388 unsigned long flags;
1389
1390 return;
1391
1392 clkmgr_lock(flags);
1393 clk_setl(AP_PLL_CON1, 0x3 << 0);
1394 clkmgr_unlock(flags);
1395 }
1396 EXPORT_SYMBOL(clksq1_hw2sw);
1397
1398
1399 #endif /* !CLKMGR_8127 */
1400
1401
1402
1403 /************************************************
1404 ********** subsys part **********
1405 ************************************************/
1406
1407 #define SYS_TYPE_MODEM 0
1408 #define SYS_TYPE_MEDIA 1
1409 #define SYS_TYPE_OTHER 2
1410 #define SYS_TYPE_CONN 3
1411
1412 static struct subsys_ops conn_sys_ops;
1413 static struct subsys_ops dpy_sys_ops;
1414 static struct subsys_ops dis_sys_ops;
1415 static struct subsys_ops mfg_sys_ops;
1416 static struct subsys_ops isp_sys_ops;
1417 static struct subsys_ops ifr_sys_ops;
1418 static struct subsys_ops vde_sys_ops;
1419
1420 static struct subsys syss[NR_SYSS] = {
1421 [SYS_CONN] = {
1422 .name = __stringify(SYS_CONN),
1423 .type = SYS_TYPE_CONN,
1424 .default_sta = PWR_DOWN,
1425 .sta_mask = 1U << 1,
1426 .ctl_addr = SPM_CONN_PWR_CON,
1427 .ops = &conn_sys_ops,
1428 },
1429 [SYS_DPY] = {
1430 .name = __stringify(SYS_DPY),
1431 .type = SYS_TYPE_OTHER,
1432 .default_sta = PWR_ON,
1433 .sta_mask = 1U << 2,
1434 .ctl_addr = SPM_DPY_PWR_CON,
1435 .ops = &dpy_sys_ops,
1436 },
1437 [SYS_DIS] = {
1438 .name = __stringify(SYS_DIS),
1439 .type = SYS_TYPE_MEDIA,
1440 .default_sta = PWR_ON,
1441 .sta_mask = 1U << 3,
1442 .ctl_addr = SPM_DIS_PWR_CON,
1443 .ops = &dis_sys_ops,
1444 .start = &grps[CG_DISP0],
1445 .nr_grps = 2,
1446 .mux = &muxs[MT_MUX_MM],
1447 },
1448 [SYS_MFG] = {
1449 .name = __stringify(SYS_MFG),
1450 .type = SYS_TYPE_MEDIA,
1451 .default_sta = PWR_ON,
1452 .sta_mask = 1U << 4,
1453 .ctl_addr = SPM_MFG_PWR_CON,
1454 .ops = &mfg_sys_ops,
1455 .start = &grps[CG_MFG],
1456 .nr_grps = 1,
1457 .mux = &muxs[MT_MUX_MFG],
1458 },
1459 [SYS_ISP] = {
1460 .name = __stringify(SYS_ISP),
1461 .type = SYS_TYPE_MEDIA,
1462 .default_sta = PWR_ON,
1463 .sta_mask = 1U << 5,
1464 .ctl_addr = SPM_ISP_PWR_CON,
1465 .ops = &isp_sys_ops,
1466 .start = &grps[CG_IMAGE],
1467 .nr_grps = 1,
1468 },
1469 [SYS_IFR] = {
1470 .name = __stringify(SYS_IFR),
1471 .type = SYS_TYPE_OTHER,
1472 .default_sta = PWR_ON,
1473 .sta_mask = 1U << 6,
1474 .ctl_addr = SPM_IFR_PWR_CON,
1475 .ops = &ifr_sys_ops,
1476 },
1477 [SYS_VDE] = {
1478 .name = __stringify(SYS_VDE),
1479 .type = SYS_TYPE_MEDIA,
1480 .default_sta = PWR_ON,
1481 .sta_mask = 1U << 7,
1482 .ctl_addr = SPM_VDE_PWR_CON,
1483 .ops = &vde_sys_ops,
1484 .start = &grps[CG_VDEC0],
1485 .nr_grps = 2,
1486 .mux = &muxs[MT_MUX_VDEC],
1487 }
1488 };
1489
1490
1491 static void larb_backup(int larb_idx);
1492 static void larb_restore(int larb_idx);
1493
1494
1495 static struct subsys *id_to_sys(unsigned int id)
1496 {
1497 return id < NR_SYSS ? syss + id : NULL;
1498 }
1499
1500 static int conn_sys_enable_op(struct subsys *sys)
1501 {
1502 int err;
1503 err = spm_mtcmos_ctrl_connsys(STA_POWER_ON);
1504 return err;
1505 }
1506
1507 static int conn_sys_disable_op(struct subsys *sys)
1508 {
1509 int err;
1510 err = spm_mtcmos_ctrl_connsys(STA_POWER_DOWN);
1511 return err;
1512 }
1513
1514 static int dpy_sys_enable_op(struct subsys *sys)
1515 {
1516 int err;
1517 err = spm_mtcmos_ctrl_ddrphy(STA_POWER_ON);
1518 return err;
1519 }
1520
1521 static int dpy_sys_disable_op(struct subsys *sys)
1522 {
1523 int err;
1524 err = spm_mtcmos_ctrl_ddrphy(STA_POWER_DOWN);
1525 return err;
1526 }
1527
1528 static int dis_sys_enable_op(struct subsys *sys)
1529 {
1530 int err;
1531 #ifdef SYS_LOG
1532 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1533 #endif
1534
1535 err = spm_mtcmos_ctrl_disp(STA_POWER_ON);
1536 larb_restore(MT_LARB_DISP);
1537 return err;
1538 }
1539
1540 static int dis_sys_disable_op(struct subsys *sys)
1541 {
1542 int err;
1543 #ifdef SYS_LOG
1544 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1545 #endif
1546
1547 larb_backup(MT_LARB_DISP);
1548 err = spm_mtcmos_ctrl_disp(STA_POWER_DOWN);
1549 return err;
1550 }
1551
1552 static int mfg_sys_enable_op(struct subsys *sys)
1553 {
1554 int err;
1555 #ifdef SYS_LOG
1556 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1557 #endif
1558
1559 err = spm_mtcmos_ctrl_mfg(STA_POWER_ON);
1560
1561 return err;
1562 }
1563
1564 static int mfg_sys_disable_op(struct subsys *sys)
1565 {
1566 int err;
1567 #ifdef SYS_LOG
1568 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1569 #endif
1570
1571 err = spm_mtcmos_ctrl_mfg(STA_POWER_DOWN);
1572
1573 return err;
1574 }
1575
1576 static int isp_sys_enable_op(struct subsys *sys)
1577 {
1578 int err;
1579 #ifdef SYS_LOG
1580 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1581 #endif
1582 err = spm_mtcmos_ctrl_isp(STA_POWER_ON);
1583 larb_restore(MT_LARB_IMG);
1584 return err;
1585 }
1586
1587 static int isp_sys_disable_op(struct subsys *sys)
1588 {
1589 int err;
1590 #ifdef SYS_LOG
1591 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1592 #endif
1593 larb_backup(MT_LARB_IMG);
1594 err = spm_mtcmos_ctrl_isp(STA_POWER_DOWN);
1595 return err;
1596 }
1597
1598 static int ifr_sys_enable_op(struct subsys *sys)
1599 {
1600 int err;
1601 #ifdef SYS_LOG
1602 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1603 #endif
1604 err = spm_mtcmos_ctrl_infra(STA_POWER_ON);
1605 return err;
1606 }
1607
1608 static int ifr_sys_disable_op(struct subsys *sys)
1609 {
1610 int err;
1611 #ifdef SYS_LOG
1612 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1613 #endif
1614 err = spm_mtcmos_ctrl_infra(STA_POWER_DOWN);
1615 return err;
1616 }
1617
1618 static int vde_sys_enable_op(struct subsys *sys)
1619 {
1620 int err;
1621 #ifdef SYS_LOG
1622 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1623 #endif
1624 err = spm_mtcmos_ctrl_vdec(STA_POWER_ON);
1625 larb_restore(MT_LARB_VDEC);
1626 return err;
1627 }
1628
1629 static int vde_sys_disable_op(struct subsys *sys)
1630 {
1631 int err;
1632 #ifdef SYS_LOG
1633 clk_info("[%s]: sys->name=%s\n", __func__, sys->name);
1634 #endif
1635 larb_backup(MT_LARB_VDEC);
1636 err = spm_mtcmos_ctrl_vdec(STA_POWER_DOWN);
1637 return err;
1638 }
1639
1640 static int sys_get_state_op(struct subsys *sys)
1641 {
1642 unsigned int sta = clk_readl(SPM_PWR_STATUS);
1643 unsigned int sta_s = clk_readl(SPM_PWR_STATUS_S);
1644
1645 return (sta & sys->sta_mask) && (sta_s & sys->sta_mask);
1646 }
1647
1648 static int sys_dump_regs_op(struct subsys *sys, unsigned int *ptr)
1649 {
1650 *(ptr) = clk_readl(sys->ctl_addr);
1651 return 1;
1652 }
1653
1654 static struct subsys_ops conn_sys_ops = {
1655 .enable = conn_sys_enable_op,
1656 .disable = conn_sys_disable_op,
1657 .get_state = sys_get_state_op,
1658 .dump_regs = sys_dump_regs_op,
1659 };
1660
1661 static struct subsys_ops dpy_sys_ops = {
1662 .enable = dpy_sys_enable_op,
1663 .disable = dpy_sys_disable_op,
1664 .get_state = sys_get_state_op,
1665 .dump_regs = sys_dump_regs_op,
1666 };
1667
1668 static struct subsys_ops dis_sys_ops = {
1669 .enable = dis_sys_enable_op,
1670 .disable = dis_sys_disable_op,
1671 .get_state = sys_get_state_op,
1672 .dump_regs = sys_dump_regs_op,
1673 };
1674
1675 static struct subsys_ops mfg_sys_ops = {
1676 .enable = mfg_sys_enable_op,
1677 .disable = mfg_sys_disable_op,
1678 .get_state = sys_get_state_op,
1679 .dump_regs = sys_dump_regs_op,
1680 };
1681
1682 static struct subsys_ops isp_sys_ops = {
1683 .enable = isp_sys_enable_op,
1684 .disable = isp_sys_disable_op,
1685 .get_state = sys_get_state_op,
1686 .dump_regs = sys_dump_regs_op,
1687 };
1688
1689 static struct subsys_ops ifr_sys_ops = {
1690 .enable = ifr_sys_enable_op,
1691 .disable = ifr_sys_disable_op,
1692 .get_state = sys_get_state_op,
1693 .dump_regs = sys_dump_regs_op,
1694 };
1695
1696 static struct subsys_ops vde_sys_ops = {
1697 .enable = vde_sys_enable_op,
1698 .disable = vde_sys_disable_op,
1699 .get_state = sys_get_state_op,
1700 .dump_regs = sys_dump_regs_op,
1701 };
1702
1703
1704
1705
1706 static int get_sys_state_locked(struct subsys *sys)
1707 {
1708 if (likely(initialized))
1709 return sys->state;
1710 else
1711 return sys->ops->get_state(sys);
1712 }
1713
1714 int subsys_is_on(int id)
1715 {
1716 int state;
1717 unsigned long flags;
1718 struct subsys *sys = id_to_sys(id);
1719
1720 #if defined(CONFIG_CLKMGR_BRINGUP)
1721 return 1;
1722 #endif
1723
1724 BUG_ON(!sys);
1725
1726 clkmgr_lock(flags);
1727 state = get_sys_state_locked(sys);
1728 clkmgr_unlock(flags);
1729
1730 return state;
1731 }
1732 EXPORT_SYMBOL(subsys_is_on);
1733
1734 /* #define STATE_CHECK_DEBUG */
1735
1736 static int sys_enable_locked(struct subsys *sys)
1737 {
1738 int err;
1739 int local_state = sys->state; /* get_subsys_local_state(sys); */
1740
1741 #ifdef STATE_CHECK_DEBUG
1742 int reg_state = sys->ops->get_state(sys); /* get_subsys_reg_state(sys); */
1743 BUG_ON(local_state != reg_state);
1744 #endif
1745
1746 #ifdef SYS_LOG
1747 clk_info("[%s]: Start. sys->name=%s, sys->state=%d\n", __func__, sys->name, sys->state);
1748 #endif
1749
1750 if (local_state == PWR_ON)
1751 return 0;
1752
1753 if (sys->mux)
1754 mux_enable_internal(sys->mux, "sys");
1755
1756 err = sys->ops->enable(sys);
1757 WARN_ON(err);
1758
1759 if (!err)
1760 sys->state = PWR_ON;
1761
1762 #ifdef SYS_LOG
1763 clk_info("[%s]: End. sys->name=%s, sys->state=%d\n", __func__, sys->name, sys->state);
1764 #endif
1765 return err;
1766 }
1767
1768 static int sys_disable_locked(struct subsys *sys, int force_off)
1769 {
1770 int err;
1771 int local_state = sys->state; /* get_subsys_local_state(sys); */
1772 int i;
1773 struct cg_grp *grp;
1774
1775 #ifdef STATE_CHECK_DEBUG
1776 int reg_state = sys->ops->get_state(sys); /* get_subsys_reg_state(sys); */
1777 BUG_ON(local_state != reg_state);
1778 #endif
1779
1780 #ifdef SYS_LOG
1781 clk_info("[%s]: Start. sys->name=%s, sys->state=%d, force_off=%d\n",
1782 __func__, sys->name, sys->state, force_off);
1783 #endif
1784 if (!force_off) {
1785 /* could be power off or not */
1786 for (i = 0; i < sys->nr_grps; i++) {
1787 grp = sys->start + i;
1788 if (grp->state)
1789 return 0;
1790 }
1791 }
1792
1793 if (local_state == PWR_DOWN)
1794 return 0;
1795
1796 err = sys->ops->disable(sys);
1797 WARN_ON(err);
1798
1799 if (!err)
1800 sys->state = PWR_DOWN;
1801
1802 if (sys->mux)
1803 mux_disable_internal(sys->mux, "sys");
1804
1805 #ifdef SYS_LOG
1806 clk_info("[%s]: End. sys->name=%s, sys->state=%d, force_off=%d\n",
1807 __func__, sys->name, sys->state, force_off);
1808 #endif
1809 return err;
1810 }
1811
1812 int enable_subsys(int id, char *name)
1813 {
1814 int err;
1815 unsigned long flags;
1816 struct subsys *sys = id_to_sys(id);
1817
1818 #if defined(CONFIG_CLKMGR_BRINGUP)
1819 return 0;
1820 #endif
1821
1822 BUG_ON(!initialized);
1823 BUG_ON(!sys);
1824
1825 clkmgr_lock(flags);
1826 err = subsys_enable_internal(sys, name);
1827 clkmgr_unlock(flags);
1828
1829 return err;
1830 }
1831 EXPORT_SYMBOL(enable_subsys);
1832
1833 int disable_subsys(int id, char *name)
1834 {
1835 int err;
1836 unsigned long flags;
1837 struct subsys *sys = id_to_sys(id);
1838
1839 #if defined(CONFIG_CLKMGR_BRINGUP)
1840 return 0;
1841 #endif
1842
1843 BUG_ON(!initialized);
1844 BUG_ON(!sys);
1845
1846 clkmgr_lock(flags);
1847 err = subsys_disable_internal(sys, 0, name);
1848 clkmgr_unlock(flags);
1849
1850 return err;
1851 }
1852 EXPORT_SYMBOL(disable_subsys);
1853
1854 int disable_subsys_force(int id, char *name)
1855 {
1856 int err;
1857 unsigned long flags;
1858 struct subsys *sys = id_to_sys(id);
1859
1860 BUG_ON(!initialized);
1861 BUG_ON(!sys);
1862
1863 clkmgr_lock(flags);
1864 err = subsys_disable_internal(sys, 1, name);
1865 clkmgr_unlock(flags);
1866
1867 return err;
1868 }
1869
1870 int subsys_dump_regs(int id, unsigned int *ptr)
1871 {
1872 struct subsys *sys = id_to_sys(id);
1873
1874 #if defined(CONFIG_CLKMGR_BRINGUP)
1875 return 0;
1876 #endif
1877
1878 BUG_ON(!initialized);
1879 BUG_ON(!sys);
1880
1881 return sys->ops->dump_regs(sys, ptr);
1882 }
1883 EXPORT_SYMBOL(subsys_dump_regs);
1884
1885 const char *subsys_get_name(int id)
1886 {
1887 struct subsys *sys = id_to_sys(id);
1888
1889 BUG_ON(!initialized);
1890 BUG_ON(!sys);
1891
1892 return sys->name;
1893 }
1894
1895 #define JIFFIES_PER_LOOP 10
1896
1897
1898 #if !CLKMGR_8127
1899
1900
1901 int md_power_on(int id)
1902 {
1903 return 0;
1904 }
1905 EXPORT_SYMBOL(md_power_on);
1906
1907 int md_power_off(int id, unsigned int timeout)
1908 {
1909 return 0;
1910 }
1911 EXPORT_SYMBOL(md_power_off);
1912
1913
1914 #endif /* !CLKMGR_8127 */
1915
1916
1917 int conn_power_on(void)
1918 {
1919 int err;
1920 unsigned long flags;
1921 struct subsys *sys = id_to_sys(SYS_CONN);
1922
1923 BUG_ON(!initialized);
1924 BUG_ON(!sys);
1925 BUG_ON(sys->type != SYS_TYPE_CONN);
1926
1927 clkmgr_lock(flags);
1928 err = subsys_enable_internal(sys, "conn");
1929 clkmgr_unlock(flags);
1930
1931 WARN_ON(err);
1932
1933 return err;
1934 }
1935 EXPORT_SYMBOL(conn_power_on);
1936
1937 int conn_power_off(void)
1938 {
1939 int err;
1940 unsigned long flags;
1941 struct subsys *sys = id_to_sys(SYS_CONN);
1942
1943 BUG_ON(!initialized);
1944 BUG_ON(!sys);
1945 BUG_ON(sys->type != SYS_TYPE_CONN);
1946
1947 clkmgr_lock(flags);
1948 err = subsys_disable_internal(sys, 0, "conn");
1949 clkmgr_unlock(flags);
1950
1951 WARN_ON(err);
1952
1953 return err;
1954 }
1955 EXPORT_SYMBOL(conn_power_off);
1956
1957
1958 static DEFINE_MUTEX(larb_monitor_lock);
1959 static LIST_HEAD(larb_monitor_handlers);
1960
1961 void register_larb_monitor(struct larb_monitor *handler)
1962 {
1963 struct list_head *pos;
1964
1965 #if defined(CONFIG_CLKMGR_BRINGUP)
1966 return;
1967 #endif
1968
1969 mutex_lock(&larb_monitor_lock);
1970 list_for_each(pos, &larb_monitor_handlers) {
1971 struct larb_monitor *l;
1972 l = list_entry(pos, struct larb_monitor, link);
1973 if (l->level > handler->level)
1974 break;
1975 }
1976 list_add_tail(&handler->link, pos);
1977 mutex_unlock(&larb_monitor_lock);
1978 }
1979 EXPORT_SYMBOL(register_larb_monitor);
1980
1981
1982 void unregister_larb_monitor(struct larb_monitor *handler)
1983 {
1984 #if defined(CONFIG_CLKMGR_BRINGUP)
1985 return;
1986 #endif
1987
1988 mutex_lock(&larb_monitor_lock);
1989 list_del(&handler->link);
1990 mutex_unlock(&larb_monitor_lock);
1991 }
1992 EXPORT_SYMBOL(unregister_larb_monitor);
1993
1994 static void larb_clk_prepare(int larb_idx)
1995 {
1996 switch (larb_idx) {
1997 case MT_LARB_DISP:
1998 /* display */
1999 clk_writel(DISP_CG_CLR0, 0x3);
2000 break;
2001 case MT_LARB_VDEC:
2002 /* vde */
2003 clk_writel(LARB_CKEN_SET, 0x1);
2004 break;
2005 case MT_LARB_IMG:
2006 /* isp */
2007 clk_writel(IMG_CG_CLR, 0x1);
2008 break;
2009 default:
2010 BUG();
2011 }
2012 }
2013
2014 static void larb_clk_finish(int larb_idx)
2015 {
2016 switch (larb_idx) {
2017 case MT_LARB_DISP:
2018 /* display */
2019 clk_writel(DISP_CG_SET0, 0x3);
2020 break;
2021 case MT_LARB_VDEC:
2022 /* vde */
2023 clk_writel(LARB_CKEN_CLR, 0x1);
2024 break;
2025 case MT_LARB_IMG:
2026 /* isp */
2027 clk_writel(IMG_CG_SET, 0x1);
2028 break;
2029 default:
2030 BUG();
2031 }
2032 }
2033
2034 static void larb_backup(int larb_idx)
2035 {
2036 struct larb_monitor *pos;
2037
2038 clk_dbg("[%s]: start to backup larb%d\n", __func__, larb_idx);
2039
2040 larb_clk_prepare(larb_idx);
2041
2042 list_for_each_entry(pos, &larb_monitor_handlers, link) {
2043 if (pos->backup != NULL)
2044 pos->backup(pos, larb_idx);
2045 }
2046
2047 larb_clk_finish(larb_idx);
2048 }
2049
2050 static void larb_restore(int larb_idx)
2051 {
2052 struct larb_monitor *pos;
2053
2054 clk_dbg("[%s]: start to restore larb%d\n", __func__, larb_idx);
2055
2056 larb_clk_prepare(larb_idx);
2057
2058 list_for_each_entry(pos, &larb_monitor_handlers, link) {
2059 if (pos->restore != NULL)
2060 pos->restore(pos, larb_idx);
2061 }
2062
2063 larb_clk_finish(larb_idx);
2064 }
2065
2066
2067
2068 /************************************************
2069 ********** clkmux part **********
2070 ************************************************/
2071
2072 static struct clkmux_ops clkmux_ops;
2073 static struct clkmux_ops dpi0_clkmux_ops;
2074
2075 static struct clkmux muxs[NR_MUXS] = {
2076 [MT_MUX_MM] = {
2077 .name = __stringify(MT_MUX_MM),
2078 .base_addr = CLK_CFG_0,
2079 .sel_mask = 0x07000000,
2080 .pdn_mask = 0x80000000,
2081 .offset = 24,
2082 .nr_inputs = 8,
2083 .ops = &clkmux_ops,
2084 .pll = &plls[VENCPLL],
2085 },
2086 [MT_MUX_DDRPHYCFG] = {
2087 .name = __stringify(MT_MUX_DDRPHYCFG),
2088 .base_addr = CLK_CFG_0,
2089 .sel_mask = 0x00010000,
2090 .pdn_mask = 0x00800000,
2091 .offset = 16,
2092 .nr_inputs = 2,
2093 .ops = &clkmux_ops,
2094 },
2095 [MT_MUX_MEM] = {
2096 .name = __stringify(MT_MUX_MEM),
2097 .base_addr = CLK_CFG_0,
2098 .sel_mask = 0x00000100,
2099 .pdn_mask = 0x00008000,
2100 .offset = 8,
2101 .nr_inputs = 2,
2102 .ops = &clkmux_ops,
2103 },
2104 [MT_MUX_AXI] = {
2105 .name = __stringify(MT_MUX_AXI),
2106 .base_addr = CLK_CFG_0,
2107 .sel_mask = 0x00000007,
2108 .pdn_mask = 0x00000080,
2109 .offset = 0,
2110 .nr_inputs = 8,
2111 .ops = &clkmux_ops,
2112 },
2113 [MT_MUX_CAMTG] = {
2114 .name = __stringify(MT_MUX_CAMTG),
2115 .base_addr = CLK_CFG_1,
2116 .sel_mask = 0x07000000,
2117 .pdn_mask = 0x80000000,
2118 .offset = 24,
2119 .nr_inputs = 7,
2120 .ops = &clkmux_ops,
2121 .pll = &plls[UNIVPLL],
2122 },
2123 [MT_MUX_MFG] = {
2124 .name = __stringify(MT_MUX_MFG),
2125 .base_addr = CLK_CFG_1,
2126 .sel_mask = 0x00070000,
2127 .pdn_mask = 0x00800000,
2128 .offset = 16,
2129 .nr_inputs = 8,
2130 .ops = &clkmux_ops,
2131 .pll = &plls[MMPLL],
2132 },
2133 [MT_MUX_VDEC] = {
2134 .name = __stringify(MT_MUX_VDEC),
2135 .base_addr = CLK_CFG_1,
2136 .sel_mask = 0x00000F00,
2137 .pdn_mask = 0x00008000,
2138 .offset = 8,
2139 .nr_inputs = 9,
2140 .ops = &clkmux_ops,
2141 },
2142 [MT_MUX_PWM] = {
2143 .name = __stringify(MT_MUX_PWM),
2144 .base_addr = CLK_CFG_1,
2145 .sel_mask = 0x00000003,
2146 .pdn_mask = 0x00000080,
2147 .offset = 0,
2148 .nr_inputs = 4,
2149 .ops = &clkmux_ops,
2150 .pll = &plls[UNIVPLL],
2151 },
2152 [MT_MUX_MSDC30_0] = {
2153 .name = __stringify(MT_MUX_MSDC30_0),
2154 .base_addr = CLK_CFG_2,
2155 .sel_mask = 0x07000000,
2156 .pdn_mask = 0x80000000,
2157 .offset = 24,
2158 .nr_inputs = 6,
2159 .ops = &clkmux_ops,
2160 .pll = &plls[MSDCPLL],
2161 },
2162 [MT_MUX_USB20] = {
2163 .name = __stringify(MT_MUX_USB20),
2164 .base_addr = CLK_CFG_2,
2165 .sel_mask = 0x00030000,
2166 .pdn_mask = 0x00800000,
2167 .offset = 16,
2168 .nr_inputs = 3,
2169 .ops = &clkmux_ops,
2170 .pll = &plls[UNIVPLL],
2171 },
2172 [MT_MUX_SPI] = {
2173 .name = __stringify(MT_MUX_SPI),
2174 .base_addr = CLK_CFG_2,
2175 .sel_mask = 0x00000700,
2176 .pdn_mask = 0x00008000,
2177 .offset = 8,
2178 .nr_inputs = 5,
2179 .ops = &clkmux_ops,
2180 },
2181 [MT_MUX_UART] = {
2182 .name = __stringify(MT_MUX_UART),
2183 .base_addr = CLK_CFG_2,
2184 .sel_mask = 0x00000001,
2185 .pdn_mask = 0x00000080,
2186 .offset = 0,
2187 .nr_inputs = 2,
2188 .ops = &clkmux_ops,
2189 },
2190 [MT_MUX_AUDINTBUS] = {
2191 .name = __stringify(MT_MUX_AUDINTBUS),
2192 .base_addr = CLK_CFG_3,
2193 .sel_mask = 0x07000000,
2194 .pdn_mask = 0x80000000,
2195 .offset = 24,
2196 .nr_inputs = 6,
2197 .ops = &clkmux_ops,
2198 .siblings = &muxs[MT_MUX_AUDIO],
2199 },
2200 [MT_MUX_AUDIO] = {
2201 .name = __stringify(MT_MUX_AUDIO),
2202 .base_addr = CLK_CFG_3,
2203 .sel_mask = 0x00010000,
2204 .pdn_mask = 0x00800000,
2205 .offset = 16,
2206 .nr_inputs = 2,
2207 .ops = &clkmux_ops,
2208 },
2209 [MT_MUX_MSDC30_2] = {
2210 .name = __stringify(MT_MUX_MSDC30_2),
2211 .base_addr = CLK_CFG_3,
2212 .sel_mask = 0x00000700,
2213 .pdn_mask = 0x00008000,
2214 .offset = 8,
2215 .nr_inputs = 6,
2216 .ops = &clkmux_ops,
2217 .pll = &plls[MSDCPLL],
2218 },
2219 [MT_MUX_MSDC30_1] = {
2220 .name = __stringify(MT_MUX_MSDC30_1),
2221 .base_addr = CLK_CFG_3,
2222 .sel_mask = 0x00000007,
2223 .pdn_mask = 0x00000080,
2224 .offset = 0,
2225 .nr_inputs = 6,
2226 .ops = &clkmux_ops,
2227 .pll = &plls[MSDCPLL],
2228 },
2229 [MT_MUX_DPI1] = {
2230 .name = __stringify(MT_MUX_DPI1),
2231 .base_addr = CLK_CFG_4,
2232 .sel_mask = 0x03000000,
2233 .pdn_mask = 0x80000000,
2234 .offset = 24,
2235 .nr_inputs = 4,
2236 .ops = &clkmux_ops,
2237 .pll = &plls[TVDPLL],
2238 },
2239 [MT_MUX_DPI0] = {
2240 .name = __stringify(MT_MUX_DPI0),
2241 .base_addr = CLK_CFG_4,
2242 .sel_mask = 0x00070000,
2243 .pdn_mask = 0x00800000,
2244 .offset = 16,
2245 .nr_inputs = 8,
2246 .ops = &dpi0_clkmux_ops,
2247 .pll = &plls[LVDSPLL],
2248 },
2249 [MT_MUX_SCP] = {
2250 .name = __stringify(MT_MUX_SCP),
2251 .base_addr = CLK_CFG_4,
2252 .sel_mask = 0x00000300,
2253 .pdn_mask = 0x00008000,
2254 .offset = 8,
2255 .nr_inputs = 4,
2256 .ops = &clkmux_ops,
2257 },
2258 [MT_MUX_PMICSPI] = {
2259 .name = __stringify(MT_MUX_PMICSPI),
2260 .base_addr = CLK_CFG_4,
2261 .sel_mask = 0x0000000F,
2262 .pdn_mask = 0x00000080,
2263 .offset = 0,
2264 .nr_inputs = 11,
2265 .ops = &clkmux_ops,
2266 },
2267 [MT_MUX_DPILVDS] = {
2268 .name = __stringify(MT_MUX_DPILVDS),
2269 .base_addr = CLK_CFG_5,
2270 .sel_mask = 0x07000000,
2271 .pdn_mask = 0x80000000,
2272 .offset = 24,
2273 .nr_inputs = 8,
2274 .ops = &clkmux_ops,
2275 .pll = &plls[LVDSPLL],
2276 },
2277 [MT_MUX_APLL] = {
2278 .name = __stringify(MT_MUX_APLL),
2279 .base_addr = CLK_CFG_5,
2280 .sel_mask = 0x00070000,
2281 .pdn_mask = 0x00800000,
2282 .offset = 16,
2283 .nr_inputs = 8,
2284 .ops = &clkmux_ops,
2285 .pll = &plls[AUDPLL],
2286 },
2287 [MT_MUX_HDMI] = {
2288 .name = __stringify(MT_MUX_HDMI),
2289 .base_addr = CLK_CFG_5,
2290 .sel_mask = 0x00000300,
2291 .pdn_mask = 0x00008000,
2292 .offset = 8,
2293 .nr_inputs = 4,
2294 .ops = &clkmux_ops,
2295 },
2296 [MT_MUX_TVE] = {
2297 .name = __stringify(MT_MUX_TVE),
2298 .base_addr = CLK_CFG_5,
2299 .sel_mask = 0x00000007,
2300 .pdn_mask = 0x00000080,
2301 .offset = 0,
2302 .nr_inputs = 8,
2303 .ops = &clkmux_ops,
2304 .pll = &plls[TVDPLL],
2305 },
2306 [MT_MUX_ETH_50M] = {
2307 .name = __stringify(MT_MUX_ETH_50M),
2308 .base_addr = CLK_CFG_6,
2309 .sel_mask = 0x00070000,
2310 .pdn_mask = 0x00800000,
2311 .offset = 16,
2312 .nr_inputs = 8,
2313 .ops = &clkmux_ops,
2314 .pll = &plls[LVDSPLL],
2315 },
2316 [MT_MUX_NFI2X] = {
2317 .name = __stringify(MT_MUX_NFI2X),
2318 .base_addr = CLK_CFG_6,
2319 .sel_mask = 0x00000700,
2320 .pdn_mask = 0x00008000,
2321 .offset = 8,
2322 .nr_inputs = 8,
2323 .ops = &clkmux_ops,
2324 },
2325 [MT_MUX_RTC] = {
2326 .name = __stringify(MT_MUX_RTC),
2327 .base_addr = CLK_CFG_6,
2328 .sel_mask = 0x00000003,
2329 .pdn_mask = 0x00000080,
2330 .offset = 0,
2331 .nr_inputs = 4,
2332 .ops = &clkmux_ops,
2333 },
2334 };
2335
2336
2337 static struct clkmux *id_to_mux(unsigned int id)
2338 {
2339 return id < NR_MUXS ? muxs + id : NULL;
2340 }
2341
2342 static void clkmux_sel_op(struct clkmux *mux, unsigned clksrc)
2343 {
2344 unsigned int reg;
2345
2346 #ifdef MUX_LOG
2347 clk_dbg("[%s]: mux->name=%s, clksrc=%d\n", __func__, mux->name, clksrc);
2348 #endif
2349
2350 reg = clk_readl(mux->base_addr);
2351
2352 reg &= ~(mux->sel_mask);
2353 reg |= (clksrc << mux->offset) & mux->sel_mask;
2354
2355 clk_writel(mux->base_addr, reg);
2356 }
2357
2358 static void clkmux_enable_op(struct clkmux *mux)
2359 {
2360 #ifdef MUX_LOG
2361 clk_dbg("[%s]: mux->name=%s\n", __func__, mux->name);
2362 #endif
2363
2364 clk_clrl(mux->base_addr, mux->pdn_mask);
2365 }
2366
2367 static void clkmux_disable_op(struct clkmux *mux)
2368 {
2369 #ifdef MUX_LOG
2370 clk_dbg("[%s]: mux->name=%s\n", __func__, mux->name);
2371 #endif
2372
2373 clk_setl(mux->base_addr, mux->pdn_mask);
2374 }
2375
2376 static struct clkmux_ops clkmux_ops = {
2377 .sel = clkmux_sel_op,
2378 .enable = clkmux_enable_op,
2379 .disable = clkmux_disable_op,
2380 };
2381
2382
2383 static void dpi0_clkmux_sel_op(struct clkmux *mux, unsigned clksrc)
2384 {
2385 unsigned int reg;
2386
2387 #ifdef MUX_LOG
2388 clk_dbg("[%s]: mux->name=%s, clksrc=%d\n", __func__, mux->name, clksrc);
2389 #endif
2390
2391 reg = clk_readl(mux->base_addr);
2392
2393 #if WORKAROUND_DPI0_MUX
2394
2395 {
2396 unsigned int old_setting = (reg & mux->sel_mask) >> mux->offset;
2397 unsigned int lsb_mask = 0x3; /* lowest 2 bits */
2398
2399 if ((old_setting != clksrc) && ((old_setting ^ clksrc) & lsb_mask) == 0) {
2400 /* if lowest 2 bits are the same, then change mux to a temp setting */
2401 unsigned int temp_setting[] = {5, 4, 5, 6};
2402 reg &= ~(mux->sel_mask);
2403 reg |= (temp_setting[clksrc & lsb_mask] << mux->offset) & mux->sel_mask;
2404 clk_writel(mux->base_addr, reg);
2405
2406 reg = clk_readl(mux->base_addr);
2407 }
2408 }
2409
2410 #endif /* WORKAROUND_DPI0_MUX */
2411
2412 reg &= ~(mux->sel_mask);
2413 reg |= (clksrc << mux->offset) & mux->sel_mask;
2414 clk_writel(mux->base_addr, reg);
2415 }
2416
2417
2418 static struct clkmux_ops dpi0_clkmux_ops = {
2419 .sel = dpi0_clkmux_sel_op,
2420 .enable = clkmux_enable_op,
2421 .disable = clkmux_disable_op,
2422 };
2423
2424 static void clkmux_sel_locked(struct clkmux *mux, unsigned int clksrc)
2425 {
2426 mux->ops->sel(mux, clksrc);
2427 }
2428
2429 static void mux_enable_locked(struct clkmux *mux)
2430 {
2431 #ifdef MUX_LOG_TOP
2432 clk_info("[%s]: Start. mux->name=%s, mux->cnt=%d\n", __func__, mux->name, mux->cnt);
2433 #endif
2434
2435 mux->cnt++;
2436
2437 if (mux->cnt > 1)
2438 return;
2439
2440 if (mux->pll)
2441 pll_enable_internal(mux->pll, "mux");
2442
2443 mux->ops->enable(mux);
2444
2445 if (mux->siblings)
2446 mux_enable_internal(mux->siblings, "mux_s");
2447
2448 #ifdef MUX_LOG_TOP
2449 clk_info("[%s]: End. mux->name=%s, mux->cnt=%d\n", __func__, mux->name, mux->cnt);
2450 #endif
2451 }
2452
2453 static void mux_disable_locked(struct clkmux *mux)
2454 {
2455 #ifdef MUX_LOG_TOP
2456 clk_info("[%s]: Start. mux->name=%s, mux->cnt=%d\n", __func__, mux->name, mux->cnt);
2457 #endif
2458
2459 #if DISABLE_BUG_ON_CNT
2460 WARN_ON(!mux->cnt);
2461 if (!mux->cnt)
2462 return 0;
2463 #else /* !DISABLE_BUG_ON_CNT */
2464 BUG_ON(!mux->cnt);
2465 #endif /* DISABLE_BUG_ON_CNT */
2466
2467 mux->cnt--;
2468
2469 if (mux->cnt > 0)
2470 return;
2471
2472 mux->ops->disable(mux);
2473
2474 if (mux->siblings)
2475 mux_disable_internal(mux->siblings, "mux_s");
2476
2477 if (mux->pll)
2478 pll_disable_internal(mux->pll, "mux");
2479
2480 #ifdef MUX_LOG_TOP
2481 clk_info("[%s]: End. mux->name=%s, mux->cnt=%d\n", __func__, mux->name, mux->cnt);
2482 #endif
2483 }
2484
2485 int clkmux_sel(int id, unsigned int clksrc, char *name)
2486 {
2487 unsigned long flags;
2488 struct clkmux *mux = id_to_mux(id);
2489
2490 #if defined(CONFIG_CLKMGR_BRINGUP)
2491 return 0;
2492 #endif
2493
2494 BUG_ON(!initialized);
2495 BUG_ON(!mux);
2496 BUG_ON(clksrc >= mux->nr_inputs);
2497
2498 clkmgr_lock(flags);
2499 clkmux_sel_locked(mux, clksrc);
2500 clkmgr_unlock(flags);
2501
2502 return 0;
2503 }
2504 EXPORT_SYMBOL(clkmux_sel);
2505
2506 void enable_mux(int id, char *name)
2507 {
2508 unsigned long flags;
2509 struct clkmux *mux = id_to_mux(id);
2510
2511 #if defined(CONFIG_CLKMGR_BRINGUP) || defined(CONFIG_MT8127_FPGA)
2512 return 0;
2513 #endif
2514
2515 BUG_ON(!initialized);
2516 BUG_ON(!mux);
2517 BUG_ON(!name);
2518 #ifdef MUX_LOG_TOP
2519 clk_info("[%s]: id=%d, name=%s\n", __func__, id, name);
2520 #endif
2521 clkmgr_lock(flags);
2522 mux_enable_internal(mux, name);
2523 clkmgr_unlock(flags);
2524
2525 return;
2526 }
2527 EXPORT_SYMBOL(enable_mux);
2528
2529 void disable_mux(int id, char *name)
2530 {
2531 unsigned long flags;
2532 struct clkmux *mux = id_to_mux(id);
2533
2534 #if defined(CONFIG_CLKMGR_BRINGUP) || defined(CONFIG_MT8127_FPGA)
2535 return 0;
2536 #endif
2537
2538 BUG_ON(!initialized);
2539 BUG_ON(!mux);
2540 BUG_ON(!name);
2541 #ifdef MUX_LOG_TOP
2542 clk_info("[%s]: id=%d, name=%s\n", __func__, id, name);
2543 #endif
2544 clkmgr_lock(flags);
2545 mux_disable_internal(mux, name);
2546 clkmgr_unlock(flags);
2547
2548 return;
2549 }
2550 EXPORT_SYMBOL(disable_mux);
2551
2552
2553 /************************************************
2554 ********** cg_grp part **********
2555 ************************************************/
2556
2557 static struct cg_grp_ops general_cg_grp_ops;
2558 static struct cg_grp_ops vdec_cg_grp_ops;
2559
2560
2561 static struct cg_grp grps[NR_GRPS] = {
2562 [CG_PERI0] = {
2563 .name = __stringify(CG_PERI0),
2564 .set_addr = PERI_PDN0_SET,
2565 .clr_addr = PERI_PDN0_CLR,
2566 .sta_addr = PERI_PDN0_STA,
2567 .ops = &general_cg_grp_ops,
2568 },
2569 [CG_PERI1] = {
2570 .name = __stringify(CG_PERI1),
2571 .set_addr = PERI_PDN1_SET,
2572 .clr_addr = PERI_PDN1_CLR,
2573 .sta_addr = PERI_PDN1_STA,
2574 .ops = &general_cg_grp_ops,
2575 },
2576 [CG_INFRA] = {
2577 .name = __stringify(CG_INFRA),
2578 .set_addr = INFRA_PDN_SET,
2579 .clr_addr = INFRA_PDN_CLR,
2580 .sta_addr = INFRA_PDN_STA,
2581 .ops = &general_cg_grp_ops,
2582 },
2583 [CG_TOPCK] = {
2584 .name = __stringify(CG_TOPCK),
2585 .set_addr = CLK_CFG_4_SET,
2586 .clr_addr = CLK_CFG_4_CLR,
2587 .sta_addr = CLK_CFG_4,
2588 .ops = &general_cg_grp_ops,
2589 },
2590 [CG_DISP0] = {
2591 .name = __stringify(CG_DISP0),
2592 .set_addr = DISP_CG_SET0,
2593 .clr_addr = DISP_CG_CLR0,
2594 .sta_addr = DISP_CG_CON0,
2595 .ops = &general_cg_grp_ops,
2596 .sys = &syss[SYS_DIS],
2597 },
2598 [CG_DISP1] = {
2599 .name = __stringify(CG_DISP1),
2600 .set_addr = DISP_CG_SET1,
2601 .clr_addr = DISP_CG_CLR1,
2602 .sta_addr = DISP_CG_CON1,
2603 .ops = &general_cg_grp_ops,
2604 .sys = &syss[SYS_DIS],
2605 },
2606 [CG_IMAGE] = {
2607 .name = __stringify(CG_IMAGE),
2608 .set_addr = IMG_CG_SET,
2609 .clr_addr = IMG_CG_CLR,
2610 .sta_addr = IMG_CG_CON,
2611 .ops = &general_cg_grp_ops,
2612 .sys = &syss[SYS_ISP],
2613 },
2614 [CG_MFG] = {
2615 .name = __stringify(CG_MFG),
2616 .set_addr = MFG_CG_SET,
2617 .clr_addr = MFG_CG_CLR,
2618 .sta_addr = MFG_CG_CON,
2619 .ops = &general_cg_grp_ops,
2620 .sys = &syss[SYS_MFG],
2621 },
2622 [CG_AUDIO] = {
2623 .name = __stringify(CG_AUDIO),
2624 .sta_addr = AUDIO_TOP_CON0,
2625 .ops = &general_cg_grp_ops,
2626 },
2627 [CG_VDEC0] = {
2628 .name = __stringify(CG_VDEC0),
2629 .set_addr = VDEC_CKEN_CLR, /* revert CLR and SET here to reuse general_cg_grp_ops */
2630 .clr_addr = VDEC_CKEN_SET,
2631 .ops = &vdec_cg_grp_ops,
2632 .sys = &syss[SYS_VDE],
2633 },
2634 [CG_VDEC1] = {
2635 .name = __stringify(CG_VDEC1),
2636 .set_addr = LARB_CKEN_CLR, /* revert CLR and SET here to reuse general_cg_grp_ops */
2637 .clr_addr = LARB_CKEN_SET,
2638 .ops = &vdec_cg_grp_ops,
2639 .sys = &syss[SYS_VDE],
2640 }
2641 };
2642
2643 static struct cg_grp *id_to_grp(unsigned int id)
2644 {
2645 return id < NR_GRPS ? grps + id : NULL;
2646 }
2647
2648 static unsigned int general_grp_get_state_op(struct cg_grp *grp)
2649 {
2650 unsigned int val;
2651 struct subsys *sys = grp->sys;
2652
2653 if (sys && !sys->state)
2654 return 0;
2655
2656 val = clk_readl(grp->sta_addr);
2657 val = (~val) & (grp->mask);
2658 return val;
2659 }
2660
2661 static int general_grp_dump_regs_op(struct cg_grp *grp, unsigned int *ptr)
2662 {
2663 *(ptr) = clk_readl(grp->sta_addr);
2664
2665 return 1;
2666 }
2667
2668 static struct cg_grp_ops general_cg_grp_ops = {
2669 .get_state = general_grp_get_state_op,
2670 .dump_regs = general_grp_dump_regs_op,
2671 };
2672
2673 static unsigned int vdec_grp_get_state_op(struct cg_grp *grp)
2674 {
2675 unsigned int val = clk_readl(grp->set_addr);
2676 val &= grp->mask;
2677 return val;
2678 }
2679
2680 static int vdec_grp_dump_regs_op(struct cg_grp *grp, unsigned int *ptr)
2681 {
2682 *(ptr) = clk_readl(grp->set_addr);
2683 *(++ptr) = clk_readl(grp->clr_addr);
2684
2685 return 2;
2686 }
2687
2688 static struct cg_grp_ops vdec_cg_grp_ops = {
2689 .get_state = vdec_grp_get_state_op,
2690 .dump_regs = vdec_grp_dump_regs_op,
2691 };
2692
2693
2694
2695 /************************************************
2696 ********** cg_clk part **********
2697 ************************************************/
2698
2699 static struct cg_clk_ops general_cg_clk_ops;
2700 static struct cg_clk_ops audio_cg_clk_ops;
2701 static struct cg_clk_ops audsys_cg_clk_ops; /* @audio sys */
2702 static struct cg_clk_ops vdec_cg_clk_ops;
2703
2704
2705 static struct cg_clk clks[NR_CLKS] = {
2706 [MT_CG_PERI_NFI] = {
2707 .name = "MT_CG_PERI_NFI",
2708 .grp = &grps[CG_PERI0],
2709 .mask = BIT(0),
2710 .ops = &general_cg_clk_ops,
2711 .mux = &muxs[MT_MUX_NFI2X],
2712 },
2713 [MT_CG_PERI_THERM] = {
2714 .name = "MT_CG_PERI_THERM",
2715 .grp = &grps[CG_PERI0],
2716 .mask = BIT(1),
2717 .ops = &general_cg_clk_ops,
2718 },
2719 [MT_CG_PERI_PWM1] = {
2720 .name = "MT_CG_PERI_PWM1",
2721 .grp = &grps[CG_PERI0],
2722 .mask = BIT(2),
2723 .ops = &general_cg_clk_ops,
2724 },
2725 [MT_CG_PERI_PWM2] = {
2726 .name = "MT_CG_PERI_PWM2",
2727 .grp = &grps[CG_PERI0],
2728 .mask = BIT(3),
2729 .ops = &general_cg_clk_ops,
2730 },
2731 [MT_CG_PERI_PWM3] = {
2732 .name = "MT_CG_PERI_PWM3",
2733 .grp = &grps[CG_PERI0],
2734 .mask = BIT(4),
2735 .ops = &general_cg_clk_ops,
2736 },
2737 [MT_CG_PERI_PWM4] = {
2738 .name = "MT_CG_PERI_PWM4",
2739 .grp = &grps[CG_PERI0],
2740 .mask = BIT(5),
2741 .ops = &general_cg_clk_ops,
2742 },
2743 [MT_CG_PERI_PWM5] = {
2744 .name = "MT_CG_PERI_PWM5",
2745 .grp = &grps[CG_PERI0],
2746 .mask = BIT(6),
2747 .ops = &general_cg_clk_ops,
2748 },
2749 [MT_CG_PERI_PWM6] = {
2750 .name = "MT_CG_PERI_PWM6",
2751 .grp = &grps[CG_PERI0],
2752 .mask = BIT(7),
2753 .ops = &general_cg_clk_ops,
2754 },
2755 [MT_CG_PERI_PWM7] = {
2756 .name = "MT_CG_PERI_PWM7",
2757 .grp = &grps[CG_PERI0],
2758 .mask = BIT(8),
2759 .ops = &general_cg_clk_ops,
2760 },
2761 [MT_CG_PERI_PWM] = {
2762 .name = "MT_CG_PERI_PWM",
2763 .grp = &grps[CG_PERI0],
2764 .mask = BIT(9),
2765 .ops = &general_cg_clk_ops,
2766 },
2767 [MT_CG_PERI_USB0] = {
2768 .name = "MT_CG_PERI_USB0",
2769 .grp = &grps[CG_PERI0],
2770 .mask = BIT(10),
2771 .ops = &general_cg_clk_ops,
2772 .mux = &muxs[MT_MUX_USB20],
2773 },
2774 [MT_CG_PERI_USB1] = {
2775 .name = "MT_CG_PERI_USB1",
2776 .grp = &grps[CG_PERI0],
2777 .mask = BIT(11),
2778 .ops = &general_cg_clk_ops,
2779 .mux = &muxs[MT_MUX_USB20],
2780 },
2781 [MT_CG_PERI_AP_DMA] = {
2782 .name = "MT_CG_PERI_AP_DMA",
2783 .grp = &grps[CG_PERI0],
2784 .mask = BIT(12),
2785 .ops = &general_cg_clk_ops,
2786 },
2787 [MT_CG_PERI_MSDC30_0] = {
2788 .name = "MT_CG_PERI_MSDC30_0",
2789 .grp = &grps[CG_PERI0],
2790 .mask = BIT(13),
2791 .ops = &general_cg_clk_ops,
2792 .mux = &muxs[MT_MUX_MSDC30_0],
2793 },
2794 [MT_CG_PERI_MSDC30_1] = {
2795 .name = "MT_CG_PERI_MSDC30_1",
2796 .grp = &grps[CG_PERI0],
2797 .mask = BIT(14),
2798 .ops = &general_cg_clk_ops,
2799 .mux = &muxs[MT_MUX_MSDC30_1],
2800 },
2801 [MT_CG_PERI_MSDC30_2] = {
2802 .name = "MT_CG_PERI_MSDC30_2",
2803 .grp = &grps[CG_PERI0],
2804 .mask = BIT(15),
2805 .ops = &general_cg_clk_ops,
2806 .mux = &muxs[MT_MUX_MSDC30_2],
2807 },
2808 [MT_CG_PERI_NLI] = {
2809 .name = "MT_CG_PERI_NLI",
2810 .grp = &grps[CG_PERI0],
2811 .mask = BIT(16),
2812 .ops = &general_cg_clk_ops,
2813 },
2814 [MT_CG_PERI_UART0] = {
2815 .name = "MT_CG_PERI_UART0",
2816 .grp = &grps[CG_PERI0],
2817 .mask = BIT(17),
2818 .ops = &general_cg_clk_ops,
2819 .mux = &muxs[MT_MUX_UART],
2820 },
2821 [MT_CG_PERI_UART1] = {
2822 .name = "MT_CG_PERI_UART1",
2823 .grp = &grps[CG_PERI0],
2824 .mask = BIT(18),
2825 .ops = &general_cg_clk_ops,
2826 .mux = &muxs[MT_MUX_UART],
2827 },
2828 [MT_CG_PERI_UART2] = {
2829 .name = "MT_CG_PERI_UART2",
2830 .grp = &grps[CG_PERI0],
2831 .mask = BIT(19),
2832 .ops = &general_cg_clk_ops,
2833 .mux = &muxs[MT_MUX_UART],
2834 },
2835 [MT_CG_PERI_UART3] = {
2836 .name = "MT_CG_PERI_UART3",
2837 .grp = &grps[CG_PERI0],
2838 .mask = BIT(20),
2839 .ops = &general_cg_clk_ops,
2840 .mux = &muxs[MT_MUX_UART],
2841 },
2842 [MT_CG_PERI_BTIF] = {
2843 .name = "MT_CG_PERI_BTIF",
2844 .grp = &grps[CG_PERI0],
2845 .mask = BIT(21),
2846 .ops = &general_cg_clk_ops,
2847 },
2848 [MT_CG_PERI_I2C0] = {
2849 .name = "MT_CG_PERI_I2C0",
2850 .grp = &grps[CG_PERI0],
2851 .mask = BIT(22),
2852 .ops = &general_cg_clk_ops,
2853 },
2854 [MT_CG_PERI_I2C1] = {
2855 .name = "MT_CG_PERI_I2C1",
2856 .grp = &grps[CG_PERI0],
2857 .mask = BIT(23),
2858 .ops = &general_cg_clk_ops,
2859 },
2860 [MT_CG_PERI_I2C2] = {
2861 .name = "MT_CG_PERI_I2C2",
2862 .grp = &grps[CG_PERI0],
2863 .mask = BIT(24),
2864 .ops = &general_cg_clk_ops,
2865 },
2866 [MT_CG_PERI_I2C3] = {
2867 .name = "MT_CG_PERI_I2C3",
2868 .grp = &grps[CG_PERI0],
2869 .mask = BIT(25),
2870 .ops = &general_cg_clk_ops,
2871 },
2872 [MT_CG_PERI_AUXADC] = {
2873 .name = "MT_CG_PERI_AUXADC",
2874 .grp = &grps[CG_PERI0],
2875 .mask = BIT(26),
2876 .ops = &general_cg_clk_ops,
2877 },
2878 [MT_CG_PERI_SPI0] = {
2879 .name = "MT_CG_PERI_SPI0",
2880 .grp = &grps[CG_PERI0],
2881 .mask = BIT(27),
2882 .ops = &general_cg_clk_ops,
2883 .mux = &muxs[MT_MUX_SPI],
2884 },
2885 [MT_CG_PERI_ETH] = {
2886 .name = "MT_CG_PERI_ETH",
2887 .grp = &grps[CG_PERI0],
2888 .mask = BIT(28),
2889 .ops = &general_cg_clk_ops,
2890 .mux = &muxs[MT_MUX_ETH_50M],
2891 },
2892 [MT_CG_PERI_USB0_MCU] = {
2893 .name = "MT_CG_PERI_USB0_MCU",
2894 .grp = &grps[CG_PERI0],
2895 .mask = BIT(29),
2896 .ops = &general_cg_clk_ops,
2897 },
2898 [MT_CG_PERI_USB1_MCU] = {
2899 .name = "MT_CG_PERI_USB1_MCU",
2900 .grp = &grps[CG_PERI0],
2901 .mask = BIT(30),
2902 .ops = &general_cg_clk_ops,
2903 },
2904 [MT_CG_PERI_USB_SLV] = {
2905 .name = "MT_CG_PERI_USB_SLV",
2906 .grp = &grps[CG_PERI0],
2907 .mask = BIT(31),
2908 .ops = &general_cg_clk_ops,
2909 },
2910 [MT_CG_PERI_GCPU] = {
2911 .name = "MT_CG_PERI_GCPU",
2912 .grp = &grps[CG_PERI1],
2913 .mask = BIT(0),
2914 .ops = &general_cg_clk_ops,
2915 },
2916 [MT_CG_PERI_NFI_ECC] = {
2917 .name = "MT_CG_PERI_NFI_ECC",
2918 .grp = &grps[CG_PERI1],
2919 .mask = BIT(1),
2920 .ops = &general_cg_clk_ops,
2921 .mux = &muxs[MT_MUX_NFI2X],
2922 },
2923 [MT_CG_PERI_NFIPAD] = {
2924 .name = "MT_CG_PERI_NFIPAD",
2925 .grp = &grps[CG_PERI1],
2926 .mask = BIT(2),
2927 .ops = &general_cg_clk_ops,
2928 .mux = &muxs[MT_MUX_NFI2X],
2929 },
2930
2931 [MT_CG_INFRA_DBGCLK] = {
2932 .name = "MT_CG_INFRA_DBGCLK",
2933 .grp = &grps[CG_INFRA],
2934 .mask = BIT(0),
2935 .ops = &general_cg_clk_ops,
2936 },
2937 [MT_CG_INFRA_SMI] = {
2938 .name = "MT_CG_INFRA_SMI",
2939 .grp = &grps[CG_INFRA],
2940 .mask = BIT(1),
2941 .ops = &general_cg_clk_ops,
2942 },
2943 [MT_CG_INFRA_AUDIO] = {
2944 .name = "MT_CG_INFRA_AUDIO",
2945 .grp = &grps[CG_INFRA],
2946 .mask = BIT(5),
2947 .ops = &audio_cg_clk_ops,
2948 .mux = &muxs[MT_MUX_AUDINTBUS],
2949 },
2950 [MT_CG_INFRA_EFUSE] = {
2951 .name = "MT_CG_INFRA_EFUSE",
2952 .grp = &grps[CG_INFRA],
2953 .mask = BIT(6),
2954 .ops = &general_cg_clk_ops,
2955 },
2956 [MT_CG_INFRA_L2C_SRAM] = {
2957 .name = "MT_CG_INFRA_L2C_SRAM",
2958 .grp = &grps[CG_INFRA],
2959 .mask = BIT(7),
2960 .ops = &general_cg_clk_ops,
2961 },
2962 [MT_CG_INFRA_M4U] = {
2963 .name = "MT_CG_INFRA_M4U",
2964 .grp = &grps[CG_INFRA],
2965 .mask = BIT(8),
2966 .ops = &general_cg_clk_ops,
2967 },
2968 [MT_CG_INFRA_CONNMCU] = {
2969 .name = "MT_CG_INFRA_CONNMCU",
2970 .grp = &grps[CG_INFRA],
2971 .mask = BIT(12),
2972 .ops = &general_cg_clk_ops,
2973 },
2974 [MT_CG_INFRA_TRNG] = {
2975 .name = "MT_CG_INFRA_TRNG",
2976 .grp = &grps[CG_INFRA],
2977 .mask = BIT(13),
2978 .ops = &general_cg_clk_ops,
2979 },
2980 [MT_CG_INFRA_CPUM] = {
2981 .name = "MT_CG_INFRA_CPUM",
2982 .grp = &grps[CG_INFRA],
2983 .mask = BIT(15),
2984 .ops = &general_cg_clk_ops,
2985 },
2986 [MT_CG_INFRA_KP] = {
2987 .name = "MT_CG_INFRA_KP",
2988 .grp = &grps[CG_INFRA],
2989 .mask = BIT(16),
2990 .ops = &general_cg_clk_ops,
2991 },
2992 [MT_CG_INFRA_CEC] = {
2993 .name = "MT_CG_INFRA_CEC",
2994 .grp = &grps[CG_INFRA],
2995 .mask = BIT(18),
2996 .ops = &general_cg_clk_ops,
2997 },
2998 [MT_CG_INFRA_IRRX] = {
2999 .name = "MT_CG_INFRA_IRRX",
3000 .grp = &grps[CG_INFRA],
3001 .mask = BIT(19),
3002 .ops = &general_cg_clk_ops,
3003 },
3004 [MT_CG_INFRA_PMICSPI_SHARE] = {
3005 .name = "MT_CG_INFRA_PMICSPI_SHARE",
3006 .grp = &grps[CG_INFRA],
3007 .mask = BIT(22),
3008 .ops = &general_cg_clk_ops,
3009 .mux = &muxs[MT_MUX_PMICSPI],
3010 },
3011 [MT_CG_INFRA_PMICWRAP] = {
3012 .name = "MT_CG_INFRA_PMICWRAP",
3013 .grp = &grps[CG_INFRA],
3014 .mask = BIT(23),
3015 .ops = &general_cg_clk_ops,
3016 },
3017
3018 [MT_CG_TOPCK_PMICSPI] = {
3019 .name = "MT_CG_TOPCK_PMICSPI",
3020 .grp = &grps[CG_TOPCK],
3021 .mask = BIT(5),
3022 .ops = &general_cg_clk_ops,
3023 },
3024
3025 [MT_CG_DISP0_SMI_COMMON] = {
3026 .name = "MT_CG_DISP0_SMI_COMMON",
3027 .grp = &grps[CG_DISP0],
3028 .mask = BIT(0),
3029 .ops = &general_cg_clk_ops,
3030 },
3031 [MT_CG_DISP0_SMI_LARB0] = {
3032 .name = "MT_CG_DISP0_SMI_LARB0",
3033 .grp = &grps[CG_DISP0],
3034 .mask = BIT(1),
3035 .ops = &general_cg_clk_ops,
3036 },
3037 [MT_CG_DISP0_MM_CMDQ] = {
3038 .name = "MT_CG_DISP0_MM_CMDQ",
3039 .grp = &grps[CG_DISP0],
3040 .mask = BIT(2),
3041 .ops = &general_cg_clk_ops,
3042 },
3043 [MT_CG_DISP0_MUTEX] = {
3044 .name = "MT_CG_DISP0_MUTEX",
3045 .grp = &grps[CG_DISP0],
3046 .mask = BIT(3),
3047 .ops = &general_cg_clk_ops,
3048 },
3049 [MT_CG_DISP0_DISP_COLOR] = {
3050 .name = "MT_CG_DISP0_DISP_COLOR",
3051 .grp = &grps[CG_DISP0],
3052 .mask = BIT(4),
3053 .ops = &general_cg_clk_ops,
3054 },
3055 [MT_CG_DISP0_DISP_BLS] = {
3056 .name = "MT_CG_DISP0_DISP_BLS",
3057 .grp = &grps[CG_DISP0],
3058 .mask = BIT(5),
3059 .ops = &general_cg_clk_ops,
3060 .mux = &muxs[MT_MUX_PWM],
3061 },
3062 [MT_CG_DISP0_DISP_WDMA] = {
3063 .name = "MT_CG_DISP0_DISP_WDMA",
3064 .grp = &grps[CG_DISP0],
3065 .mask = BIT(6),
3066 .ops = &general_cg_clk_ops,
3067 },
3068 [MT_CG_DISP0_DISP_RDMA] = {
3069 .name = "MT_CG_DISP0_DISP_RDMA",
3070 .grp = &grps[CG_DISP0],
3071 .mask = BIT(7),
3072 .ops = &general_cg_clk_ops,
3073 },
3074 [MT_CG_DISP0_DISP_OVL] = {
3075 .name = "MT_CG_DISP0_DISP_OVL",
3076 .grp = &grps[CG_DISP0],
3077 .mask = BIT(8),
3078 .ops = &general_cg_clk_ops,
3079 },
3080 [MT_CG_DISP0_MDP_TDSHP] = {
3081 .name = "MT_CG_DISP0_MDP_TDSHP",
3082 .grp = &grps[CG_DISP0],
3083 .mask = BIT(9),
3084 .ops = &general_cg_clk_ops,
3085 },
3086 [MT_CG_DISP0_MDP_WROT] = {
3087 .name = "MT_CG_DISP0_MDP_WROT",
3088 .grp = &grps[CG_DISP0],
3089 .mask = BIT(10),
3090 .ops = &general_cg_clk_ops,
3091 },
3092 [MT_CG_DISP0_MDP_WDMA] = {
3093 .name = "MT_CG_DISP0_MDP_WDMA",
3094 .grp = &grps[CG_DISP0],
3095 .mask = BIT(11),
3096 .ops = &general_cg_clk_ops,
3097 },
3098 [MT_CG_DISP0_MDP_RSZ1] = {
3099 .name = "MT_CG_DISP0_MDP_RSZ1",
3100 .grp = &grps[CG_DISP0],
3101 .mask = BIT(12),
3102 .ops = &general_cg_clk_ops,
3103 },
3104 [MT_CG_DISP0_MDP_RSZ0] = {
3105 .name = "MT_CG_DISP0_MDP_RSZ0",
3106 .grp = &grps[CG_DISP0],
3107 .mask = BIT(13),
3108 .ops = &general_cg_clk_ops,
3109 },
3110 [MT_CG_DISP0_MDP_RDMA] = {
3111 .name = "MT_CG_DISP0_MDP_RDMA",
3112 .grp = &grps[CG_DISP0],
3113 .mask = BIT(14),
3114 .ops = &general_cg_clk_ops,
3115 },
3116 [MT_CG_DISP0_MDP_BLS_26M] = {
3117 .name = "MT_CG_DISP0_MDP_BLS_26M",
3118 .grp = &grps[CG_DISP0],
3119 .mask = BIT(15),
3120 .ops = &general_cg_clk_ops,
3121 .mux = &muxs[MT_MUX_PWM],
3122 },
3123 [MT_CG_DISP0_CAM_MDP] = {
3124 .name = "MT_CG_DISP0_CAM_MDP",
3125 .grp = &grps[CG_DISP0],
3126 .mask = BIT(16),
3127 .ops = &general_cg_clk_ops,
3128 },
3129 [MT_CG_DISP0_FAKE_ENG] = {
3130 .name = "MT_CG_DISP0_FAKE_ENG",
3131 .grp = &grps[CG_DISP0],
3132 .mask = BIT(17),
3133 .ops = &general_cg_clk_ops,
3134 },
3135 [MT_CG_DISP0_MUTEX_32K] = {
3136 .name = "MT_CG_DISP0_MUTEX_32K",
3137 .grp = &grps[CG_DISP0],
3138 .mask = BIT(18),
3139 .ops = &general_cg_clk_ops,
3140 },
3141 [MT_CG_DISP0_DISP_RMDA1] = {
3142 .name = "MT_CG_DISP0_DISP_RMDA1",
3143 .grp = &grps[CG_DISP0],
3144 .mask = BIT(19),
3145 .ops = &general_cg_clk_ops,
3146 },
3147 [MT_CG_DISP0_DISP_UFOE] = {
3148 .name = "MT_CG_DISP0_DISP_UFOE",
3149 .grp = &grps[CG_DISP0],
3150 .mask = BIT(20),
3151 .ops = &general_cg_clk_ops,
3152 },
3153
3154 [MT_CG_DISP1_DSI_ENGINE] = {
3155 .name = "MT_CG_DISP1_DSI_ENGINE",
3156 .grp = &grps[CG_DISP1],
3157 .mask = BIT(0),
3158 .ops = &general_cg_clk_ops,
3159 },
3160 [MT_CG_DISP1_DSI_DIGITAL] = {
3161 .name = "MT_CG_DISP1_DSI_DIGITAL",
3162 .grp = &grps[CG_DISP1],
3163 .mask = BIT(1),
3164 .ops = &general_cg_clk_ops,
3165 },
3166 [MT_CG_DISP1_DPI_DIGITAL_LANE] = {
3167 .name = "MT_CG_DISP1_DPI_DIGITAL_LANE",
3168 .grp = &grps[CG_DISP1],
3169 .mask = BIT(2),
3170 .ops = &general_cg_clk_ops,
3171 },
3172 [MT_CG_DISP1_DPI_ENGINE] = {
3173 .name = "MT_CG_DISP1_DPI_ENGINE",
3174 .grp = &grps[CG_DISP1],
3175 .mask = BIT(3),
3176 .ops = &general_cg_clk_ops,
3177 },
3178 [MT_CG_DISP1_DPI1_DIGITAL_LANE] = {
3179 .name = "MT_CG_DISP1_DPI1_DIGITAL_LANE",
3180 .grp = &grps[CG_DISP1],
3181 .mask = BIT(4),
3182 .ops = &general_cg_clk_ops,
3183 .mux = &muxs[MT_MUX_DPI1],
3184 },
3185 [MT_CG_DISP1_DPI1_ENGINE] = {
3186 .name = "MT_CG_DISP1_DPI1_ENGINE",
3187 .grp = &grps[CG_DISP1],
3188 .mask = BIT(5),
3189 .ops = &general_cg_clk_ops,
3190 },
3191 [MT_CG_DISP1_TVE_OUTPUT_CLOCK] = {
3192 .name = "MT_CG_DISP1_TVE_OUTPUT_CLOCK",
3193 .grp = &grps[CG_DISP1],
3194 .mask = BIT(6),
3195 .ops = &general_cg_clk_ops,
3196 .mux = &muxs[MT_MUX_TVE],
3197 },
3198 [MT_CG_DISP1_TVE_INPUT_CLOCK] = {
3199 .name = "MT_CG_DISP1_TVE_INPUT_CLOCK",
3200 .grp = &grps[CG_DISP1],
3201 .mask = BIT(7),
3202 .ops = &general_cg_clk_ops,
3203 },
3204 [MT_CG_DISP1_HDMI_PIXEL_CLOCK] = {
3205 .name = "MT_CG_DISP1_HDMI_PIXEL_CLOCK",
3206 .grp = &grps[CG_DISP1],
3207 .mask = BIT(8),
3208 .ops = &general_cg_clk_ops,
3209 .mux = &muxs[MT_MUX_DPI1],
3210 },
3211 [MT_CG_DISP1_HDMI_PLL_CLOCK] = {
3212 .name = "MT_CG_DISP1_HDMI_PLL_CLOCK",
3213 .grp = &grps[CG_DISP1],
3214 .mask = BIT(9),
3215 .ops = &general_cg_clk_ops,
3216 .mux = &muxs[MT_MUX_HDMI],
3217 },
3218 [MT_CG_DISP1_HDMI_AUDIO_CLOCK] = {
3219 .name = "MT_CG_DISP1_HDMI_AUDIO_CLOCK",
3220 .grp = &grps[CG_DISP1],
3221 .mask = BIT(10),
3222 .ops = &general_cg_clk_ops,
3223 },
3224 [MT_CG_DISP1_HDMI_SPDIF_CLOCK] = {
3225 .name = "MT_CG_DISP1_HDMI_SPDIF_CLOCK",
3226 .grp = &grps[CG_DISP1],
3227 .mask = BIT(11),
3228 .ops = &general_cg_clk_ops,
3229 .mux = &muxs[MT_MUX_APLL],
3230 },
3231 [MT_CG_DISP1_LVDS_PIXEL_CLOCK] = {
3232 .name = "MT_CG_DISP1_LVDS_PIXEL_CLOCK",
3233 .grp = &grps[CG_DISP1],
3234 .mask = BIT(12),
3235 .ops = &general_cg_clk_ops,
3236 },
3237 [MT_CG_DISP1_LVDS_CTS_CLOCK] = {
3238 .name = "MT_CG_DISP1_LVDS_CTS_CLOCK",
3239 .grp = &grps[CG_DISP1],
3240 .mask = BIT(13),
3241 .ops = &general_cg_clk_ops,
3242 },
3243
3244 [MT_CG_IMAGE_LARB2_SMI] = {
3245 .name = "MT_CG_IMAGE_LARB2_SMI",
3246 .grp = &grps[CG_IMAGE],
3247 .mask = BIT(0),
3248 .ops = &general_cg_clk_ops,
3249 },
3250 [MT_CG_IMAGE_CAM_SMI] = {
3251 .name = "MT_CG_IMAGE_CAM_SMI",
3252 .grp = &grps[CG_IMAGE],
3253 .mask = BIT(5),
3254 .ops = &general_cg_clk_ops,
3255 },
3256 [MT_CG_IMAGE_CAM_CAM] = {
3257 .name = "MT_CG_IMAGE_CAM_CAM",
3258 .grp = &grps[CG_IMAGE],
3259 .mask = BIT(6),
3260 .ops = &general_cg_clk_ops,
3261 },
3262 [MT_CG_IMAGE_SEN_TG] = {
3263 .name = "MT_CG_IMAGE_SEN_TG",
3264 .grp = &grps[CG_IMAGE],
3265 .mask = BIT(7),
3266 .ops = &general_cg_clk_ops,
3267 .mux = &muxs[MT_MUX_CAMTG],
3268 },
3269 [MT_CG_IMAGE_SEN_CAM] = {
3270 .name = "MT_CG_IMAGE_SEN_CAM",
3271 .grp = &grps[CG_IMAGE],
3272 .mask = BIT(8),
3273 .ops = &general_cg_clk_ops,
3274 .mux = &muxs[MT_MUX_CAMTG],
3275 },
3276 [MT_CG_IMAGE_VENC_JPENC] = {
3277 .name = "MT_CG_IMAGE_VENC_JPENC",
3278 .grp = &grps[CG_IMAGE],
3279 .mask = BIT(9),
3280 .ops = &general_cg_clk_ops,
3281 },
3282
3283 [MT_CG_MFG_G3D] = {
3284 .name = "MT_CG_MFG_G3D",
3285 .grp = &grps[CG_MFG],
3286 .mask = BIT(0),
3287 .ops = &general_cg_clk_ops,
3288 },
3289
3290 [MT_CG_AUDIO_AFE] = {
3291 .name = "MT_CG_AUDIO_AFE",
3292 .grp = &grps[CG_AUDIO],
3293 .mask = BIT(2),
3294 .ops = &audsys_cg_clk_ops,
3295 .parent = &clks[MT_CG_INFRA_AUDIO],
3296 },
3297 [MT_CG_AUDIO_I2S] = {
3298 .name = "MT_CG_AUDIO_I2S",
3299 .grp = &grps[CG_AUDIO],
3300 .mask = BIT(6),
3301 .ops = &audsys_cg_clk_ops,
3302 .parent = &clks[MT_CG_INFRA_AUDIO],
3303 },
3304 [MT_CG_AUDIO_APLL_TUNER_CK] = {
3305 .name = "MT_CG_AUDIO_APLL_TUNER_CK",
3306 .grp = &grps[CG_AUDIO],
3307 .mask = BIT(19),
3308 .ops = &audsys_cg_clk_ops,
3309 .mux = &muxs[MT_MUX_APLL],
3310 .parent = &clks[MT_CG_INFRA_AUDIO],
3311 },
3312 [MT_CG_AUDIO_HDMI_CK] = {
3313 .name = "MT_CG_AUDIO_HDMI_CK",
3314 .grp = &grps[CG_AUDIO],
3315 .mask = BIT(20),
3316 .ops = &audsys_cg_clk_ops,
3317 .mux = &muxs[MT_MUX_APLL],
3318 .parent = &clks[MT_CG_INFRA_AUDIO],
3319 },
3320 [MT_CG_AUDIO_SPDF_CK] = {
3321 .name = "MT_CG_AUDIO_SPDF_CK",
3322 .grp = &grps[CG_AUDIO],
3323 .mask = BIT(21),
3324 .ops = &audsys_cg_clk_ops,
3325 .mux = &muxs[MT_MUX_APLL],
3326 .parent = &clks[MT_CG_INFRA_AUDIO],
3327 },
3328 [MT_CG_AUDIO_SPDF2_CK] = {
3329 .name = "MT_CG_AUDIO_SPDF2_CK",
3330 .grp = &grps[CG_AUDIO],
3331 .mask = BIT(22),
3332 .ops = &audsys_cg_clk_ops,
3333 .mux = &muxs[MT_MUX_APLL],
3334 .parent = &clks[MT_CG_INFRA_AUDIO],
3335 },
3336
3337 [MT_CG_VDEC0_VDEC] = {
3338 .name = "MT_CG_VDEC0_VDEC",
3339 .grp = &grps[CG_VDEC0],
3340 .mask = BIT(0),
3341 .ops = &vdec_cg_clk_ops,
3342 .mux = &muxs[MT_MUX_VDEC],
3343 },
3344
3345 [MT_CG_VDEC1_LARB] = {
3346 .name = "MT_CG_VDEC1_LARB",
3347 .grp = &grps[CG_VDEC1],
3348 .mask = BIT(0),
3349 .ops = &vdec_cg_clk_ops,
3350 },
3351 };
3352
3353
3354 static struct cg_clk *id_to_clk(unsigned int id)
3355 {
3356 return id < NR_CLKS ? clks + id : NULL;
3357 }
3358
3359 static int general_clk_get_state_op(struct cg_clk *clk)
3360 {
3361 struct subsys *sys = clk->grp->sys;
3362 if (sys && !sys->state)
3363 return PWR_DOWN;
3364
3365 return (clk_readl(clk->grp->sta_addr) & (clk->mask)) ? PWR_DOWN : PWR_ON;
3366 }
3367
3368 static int general_clk_check_validity_op(struct cg_clk *clk)
3369 {
3370 int valid = 0;
3371 if (clk->mask & clk->grp->mask)
3372 valid = 1;
3373
3374 return valid;
3375 }
3376
3377 static int general_clk_enable_op(struct cg_clk *clk)
3378 {
3379 #ifdef CLK_LOG
3380 clk_info("[%s]: clk->grp->name=%s, clk->mask=0x%x\n", __func__, clk->grp->name, clk->mask);
3381 #endif
3382
3383 clk_writel(clk->grp->clr_addr, clk->mask);
3384 return 0;
3385 }
3386
3387 static int general_clk_disable_op(struct cg_clk *clk)
3388 {
3389 #ifdef CLK_LOG
3390 clk_info("[%s]: clk->grp->name=%s, clk->mask=0x%x\n", __func__, clk->grp->name, clk->mask);
3391 #endif
3392
3393 clk_writel(clk->grp->set_addr, clk->mask);
3394 return 0;
3395 }
3396
3397 static struct cg_clk_ops general_cg_clk_ops = {
3398 .get_state = general_clk_get_state_op,
3399 .check_validity = general_clk_check_validity_op,
3400 .enable = general_clk_enable_op,
3401 .disable = general_clk_disable_op,
3402 };
3403
3404 static int audio_clk_enable_op(struct cg_clk *clk)
3405 {
3406 #ifdef CLK_LOG
3407 clk_info("[%s]: clk->grp->name=%s, clk->mask=0x%x\n", __func__, clk->grp->name, clk->mask);
3408 #endif
3409
3410 clk_writel(clk->grp->clr_addr, clk->mask);
3411 return 0;
3412 }
3413
3414 static int audio_clk_disable_op(struct cg_clk *clk)
3415 {
3416 #ifdef CLK_LOG
3417 clk_info("[%s]: clk->grp->name=%s, clk->mask=0x%x\n", __func__, clk->grp->name, clk->mask);
3418 #endif
3419
3420 clk_writel(clk->grp->set_addr, clk->mask);
3421 return 0;
3422 }
3423
3424 static struct cg_clk_ops audio_cg_clk_ops = {
3425 .get_state = general_clk_get_state_op,
3426 .check_validity = general_clk_check_validity_op,
3427 .enable = audio_clk_enable_op,
3428 .disable = audio_clk_disable_op,
3429 };
3430
3431
3432 static int audsys_clk_enable_op(struct cg_clk *clk)
3433 {
3434 clk_clrl(clk->grp->sta_addr, clk->mask);
3435 return 0;
3436 }
3437
3438 static int audsys_clk_disable_op(struct cg_clk *clk)
3439 {
3440 clk_setl(clk->grp->sta_addr, clk->mask);
3441 return 0;
3442 }
3443
3444 static struct cg_clk_ops audsys_cg_clk_ops = {
3445 .get_state = general_clk_get_state_op,
3446 .check_validity = general_clk_check_validity_op,
3447 .enable = audsys_clk_enable_op,
3448 .disable = audsys_clk_disable_op,
3449 };
3450
3451 static int vdec_clk_get_state_op(struct cg_clk *clk)
3452 {
3453 return (clk_readl(clk->grp->set_addr) & (clk->mask)) ? PWR_ON : PWR_DOWN;
3454 }
3455
3456 static struct cg_clk_ops vdec_cg_clk_ops = {
3457 .get_state = vdec_clk_get_state_op,
3458 .check_validity = general_clk_check_validity_op,
3459 .enable = general_clk_enable_op,
3460 .disable = general_clk_disable_op,
3461 };
3462
3463
3464 static int power_prepare_locked(struct cg_grp *grp)
3465 {
3466 int err = 0;
3467 if (grp->sys)
3468 err = subsys_enable_internal(grp->sys, "clk");
3469
3470 return err;
3471 }
3472
3473 static int power_finish_locked(struct cg_grp *grp)
3474 {
3475 int err = 0;
3476 if (grp->sys)
3477 err = subsys_disable_internal(grp->sys, 0, "clk");
3478
3479 return err;
3480 }
3481
3482 static int clk_enable_locked(struct cg_clk *clk)
3483 {
3484 struct cg_grp *grp = clk->grp;
3485 unsigned int local_state;
3486 #ifdef STATE_CHECK_DEBUG
3487 unsigned int reg_state;
3488 #endif
3489 int err;
3490
3491 #ifdef CLK_LOG
3492 clk_info("[%s]: Start. grp->name=%s, grp->state=0x%x, clk->mask=0x%x, clk->cnt=%d, clk->state=%d\n",
3493 __func__, grp->name, grp->state, clk->mask, clk->cnt, clk->state);
3494 #endif
3495
3496 clk->cnt++;
3497
3498 if (clk->cnt > 1)
3499 return 0;
3500
3501 local_state = clk->state;
3502
3503 #ifdef STATE_CHECK_DEBUG
3504 reg_state = grp->ops->get_state(grp, clk);
3505 BUG_ON(local_state != reg_state);
3506 #endif
3507
3508 #if !defined(CONFIG_MTK_LDVT)
3509 if (clk->mux)
3510 mux_enable_internal(clk->mux, "clk");
3511
3512 err = power_prepare_locked(grp);
3513 BUG_ON(err);
3514 #endif
3515
3516 if (clk->parent)
3517 clk_enable_internal(clk->parent, "clk");
3518
3519 if (local_state == PWR_ON)
3520 return 0;
3521
3522 clk->ops->enable(clk);
3523
3524 clk->state = PWR_ON;
3525 grp->state |= clk->mask;
3526 #ifdef CLK_LOG
3527 clk_info("[%s]: End. grp->name=%s, grp->state=0x%x, clk->mask=0x%x, clk->cnt=%d, clk->state=%d\n",
3528 __func__, grp->name, grp->state, clk->mask, clk->cnt, clk->state);
3529 #endif
3530
3531 return 0;
3532 }
3533
3534 static int clk_disable_locked(struct cg_clk *clk)
3535 {
3536 struct cg_grp *grp = clk->grp;
3537 unsigned int local_state;
3538 #ifdef STATE_CHECK_DEBUG
3539 unsigned int reg_state;
3540 #endif
3541 int err;
3542
3543 #ifdef CLK_LOG
3544 clk_info("[%s]: Start. grp->name=%s, grp->state=0x%x, clk->mask=0x%x, clk->cnt=%d, clk->state=%d\n",
3545 __func__, grp->name, grp->state, clk->mask, clk->cnt, clk->state);
3546 #endif
3547
3548 #if defined(CONFIG_CLKMGR_BRINGUP)
3549 return 0;
3550 #endif
3551
3552 #if DISABLE_BUG_ON_CNT
3553 WARN_ON(!clk->cnt);
3554 if (!clk->cnt)
3555 return 0;
3556 #else /* !DISABLE_BUG_ON_CNT */
3557 BUG_ON(!clk->cnt);
3558 #endif /* DISABLE_BUG_ON_CNT */
3559
3560 clk->cnt--;
3561
3562 if (clk->cnt > 0)
3563 return 0;
3564
3565 local_state = clk->state;
3566
3567 #ifdef STATE_CHECK_DEBUG
3568 reg_state = grp->ops->get_state(grp, clk);
3569 BUG_ON(local_state != reg_state);
3570 #endif
3571
3572 if (local_state == PWR_DOWN)
3573 return 0;
3574
3575 if (clk->force_on)
3576 return 0;
3577
3578 clk->ops->disable(clk);
3579
3580 clk->state = PWR_DOWN;
3581 grp->state &= ~(clk->mask);
3582
3583 if (clk->parent)
3584 clk_disable_internal(clk->parent, "clk");
3585
3586 #if !defined(CONFIG_MTK_LDVT)
3587 err = power_finish_locked(grp);
3588 BUG_ON(err);
3589
3590 if (clk->mux)
3591 mux_disable_internal(clk->mux, "clk");
3592
3593 #endif
3594
3595 #ifdef CLK_LOG
3596 clk_info("[%s]: End. grp->name=%s, grp->state=0x%x, clk->mask=0x%x, clk->cnt=%d, clk->state=%d\n",
3597 __func__, grp->name, grp->state, clk->mask, clk->cnt, clk->state);
3598 #endif
3599
3600 return 0;
3601 }
3602
3603 static int get_clk_state_locked(struct cg_clk *clk)
3604 {
3605 if (likely(initialized))
3606 return clk->state;
3607 else
3608 return clk->ops->get_state(clk);
3609 }
3610
3611 int mt_enable_clock(enum cg_clk_id id, char *name)
3612 {
3613 int err;
3614 unsigned long flags;
3615 struct cg_clk *clk = id_to_clk(id);
3616
3617 #if defined(CONFIG_CLKMGR_BRINGUP) || defined(CONFIG_MT8127_FPGA)
3618 return 0;
3619 #endif
3620
3621 BUG_ON(!initialized);
3622 BUG_ON(!clk);
3623 BUG_ON(!clk->grp);
3624 BUG_ON(!clk->ops->check_validity(clk));
3625 BUG_ON(!name);
3626 #ifdef CLK_LOG_TOP
3627 clk_info("[%s]: id=%d, names=%s\n", __func__, id, name);
3628 #else
3629 if (id == MT_CG_DISP0_SMI_COMMON)
3630 clk_dbg("[%s]: id=%d, names=%s\n", __func__, id, name);
3631 #endif
3632
3633 clkmgr_lock(flags);
3634 err = clk_enable_internal(clk, name);
3635 clkmgr_unlock(flags);
3636
3637 return err;
3638 }
3639 EXPORT_SYMBOL(mt_enable_clock);
3640
3641
3642 int mt_disable_clock(enum cg_clk_id id, char *name)
3643 {
3644 int err;
3645 unsigned long flags;
3646 struct cg_clk *clk = id_to_clk(id);
3647
3648 #if defined(CONFIG_CLKMGR_BRINGUP) || defined(CONFIG_MT8127_FPGA)
3649 return 0;
3650 #endif
3651
3652 BUG_ON(!initialized);
3653 BUG_ON(!clk);
3654 BUG_ON(!clk->grp);
3655 BUG_ON(!clk->ops->check_validity(clk));
3656 BUG_ON(!name);
3657 #ifdef CLK_LOG_TOP
3658 clk_info("[%s]: id=%d, names=%s\n", __func__, id, name);
3659 #else
3660 if (id == MT_CG_DISP0_SMI_COMMON)
3661 clk_dbg("[%s]: id=%d, names=%s\n", __func__, id, name);
3662 #endif
3663
3664 clkmgr_lock(flags);
3665 err = clk_disable_internal(clk, name);
3666 clkmgr_unlock(flags);
3667
3668 return err;
3669 }
3670 EXPORT_SYMBOL(mt_disable_clock);
3671
3672
3673 #if !CLKMGR_8127
3674
3675
3676 int enable_clock_ext_locked(int id, char *name)
3677 {
3678 int err;
3679 struct cg_clk *clk = id_to_clk(id);
3680
3681 #if defined(CONFIG_CLKMGR_BRINGUP)
3682 return 0;
3683 #endif
3684
3685 BUG_ON(!initialized);
3686 BUG_ON(!clk);
3687 BUG_ON(!clk->grp);
3688 BUG_ON(!clk->ops->check_validity(clk));
3689
3690 BUG_ON(!clkmgr_locked());
3691 err = clk_enable_internal(clk, name);
3692
3693 return err;
3694 }
3695 EXPORT_SYMBOL(enable_clock_ext_locked);
3696
3697
3698 int disable_clock_ext_locked(int id, char *name)
3699 {
3700 int err;
3701 struct cg_clk *clk = id_to_clk(id);
3702
3703 #if defined(CONFIG_CLKMGR_BRINGUP)
3704 return 0;
3705 #endif
3706
3707 BUG_ON(!initialized);
3708 BUG_ON(!clk);
3709 BUG_ON(!clk->grp);
3710 BUG_ON(!clk->ops->check_validity(clk));
3711
3712 BUG_ON(!clkmgr_locked());
3713 err = clk_disable_internal(clk, name);
3714
3715 return err;
3716 }
3717 EXPORT_SYMBOL(disable_clock_ext_locked);
3718
3719
3720 #endif /* !CLKMGR_8127 */
3721
3722
3723 int clock_is_on(int id)
3724 {
3725 int state;
3726 unsigned long flags;
3727 struct cg_clk *clk = id_to_clk(id);
3728
3729 #if defined(CONFIG_CLKMGR_BRINGUP) || defined(CONFIG_MT8127_FPGA)
3730 return 1;
3731 #endif
3732
3733 BUG_ON(!clk);
3734 BUG_ON(!clk->grp);
3735 BUG_ON(!clk->ops->check_validity(clk));
3736
3737 clkmgr_lock(flags);
3738 state = get_clk_state_locked(clk);
3739 clkmgr_unlock(flags);
3740
3741 return state;
3742 }
3743 EXPORT_SYMBOL(clock_is_on);
3744
3745
3746 static void clk_set_force_on_locked(struct cg_clk *clk)
3747 {
3748 clk->force_on = 1;
3749 }
3750
3751 static void clk_clr_force_on_locked(struct cg_clk *clk)
3752 {
3753 clk->force_on = 0;
3754 }
3755
3756 void clk_set_force_on(int id)
3757 {
3758 unsigned long flags;
3759 struct cg_clk *clk = id_to_clk(id);
3760
3761 #if defined(CONFIG_CLKMGR_BRINGUP)
3762 return;
3763 #endif
3764
3765 BUG_ON(!initialized);
3766 BUG_ON(!clk);
3767 BUG_ON(!clk->grp);
3768 BUG_ON(!clk->ops->check_validity(clk));
3769
3770 clkmgr_lock(flags);
3771 clk_set_force_on_locked(clk);
3772 clkmgr_unlock(flags);
3773 }
3774 EXPORT_SYMBOL(clk_set_force_on);
3775
3776 void clk_clr_force_on(int id)
3777 {
3778 unsigned long flags;
3779 struct cg_clk *clk = id_to_clk(id);
3780
3781 #if defined(CONFIG_CLKMGR_BRINGUP)
3782 return;
3783 #endif
3784
3785 BUG_ON(!initialized);
3786 BUG_ON(!clk);
3787 BUG_ON(!clk->grp);
3788 BUG_ON(!clk->ops->check_validity(clk));
3789
3790 clkmgr_lock(flags);
3791 clk_clr_force_on_locked(clk);
3792 clkmgr_unlock(flags);
3793 }
3794 EXPORT_SYMBOL(clk_clr_force_on);
3795
3796 int clk_is_force_on(int id)
3797 {
3798 struct cg_clk *clk = id_to_clk(id);
3799
3800 #if defined(CONFIG_CLKMGR_BRINGUP)
3801 return 1;
3802 #endif
3803
3804 BUG_ON(!initialized);
3805 BUG_ON(!clk);
3806 BUG_ON(!clk->grp);
3807 BUG_ON(!clk->ops->check_validity(clk));
3808
3809 return clk->force_on;
3810 }
3811
3812 int grp_dump_regs(int id, unsigned int *ptr)
3813 {
3814 struct cg_grp *grp = id_to_grp(id);
3815
3816 BUG_ON(!grp);
3817
3818 return grp->ops->dump_regs(grp, ptr);
3819 }
3820 EXPORT_SYMBOL(grp_dump_regs);
3821
3822 const char *grp_get_name(int id)
3823 {
3824 struct cg_grp *grp = id_to_grp(id);
3825
3826 BUG_ON(!grp);
3827
3828 return grp->name;
3829 }
3830
3831 void print_grp_regs(void)
3832 {
3833 int i;
3834 int cnt;
3835 unsigned int value[2];
3836 const char *name;
3837
3838 for (i = 0; i < NR_GRPS; i++) {
3839 name = grp_get_name(i);
3840 cnt = grp_dump_regs(i, value);
3841 if (cnt == 1)
3842 clk_info("[%02d][%-8s]=[0x%08x]\n", i, name, value[0]);
3843 else
3844 clk_info("[%02d][%-8s]=[0x%08x][0x%08x]\n", i, name, value[0], value[1]);
3845 }
3846 }
3847
3848 int clk_id_to_grp_id(enum cg_clk_id id)
3849 {
3850 struct cg_clk *clk = id_to_clk(id);
3851 return (NULL == clk) ? NR_GRPS : (clk->grp - &grps[0]);
3852 }
3853
3854 unsigned int clk_id_to_mask(enum cg_clk_id id)
3855 {
3856 struct cg_clk *clk = id_to_clk(id);
3857 return (NULL == clk) ? 0 : clk->mask;
3858 }
3859
3860
3861
3862 /************************************************
3863 ********** initialization **********
3864 ************************************************/
3865
3866 static void cg_all_force_on(void)
3867 {
3868 int i;
3869 for (i = 0; i < NR_CLKS; i++) {
3870 struct cg_clk *clk = id_to_clk(i);
3871 BUG_ON(!clk || !clk->ops);
3872
3873 clk->ops->enable(clk);
3874 #if WORKAROUND_DAPC
3875 clk->state = PWR_ON;
3876 clk->grp->mask |= clk->mask;
3877 clk->grp->state |= clk->mask;
3878 #ifdef CONFIG_CLKMGR_STAT
3879 INIT_LIST_HEAD(&clk->head);
3880 #endif
3881 #endif /* !WORKAROUND_DAPC */
3882 }
3883 }
3884
3885 static void cg_bootup_pdn(void)
3886 {
3887 enum cg_clk_id ignored_pdn[] = {
3888 MT_CG_PERI_THERM,
3889 MT_CG_PERI_AP_DMA,
3890 MT_CG_PERI_UART0,
3891 MT_CG_PERI_AUXADC,
3892 MT_CG_PERI_USB0_MCU,
3893 MT_CG_PERI_USB1_MCU,
3894 MT_CG_PERI_USB_SLV,
3895 MT_CG_PERI_GCPU,
3896 MT_CG_INFRA_DBGCLK,
3897 MT_CG_INFRA_SMI,
3898 MT_CG_INFRA_EFUSE,
3899 MT_CG_INFRA_M4U,
3900 MT_CG_INFRA_KP,
3901 MT_CG_INFRA_PMICSPI_SHARE,
3902 MT_CG_INFRA_PMICWRAP,
3903 MT_CG_TOPCK_PMICSPI,
3904 MT_CG_DISP0_SMI_COMMON,
3905 MT_CG_DISP0_SMI_LARB0,
3906 MT_CG_DISP0_DISP_COLOR,
3907 MT_CG_DISP0_DISP_BLS,
3908 MT_CG_DISP0_DISP_RDMA,
3909 MT_CG_DISP0_DISP_OVL,
3910 MT_CG_DISP0_MDP_BLS_26M,
3911 MT_CG_DISP0_MUTEX_32K,
3912 MT_CG_DISP0_DISP_UFOE,
3913 MT_CG_DISP1_DSI_ENGINE,
3914 MT_CG_DISP1_DSI_DIGITAL,
3915 MT_CG_DISP1_DPI_DIGITAL_LANE,
3916 MT_CG_DISP1_DPI_ENGINE,
3917 MT_CG_DISP1_LVDS_PIXEL_CLOCK,
3918 MT_CG_DISP1_LVDS_CTS_CLOCK,
3919 };
3920
3921 int len = ARRAY_SIZE(ignored_pdn);
3922 int i;
3923 for (i = NR_CLKS - 1; i >= 0; i--) {
3924 int j;
3925 struct cg_clk *clk;
3926
3927 for (j = 0; j < len && i != ignored_pdn[j]; j++)
3928 ;
3929
3930 if (j != len) /* ignore this clock */
3931 continue;
3932
3933 clk = id_to_clk(i);
3934 clk->ops->disable(clk);
3935 #if WORKAROUND_DAPC
3936 clk->state = PWR_DOWN;
3937 clk->grp->state &= ~(clk->mask);
3938 #endif /* !WORKAROUND_DAPC */
3939 }
3940 }
3941
3942
3943 static void mt_subsys_init(void)
3944 {
3945 int i;
3946 struct subsys *sys;
3947
3948 for (i = 0; i < NR_SYSS; i++) {
3949 sys = &syss[i];
3950 sys->state = sys->ops->get_state(sys);
3951 if (sys->state != sys->default_sta) {
3952 clk_info("[%s]%s, change state: (%u->%u)\n", __func__,
3953 sys->name, sys->state, sys->default_sta);
3954 if (sys->default_sta == PWR_DOWN)
3955 sys_disable_locked(sys, 1);
3956 else
3957 sys_enable_locked(sys);
3958 }
3959 #ifdef CONFIG_CLKMGR_STAT
3960 INIT_LIST_HEAD(&sys->head);
3961 #endif
3962 }
3963 }
3964
3965 static void mt_plls_init(void)
3966 {
3967 int i;
3968 struct pll *pll;
3969 for (i = 0; i < NR_PLLS; i++) {
3970 pll = &plls[i];
3971 pll->state = pll->ops->get_state(pll);
3972
3973 #ifdef CONFIG_CLKMGR_STAT
3974 INIT_LIST_HEAD(&pll->head);
3975 #endif
3976 }
3977 }
3978
3979
3980 #if !CLKMGR_8127
3981
3982
3983 static void mt_plls_enable_hp(void)
3984 {
3985 int i;
3986 struct pll *pll;
3987 for (i = 0; i < NR_PLLS; i++) {
3988 pll = &plls[i];
3989 if (pll->ops->hp_enable)
3990 pll->ops->hp_enable(pll);
3991 }
3992 }
3993
3994
3995 #endif /* CLKMGR_8127 */
3996
3997
3998 static void mt_muxs_init(void)
3999 {
4000 int i;
4001 struct clkmux *mux;
4002
4003 clk_setl(CLK_CFG_2, 0x00008000);
4004
4005 for (i = 0; i < NR_MUXS; i++) {
4006 mux = &muxs[i];
4007 #ifdef CONFIG_CLKMGR_STAT
4008 INIT_LIST_HEAD(&mux->head);
4009 #endif
4010
4011 }
4012 }
4013
4014
4015 static void mt_clks_init(void)
4016 {
4017 #if !WORKAROUND_DAPC
4018 int i;
4019 struct cg_grp *grp;
4020 struct cg_clk *clk;
4021
4022 for (i = 0; i < NR_CLKS; i++) {
4023 clk = id_to_clk(i);
4024 BUG_ON(!clk || !clk->ops);
4025
4026 clk->state = clk->ops->get_state(clk);
4027 clk->grp->mask |= clk->mask;
4028
4029 #ifdef CONFIG_CLKMGR_STAT
4030 INIT_LIST_HEAD(&clk->head);
4031 #endif
4032 }
4033
4034 for (i = 0; i < NR_GRPS; i++) {
4035 grp = id_to_grp(i);
4036 grp->state = grp->ops->get_state(grp);
4037 }
4038 #endif /* !WORKAROUND_DAPC */
4039
4040 /* Don't disable these clock until it's clk_clr_force_on() is called */
4041 clk_set_force_on_locked(&clks[MT_CG_DISP0_SMI_LARB0]);
4042 clk_set_force_on_locked(&clks[MT_CG_DISP0_SMI_COMMON]);
4043 }
4044
4045
4046 #if CLKMGR_8127
4047
4048 static int id_from_mux(struct clkmux *mux)
4049 {
4050 int i;
4051 for (i = 0; i < NR_MUXS; i++) {
4052 if (mux == &muxs[i])
4053 return i;
4054 }
4055
4056 return -1;
4057 }
4058
4059
4060 static int id_from_pll(struct pll *p)
4061 {
4062 int i;
4063 for (i = 0; i < NR_PLLS; i++) {
4064 if (p == &plls[i])
4065 return i;
4066 }
4067
4068 return -1;
4069 }
4070
4071
4072 static void init_pll_by_mux(int muxid, int8_t *mux_init, int8_t *pll_init, int clkstate, int sysstate)
4073 {
4074 struct clkmux *mux;
4075
4076 if (muxid == -1)
4077 return;
4078
4079 if (mux_init[muxid] < 0)
4080 mux_init[muxid] = 0;
4081
4082 if (clkstate == PWR_ON || sysstate == PWR_ON)
4083 mux_init[muxid]++;
4084
4085 mux = id_to_mux(muxid);
4086
4087 if (sysstate == PWR_ON) {
4088 mux->cnt++;
4089
4090 if (mux->pll)
4091 mux->pll->cnt++;
4092 }
4093
4094 if (mux_init[muxid] > 1 && sysstate != PWR_ON)
4095 return;
4096
4097 if (mux->pll) {
4098 int pllid = id_from_pll(mux->pll);
4099 if (pllid != -1) {
4100 if (pll_init[pllid] < 0)
4101 pll_init[pllid] = 0;
4102
4103 if (clkstate == PWR_ON)
4104 pll_init[pllid]++;
4105 }
4106 }
4107
4108 if (mux->parent) {
4109 int id = id_from_mux(mux->parent);
4110 init_pll_by_mux(id, mux_init, pll_init, clkstate, sysstate);
4111 }
4112
4113 if (mux->siblings) {
4114 int id = id_from_mux(mux->siblings);
4115 init_pll_by_mux(id, mux_init, pll_init, clkstate, sysstate);
4116 }
4117 }
4118
4119
4120 static void init_mux_pll_by_clk(struct cg_clk *clk, int8_t *mux_init, int8_t *pll_init)
4121 {
4122 if (!clk)
4123 return;
4124
4125 if (clk->mux) {
4126 int id = id_from_mux(clk->mux);
4127 init_pll_by_mux(id, mux_init, pll_init, clk->state, PWR_DOWN);
4128 }
4129
4130 if (clk->grp && clk->grp->sys && clk->grp->sys->mux) {
4131 int id = id_from_mux(clk->grp->sys->mux);
4132 init_pll_by_mux(id, mux_init, pll_init, clk->state, PWR_DOWN);
4133 }
4134
4135 if (clk->parent)
4136 init_mux_pll_by_clk(clk->parent, mux_init, pll_init);
4137 }
4138
4139
4140 static void init_mux_pll_by_subsys(struct subsys *sys, int8_t *mux_init, int8_t *pll_init)
4141 {
4142 if (!sys)
4143 return;
4144
4145 if (sys->mux) {
4146 int id = id_from_mux(sys->mux);
4147 init_pll_by_mux(id, mux_init, pll_init, PWR_DOWN, sys->state);
4148 }
4149 }
4150
4151
4152 static void mt_clk_mux_pll_post_init(void)
4153 {
4154 int i;
4155
4156 int8_t mux_init[NR_MUXS]; /* -1: ignore ; 0: off ; 1+: on */
4157 int8_t pll_init[NR_PLLS];
4158
4159 memset(mux_init, -1, sizeof(mux_init));
4160 memset(pll_init, -1, sizeof(pll_init));
4161
4162 for (i = 0; i < NR_CLKS; i++) {
4163 struct cg_clk *clk = id_to_clk(i);
4164 init_mux_pll_by_clk(clk, mux_init, pll_init);
4165 }
4166
4167 for (i = 0; i < NR_SYSS; i++) {
4168 struct subsys *sys = id_to_sys(i);
4169 init_mux_pll_by_subsys(sys, mux_init, pll_init);
4170 }
4171
4172 for (i = 0; i < NR_MUXS; i++) {
4173 struct clkmux *mux = id_to_mux(i);
4174
4175 if (mux_init[i] || mux->cnt > 0)
4176 mux->ops->enable(mux);
4177 else
4178 mux->ops->disable(mux);
4179 }
4180
4181 for (i = 0; i < NR_PLLS; i++) {
4182 struct pll *p = id_to_pll(i);
4183
4184 if (pll_init[i] || p->cnt > 0) {
4185 p->ops->enable(p);
4186 p->state = PWR_ON;
4187 } else {
4188 p->ops->disable(p);
4189 p->state = PWR_DOWN;
4190 }
4191 }
4192 }
4193
4194
4195 #endif /* CLKMGR_8127 */
4196
4197
4198 int mt_clkmgr_bringup_init(void)
4199 {
4200 #if (!defined(CONFIG_CLKMGR_BRINGUP) && !defined(CONFIG_MTK_LDVT))
4201 BUG_ON(initialized);
4202 #else
4203 if (initialized)
4204 return 0;
4205 #endif
4206
4207 spm_mtcmos_ctrl_vdec(STA_POWER_ON);
4208 spm_mtcmos_ctrl_isp(STA_POWER_ON);
4209 spm_mtcmos_ctrl_mfg(STA_POWER_ON);
4210
4211 cg_all_force_on();
4212 #if (!defined(CONFIG_CLKMGR_BRINGUP) && !defined(CONFIG_MTK_LDVT))
4213 cg_bootup_pdn();
4214 #endif
4215 #if (!defined(CONFIG_CLKMGR_BRINGUP))
4216 mt_plls_init();
4217 mt_subsys_init();
4218 mt_muxs_init();
4219 mt_clks_init();
4220 #if CLKMGR_8127
4221 mt_clk_mux_pll_post_init();
4222 #endif /* CLKMGR_8127 */
4223 #endif
4224 initialized = 1;
4225
4226 mt_freqhopping_init();
4227 mt_freqhopping_pll_init();
4228 #if !defined(CONFIG_CLKMGR_BRINGUP) && !WORKAROUND_DAPC
4229 print_grp_regs();
4230 #endif
4231 return 0;
4232 }
4233
4234 void mt_clkmgr_init(void)
4235 {
4236 #if CLKMGR_8127
4237
4238 mt_clkmgr_bringup_init();
4239
4240 #else /* !CLKMGR_8127 */
4241
4242 unsigned long flags;
4243 BUG_ON(initialized);
4244
4245 mt_plls_init();
4246 mt_subsys_init();
4247 mt_muxs_init();
4248 mt_clks_init();
4249 mt_clk_mux_pll_post_init();
4250
4251 initialized = 1;
4252
4253 mt_freqhopping_init();
4254
4255 clkmgr_lock(flags);
4256 mt_freqhopping_pll_init();
4257 mt_plls_enable_hp();
4258 clkmgr_unlock(flags);
4259
4260 #endif /* CLKMGR_8127 */
4261 }
4262
4263
4264
4265 #ifdef CONFIG_MTK_MMC
4266 /* msdc_clk_status() is declared in mt_clkmgr.h */
4267 #else
4268 void msdc_clk_status(int *status)
4269 {
4270 *status = 0;
4271 }
4272 #endif
4273
4274 bool clkmgr_idle_can_enter(unsigned int *condition_mask, unsigned int *block_mask)
4275 {
4276 int i, j;
4277 unsigned int cg_mask = 0;
4278
4279 #ifdef MTK_EMMC_SUPPORT
4280 unsigned int sd_mask = 0;
4281 msdc_clk_status(&sd_mask);
4282 if (sd_mask) {
4283 block_mask[CG_PERI0] |= sd_mask;
4284 return false;
4285 }
4286 #endif
4287
4288 for (i = CG_PERI0; i < NR_GRPS; i++) {
4289 cg_mask = grps[i].state & condition_mask[i];
4290 if (cg_mask) {
4291 for (j = CG_PERI0; j < NR_GRPS; j++)
4292 block_mask[j] = grps[j].state & condition_mask[j];
4293
4294 return false;
4295 }
4296 }
4297
4298 return true;
4299 }
4300
4301
4302 bool isp_vdec_on_off(void)
4303 {
4304 unsigned int state;
4305
4306 state = subsys_is_on(SYS_ISP);
4307 if (state == PWR_ON)
4308 return true;
4309
4310 state = subsys_is_on(SYS_VDE);
4311 if (state == PWR_ON)
4312 return true;
4313
4314 return false;
4315 }
4316 EXPORT_SYMBOL(isp_vdec_on_off);
4317
4318
4319 /************************************************
4320 ********** function debug **********
4321 ************************************************/
4322
4323 #if CLKMGR_8127
4324
4325
4326 static void dump_pll_info1(struct seq_file *s, int clkidx)
4327 {
4328 if (clkidx < NR_PLLS) {
4329 struct pll *pll = &plls[clkidx];
4330 unsigned int freq = pll_freq_calc_op(pll);
4331
4332 seq_printf(s, "[%d] %7s: %4d.%03d MHz: %3s (%2d)\n",
4333 clkidx, pll->name, freq / 1000, freq % 1000, pll->state ? "ON" : "off", pll->cnt);
4334 }
4335 }
4336
4337
4338 #endif /* CLKMGR_8127 */
4339
4340
4341 static int pll_test_show(struct seq_file *s, void *v)
4342 {
4343 int i, j;
4344 int cnt;
4345 unsigned int value[3];
4346 const char *name;
4347
4348 #if CLKMGR_8127
4349 for (i = 0; i < NR_PLLS; i++)
4350 dump_pll_info1(s, i);
4351 #endif /* CLKMGR_8127 */
4352
4353 seq_printf(s, "********** pll register dump **********\n");
4354 for (i = 0; i < NR_PLLS; i++) {
4355 name = pll_get_name(i);
4356 cnt = pll_dump_regs(i, value);
4357 for (j = 0; j < cnt; j++)
4358 seq_printf(s, "[%d][%-7s reg%d]=[0x%08x]\n", i, name, j, value[j]);
4359 }
4360 seq_printf(s, "MIPI : CLK_DSI_PLL_CON0=0x%08x\n", clk_readl(CLK_DSI_PLL_CON0));
4361
4362 seq_printf(s, "\n********** pll_test help **********\n");
4363 seq_printf(s, "enable pll: echo enable id [mod_name] > /proc/clkmgr/pll_test\n");
4364 seq_printf(s, "disable pll: echo disable id [mod_name] > /proc/clkmgr/pll_test\n");
4365 #if CLKMGR_8127
4366 seq_printf(s, "set freq : echo setfreq id freq_khz > /proc/clkmgr/pll_test\n");
4367 #endif /* CLKMGR_8127 */
4368
4369 return 0;
4370 }
4371
4372
4373 static int pll_test_open(struct inode *inode, struct file *file)
4374 {
4375 return single_open(file, pll_test_show, NULL);
4376 }
4377
4378
4379 static int pll_test_write(struct file *file, const char *buffer, size_t count, loff_t *data)
4380 {
4381 char desc[32];
4382 int len = 0;
4383
4384 char cmd[10];
4385 char mod_name[10];
4386 int id;
4387 unsigned int freq;
4388 int err = 0;
4389
4390 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
4391 if (copy_from_user(desc, buffer, len))
4392 return 0;
4393
4394 desc[len] = '\0';
4395
4396 if (sscanf(desc, "%s %d %u", cmd, &id, &freq) == 3) {
4397 if (!strcmp(cmd, "setfreq")) {
4398 unsigned int r = pll_set_freq(id, freq);
4399 if (r != 0)
4400 clk_info("pll_set_freq(): 0x%08x, id: %d, freq: %u\n", r, id, freq);
4401 }
4402 } else if (sscanf(desc, "%s %d %s", cmd, &id, mod_name) == 3) {
4403 if (!strcmp(cmd, "enable"))
4404 err = enable_pll(id, mod_name);
4405 else if (!strcmp(cmd, "disable"))
4406 err = disable_pll(id, mod_name);
4407 } else if (sscanf(desc, "%s %d", cmd, &id) == 2) {
4408 if (!strcmp(cmd, "enable"))
4409 err = enable_pll(id, "pll_test");
4410 else if (!strcmp(cmd, "disable"))
4411 err = disable_pll(id, "pll_test");
4412 }
4413
4414 clk_info("[%s]%s pll %d: result is %d\n", __func__, cmd, id, err);
4415
4416 return count;
4417 }
4418
4419
4420 static const struct file_operations pll_test_fops = {
4421 .owner = THIS_MODULE,
4422 .write = pll_test_write,
4423 .open = pll_test_open,
4424 .read = seq_read,
4425 .llseek = seq_lseek,
4426 .release = seq_release
4427 };
4428
4429
4430 static int pll_fsel_show(struct seq_file *s, void *v)
4431 {
4432 int i;
4433 int cnt;
4434 unsigned int value[3];
4435 const char *name;
4436
4437 for (i = 0; i < NR_PLLS; i++) {
4438 name = pll_get_name(i);
4439 if (pll_is_on(i)) {
4440 cnt = pll_dump_regs(i, value);
4441 if (cnt >= 2)
4442 seq_printf(s, "[%d][%-7s]=[0x%08x%08x]\n", i, name, value[0], value[1]);
4443 else
4444 seq_printf(s, "[%d][%-7s]=[0x%08x]\n", i, name, value[0]);
4445 } else
4446 seq_printf(s, "[%d][%-7s]=[-1]\n", i, name);
4447 }
4448
4449 seq_printf(s, "\n********** pll_fsel help **********\n");
4450 seq_printf(s, "adjust pll frequency: echo id freq > /proc/clkmgr/pll_fsel\n");
4451
4452 return 0;
4453 }
4454
4455
4456 static int pll_fsel_open(struct inode *inode, struct file *file)
4457 {
4458 return single_open(file, pll_fsel_show, NULL);
4459 }
4460
4461
4462 static int pll_fsel_write(struct file *file, const char *buffer, size_t count, loff_t *data)
4463 {
4464 char desc[32];
4465 int len = 0;
4466
4467 int id;
4468 unsigned int value;
4469
4470 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
4471 if (copy_from_user(desc, buffer, len))
4472 return 0;
4473
4474 desc[len] = '\0';
4475
4476 if (sscanf(desc, "%d %x", &id, &value) == 2)
4477 pll_fsel(id, value);
4478
4479 return count;
4480 }
4481
4482
4483 static const struct file_operations pll_fsel_fops = {
4484 .owner = THIS_MODULE,
4485 .write = pll_fsel_write,
4486 .open = pll_fsel_open,
4487 .read = seq_read,
4488 .llseek = seq_lseek,
4489 .release = seq_release
4490 };
4491
4492
4493 #ifdef CONFIG_CLKMGR_STAT
4494
4495
4496 static int pll_stat_show(struct seq_file *s, void *v)
4497 {
4498 struct pll *pll;
4499 struct list_head *pos;
4500 struct stat_node *node;
4501 int i;
4502
4503 seq_printf(s, "\n********** pll stat dump **********\n");
4504 for (i = 0; i < NR_PLLS; i++) {
4505 pll = id_to_pll(i);
4506 seq_printf(s, "[%d][%-7s]state=%u, cnt=%u", i, pll->name,
4507 pll->state, pll->cnt);
4508 list_for_each(pos, &pll->head) {
4509 node = list_entry(pos, struct stat_node, link);
4510 seq_printf(s, "\t(%s,%u,%u)", node->name, node->cnt_on, node->cnt_off);
4511 }
4512 seq_printf(s, "\n");
4513 }
4514
4515 seq_printf(s, "\n********** pll_dump help **********\n");
4516
4517 return 0;
4518 }
4519
4520
4521 static int pll_stat_open(struct inode *inode, struct file *file)
4522 {
4523 return single_open(file, pll_stat_show, NULL);
4524 }
4525
4526
4527 static const struct file_operations pll_stat_fops = {
4528 .owner = THIS_MODULE,
4529 .open = pll_stat_open,
4530 .read = seq_read,
4531 .llseek = seq_lseek,
4532 .release = seq_release
4533 };
4534
4535
4536 #endif /* CONFIG_CLKMGR_STAT */
4537
4538
4539 static int subsys_test_show(struct seq_file *s, void *v)
4540 {
4541 int i;
4542 int state;
4543 unsigned int value = 0, sta, sta_s;
4544 const char *name;
4545
4546 sta = clk_readl(SPM_PWR_STATUS);
4547 sta_s = clk_readl(SPM_PWR_STATUS_S);
4548
4549 seq_printf(s, "********** subsys register dump **********\n");
4550 for (i = 0; i < NR_SYSS; i++) {
4551 name = subsys_get_name(i);
4552 state = subsys_is_on(i);
4553 subsys_dump_regs(i, &value);
4554 seq_printf(s, "[%d][%-8s]=[0x%08x], state(%u)\n", i, name, value, state);
4555 }
4556 seq_printf(s, "SPM_PWR_STATUS=0x%08x, SPM_PWR_STATUS_S=0x%08x\n", sta, sta_s);
4557
4558 seq_printf(s, "\n********** subsys_test help **********\n");
4559 seq_printf(s, "enable subsys: echo enable id > /proc/clkmgr/subsys_test\n");
4560 seq_printf(s, "disable subsys: echo disable id [force_off] > /proc/clkmgr/subsys_test\n");
4561
4562 return 0;
4563 }
4564
4565
4566 static int subsys_test_open(struct inode *inode, struct file *file)
4567 {
4568 return single_open(file, subsys_test_show, NULL);
4569 }
4570
4571
4572 static int subsys_test_write(struct file *file, const char *buffer, size_t count, loff_t *data)
4573 {
4574 char desc[32];
4575 int len = 0;
4576
4577 char cmd[10];
4578 int id;
4579 int force_off;
4580 int err = 0;
4581
4582 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
4583 if (copy_from_user(desc, buffer, len))
4584 return 0;
4585
4586 desc[len] = '\0';
4587
4588 if (sscanf(desc, "%s %d %d", cmd, &id, &force_off) == 3) {
4589 if (!strcmp(cmd, "disable"))
4590 err = disable_subsys_force(id, "test");
4591 } else if (sscanf(desc, "%s %d", cmd, &id) == 2) {
4592 if (!strcmp(cmd, "enable"))
4593 err = enable_subsys(id, "test");
4594 else if (!strcmp(cmd, "disable"))
4595 err = disable_subsys(id, "test");
4596 }
4597
4598 clk_info("[%s]%s subsys %d: result is %d\n", __func__, cmd, id, err);
4599
4600 return count;
4601 }
4602
4603
4604 static const struct file_operations subsys_test_fops = {
4605 .owner = THIS_MODULE,
4606 .write = subsys_test_write,
4607 .open = subsys_test_open,
4608 .read = seq_read,
4609 .llseek = seq_lseek,
4610 .release = seq_release
4611 };
4612
4613
4614 #ifdef CONFIG_CLKMGR_STAT
4615
4616
4617 static int subsys_stat_show(struct seq_file *s, void *v)
4618 {
4619 struct subsys *sys;
4620 struct list_head *pos;
4621 struct stat_node *node;
4622 int i;
4623
4624 seq_printf(s, "\n********** subsys stat dump **********\n");
4625 for (i = 0; i < NR_SYSS; i++) {
4626 sys = id_to_sys(i);
4627 seq_printf(s, "[%d][%-7s]state=%u", i, sys->name, sys->state);
4628 list_for_each(pos, &sys->head) {
4629 node = list_entry(pos, struct stat_node, link);
4630 seq_printf(s, "\t(%s,%u,%u)", node->name, node->cnt_on, node->cnt_off);
4631 }
4632 seq_printf(s, "\n");
4633 }
4634
4635 seq_printf(s, "\n********** subsys_dump help **********\n");
4636
4637 return 0;
4638 }
4639
4640
4641 static int subsys_stat_open(struct inode *inode, struct file *file)
4642 {
4643 return single_open(file, subsys_stat_show, NULL);
4644 }
4645
4646
4647 static const struct file_operations subsys_stat_fops = {
4648 .owner = THIS_MODULE,
4649 .open = subsys_stat_open,
4650 .read = seq_read,
4651 .llseek = seq_lseek,
4652 .release = seq_release
4653 };
4654
4655
4656 #endif
4657
4658
4659 #if CLKMGR_8127
4660
4661
4662 #define MAX_MUX_CLKSRC 12
4663
4664
4665 enum FMETER_TYPE {
4666 ABIST,
4667 CKGEN
4668 };
4669
4670
4671 static const char * const ABIST_CLK_NAME[] = {
4672 [ABIST_AD_MAIN_H546M_CK] = "AD_MAIN_H546M_CK",
4673 [ABIST_AD_MAIN_H364M_CK] = "AD_MAIN_H364M_CK",
4674 [ABIST_AD_MAIN_H218P4M_CK] = "AD_MAIN_H218P4M_CK",
4675 [ABIST_AD_MAIN_H156M_CK] = "AD_MAIN_H156M_CK",
4676 [ABIST_AD_UNIV_624M_CK] = "AD_UNIV_624M_CK",
4677 [ABIST_AD_UNIV_416M_CK] = "AD_UNIV_416M_CK",
4678 [ABIST_AD_UNIV_249P6M_CK] = "AD_UNIV_249P6M_CK",
4679 [ABIST_AD_UNIV_178P3M_CK] = "AD_UNIV_178P3M_CK",
4680 [ABIST_AD_UNIV_48M_CK] = "AD_UNIV_48M_CK",
4681 [ABIST_AD_USB_48M_CK] = "AD_USB_48M_CK",
4682 [ABIST_AD_MMPLL_CK] = "AD_MMPLL_CK",
4683 [ABIST_AD_MSDCPLL_CK] = "AD_MSDCPLL_CK",
4684 [ABIST_AD_DPICLK] = "AD_DPICLK",
4685 [ABIST_CLKPH_MCK_O] = "clkph_mck_o",
4686 [ABIST_AD_MEMPLL2_CKOUT0_PRE_ISO] = "AD_MEMPLL2_CKOUT0_PRE_ISO",
4687 [ABIST_AD_MCUPLL1_H481M_CK] = "AD_MCUPLL1_H481M_CK",
4688 [ABIST_AD_MDPLL1_416M_CK] = "AD_MDPLL1_416M_CK",
4689 [ABIST_AD_WPLL_CK] = "AD_WPLL_CK",
4690 [ABIST_AD_WHPLL_CK] = "AD_WHPLL_CK",
4691 [ABIST_RTC32K_CK_I] = "rtc32k_ck_i",
4692 [ABIST_AD_SYS_26M_CK] = "AD_SYS_26M_CK",
4693 [ABIST_AD_VENCPLL_CK] = "AD_VENCPLL_CK",
4694 [ABIST_AD_MIPI_26M_CK] = "AD_MIPI_26M_CK",
4695 [ABIST_AD_MEM_26M_CK] = "AD_MEM_26M_CK",
4696 [ABIST_AD_PLLGP_TST_CK] = "AD_PLLGP_TST_CK",
4697 [ABIST_AD_DSI0_LNTC_DSICLK] = "AD_DSI0_LNTC_DSICLK",
4698 [ABIST_AD_MPPLL_TST_CK] = "AD_MPPLL_TST_CK",
4699 [ABIST_ARMPLL_OCC_MON] = "armpll_occ_mon",
4700 [ABIST_AD_MEM2MIPI_26M_CK] = "AD_MEM2MIPI_26M_CK",
4701 [ABIST_AD_MEMPLL_MONCLK] = "AD_MEMPLL_MONCLK",
4702 [ABIST_AD_MEMPLL2_MONCLK] = "AD_MEMPLL2_MONCLK",
4703 [ABIST_AD_MEMPLL3_MONCLK] = "AD_MEMPLL3_MONCLK",
4704 [ABIST_AD_MEMPLL4_MONCLK] = "AD_MEMPLL4_MONCLK",
4705 [ABIST_AD_MEMPLL_REFCLK] = "AD_MEMPLL_REFCLK",
4706 [ABIST_AD_MEMPLL_FBCLK] = "AD_MEMPLL_FBCLK",
4707 [ABIST_AD_MEMPLL2_REFCLK] = "AD_MEMPLL2_REFCLK",
4708 [ABIST_AD_MEMPLL2_FBCLK] = "AD_MEMPLL2_FBCLK",
4709 [ABIST_AD_MEMPLL3_REFCLK] = "AD_MEMPLL3_REFCLK",
4710 [ABIST_AD_MEMPLL3_FBCLK] = "AD_MEMPLL3_FBCLK",
4711 [ABIST_AD_MEMPLL4_REFCLK] = "AD_MEMPLL4_REFCLK",
4712 [ABIST_AD_MEMPLL4_FBCLK] = "AD_MEMPLL4_FBCLK",
4713 [ABIST_AD_MEMPLL_TSTDIV2_CK] = "AD_MEMPLL_TSTDIV2_CK",
4714 [ABIST_AD_LVDSPLL_CK] = "AD_LVDSPLL_CK",
4715 [ABIST_AD_LVDSTX_MONCLK] = "AD_LVDSTX_MONCLK",
4716 [ABIST_AD_HDMITX_MONCLK] = "AD_HDMITX_MONCLK",
4717 [ABIST_AD_USB20_C240M] = "AD_USB20_C240M",
4718 [ABIST_AD_USB20_C240M_1P] = "AD_USB20_C240M_1P",
4719 [ABIST_AD_MONREF_CK] = "AD_MONREF_CK",
4720 [ABIST_AD_MONFBK_CK] = "AD_MONFBK_CK",
4721 [ABIST_AD_TVDPLL_CK] = "AD_TVDPLL_CK",
4722 [ABIST_AD_AUDPLL_CK] = "AD_AUDPLL_CK",
4723 [ABIST_AD_LVDSPLL_ETH_CK] = "AD_LVDSPLL_ETH_CK",
4724 };
4725
4726
4727 static const char * const CKGEN_CLK_NAME[] = {
4728 [CKGEN_HF_FAXI_CK] = "hf_faxi_ck",
4729 [CKGEN_HD_FAXI_CK] = "hd_faxi_ck",
4730 [CKGEN_HF_FNFI2X_CK] = "hf_fnfi2x_ck",
4731 [CKGEN_HF_FDDRPHYCFG_CK] = "hf_fddrphycfg_ck",
4732 [CKGEN_HF_FMM_CK] = "hf_fmm_ck",
4733 [CKGEN_F_FPWM_CK] = "f_fpwm_ck",
4734 [CKGEN_HF_FVDEC_CK] = "hf_fvdec_ck",
4735 [CKGEN_HF_FMFG_CK] = "hf_fmfg_ck",
4736 [CKGEN_HF_FCAMTG_CK] = "hf_fcamtg_ck",
4737 [CKGEN_F_FUART_CK] = "f_fuart_ck",
4738 [CKGEN_HF_FSPI_CK] = "hf_fspi_ck",
4739 [CKGEN_F_FUSB20_CK] = "f_fusb20_ck",
4740 [CKGEN_HF_FMSDC30_0_CK] = "hf_fmsdc30_0_ck",
4741 [CKGEN_HF_FMSDC30_1_CK] = "hf_fmsdc30_1_ck",
4742 [CKGEN_HF_FMSDC30_2_CK] = "hf_fmsdc30_2_ck",
4743 [CKGEN_HF_FAUDIO_CK] = "hf_faudio_ck",
4744 [CKGEN_HF_FAUD_INTBUS_CK] = "hf_faud_intbus_ck",
4745 [CKGEN_HF_FPMICSPI_CK] = "hf_fpmicspi_ck",
4746 [CKGEN_F_FRTC_CK] = "f_frtc_ck",
4747 [CKGEN_F_F26M_CK] = "f_f26m_ck",
4748 [CKGEN_F_F32K_MD1_CK] = "f_f32k_md1_ck",
4749 [CKGEN_F_FRTC_CONN_CK] = "f_frtc_conn_ck",
4750 [CKGEN_HF_FETH_50M_CK] = "hf_feth_50m_ck",
4751 [CKGEN_HD_HAXI_NLI_CK] = "hd_haxi_nli_ck",
4752 [CKGEN_HD_QAXIDCM_CK] = "hd_qaxidcm_ck",
4753 [CKGEN_F_FFPC_CK] = "f_ffpc_ck",
4754 [CKGEN_HF_FDPI0_CK] = "hf_fdpi0_ck",
4755 [CKGEN_F_FCKBUS_CK_SCAN] = "f_fckbus_ck_scan",
4756 [CKGEN_F_FCKRTC_CK_SCAN] = "f_fckrtc_ck_scan",
4757 [CKGEN_HF_FDPILVDS_CK] = "hf_fdpilvds_ck",
4758 };
4759
4760
4761 enum mux_clksrc_id {
4762 mux_clksrc_null,
4763
4764 external_32k,
4765 internal_32k,
4766 audpll,
4767 audpll_d16,
4768 audpll_d24,
4769 audpll_d4,
4770 audpll_d8,
4771 clk26m,
4772 dmpll_ck,
4773 dmpll_d2,
4774 dmpll_d4,
4775 dmpll_x2_ck,
4776 f_f26m_ck,
4777 fpc_ck,
4778 hdmipll,
4779 hdmipll_d2,
4780 hdmipll_d3,
4781 lvdspll,
4782 lvdspll_d2,
4783 lvdspll_d4,
4784 lvdspll_d8,
4785 lvdspll_eth,
4786 mipipll,
4787 mipipll_d2,
4788 mipipll_d4,
4789 mmpll_ck,
4790 mmpll_d2,
4791 msdcpll_ck,
4792 msdcpll_d2,
4793 syspll1_d16,
4794 syspll1_d2,
4795 syspll1_d4,
4796 syspll1_d8,
4797 syspll2_d2,
4798 syspll2_d4,
4799 syspll2_d8,
4800 syspll3_d2,
4801 syspll3_d4,
4802 syspll4_d2,
4803 syspll4_d4,
4804 syspll_d3,
4805 syspll_d5,
4806 syspll_d7,
4807 tvdpll,
4808 tvdpll_d2,
4809 tvdpll_d4,
4810 univpll1_d2,
4811 univpll1_d4,
4812 univpll1_d8,
4813 univpll2_d2,
4814 univpll2_d4,
4815 univpll2_d8,
4816 univpll3_d2,
4817 univpll3_d4,
4818 univpll3_d8,
4819 univpll_d26,
4820 univpll_d3,
4821 univpll_d5,
4822 vencpll_ck,
4823
4824 mux_clksrc_end
4825 };
4826
4827
4828 struct mux_t {
4829 enum CKGEN_CLK ckgen_clk;
4830 enum mux_clksrc_id clksrc[MAX_MUX_CLKSRC];
4831 };
4832
4833
4834 static const char * const clksrc_name[] = {
4835 [external_32k] = "32k_external",
4836 [internal_32k] = "32k_internal",
4837 [audpll] = "audpll",
4838 [audpll_d16] = "audpll_d16",
4839 [audpll_d24] = "audpll_d24",
4840 [audpll_d4] = "audpll_d4",
4841 [audpll_d8] = "audpll_d8",
4842 [clk26m] = "clk26m",
4843 [dmpll_ck] = "dmpll_ck",
4844 [dmpll_d2] = "dmpll_d2",
4845 [dmpll_d4] = "dmpll_d4",
4846 [dmpll_x2_ck] = "dmpll_x2_ck",
4847 [f_f26m_ck] = "f_f26m_ck",
4848 [fpc_ck] = "fpc_ck",
4849 [hdmipll] = "hdmipll",
4850 [hdmipll_d2] = "hdmipll_d2",
4851 [hdmipll_d3] = "hdmipll_d3",
4852 [lvdspll] = "lvdspll",
4853 [lvdspll_d2] = "lvdspll_d2",
4854 [lvdspll_d4] = "lvdspll_d4",
4855 [lvdspll_d8] = "lvdspll_d8",
4856 [lvdspll_eth] = "lvdspll_eth",
4857 [mipipll] = "mipipll",
4858 [mipipll_d2] = "mipipll_d2",
4859 [mipipll_d4] = "mipipll_d4",
4860 [mmpll_ck] = "mmpll_ck",
4861 [mmpll_d2] = "mmpll_d2",
4862 [msdcpll_ck] = "msdcpll_ck",
4863 [msdcpll_d2] = "msdcpll_d2",
4864 [syspll1_d16] = "syspll1_d16",
4865 [syspll1_d2] = "syspll1_d2",
4866 [syspll1_d4] = "syspll1_d4",
4867 [syspll1_d8] = "syspll1_d8",
4868 [syspll2_d2] = "syspll2_d2",
4869 [syspll2_d4] = "syspll2_d4",
4870 [syspll2_d8] = "syspll2_d8",
4871 [syspll3_d2] = "syspll3_d2",
4872 [syspll3_d4] = "syspll3_d4",
4873 [syspll4_d2] = "syspll4_d2",
4874 [syspll4_d4] = "syspll4_d4",
4875 [syspll_d3] = "syspll_d3",
4876 [syspll_d5] = "syspll_d5",
4877 [syspll_d7] = "syspll_d7",
4878 [tvdpll] = "tvdpll",
4879 [tvdpll_d2] = "tvdpll_d2",
4880 [tvdpll_d4] = "tvdpll_d4",
4881 [univpll1_d2] = "univpll1_d2",
4882 [univpll1_d4] = "univpll1_d4",
4883 [univpll1_d8] = "univpll1_d8",
4884 [univpll2_d2] = "univpll2_d2",
4885 [univpll2_d4] = "univpll2_d4",
4886 [univpll2_d8] = "univpll2_d8",
4887 [univpll3_d2] = "univpll3_d2",
4888 [univpll3_d4] = "univpll3_d4",
4889 [univpll3_d8] = "univpll3_d8",
4890 [univpll_d26] = "univpll_d26",
4891 [univpll_d3] = "univpll_d3",
4892 [univpll_d5] = "univpll_d5",
4893 [vencpll_ck] = "vencpll_ck",
4894 };
4895
4896
4897 static struct mux_t g_mux[] = {
4898 [MT_MUX_MM] = {.ckgen_clk = CKGEN_HF_FMM_CK,
4899 .clksrc = {
4900 [0] = clk26m,
4901 [1] = vencpll_ck,
4902 [2] = syspll1_d2,
4903 [3] = syspll1_d4,
4904 [4] = univpll_d5,
4905 [5] = univpll1_d2,
4906 [6] = univpll2_d2,
4907 [7] = dmpll_ck
4908 },
4909 },
4910 [MT_MUX_DDRPHYCFG] = {.ckgen_clk = CKGEN_HF_FDDRPHYCFG_CK,
4911 .clksrc = {
4912 [0] = clk26m,
4913 [1] = syspll1_d8,
4914 },
4915 },
4916 [MT_MUX_MEM] = {
4917 .clksrc = {
4918 [0] = clk26m,
4919 [1] = dmpll_ck,
4920 },
4921 },
4922 [MT_MUX_AXI] = {.ckgen_clk = CKGEN_HF_FAXI_CK,
4923 .clksrc = {
4924 [0] = clk26m,
4925 [1] = syspll1_d2,
4926 [2] = syspll_d5,
4927 [3] = syspll1_d4,
4928 [4] = univpll_d5,
4929 [5] = univpll2_d2,
4930 [6] = dmpll_ck,
4931 [7] = dmpll_d2,
4932 },
4933 },
4934 [MT_MUX_CAMTG] = {.ckgen_clk = CKGEN_HF_FCAMTG_CK,
4935 .clksrc = {
4936 [0] = clk26m,
4937 [1] = univpll_d26,
4938 [2] = univpll2_d2,
4939 [3] = syspll3_d2,
4940 [4] = syspll3_d4,
4941 [5] = msdcpll_d2,
4942 [6] = mmpll_d2,
4943 },
4944 },
4945 [MT_MUX_MFG] = {.ckgen_clk = CKGEN_HF_FMFG_CK,
4946 .clksrc = {
4947 [0] = clk26m,
4948 [1] = mmpll_ck,
4949 [2] = dmpll_x2_ck,
4950 [3] = msdcpll_ck,
4951 [4] = clk26m,
4952 [5] = syspll_d3,
4953 [6] = univpll_d3,
4954 [7] = univpll1_d2,
4955 },
4956 },
4957 [MT_MUX_VDEC] = {.ckgen_clk = CKGEN_HF_FVDEC_CK,
4958 .clksrc = {
4959 [0] = clk26m,
4960 [1] = syspll1_d2,
4961 [2] = syspll_d5,
4962 [3] = syspll1_d4,
4963 [4] = univpll_d5,
4964 [5] = univpll2_d2,
4965 [6] = univpll2_d4,
4966 [7] = msdcpll_d2,
4967 [8] = mmpll_d2,
4968 },
4969 },
4970 [MT_MUX_PWM] = {.ckgen_clk = CKGEN_F_FPWM_CK,
4971 .clksrc = {
4972 [0] = clk26m,
4973 [1] = univpll2_d4,
4974 [2] = univpll3_d2,
4975 [3] = univpll1_d4,
4976 },
4977 },
4978 [MT_MUX_MSDC30_0] = {.ckgen_clk = CKGEN_HF_FMSDC30_0_CK,
4979 .clksrc = {
4980 [0] = clk26m,
4981 [1] = msdcpll_d2,
4982 [2] = syspll2_d2,
4983 [3] = syspll1_d4,
4984 [4] = univpll1_d4,
4985 [5] = univpll2_d4,
4986 },
4987 },
4988 [MT_MUX_USB20] = {.ckgen_clk = CKGEN_F_FUSB20_CK,
4989 .clksrc = {
4990 [0] = clk26m,
4991 [1] = univpll1_d8,
4992 [2] = univpll3_d4,
4993 },
4994 },
4995 [MT_MUX_SPI] = {.ckgen_clk = CKGEN_HF_FSPI_CK,
4996 .clksrc = {
4997 [0] = clk26m,
4998 [1] = syspll3_d2,
4999 [2] = syspll4_d2,
5000 [3] = univpll2_d4,
5001 [4] = univpll1_d8,
5002 },
5003 },
5004 [MT_MUX_UART] = {.ckgen_clk = CKGEN_F_FUART_CK,
5005 .clksrc = {
5006 [0] = clk26m,
5007 [1] = univpll2_d8,
5008 },
5009 },
5010 [MT_MUX_AUDINTBUS] = {.ckgen_clk = CKGEN_HF_FAUD_INTBUS_CK,
5011 .clksrc = {
5012 [0] = clk26m,
5013 [1] = syspll1_d4,
5014 [2] = syspll3_d2,
5015 [3] = syspll4_d2,
5016 [4] = univpll3_d2,
5017 [5] = univpll2_d4,
5018 },
5019 },
5020 [MT_MUX_AUDIO] = {.ckgen_clk = CKGEN_HF_FAUDIO_CK,
5021 .clksrc = {
5022 [0] = f_f26m_ck,
5023 [1] = syspll1_d16,
5024 },
5025 },
5026 [MT_MUX_MSDC30_2] = {.ckgen_clk = CKGEN_HF_FMSDC30_2_CK,
5027 .clksrc = {
5028 [0] = clk26m,
5029 [1] = msdcpll_d2,
5030 [2] = syspll2_d2,
5031 [3] = syspll1_d4,
5032 [4] = univpll1_d4,
5033 [5] = univpll2_d4,
5034 },
5035 },
5036 [MT_MUX_MSDC30_1] = {.ckgen_clk = CKGEN_HF_FMSDC30_1_CK,
5037 .clksrc = {
5038 [0] = clk26m,
5039 [1] = msdcpll_d2,
5040 [2] = syspll2_d2,
5041 [3] = syspll1_d4,
5042 [4] = univpll1_d4,
5043 [5] = univpll2_d4,
5044 },
5045 },
5046 [MT_MUX_DPI1] = {
5047 .clksrc = {
5048 [0] = clk26m,
5049 [1] = tvdpll,
5050 [2] = tvdpll_d2,
5051 [3] = tvdpll_d4,
5052 },
5053 },
5054 [MT_MUX_DPI0] = {.ckgen_clk = CKGEN_HF_FDPI0_CK,
5055 .clksrc = {
5056 [0] = clk26m,
5057 [1] = mipipll,
5058 [2] = mipipll_d2,
5059 [3] = mipipll_d4,
5060 [4] = lvdspll,
5061 [5] = lvdspll_d2,
5062 [6] = lvdspll_d4,
5063 [7] = lvdspll_d8,
5064 },
5065 },
5066 [MT_MUX_SCP] = {
5067 .clksrc = {
5068 [0] = clk26m,
5069 [1] = syspll1_d8,
5070 [2] = dmpll_d2,
5071 [3] = dmpll_d4,
5072 },
5073 },
5074 [MT_MUX_PMICSPI] = {.ckgen_clk = CKGEN_HF_FPMICSPI_CK,
5075 .clksrc = {
5076 [0] = clk26m,
5077 [1] = syspll1_d8,
5078 [2] = syspll2_d4,
5079 [3] = syspll4_d2,
5080 [4] = syspll3_d4,
5081 [5] = syspll2_d8,
5082 [6] = syspll1_d16,
5083 [7] = univpll3_d4,
5084 [8] = univpll_d26,
5085 [9] = dmpll_d2,
5086 [10] = dmpll_d4,
5087 },
5088 },
5089 [MT_MUX_DPILVDS] = {.ckgen_clk = CKGEN_HF_FDPILVDS_CK,
5090 .clksrc = {
5091 [0] = clk26m,
5092 [1] = lvdspll,
5093 [2] = lvdspll_d2,
5094 [3] = lvdspll_d4,
5095 [4] = lvdspll_d8,
5096 [5] = fpc_ck,
5097 [6] = clk26m,
5098 [7] = clk26m,
5099 },
5100 },
5101 [MT_MUX_APLL] = {
5102 .clksrc = {
5103 [0] = clk26m,
5104 [1] = audpll,
5105 [2] = audpll_d4,
5106 [3] = audpll_d8,
5107 [4] = audpll_d16,
5108 [5] = audpll_d24,
5109 [6] = clk26m,
5110 [7] = clk26m,
5111 },
5112 },
5113 [MT_MUX_HDMI] = {
5114 .clksrc = {
5115 [0] = clk26m,
5116 [1] = hdmipll,
5117 [2] = hdmipll_d2,
5118 [3] = hdmipll_d3,
5119 },
5120 },
5121 [MT_MUX_TVE] = {
5122 .clksrc = {
5123 [0] = clk26m,
5124 [1] = mipipll,
5125 [2] = mipipll_d2,
5126 [3] = mipipll_d4,
5127 [4] = clk26m,
5128 [5] = tvdpll,
5129 [6] = tvdpll_d2,
5130 [7] = tvdpll_d4,
5131 },
5132 },
5133 [MT_MUX_ETH_50M] = {.ckgen_clk = CKGEN_HF_FETH_50M_CK,
5134 .clksrc = {
5135 [0] = clk26m,
5136 [1] = syspll3_d4,
5137 [2] = univpll2_d8,
5138 [3] = lvdspll_eth,
5139 [4] = univpll_d26,
5140 [5] = syspll2_d8,
5141 [6] = syspll4_d4,
5142 [7] = univpll3_d8,
5143 },
5144 },
5145 [MT_MUX_NFI2X] = {.ckgen_clk = CKGEN_HF_FNFI2X_CK,
5146 .clksrc = {
5147 [0] = clk26m,
5148 [1] = syspll2_d2,
5149 [2] = syspll_d7,
5150 [3] = univpll3_d2,
5151 [4] = syspll2_d4,
5152 [5] = univpll3_d4,
5153 [6] = syspll4_d4,
5154 [7] = clk26m,
5155 },
5156 },
5157 [MT_MUX_RTC] = {.ckgen_clk = CKGEN_F_FRTC_CK,
5158 .clksrc = {
5159 [0] = internal_32k,
5160 [1] = external_32k,
5161 [2] = clk26m,
5162 [3] = univpll3_d8,
5163 },
5164 },
5165 };
5166
5167
5168 static void seq_printf_mux(struct seq_file *s, int mux_id)
5169 {
5170 int reg_value;
5171 int mux_value;
5172 int mux_pdn;
5173 const char *mux_en;
5174 const char *mux_clksrc;
5175
5176 struct clkmux *mux = id_to_mux(mux_id);
5177 if (!mux)
5178 return;
5179
5180 reg_value = clk_readl(mux->base_addr);
5181 mux_value = (reg_value & mux->sel_mask) >> mux->offset;
5182 mux_pdn = reg_value & mux->pdn_mask;
5183 mux_en = mux_pdn ? "off" : "ON";
5184 mux_clksrc = clksrc_name[g_mux[mux_id].clksrc[mux_value]];
5185
5186 seq_printf(s, "[ %2d, %2d, %3s, %-16s, %2d: %-12s ]\n",
5187 mux_id, mux->cnt, mux_en, mux->name, mux_value, mux_clksrc);
5188 }
5189
5190
5191 #endif /* CLKMGR_8127 */
5192
5193
5194 static int mux_test_show(struct seq_file *s, void *v)
5195 {
5196 #if CLKMGR_8127
5197 int i;
5198 for (i = 0; i < NR_MUXS; i++)
5199 seq_printf_mux(s, i);
5200 #endif /* CLKMGR_8127 */
5201
5202 seq_printf(s, "********** mux register dump *********\n");
5203 seq_printf(s, "[CLK_CFG_0] =0x%08x\n", clk_readl(CLK_CFG_0));
5204 seq_printf(s, "[CLK_CFG_1] =0x%08x\n", clk_readl(CLK_CFG_1));
5205 seq_printf(s, "[CLK_CFG_2] =0x%08x\n", clk_readl(CLK_CFG_2));
5206 seq_printf(s, "[CLK_CFG_3] =0x%08x\n", clk_readl(CLK_CFG_3));
5207 seq_printf(s, "[CLK_CFG_4] =0x%08x\n", clk_readl(CLK_CFG_4));
5208 seq_printf(s, "[CLK_CFG_5] =0x%08x\n", clk_readl(CLK_CFG_5));
5209 seq_printf(s, "[CLK_CFG_6] =0x%08x\n", clk_readl(CLK_CFG_6));
5210 seq_printf(s, "[CLK_CFG_8] =0x%08x\n", clk_readl(CLK_CFG_8));
5211 seq_printf(s, "[CLK_CFG_9] =0x%08x\n", clk_readl(CLK_CFG_9));
5212 seq_printf(s, "[CLK_CFG_10]=0x%08x\n", clk_readl(CLK_CFG_10));
5213 seq_printf(s, "[CLK_CFG_11]=0x%08x\n", clk_readl(CLK_CFG_11));
5214
5215 seq_printf(s, "\n********** mux_test help *********\n");
5216 seq_printf(s, "clkmux : echo clkmux mux_id val [mod_name] > /proc/clkmgr/mux_test\n");
5217 seq_printf(s, "enable mux: echo enable mux_id [mod_name] > /proc/clkmgr/mux_test\n");
5218 seq_printf(s, "disable mux: echo disable mux_id [mod_name] > /proc/clkmgr/mux_test\n");
5219
5220 return 0;
5221 }
5222
5223
5224 static int mux_test_open(struct inode *inode, struct file *file)
5225 {
5226 return single_open(file, mux_test_show, NULL);
5227 }
5228
5229
5230 #if CLKMGR_8127
5231
5232
5233 static int mux_test_write(struct file *file, const char *buffer, size_t count, loff_t *data)
5234 {
5235 char desc[32];
5236 int len = 0;
5237
5238 char cmd[10];
5239 char mod_name[10];
5240 int mux_id;
5241 int val;
5242
5243 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
5244
5245 if (copy_from_user(desc, buffer, len))
5246 return 0;
5247
5248 desc[len] = '\0';
5249
5250 if (sscanf(desc, "%s %d %d %s", cmd, &mux_id, &val, mod_name) == 4) {
5251 if (!strcmp(cmd, "clkmux"))
5252 clkmux_sel(mux_id, val, mod_name);
5253 } else if (sscanf(desc, "%s %d %s", cmd, &mux_id, mod_name) == 3) {
5254 if (!strcmp(cmd, "enable"))
5255 enable_mux(mux_id, mod_name);
5256 else if (!strcmp(cmd, "disable"))
5257 disable_mux(mux_id, mod_name);
5258 } else if (sscanf(desc, "%s %d", cmd, &mux_id) == 2) {
5259 if (!strcmp(cmd, "enable"))
5260 enable_mux(mux_id, "mux_test");
5261 else if (!strcmp(cmd, "disable"))
5262 disable_mux(mux_id, "mux_test");
5263 }
5264
5265 return count;
5266 }
5267
5268
5269 #endif /* CLKMGR_8127 */
5270
5271
5272 static const struct file_operations mux_test_fops = {
5273 .owner = THIS_MODULE,
5274 .write = mux_test_write,
5275 .open = mux_test_open,
5276 .read = seq_read,
5277 .llseek = seq_lseek,
5278 .release = seq_release
5279 };
5280
5281
5282 #ifdef CONFIG_CLKMGR_STAT
5283
5284
5285 static int mux_stat_show(struct seq_file *s, void *v)
5286 {
5287 struct clkmux *mux;
5288 struct list_head *pos;
5289 struct stat_node *node;
5290 int i;
5291
5292 seq_printf(s, "********** mux stat dump **********\n");
5293 for (i = 0; i < NR_MUXS; i++) {
5294 mux = id_to_mux(i);
5295
5296 seq_printf(s, "[%02d][%-14s]cnt=%u", i, mux->name, mux->cnt);
5297
5298 list_for_each(pos, &mux->head) {
5299 node = list_entry(pos, struct stat_node, link);
5300 seq_printf(s, "\t(%s,%u,%u)", node->name, node->cnt_on, node->cnt_off);
5301 }
5302 seq_printf(s, "\n");
5303 }
5304
5305 seq_printf(s, "\n********** mux_dump help **********\n");
5306
5307 return 0;
5308 }
5309
5310
5311 static int mux_stat_open(struct inode *inode, struct file *file)
5312 {
5313 return single_open(file, mux_stat_show, NULL);
5314 }
5315
5316
5317 static const struct file_operations mux_stat_fops = {
5318 .owner = THIS_MODULE,
5319 .open = mux_stat_open,
5320 .read = seq_read,
5321 .llseek = seq_lseek,
5322 .release = seq_release
5323 };
5324
5325
5326 #endif
5327
5328
5329 static int clk_test_read(char *page, char **start, off_t off,
5330 int count, int *eof, void *data)
5331 {
5332 char *p = page;
5333 int len = 0;
5334
5335 int i;
5336 int cnt;
5337 unsigned int value[2];
5338 const char *name;
5339
5340 p += sprintf(p, "********** clk register dump **********\n");
5341
5342 for (i = 0; i < NR_GRPS; i++) {
5343 name = grp_get_name(i);
5344 cnt = grp_dump_regs(i, value);
5345 if (cnt == 1)
5346 p += sprintf(p, "[%02d][%-8s]=[0x%08x]\n", i, name, value[0]);
5347 else
5348 p += sprintf(p, "[%02d][%-8s]=[0x%08x][0x%08x]\n", i, name, value[0], value[1]);
5349 }
5350
5351 p += sprintf(p, "\n********** clk_test help **********\n");
5352 p += sprintf(p, "enable clk: echo enable id [mod_name] > /proc/clkmgr/clk_test\n");
5353 p += sprintf(p, "disable clk: echo disable id [mod_name] > /proc/clkmgr/clk_test\n");
5354 p += sprintf(p, "read state: echo id > /proc/clkmgr/clk_test\n");
5355
5356 *start = page + off;
5357
5358 len = p - page;
5359 if (len > off)
5360 len -= off;
5361 else
5362 len = 0;
5363
5364 *eof = 1;
5365 return len < count ? len : count;
5366 }
5367
5368 static int clk_test_write(struct file *file, const char *buffer,
5369 size_t count, loff_t *data)
5370 {
5371 char desc[32];
5372 int len = 0;
5373
5374 char cmd[10];
5375 char mod_name[10];
5376 int id;
5377 int err;
5378
5379 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
5380 if (copy_from_user(desc, buffer, len))
5381 return 0;
5382
5383 desc[len] = '\0';
5384
5385 if (sscanf(desc, "%s %d %s", cmd, &id, mod_name) == 3) {
5386 if (!strcmp(cmd, "enable"))
5387 err = enable_clock(id, mod_name);
5388 else if (!strcmp(cmd, "disable"))
5389 err = disable_clock(id, mod_name);
5390 } else if (sscanf(desc, "%s %d", cmd, &id) == 2) {
5391 if (!strcmp(cmd, "enable"))
5392 err = enable_clock(id, "pll_test");
5393 else if (!strcmp(cmd, "disable"))
5394 err = disable_clock(id, "pll_test");
5395 } else if (sscanf(desc, "%d", &id) == 1)
5396 clk_info("clock %d is %s\n", id, clock_is_on(id) ? "on" : "off");
5397
5398 return count;
5399 }
5400
5401
5402 #if CLKMGR_8127
5403
5404 static void *clk_test_seq_start(struct seq_file *s, loff_t *pos)
5405 {
5406 loff_t *spos;
5407
5408 if (*pos >= NR_CLKS + 1)
5409 return NULL;
5410
5411 spos = kmalloc(sizeof(loff_t), GFP_KERNEL);
5412 if (!spos)
5413 return NULL;
5414
5415 *spos = *pos;
5416 return spos;
5417 }
5418
5419
5420 static void *clk_test_seq_next(struct seq_file *s, void *v, loff_t *pos)
5421 {
5422 loff_t *spos = (loff_t *)v;
5423 loff_t i = *spos;
5424
5425 if (i == NR_CLKS)
5426 ++i;
5427 else {
5428 while (i < NR_CLKS && clks[++i].name == NULL)
5429 ;
5430 }
5431
5432 *pos = i;
5433 *spos = i;
5434
5435 if (*pos >= NR_CLKS + 1)
5436 return NULL;
5437
5438 return spos;
5439 }
5440
5441
5442 static void clk_test_seq_stop(struct seq_file *s, void *v)
5443 {
5444 kfree(v);
5445 }
5446
5447
5448 static int clk_test_seq_show(struct seq_file *s, void *v)
5449 {
5450 loff_t *spos = (loff_t *)v;
5451 loff_t i = *spos;
5452 struct cg_clk *clk = &clks[i];
5453
5454 if (i < NR_CLKS) {
5455 seq_printf(s, "[ %3lld,%3d,%4s, 0x%08X, %-29s, %-29s, %-8s, %-16s ]\n",
5456 i,
5457 clk->cnt,
5458 clk->state ? "ON" : "off",
5459 clk->mask,
5460 clk->name ? clk->name : "",
5461 clk->parent ? clk->parent->name : "",
5462 clk->grp ? clk->grp->name : "",
5463 clk->mux ? clk->mux->name : "");
5464 } else {
5465 const int PS = 1280;
5466 char page[PS];
5467 char *start = NULL;
5468 int eof = 0;
5469 clk_test_read(page, &start, 0, PS, &eof, NULL);
5470 seq_puts(s, page);
5471 }
5472
5473 return 0;
5474 }
5475
5476
5477 static const struct seq_operations clk_test_seq_ops = {
5478 .start = clk_test_seq_start,
5479 .next = clk_test_seq_next,
5480 .stop = clk_test_seq_stop,
5481 .show = clk_test_seq_show
5482 };
5483
5484
5485 static int clk_test_open(struct inode *inode, struct file *file)
5486 {
5487 return seq_open(file, &clk_test_seq_ops);
5488 };
5489
5490
5491 static const struct file_operations clk_test_fops = {
5492 .owner = THIS_MODULE,
5493 .write = clk_test_write,
5494 .open = clk_test_open,
5495 .read = seq_read,
5496 .llseek = seq_lseek,
5497 .release = seq_release
5498 };
5499
5500
5501 #endif /* CLKMGR_8127 */
5502
5503
5504 #if CLKMGR_8127
5505
5506
5507 static void set_fmeter_divider(uint32_t k1)
5508 {
5509 uint32_t v = k1 << 24 | 0xFF << 16 | k1 << 8 | k1;
5510 clk_writel(CLK_MISC_CFG_1, v);
5511 }
5512
5513
5514 static uint32_t fmeter_freq(enum FMETER_TYPE type, int k1, int clk)
5515 {
5516 int i;
5517 uint32_t freq = 0;
5518
5519 uint32_t clk_cfg_reg = (type == CKGEN) ? CLK_CFG_9 : CLK_CFG_8;
5520 uint32_t cksw_mask = (type == CKGEN) ? BITMASK(20 : 16) : BITMASK(13 : 8);
5521 uint32_t cksw_val = (type == CKGEN) ? BITS(20 : 16, clk) : BITS(13 : 8, clk);
5522 uint32_t tri_bit = (type == CKGEN) ? BIT(4) : BIT(0);
5523 uint32_t cnt_reg = (type == CKGEN) ? CLK26CALI_2 : CLK26CALI_1;
5524 uint32_t clk_misc_cfg_1;
5525 uint32_t clk_cfg_val;
5526
5527 /* setup fmeter */
5528 clk_setl(CLK26CALI_0, BIT(7)); /* enable fmeter_en */
5529
5530 clk_misc_cfg_1 = clk_readl(CLK_MISC_CFG_1); /* backup CLK_MISC_CFG_1 value */
5531 set_fmeter_divider(k1); /* set divider (0 = /1) */
5532
5533 clk_cfg_val = clk_readl(clk_cfg_reg); /* backup clk_cfg_reg value */
5534 clk_writel_mask(clk_cfg_reg, cksw_mask, cksw_val); /* select cksw */
5535
5536 clk_setl(CLK26CALI_0, tri_bit); /* start fmeter */
5537
5538 /* wait fmeter */
5539 for (i = 100; i > 0 && clk_readl(CLK26CALI_0) & tri_bit; i--)
5540 udelay(50);
5541
5542 if (clk_readl(CLK26CALI_0) & tri_bit) {
5543 /* failed */
5544 } else {
5545 uint32_t cnt = clk_readl(cnt_reg) & 0xFFFF;
5546 freq = (cnt * 26000) * (k1 + 1) / 1024; /* (KHz) ; freq = counter * 26M / 1024 */
5547 }
5548
5549 /* restore register settings */
5550 clk_writel(clk_cfg_reg, clk_cfg_val);
5551 clk_writel(CLK_MISC_CFG_1, clk_misc_cfg_1);
5552
5553 return freq;
5554 }
5555
5556
5557 static uint32_t measure_stable_fmeter_freq(enum FMETER_TYPE type, int k1, int clk)
5558 {
5559 const int diff_threshold = 10;
5560 uint32_t last_freq = 0;
5561 uint32_t freq = fmeter_freq(type, k1, clk);
5562 uint32_t maxfreq = max(freq, last_freq);
5563
5564 while (maxfreq > 0 && ABS_DIFF(freq, last_freq) * 100 / maxfreq > diff_threshold) {
5565 last_freq = freq;
5566 freq = fmeter_freq(type, k1, clk);
5567 maxfreq = max(freq, last_freq);
5568 }
5569
5570 return freq;
5571 }
5572
5573
5574 uint32_t measure_abist_freq(enum ABIST_CLK clk)
5575 {
5576 return measure_stable_fmeter_freq(ABIST, 0, clk);
5577 }
5578 EXPORT_SYMBOL(measure_abist_freq);
5579
5580
5581 uint32_t measure_ckgen_freq(enum CKGEN_CLK clk)
5582 {
5583 return measure_stable_fmeter_freq(CKGEN, 0, clk);
5584 }
5585 EXPORT_SYMBOL(measure_ckgen_freq);
5586
5587
5588 static void measure_abist_clock(enum ABIST_CLK clk, struct seq_file *s)
5589 {
5590 uint32_t freq = measure_abist_freq(clk);
5591 seq_printf(s, "%2d: %-25s %7u\n", clk, ABIST_CLK_NAME[clk], freq);
5592 }
5593
5594
5595 static void measure_ckgen_clock(enum CKGEN_CLK clk, struct seq_file *s)
5596 {
5597 uint32_t freq = measure_ckgen_freq(clk);
5598 seq_printf(s, "%2d: %-25s %7u\n", clk, CKGEN_CLK_NAME[clk], freq);
5599 }
5600
5601
5602 static int fmeter_show(struct seq_file *s, void *v)
5603 {
5604 enum ABIST_CLK abist_clks[] = {
5605 ABIST_AD_MAIN_H546M_CK,
5606 ABIST_AD_MAIN_H364M_CK,
5607 ABIST_AD_MAIN_H218P4M_CK,
5608 ABIST_AD_MAIN_H156M_CK,
5609 ABIST_AD_UNIV_624M_CK,
5610 ABIST_AD_UNIV_416M_CK,
5611 ABIST_AD_UNIV_249P6M_CK,
5612 ABIST_AD_UNIV_178P3M_CK,
5613 ABIST_AD_UNIV_48M_CK,
5614 ABIST_AD_USB_48M_CK,
5615 ABIST_AD_MMPLL_CK,
5616 ABIST_AD_MSDCPLL_CK,
5617 ABIST_AD_DPICLK,
5618 ABIST_CLKPH_MCK_O,
5619 ABIST_AD_MEMPLL2_CKOUT0_PRE_ISO,
5620 ABIST_AD_MCUPLL1_H481M_CK,
5621 ABIST_AD_MDPLL1_416M_CK,
5622 ABIST_AD_WPLL_CK,
5623 ABIST_AD_WHPLL_CK,
5624 ABIST_RTC32K_CK_I,
5625 ABIST_AD_SYS_26M_CK,
5626 ABIST_AD_VENCPLL_CK,
5627 ABIST_AD_MIPI_26M_CK,
5628 ABIST_AD_MEM_26M_CK,
5629 ABIST_AD_PLLGP_TST_CK,
5630 ABIST_AD_DSI0_LNTC_DSICLK,
5631 ABIST_AD_MPPLL_TST_CK,
5632 ABIST_ARMPLL_OCC_MON,
5633 ABIST_AD_MEM2MIPI_26M_CK,
5634 ABIST_AD_MEMPLL_MONCLK,
5635 ABIST_AD_MEMPLL2_MONCLK,
5636 ABIST_AD_MEMPLL3_MONCLK,
5637 ABIST_AD_MEMPLL4_MONCLK,
5638 ABIST_AD_MEMPLL_REFCLK,
5639 ABIST_AD_MEMPLL_FBCLK,
5640 ABIST_AD_MEMPLL2_REFCLK,
5641 ABIST_AD_MEMPLL2_FBCLK,
5642 ABIST_AD_MEMPLL3_REFCLK,
5643 ABIST_AD_MEMPLL3_FBCLK,
5644 ABIST_AD_MEMPLL4_REFCLK,
5645 ABIST_AD_MEMPLL4_FBCLK,
5646 ABIST_AD_MEMPLL_TSTDIV2_CK,
5647 ABIST_AD_LVDSPLL_CK,
5648 ABIST_AD_LVDSTX_MONCLK,
5649 ABIST_AD_HDMITX_MONCLK,
5650 ABIST_AD_USB20_C240M,
5651 ABIST_AD_USB20_C240M_1P,
5652 ABIST_AD_MONREF_CK,
5653 ABIST_AD_MONFBK_CK,
5654 ABIST_AD_TVDPLL_CK,
5655 ABIST_AD_AUDPLL_CK,
5656 ABIST_AD_LVDSPLL_ETH_CK,
5657 };
5658
5659 enum CKGEN_CLK ckgen_clks[] = {
5660 CKGEN_HF_FAXI_CK,
5661 CKGEN_HD_FAXI_CK,
5662 CKGEN_HF_FNFI2X_CK,
5663 CKGEN_HF_FDDRPHYCFG_CK,
5664 CKGEN_HF_FMM_CK,
5665 CKGEN_F_FPWM_CK,
5666 CKGEN_HF_FVDEC_CK,
5667 CKGEN_HF_FMFG_CK,
5668 CKGEN_HF_FCAMTG_CK,
5669 CKGEN_F_FUART_CK,
5670 CKGEN_HF_FSPI_CK,
5671 CKGEN_F_FUSB20_CK,
5672 CKGEN_HF_FMSDC30_0_CK,
5673 CKGEN_HF_FMSDC30_1_CK,
5674 CKGEN_HF_FMSDC30_2_CK,
5675 CKGEN_HF_FAUDIO_CK,
5676 CKGEN_HF_FAUD_INTBUS_CK,
5677 CKGEN_HF_FPMICSPI_CK,
5678 CKGEN_F_FRTC_CK,
5679 CKGEN_F_F26M_CK,
5680 CKGEN_F_F32K_MD1_CK,
5681 CKGEN_F_FRTC_CONN_CK,
5682 CKGEN_HF_FETH_50M_CK,
5683 CKGEN_HD_HAXI_NLI_CK,
5684 CKGEN_HD_QAXIDCM_CK,
5685 CKGEN_F_FFPC_CK,
5686 CKGEN_HF_FDPI0_CK,
5687 CKGEN_F_FCKBUS_CK_SCAN,
5688 CKGEN_F_FCKRTC_CK_SCAN,
5689 CKGEN_HF_FDPILVDS_CK,
5690 };
5691
5692 int i;
5693
5694 uint32_t old_pll_hp_con0 = clk_readl(PLL_HP_CON0);
5695 clk_writel(PLL_HP_CON0, 0x0); /* disable PLL hopping */
5696
5697 seq_puts(s, "abist:\n");
5698
5699 for (i = 0; i < ARRAY_SIZE(abist_clks); i++)
5700 measure_abist_clock(abist_clks[i], s);
5701
5702 seq_puts(s, "ckgen:\n");
5703
5704 for (i = 0; i < ARRAY_SIZE(ckgen_clks); i++)
5705 measure_ckgen_clock(ckgen_clks[i], s);
5706
5707 /* restore old setting */
5708 clk_writel(PLL_HP_CON0, old_pll_hp_con0);
5709
5710 return 0;
5711 }
5712
5713
5714 static int fmeter_open(struct inode *inode, struct file *file)
5715 {
5716 return single_open(file, fmeter_show, NULL);
5717 }
5718
5719
5720 static const struct file_operations fmeter_fops = {
5721 .owner = THIS_MODULE,
5722 .open = fmeter_open,
5723 .read = seq_read,
5724 .llseek = seq_lseek,
5725 .release = single_release,
5726 };
5727
5728
5729 #endif /* CLKMGR_8127 */
5730
5731
5732 #ifdef CONFIG_CLKMGR_STAT
5733
5734
5735 static int clk_stat_show(struct seq_file *s, void *v)
5736 {
5737 struct cg_clk *clk;
5738 struct list_head *pos;
5739 struct stat_node *node;
5740 int i, grp, offset;
5741 int skip;
5742
5743 seq_printf(s, "\n********** clk stat dump **********\n");
5744 for (i = 0; i < NR_CLKS; i++) {
5745 grp = i / 32;
5746 offset = i % 32;
5747 if (offset == 0)
5748 seq_printf(s, "\n*****[%02d][%-8s]*****\n", grp, grp_get_name(grp));
5749
5750 clk = id_to_clk(i);
5751 if (!clk || !clk->grp || !clk->ops->check_validity(clk))
5752 continue;
5753
5754 skip = (clk->cnt == 0) && (clk->state == 0) && list_empty(&clk->head);
5755 if (skip)
5756 continue;
5757
5758 seq_printf(s, "[%02d]state=%u, cnt=%u", offset, clk->state, clk->cnt);
5759 list_for_each(pos, &clk->head) {
5760 node = list_entry(pos, struct stat_node, link);
5761 seq_printf(s, "\t(%s,%u,%u)", node->name, node->cnt_on, node->cnt_off);
5762 }
5763 seq_printf(s, "\n");
5764 }
5765
5766 return 0;
5767 }
5768
5769
5770 static int clk_stat_open(struct inode *inode, struct file *file)
5771 {
5772 return single_open(file, clk_stat_show, NULL);
5773 }
5774
5775
5776 static const struct file_operations clk_stat_fops = {
5777 .owner = THIS_MODULE,
5778 .open = clk_stat_open,
5779 .read = seq_read,
5780 .llseek = seq_lseek,
5781 .release = seq_release
5782 };
5783
5784
5785 #endif
5786
5787
5788 static int clk_force_on_show(struct seq_file *s, void *v)
5789 {
5790 int i;
5791 struct cg_clk *clk;
5792
5793 seq_printf(s, "********** clk force on info dump **********\n");
5794 for (i = 0; i < NR_CLKS; i++) {
5795 clk = &clks[i];
5796 if (clk->force_on) {
5797 seq_printf(s, "clock %d (0x%08x @ %s) is force on\n", i,
5798 clk->mask, clk->grp->name);
5799 }
5800 }
5801
5802 seq_printf(s, "\n********** clk_force_on help **********\n");
5803 seq_printf(s, "set clk force on: echo set id > /proc/clkmgr/clk_force_on\n");
5804 seq_printf(s, "clr clk force on: echo clr id > /proc/clkmgr/clk_force_on\n");
5805
5806 return 0;
5807 }
5808
5809
5810 static int clk_force_on_open(struct inode *inode, struct file *file)
5811 {
5812 return single_open(file, clk_force_on_show, NULL);
5813 }
5814
5815
5816 static int clk_force_on_write(struct file *file, const char *buffer, size_t count, loff_t *data)
5817 {
5818 char desc[32];
5819 int len = 0;
5820
5821 char cmd[10];
5822 int id;
5823
5824 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
5825 if (copy_from_user(desc, buffer, len))
5826 return 0;
5827
5828 desc[len] = '\0';
5829
5830 if (sscanf(desc, "%s %d", cmd, &id) == 2) {
5831 if (!strcmp(cmd, "set"))
5832 clk_set_force_on(id);
5833 else if (!strcmp(cmd, "clr"))
5834 clk_clr_force_on(id);
5835 }
5836
5837 return count;
5838 }
5839
5840
5841 static const struct file_operations clk_force_on_fops = {
5842 .owner = THIS_MODULE,
5843 .write = clk_force_on_write,
5844 .open = clk_force_on_open,
5845 .read = seq_read,
5846 .llseek = seq_lseek,
5847 .release = seq_release
5848 };
5849
5850
5851 static int udelay_test_show(struct seq_file *s, void *v)
5852 {
5853 seq_printf(s, "\n********** udelay_test help **********\n");
5854 seq_printf(s, "test udelay: echo delay > /proc/clkmgr/udelay_test\n");
5855
5856 return 0;
5857 }
5858
5859
5860 static int udelay_test_open(struct inode *inode, struct file *file)
5861 {
5862 return single_open(file, udelay_test_show, NULL);
5863 }
5864
5865
5866 static int udelay_test_write(struct file *file, const char *buffer, size_t count, loff_t *data)
5867 {
5868 char desc[32];
5869 int len = 0;
5870
5871 unsigned int delay;
5872 unsigned int pre, pos;
5873
5874 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
5875 if (copy_from_user(desc, buffer, len))
5876 return 0;
5877
5878 desc[len] = '\0';
5879
5880 if (sscanf(desc, "%u", &delay) == 1) {
5881 pre = clk_readl(0xF0008028);
5882 udelay(delay);
5883 pos = clk_readl(0xF0008028);
5884 clk_info("udelay(%u) test: pre=0x%08x, pos=0x%08x, delta=%u\n",
5885 delay, pre, pos, pos-pre);
5886 }
5887
5888 return count;
5889 }
5890
5891
5892 static const struct file_operations udelay_test_fops = {
5893 .owner = THIS_MODULE,
5894 .write = udelay_test_write,
5895 .open = udelay_test_open,
5896 .read = seq_read,
5897 .llseek = seq_lseek,
5898 .release = seq_release
5899 };
5900
5901
5902 void mt_clkmgr_debug_init(void)
5903 {
5904 struct proc_dir_entry *entry;
5905 struct proc_dir_entry *clkmgr_dir;
5906
5907 clkmgr_dir = proc_mkdir("clkmgr", NULL);
5908 if (!clkmgr_dir) {
5909 clk_err("[%s]: fail to mkdir /proc/clkmgr\n", __func__);
5910 return;
5911 }
5912
5913 entry = proc_create("pll_test", 00640, clkmgr_dir, &pll_test_fops);
5914 entry = proc_create("pll_fsel", 00640, clkmgr_dir, &pll_fsel_fops);
5915
5916 #ifdef CONFIG_CLKMGR_STAT
5917 entry = proc_create("pll_stat", 00440, clkmgr_dir, &pll_stat_fops);
5918 #endif
5919
5920 entry = proc_create("subsys_test", 00640, clkmgr_dir, &subsys_test_fops);
5921
5922 #ifdef CONFIG_CLKMGR_STAT
5923 entry = proc_create("subsys_stat", 00440, clkmgr_dir, &subsys_stat_fops);
5924 #endif
5925
5926 entry = proc_create("mux_test", 00640, clkmgr_dir, &mux_test_fops);
5927
5928 #ifdef CONFIG_CLKMGR_STAT
5929 entry = proc_create("mux_stat", 00440, clkmgr_dir, &mux_stat_fops);
5930 #endif
5931
5932 entry = proc_create("clk_test", 00640, clkmgr_dir, &clk_test_fops);
5933
5934 #ifdef CONFIG_CLKMGR_STAT
5935 entry = proc_create("clk_stat", 00440, clkmgr_dir, &clk_stat_fops);
5936 #endif
5937
5938 entry = proc_create("clk_force_on", 00640, clkmgr_dir, &clk_force_on_fops);
5939 entry = proc_create("udelay_test", 00640, clkmgr_dir, &udelay_test_fops);
5940
5941 #if CLKMGR_8127
5942 entry = proc_create("fmeter", 00640, clkmgr_dir, &fmeter_fops);
5943 #endif /* CLKMGR_8127 */
5944
5945 }
5946
5947 /***********************************
5948 *for early suspend
5949 ************************************/
5950 #ifdef CONFIG_HAS_EARLYSUSPEND
5951 static void clkmgr_early_suspend(struct early_suspend *h)
5952 {
5953 clk_info("[%s]: Dump Top MUX register, CLK_CFG_0=0x%x, CLK_CFG_1=0x%x, CLK_CFG_2=0x%x, CLK_CFG_3=0x%x\n",
5954 __func__, clk_readl(CLK_CFG_0), clk_readl(CLK_CFG_1), clk_readl(CLK_CFG_2), clk_readl(CLK_CFG_3));
5955
5956 return;
5957 }
5958 static void clkmgr_late_resume(struct early_suspend *h)
5959 {
5960 clk_info("[%s]: Dump Top MUX register, CLK_CFG_0=0x%x, CLK_CFG_1=0x%x, CLK_CFG_2=0x%x, CLK_CFG_3=0x%x\n",
5961 __func__, clk_readl(CLK_CFG_0), clk_readl(CLK_CFG_1), clk_readl(CLK_CFG_2), clk_readl(CLK_CFG_3));
5962
5963 return;
5964 }
5965
5966 static struct early_suspend mt_clkmgr_early_suspend_handler = {
5967 .level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 250,
5968 .suspend = clkmgr_early_suspend,
5969 .resume = clkmgr_late_resume,
5970 };
5971 #endif /* CONFIG_HAS_EARLYSUSPEND */
5972
5973 struct platform_device CLK_helper_device = {
5974 .name = "CLK",
5975 .id = -1,
5976 .dev = {},
5977 };
5978
5979 int CLK_pm_restore_noirq(struct device *device)
5980 {
5981 struct subsys *sys;
5982
5983 sys = &syss[SYS_DIS];
5984 sys->state = sys->ops->get_state(sys);
5985
5986 muxs[MT_MUX_MM].cnt = 1;
5987 plls[VENCPLL].cnt = 1;
5988
5989 clk_set_force_on_locked(&clks[MT_CG_DISP0_SMI_LARB0]);
5990 clk_set_force_on_locked(&clks[MT_CG_DISP0_SMI_COMMON]);
5991
5992 clk_info("CLK_pm_restore_noirq\n");
5993
5994 return 0;
5995 }
5996
5997 static const struct dev_pm_ops CLK_helper_pm_ops = {
5998 .restore_noirq = CLK_pm_restore_noirq,
5999 };
6000
6001 static struct platform_driver CLK_helper_driver = {
6002 .driver = {
6003 .name = "CLK",
6004 #ifdef CONFIG_PM
6005 .pm = &CLK_helper_pm_ops,
6006 #endif
6007 .owner = THIS_MODULE,
6008 },
6009 };
6010
6011 static int mt_clkmgr_debug_bringup_init(void)
6012 {
6013 int ret;
6014
6015 #if defined(CONFIG_CLKMGR_BRINGUP) || defined(CONFIG_MTK_LDVT)
6016 mt_clkmgr_bringup_init();
6017 #endif
6018
6019 mt_clkmgr_debug_init();
6020
6021 #ifdef CONFIG_HAS_EARLYSUSPEND
6022 register_early_suspend(&mt_clkmgr_early_suspend_handler);
6023 #endif
6024
6025 ret = platform_device_register(&CLK_helper_device);
6026 if (ret) {
6027 clk_warn("CLK_helper_device register fail(%d)\n", ret);
6028 return ret;
6029 }
6030
6031 ret = platform_driver_register(&CLK_helper_driver);
6032 if (ret) {
6033 clk_warn("CLK_helper_driver register fail(%d)\n", ret);
6034 return ret;
6035 }
6036
6037 return 0;
6038 }
6039 static int __init mt_clkmgr_late_init(void)
6040 {
6041 return 0;
6042 }
6043
6044 module_init(mt_clkmgr_debug_bringup_init);
6045 late_initcall(mt_clkmgr_late_init);
6046
6047
6048 /*************CLKM****************/
6049 void CLKM_32K(bool flag)
6050 {
6051 unsigned long flags;
6052
6053 clkmgr_lock(flags);
6054 if (flag == true) {
6055 /* output 32K */
6056 clk_setl(CLK_CFG_10, 0x00000002); /* CLK_CKMON1_SEL use 2:rtc32k_ck_i */
6057 } else {
6058 /* disable 32K */
6059 clk_clrl(CLK_CFG_10, 0x00000002);
6060 }
6061 clkmgr_unlock(flags);
6062 return;
6063 }
6064 EXPORT_SYMBOL(CLKM_32K);
6065
6066
6067 int CLK_Monitor(enum ckmon_sel ckmon, enum monitor_clk_sel sel, int div)
6068 {
6069 unsigned long flags;
6070 unsigned int ckmon_shift = 0;
6071 unsigned int temp;
6072
6073 if (div > 255 || ckmon == 0) {
6074 clk_info("CLK_Monitor error parameter\n");
6075 return 1;
6076 }
6077
6078 clkmgr_lock(flags);
6079
6080 if (ckmon == 1)
6081 ckmon_shift = 0;
6082 else if (ckmon == 2)
6083 ckmon_shift = 8;
6084 else if (ckmon == 3)
6085 ckmon_shift = 16;
6086
6087 temp = clk_readl(CLK_CFG_10);
6088 temp = temp & (~(0xf << ckmon_shift));
6089 temp = temp | ((sel & 0xf) << ckmon_shift);
6090 clk_writel(CLK_CFG_10, temp);
6091
6092 temp = clk_readl(CLK_CFG_11);
6093 temp = temp & (~(0xff << ckmon_shift));
6094 temp = temp | ((div & 0xff) << ckmon_shift);
6095 clk_writel(CLK_CFG_11, temp);
6096
6097 clk_info("CLK_Monitor Reg: CLK_CFG_10=0x%x, CLK_CFG_11=0x%x\n",
6098 clk_readl(CLK_CFG_10), clk_readl(CLK_CFG_11));
6099
6100 clkmgr_unlock(flags);
6101 return 0;
6102 }
6103 EXPORT_SYMBOL(CLK_Monitor);
6104
6105
6106 #if CLKMGR_CLKM0
6107
6108
6109 int CLK_Monitor_0(enum ckmon_sel ckmon, enum monitor_clk_sel_0 sel, int div)
6110 {
6111 unsigned long flags;
6112 unsigned int temp;
6113
6114 if (div > 255 || ckmon > 0) {
6115 clk_info("CLK_Monitor_0 error parameter\n");
6116 return 1;
6117 }
6118
6119 clkmgr_lock(flags);
6120
6121 temp = clk_readl(CLK26CALI_0);
6122 clk_writel(CLK26CALI_0, temp | 0x80);
6123
6124 clk_writel(CLK_CFG_8, sel << 8);
6125
6126 temp = clk_readl(CLK_MISC_CFG_1);
6127 clk_writel(CLK_MISC_CFG_1, div & 0xff);
6128
6129 clk_info("CLK_Monitor_0 Reg: CLK26CALI_0=0x%08x, CLK_CFG_8=0x%08x, CLK_MISC_CFG_1=0x%08x\n",
6130 clk_readl(CLK26CALI_0), clk_readl(CLK_CFG_8), clk_readl(CLK_MISC_CFG_1));
6131
6132 clkmgr_unlock(flags);
6133 return 0;
6134 }
6135 EXPORT_SYMBOL(CLK_Monitor_0);
6136
6137
6138 #endif /* CLKMGR_CLKM0 */