blob: a53e624e000dc5659be7391a32d0cee76cd36448 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001// SPDX-License-Identifier: GPL-2.0
2
3/*
4
5 * Copyright (c) 2019 MediaTek Inc.
6
7 */
8
9#include <linux/clk-provider.h>
10
11#include <dt-bindings/power/mt6880-power.h>
12
13#define TAG "[scpchk] "
14#define BUG_ON_CHK_ENABLE 0
15
16/*
17 * The clk names in Mediatek CCF.
18 */
19/* audiosys */
20struct scpsys_check_swcg audiosys_swcgs[] = {
21 SWCG("aud_afe"),
22 SWCG("aud_22m"),
23 SWCG("aud_24m"),
24 SWCG("aud_apll2_tuner"),
25 SWCG("aud_apll_tuner"),
26 SWCG("aud_tdm_ck"),
27 SWCG("aud_adc"),
28 SWCG("aud_dac"),
29 SWCG("aud_dac_predis"),
30 SWCG("aud_tml"),
31 SWCG("aud_i2s0_bclk"),
32 SWCG("aud_i2s1_bclk"),
33 SWCG("aud_i2s2_bclk"),
34 SWCG("aud_i2s4_bclk"),
35 SWCG("aud_i2s5_bclk"),
36 SWCG("aud_i2s6_bclk"),
37 SWCG("aud_general1_asrc"),
38 SWCG("aud_general2_asrc"),
39 SWCG("aud_adda6_adc"),
40 SWCG("aud_connsys_i2s_asrc"),
41 SWCG("aud_afe_src_pcm_tx"),
42 SWCG("aud_afe_src_pcm_tx2"),
43 SWCG("aud_afe_src_pcm_tx3"),
44 SWCG("aud_afe_src_pcm_rx"),
45 SWCG("aud_afe_src_i2sin"),
46 SWCG("aud_afe_src_i2sout"),
47 SWCG(NULL),
48};
49/* mfgsys */
50struct scpsys_check_swcg mfgsys_swcgs[] = {
51 SWCG("mfgcfg_bg3d"),
52 SWCG(NULL),
53};
54
55struct subsys_cgs_check mtk_subsys_check[] = {
56 {MT6880_POWER_DOMAIN_AUDIO, audiosys_swcgs},
57 {MT6880_POWER_DOMAIN_MFG0, mfgsys_swcgs},
58};
59
60static unsigned int check_cg_state(struct scpsys_check_swcg *swcg)
61{
62 int enable_count = 0;
63
64 if (!swcg)
65 return 0;
66
67 while (swcg->name) {
68 if (!IS_ERR_OR_NULL(swcg->c)) {
69 if (__clk_get_enable_count(swcg->c) > 0) {
70 pr_notice("%s[%-17s: %3d]\n",
71 __func__,
72 __clk_get_name(swcg->c),
73 __clk_get_enable_count(swcg->c));
74 enable_count++;
75 }
76 }
77 swcg++;
78 }
79
80 return enable_count;
81}
82
83void mtk_check_subsys_swcg(enum subsys_id id)
84{
85 int i;
86 unsigned int ret = 0;
87
88 for (i = 0; i < ARRAY_SIZE(mtk_subsys_check); i++) {
89 if (mtk_subsys_check[i].id != id)
90 continue;
91
92 /* check if Subsys CGs are still on */
93 ret = check_cg_state(mtk_subsys_check[i].swcgs);
94 if (ret)
95 pr_notice("%s:(%d) warning!\n", __func__, id);
96 }
97
98 if (ret) {
99 pr_err("%s(%d): %d\n", __func__, id, ret);
100#if BUG_ON_CHK_ENABLE
101 BUG_ON(1);
102#endif
103 }
104}
105
106static void __init scpsys_check_swcg_init_common(struct scpsys_check_swcg *swcg)
107{
108 if (!swcg)
109 return;
110
111 while (swcg->name) {
112 struct clk *c = __clk_lookup(swcg->name);
113
114 if (IS_ERR_OR_NULL(c))
115 pr_notice("[%17s: NULL]\n", swcg->name);
116 else
117 swcg->c = c;
118 swcg++;
119 }
120}
121
122static int __init scpchk_init(void)
123{
124 /* fill the 'struct clk *' ptr of every CGs*/
125 int i;
126
127 if (!of_machine_is_compatible("mediatek,MT6880"))
128 return -ENODEV;
129
130 for (i = 0; i < ARRAY_SIZE(mtk_subsys_check); i++)
131 scpsys_check_swcg_init_common(mtk_subsys_check[i].swcgs);
132
133 return 0;
134}
135subsys_initcall(scpchk_init);