import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / mt_dcm.c
1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/kernel.h>
4
5 #include <mach/mt_typedefs.h>
6 #include <mach/sync_write.h>
7 #include <mach/mt_dcm.h>
8 #include <mach/mt_clkmgr.h>
9
10 /* support mtk in-house tee */
11 #ifdef CONFIG_MTK_IN_HOUSE_TEE_SUPPORT
12 /* enable protection for SMI DCM due to DAPC protecting SMI control register */
13 #define SUPPORT_MTEE_SMI_DCM_PROT 1
14 #else
15 #define SUPPORT_MTEE_SMI_DCM_PROT 0
16 #endif
17
18
19 #define USING_XLOG
20
21 #ifdef USING_XLOG
22
23 #include <linux/xlog.h>
24 #define TAG "Power/dcm"
25
26 /* #define DCM_ENABLE_DCM_CFG */
27
28 #define dcm_err(fmt, args...) \
29 xlog_printk(ANDROID_LOG_ERROR, TAG, fmt, ##args)
30 #define dcm_warn(fmt, args...) \
31 xlog_printk(ANDROID_LOG_WARN, TAG, fmt, ##args)
32 #define dcm_info(fmt, args...) \
33 xlog_printk(ANDROID_LOG_INFO, TAG, fmt, ##args)
34 #define dcm_dbg(fmt, args...) \
35 xlog_printk(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
36 #define dcm_ver(fmt, args...) \
37 xlog_printk(ANDROID_LOG_VERBOSE, TAG, fmt, ##args)
38
39 #else /* !USING_XLOG */
40
41 #define TAG "[Power/dcm] "
42
43 #define dcm_err(fmt, args...) \
44 pr_err(TAG fmt, ##args)
45 #define dcm_warn(fmt, args...) \
46 pr_warn(TAG fmt, ##args)
47 #define dcm_info(fmt, args...) \
48 pr_notice(TAG fmt, ##args)
49 #define dcm_dbg(fmt, args...) \
50 pr_info(TAG fmt, ##args)
51 #define dcm_ver(fmt, args...) \
52 pr_debug(TAG fmt, ##args)
53
54 #endif
55
56
57 #if SUPPORT_MTEE_SMI_DCM_PROT
58 #include "trustzone/kree/system.h"
59 #include "tz_cross/trustzone.h"
60 #include "tz_cross/ta_dcm.h"
61
62 /*
63 control SMI DCM in MTEE
64 */
65 int i4MTEE_SMI_DCM_Ctrl(unsigned int ui4_enable)
66 {
67 TZ_RESULT ret;
68 KREE_SESSION_HANDLE dcm_session;
69 MTEEC_PARAM param[4];
70 uint32_t cmd;
71 uint32_t paramTypes;
72
73 dcm_info("Ctrl SMI DCM in kernel (%d) - start\n", ui4_enable);
74
75 if (0 == ui4_enable)
76 cmd = TZCMD_DCM_DISABLE_DCM;
77 else
78 cmd = TZCMD_DCM_ENABLE_DCM;
79
80 ret = KREE_CreateSession(TZ_TA_DCM_UUID, &dcm_session);
81 if (ret != TZ_RESULT_SUCCESS) {
82 dcm_info("Error: create dcm_session error %d\n", ret);
83 return -1;
84 }
85
86 paramTypes = TZ_ParamTypes1(TZPT_VALUE_INPUT);
87
88 param[0].value.a = SMI_DCM;
89 ret = KREE_TeeServiceCall(dcm_session, cmd, paramTypes, param);
90 if (TZ_RESULT_SUCCESS != ret)
91 dcm_info("Error: fail to control SMI DCM in MTEE (%d)\n", ret);
92
93 ret = KREE_CloseSession(dcm_session);
94 if (ret != TZ_RESULT_SUCCESS) {
95 dcm_info("Error: close dcm_session error %d\n", ret);
96 return -1;
97 }
98
99 dcm_info("Ctrl SMI DCM in kernel (%d) - end\n", ui4_enable);
100 return 0;
101 }
102
103 /*
104 Dump SMI DCM register in MTEE
105 */
106 int i4MTEE_SMI_DCM_GetStatus(
107 unsigned int *pui4_smi_com_dcm,
108 unsigned int *pui4_smi_sec_dcm,
109 unsigned int *pui4_m4u_dcm)
110 {
111 TZ_RESULT ret;
112 KREE_SESSION_HANDLE dcm_session;
113 MTEEC_PARAM param[4];
114 uint32_t paramTypes;
115
116 dcm_info("Get SMI DCM status in kernel - start\n");
117
118 if ((NULL == pui4_smi_com_dcm) ||
119 (NULL == pui4_smi_sec_dcm) ||
120 (NULL == pui4_m4u_dcm)) {
121 dcm_warn("Error: NULL pointers for get SMI DCM status !!!\n");
122 return -1;
123 }
124
125 ret = KREE_CreateSession(TZ_TA_DCM_UUID, &dcm_session);
126 if (ret != TZ_RESULT_SUCCESS) {
127 dcm_warn("Error: create dcm_session error %d\n", ret);
128 return -1;
129 }
130
131 paramTypes = TZ_ParamTypes3(TZPT_VALUE_INPUT, TZPT_VALUE_OUTPUT, TZPT_VALUE_OUTPUT);
132 param[0].value.a = SMI_DCM;
133 param[1].value.a = 0;
134 param[1].value.b = 0;
135 param[2].value.a = 0;
136
137 ret = KREE_TeeServiceCall(dcm_session, TZCMD_DCM_GET_DCM_STATUS, paramTypes, param);
138 if (TZ_RESULT_SUCCESS != ret)
139 dcm_info("Error: fail to get status of SMI DCM in MTEE (%d)\n", ret);
140
141 ret = KREE_CloseSession(dcm_session);
142 if (ret != TZ_RESULT_SUCCESS) {
143 dcm_info("Error: close dcm_session error %d\n", ret);
144 return -1;
145 }
146
147 *pui4_smi_com_dcm = param[1].value.a;
148 *pui4_smi_sec_dcm = param[1].value.b;
149 *pui4_m4u_dcm = param[2].value.a;
150
151 dcm_info("Get SMI DCM status in kernel - done\n");
152 return 0;
153 }
154
155 /*
156 Dump SMI DCM operation register in MTEE
157 */
158 int i4MTEE_SMI_DCM_GetOpStatus(
159 unsigned int *pui4_smi_com_set,
160 unsigned int *pui4_smi_com_clr)
161 {
162 TZ_RESULT ret;
163 KREE_SESSION_HANDLE dcm_session;
164 MTEEC_PARAM param[4];
165 uint32_t paramTypes;
166
167 dcm_info("Get SMI DCM op status in kernel - start\n");
168
169 if ((NULL == pui4_smi_com_set) ||
170 (NULL == pui4_smi_com_clr)) {
171 dcm_warn("Error: NULL pointers for get SMI DCM op status !!!\n");
172 return -1;
173 }
174
175 ret = KREE_CreateSession(TZ_TA_DCM_UUID, &dcm_session);
176 if (ret != TZ_RESULT_SUCCESS) {
177 dcm_warn("Error: create dcm_session error %d\n", ret);
178 return -1;
179 }
180
181 paramTypes = TZ_ParamTypes2(TZPT_VALUE_INPUT, TZPT_VALUE_OUTPUT);
182 param[0].value.a = SMI_DCM;
183 param[1].value.a = 0;
184 param[1].value.b = 0;
185
186 ret = KREE_TeeServiceCall(dcm_session, TZCMD_DCM_GET_DCM_OP_STATUS, paramTypes, param);
187 if (TZ_RESULT_SUCCESS != ret)
188 dcm_info("Error: fail to get op status of SMI DCM in MTEE (%d)\n", ret);
189
190 ret = KREE_CloseSession(dcm_session);
191 if (ret != TZ_RESULT_SUCCESS) {
192 dcm_info("Error: close dcm_session error %d\n", ret);
193 return -1;
194 }
195
196 *pui4_smi_com_set = param[1].value.a;
197 *pui4_smi_com_clr = param[1].value.b;
198
199 dcm_info("Get SMI DCM op status in kernel - done\n");
200 return 0;
201 }
202 #endif /* SUPPORT_MTEE_SMI_DCM_PROT */
203
204
205 #define dcm_readl(addr) DRV_Reg32(addr)
206
207
208 #define dcm_writel(addr, val) mt65xx_reg_sync_writel((val), ((void *)addr))
209
210 #define dcm_setl(addr, val) mt65xx_reg_sync_writel(dcm_readl(addr) | (val), ((void *)addr))
211
212 #define dcm_clrl(addr, val) mt65xx_reg_sync_writel(dcm_readl(addr) & ~(val), ((void *)addr))
213
214
215 static DEFINE_MUTEX(dcm_lock);
216
217 static unsigned int dcm_sta;
218
219 void dcm_dump_regs(unsigned int type)
220 {
221 mutex_lock(&dcm_lock);
222
223 if (type & CPU_DCM) {
224 unsigned int mcf_biu_con, ca7_misc_config;
225
226 mcf_biu_con = dcm_readl(MCU_BIU_CON);
227 ca7_misc_config = dcm_readl(CA7_MISC_CONFIG);
228 dcm_info("[CPU_DCM]MCU_BIU_CON(0x%08x), CA7_MISC_CONFIG(0x%08x)\n", mcf_biu_con, ca7_misc_config);
229 }
230
231 if (type & TOPCKGEN_DCM) {
232 unsigned int dcm_cfg, dcm_scp_cfg_cfg0, dcm_scp_cfg_cfg1;
233 dcm_cfg = dcm_readl(DCM_CFG);
234 dcm_scp_cfg_cfg0 = dcm_readl(CLK_SCP_CFG_0);
235 dcm_scp_cfg_cfg1 = dcm_readl(CLK_SCP_CFG_1);
236
237 dcm_info("[IFR_DCM]DCM_CFG(0x%08x)\n", dcm_cfg);
238 dcm_info("[IFR_DCM]CLK_SCP_CFG_0(0x%08x)\n", dcm_scp_cfg_cfg0);
239 dcm_info("[IFR_DCM]CLK_SCP_CFG_1(0x%08x)\n", dcm_scp_cfg_cfg1);
240
241 }
242
243 if (type & IFR_DCM) {
244 unsigned int fsel, dbc, ctl;
245 unsigned int dramc;
246 fsel = dcm_readl(INFRA_DCMFSEL);
247 dbc = dcm_readl(INFRA_DCMDBC);
248 ctl = dcm_readl(INFRA_DCMCTL);
249 dramc = dcm_readl(DRAMC_PD_CTRL);
250 dcm_info("[IFR_DCM]FSEL(0x%08x), DBC(0x%08x), CTL(0x%08x)\n", fsel, dbc, ctl);
251 dcm_info("[IFR_DCM]DRAMC_PD_CTRL(0x%08x)\n", dramc);
252 }
253
254 if (type & PER_DCM) {
255 unsigned int top_ckdiv1, top_dcmctl, top_dcmdbc;
256 unsigned int infra_dcmctl, infra_dcmdbc, infra_dcmsel, infra_pd_Ctrl;
257
258 top_ckdiv1 = dcm_readl(TOP_CKDIV1);
259 top_dcmctl = dcm_readl(TOP_DCMCTL);
260 top_dcmdbc = dcm_readl(TOP_DCMDBC);
261 infra_dcmctl = dcm_readl(INFRA_DCMCTL);
262 infra_dcmdbc = dcm_readl(INFRA_DCMDBC);
263 infra_dcmsel = dcm_readl(INFRA_DCMFSEL);
264 infra_pd_Ctrl = dcm_readl(DRAMC_PD_CTRL);
265
266 dcm_info("[PER_DCM]TOP_CKDIV1(0x%08x), TOP_DCMCTL(0x%08x), TOP_DCMDBC(0x%08x), INFRA_DCMCTL(0x%08x), INFRA_DCMDBC(0x%08x), INFRA_DCMFSEL(0x%08x), DRAMC_PD_CTRL(0x%08x)\n",
267 top_ckdiv1, top_dcmctl, top_dcmdbc, infra_dcmctl, infra_dcmdbc, infra_dcmsel, infra_pd_Ctrl);
268 }
269
270 if (type & SMI_DCM) {
271
272 unsigned int smi_dcm_control, smi_common_ao_smi_con, mmu_dcm;
273 unsigned int smi_common_ao_smi_con_set, smi_common_ao_smi_con_clr;
274 #if SUPPORT_MTEE_SMI_DCM_PROT
275 /* SMI_SECURE_XXX register is protected by MTEE */
276 /* Note: driver initialization should not call this function due to driver iniitializaion sequence */
277 int iret;
278 iret = i4MTEE_SMI_DCM_GetStatus(&smi_dcm_control, &smi_common_ao_smi_con, &mmu_dcm);
279 iret = i4MTEE_SMI_DCM_GetOpStatus(&smi_common_ao_smi_con_set, &smi_common_ao_smi_con_clr);
280 #else
281 smi_dcm_control = dcm_readl(SMI_DCM_CONTROL);
282
283 smi_common_ao_smi_con = dcm_readl(SMI_COMMON_AO_SMI_CON);
284 smi_common_ao_smi_con_set = dcm_readl(SMI_COMMON_AO_SMI_CON_SET);
285 smi_common_ao_smi_con_clr = dcm_readl(SMI_COMMON_AO_SMI_CON_CLR);
286
287 mmu_dcm = dcm_readl(MMU_DCM);
288 #endif /* SUPPORT_MTEE_SMI_DCM_PROT */
289 dcm_info("[SMI_DCM]SMI_DCM_CONTROL(0x%08x), SMI_COMMON_AO_SMI_CON(0x%08x), MMU_DCM(0x%08x)\n" ,
290 smi_dcm_control, smi_common_ao_smi_con, mmu_dcm);
291 dcm_info("[SMI_DCM]SMI_COMMON_AO_SMI_CON_SET(0x%08x)\n", smi_common_ao_smi_con_set);
292 dcm_info("[SMI_DCM]SMI_COMMON_AO_SMI_CON_CLR(0x%08x)\n", smi_common_ao_smi_con_clr);
293
294 }
295
296 if (type & MFG_DCM) {
297 if (subsys_is_on(SYS_MFG)) {
298 unsigned int mfg0;
299 mfg0 = dcm_readl(MFG_DCM_CON_0);
300 dcm_info("[MFG_DCM]MFG_DCM_CON_0(0x%08x)\n", mfg0);
301 } else
302 dcm_info("[MFG_DCM]subsy MFG is off\n");
303 }
304
305 if (type & DIS_DCM) {
306 if (subsys_is_on(SYS_DIS)) {
307 unsigned int dis0, dis_set0, dis_clr0, dis1, dis_set1, dis_clr1;
308 unsigned int smilarb0_dcm_sta, smilarb0_dcm_con, smilarb0_dcm_set;
309 dis0 = dcm_readl(DISP_HW_DCM_DIS0);
310 dis_set0 = dcm_readl(DISP_HW_DCM_DIS_SET0);
311 dis_clr0 = dcm_readl(DISP_HW_DCM_DIS_CLR0);
312
313 dis1 = dcm_readl(DISP_HW_DCM_DIS1);
314 dis_set1 = dcm_readl(DISP_HW_DCM_DIS_SET1);
315 dis_clr1 = dcm_readl(DISP_HW_DCM_DIS_CLR1);
316
317 smilarb0_dcm_sta = dcm_readl(SMILARB0_DCM_STA);
318 smilarb0_dcm_con = dcm_readl(SMILARB0_DCM_CON);
319 smilarb0_dcm_set = dcm_readl(SMILARB0_DCM_SET);
320
321 dcm_info("[DIS_DCM]DISP_HW_DCM_DIS_SET0(0x%08x), DISP_HW_DCM_DIS_CLR0(0x%08x), DISP_HW_DCM_DIS_CLR0(0x%08x)\n",
322 dis0, dis_set0, dis_clr0);
323 dcm_info("[DIS_DCM]DISP_HW_DCM_DIS_SET1(0x%08x), DISP_HW_DCM_DIS_CLR1(0x%08x), DISP_HW_DCM_DIS_CLR1(0x%08x)\n",
324 dis1, dis_set1, dis_clr1);
325 dcm_info("[DIS_DCM]SMILARB0_DCM_STA(0x%08x), SMILARB0_DCM_CON(0x%08x), SMILARB0_DCM_SET(0x%08x)\n",
326 smilarb0_dcm_sta, smilarb0_dcm_con, smilarb0_dcm_set);
327 } else
328 dcm_info("[DIS_DCM]subsys DIS is off\n");
329 }
330
331 if (type & ISP_DCM) {
332 if (subsys_is_on(SYS_ISP)) {
333 unsigned int raw, rgb, yuv, cdp, dma;
334 unsigned int jpgenc, venc_dcm, venc_cg, smilarb2_dcm_sta, smilarb2_dcm_com;
335 raw = dcm_readl(CAM_CTL_RAW_DCM);
336 rgb = dcm_readl(CAM_CTL_RGB_DCM);
337 yuv = dcm_readl(CAM_CTL_YUV_DCM);
338 cdp = dcm_readl(CAM_CTL_CDP_DCM);
339 dma = dcm_readl(CAM_CTL_DMA_DCM);
340 jpgenc = dcm_readl(JPGENC_DCM_CTRL);
341 venc_dcm = dcm_readl(VENC_CLK_DCM_CTRL);
342 venc_cg = dcm_readl(VENC_CLK_CG_CTRL);
343 smilarb2_dcm_sta = dcm_readl(SMILARB2_DCM_STA);
344 smilarb2_dcm_com = dcm_readl(SMILARB2_DCM_CON);
345
346 dcm_info("[ISP_DCM]CAM_CTL_RAW_DCM(0x%08x), CAM_CTL_RGB_DCM(0x%08x)\n",
347 raw, rgb);
348 dcm_info("[ISP_DCM]CAM_CTL_YUV_DCM(0x%08x), CAM_CTL_CDP_DCM(0x%08x)\n",
349 yuv, cdp);
350 dcm_info("[ISP_DCM] JPGENC_DCM_CTRL(0x%08x), VENC_CLK_CG_CTRL(0x%08x)\n",
351 jpgenc, venc_cg);
352
353 dcm_info("[ISP_DCM]SMILARB2_DCM_STA(0x%08x)\n", smilarb2_dcm_sta);
354 dcm_info("[ISP_DCM]SMILARB2_DCM_CON(0x%08x)\n", smilarb2_dcm_com);
355 } else
356 dcm_info("[ISP_DCM]subsys ISP is off\n");
357 }
358
359 if (type & VDE_DCM) {
360 if (subsys_is_on(SYS_VDE)) {
361 unsigned int vdec, smilarb1_dcm_sta, smilarb1_dcm_com, smilarb1_dcm_set;
362 vdec = dcm_readl(VDEC_DCM_CON);
363 smilarb1_dcm_sta = dcm_readl(SMILARB1_DCM_STA);
364 smilarb1_dcm_com = dcm_readl(SMILARB1_DCM_CON);
365 smilarb1_dcm_set = dcm_readl(SMILARB1_DCM_SET);
366 dcm_info("[VDE_DCM]VDEC_DCM_CON(0x%08x), SMILARB1_DCM_STA(0x%08x), SMILARB1_DCM_CON(0x%08x), SMILARB1_DCM_SET(0x%08x)\n",
367 vdec, smilarb1_dcm_sta, smilarb1_dcm_com, smilarb1_dcm_set);
368 } else
369 dcm_info("[VDE_DCM]subsys VDE is off\n");
370 }
371
372 mutex_unlock(&dcm_lock);
373
374 }
375
376 void dcm_enable(unsigned int type)
377 {
378 unsigned int temp;
379
380 dcm_info("[%s]type:0x%08x\n", __func__, type);
381
382 mutex_lock(&dcm_lock);
383
384 if (type & CPU_DCM) {
385 dcm_info("[%s][CPU_DCM ]=0x%08x\n", __func__, CPU_DCM);
386
387 dcm_setl(MCU_BIU_CON, 0x1 << 12);
388 dcm_setl(CA7_MISC_CONFIG, 0x1 << 9);
389 dcm_sta |= CPU_DCM;
390
391 }
392
393
394 if (type & TOPCKGEN_DCM) {
395 dcm_info("[%s][TOPCKGEN_DCM]=0x%08x\n", __func__, TOPCKGEN_DCM);
396
397 #ifdef DCM_ENABLE_DCM_CFG /* AXI bus dcm, don't need to set by KL Tong */
398 /* default value are all 0, use default value */
399 dcm_writel(DCM_CFG, 0xFFFFFF7F); /* set bit0~bit4=0, bit7=0, bit8~bit14=0, bit15=0???? */
400 #endif
401 dcm_setl(CLK_SCP_CFG_0, 0x3FF); /* set bit0~bit9=1, SCP control register 1 */
402 dcm_setl(CLK_SCP_CFG_1, ((0x1 << 4) | 0x1)); /* set bit0=1 and bit4=1, SCP control register 1 */
403 dcm_sta |= TOPCKGEN_DCM;
404
405 }
406
407 /* Infrasys_dcm */
408 if (type & IFR_DCM) {
409 dcm_info("[%s][IFR_DCM ]=0x%08x\n", __func__, IFR_DCM);
410
411 dcm_clrl(TOP_CKDIV1, 0x0000001f); /* 5'h0, 00xxx: 1/1 */
412 dcm_setl(TOP_DCMCTL, 0x00000007); /* set bit0~bit2=1 */
413 dcm_setl(TOP_DCMDBC, 0x00000001); /* set bit0=1, force to 26M */
414 dcm_setl(INFRA_DCMCTL, 0x00000303); /* set bit0, bit1, bit8, bit9=1, DCM debouncing counter=0 */
415 dcm_setl(INFRA_DCMDBC, 0x00000300); /* set bit8, bit9=1 first */
416 dcm_clrl(INFRA_DCMDBC, 0x0000007F); /* then clear b0~b6 */
417
418 #if 0 /* divided most, save power, */
419 dcm_writel(INFRA_DCMFSEL, 0xFFE0F0F8); /* clear bit0~bit2, clear bit8~bit11, clear bit16~bit20 */
420 #else /* divided by 1 */
421 dcm_writel(INFRA_DCMFSEL, 0xFFF0F0F8); /* clear bit0~bit2, clear bit8~bit11, set bit20=1 */
422 #endif
423
424 dcm_setl(DRAMC_PD_CTRL, 0x3 << 24); /* set bit24, bit25=1 */
425 dcm_sta |= IFR_DCM;
426
427 }
428
429 if (type & PER_DCM) {
430 dcm_info("[%s][PER_DCM ]=0x%08x\n", __func__, PER_DCM);
431
432 dcm_clrl(PERI_GLOBALCON_DCMCTL, 0x00001F00); /* clear bit8~bit12=0 */
433 dcm_setl(PERI_GLOBALCON_DCMCTL, 0x000000F3); /* set bit0, bit1, bit4~bit7=1 */
434
435 dcm_setl(PERI_GLOBALCON_DCMDBC, 0x1<<7); /* set bit7=1 */
436 dcm_clrl(PERI_GLOBALCON_DCMDBC, 0x0000007F); /* clear bit0~bit6=0 */
437
438 dcm_clrl(PERI_GLOBALCON_DCMFSEL, 0x00000007); /* clear bit0~bit2 */
439 dcm_clrl(PERI_GLOBALCON_DCMFSEL, 0x00000F00); /* clear bit8~bit11 */
440 dcm_clrl(PERI_GLOBALCON_DCMFSEL, 0x001F0000); /* clear bit16~bit20 */
441
442 /* MSDC module */
443 dcm_clrl(MSDC0_IP_DCM, 0xFF800000); /* clear bit23~bit31=0 */
444 dcm_clrl(MSDC1_IP_DCM, 0xFF800000); /* clear bit23~bit31=0 */
445 dcm_clrl(MSDC2_IP_DCM, 0xFF800000); /* clear bit23~bit31=0 */
446
447 /* USB */
448 dcm_clrl(PERI_USB0_DCM, 0x00070000); /* clear bit16~bit18=0 */
449
450 /* PMIC */
451 dcm_setl(PMIC_WRAP_DCM_EN, 0x1); /* set bit0=1 */
452
453 /* I2C */
454 dcm_setl(I2C0_I2CREG_HW_CG_EN, 0x1); /* set bit0=1 */
455 dcm_setl(I2C1_I2CREG_HW_CG_EN, 0x1); /* set bit0=1 */
456 dcm_setl(I2C2_I2CREG_HW_CG_EN, 0x1); /* set bit0=1 */
457
458 dcm_sta |= PER_DCM;
459
460 }
461
462 if (type & SMI_DCM) {
463 #if SUPPORT_MTEE_SMI_DCM_PROT
464 int iret;
465 #endif /* SUPPORT_MTEE_SMI_DCM_PROT */
466
467 dcm_info("[%s][SMI_DCM ]=0x%08x\n", __func__, SMI_DCM);
468
469 #if SUPPORT_MTEE_SMI_DCM_PROT
470 /* SMI_SECURE_XXX register is protected by MTEE */
471 /* Note: driver initialization should not call this function due to driver iniitializaion sequence */
472 iret = i4MTEE_SMI_DCM_Ctrl(1);
473 #else
474 /* smi_common */
475 dcm_writel(SMI_DCM_CONTROL, 0x1); /* set bit 0=1 */
476 /* RO */
477 dcm_readl(SMI_COMMON_AO_SMI_CON);
478
479 dcm_setl(SMI_COMMON_AO_SMI_CON_SET, 0x1 << 2);
480
481 /* NA */
482 dcm_readl(SMI_COMMON_AO_SMI_CON_CLR);
483
484 /* m4u_dcm */
485 dcm_setl(MMU_DCM, 0x1); /* set bit0=1 */
486 #endif /* SUPPORT_MTEE_SMI_DCM_PROT */
487 dcm_sta |= SMI_DCM;
488
489 }
490
491 if (type & MFG_DCM) {
492 dcm_info("[%s][MFG_DCM ]=0x%08x, subsys_is_on(SYS_MFG)=%d\n",
493 __func__, MFG_DCM, subsys_is_on(SYS_MFG));
494
495 if (subsys_is_on(SYS_MFG)) {
496 temp = dcm_readl(MFG_DCM_CON_0);
497 temp &= 0xFFFE0000; /* set B[0:6]=0111111, B[8:13]=0,, B[14]=1,, B[15]=1,, B[16]=0 */
498 temp |= 0x0000C03F;
499 dcm_writel(MFG_DCM_CON_0, temp);
500 dcm_sta |= MFG_DCM;
501 }
502 }
503
504 if (type & DIS_DCM) {
505 dcm_info("[%s][DIS_DCM ]=0x%08x, subsys_is_on(SYS_DIS)=%d\n",
506 __func__, DIS_DCM, subsys_is_on(SYS_DIS));
507
508 if (subsys_is_on(SYS_DIS)) {
509 dcm_writel(DISP_HW_DCM_DIS0, 0x0);
510 dcm_writel(DISP_HW_DCM_DIS_SET0, 0x0);
511 dcm_writel(DISP_HW_DCM_DIS_CLR0, 0xFFFFFFFF);
512
513 dcm_writel(DISP_HW_DCM_DIS1, 0x0);
514 dcm_writel(DISP_HW_DCM_DIS_SET1, 0x0);
515 dcm_writel(DISP_HW_DCM_DIS_CLR1, 0xFFFFFFFF);
516
517 /* LARB0 \84³ DISP, MDP */
518 /* RO, bootup set once status = 1'b0, DCM off setting=N/A */
519 dcm_readl(SMILARB0_DCM_STA);
520 /* RO, bootup set once status = 1'b1, DCM off setting=1'b0 */
521 dcm_readl(SMILARB0_DCM_CON);
522 dcm_setl(SMILARB0_DCM_SET, 0x1<<15); /* set bit15=1 */
523 /* N/A */
524 dcm_readl(SMILARB0_DCM_CON);
525
526 dcm_sta |= DIS_DCM;
527 }
528
529 }
530
531 if (type & ISP_DCM) {
532
533 dcm_info("[%s][ISP_DCM ]=0x%08x, subsys_is_on(SYS_ISP)=%d\n",
534 __func__, ISP_DCM, subsys_is_on(SYS_ISP));
535
536 if (subsys_is_on(SYS_ISP)) {
537 dcm_writel(CAM_CTL_RAW_DCM, 0xFFFF8000); /* set bit0~bit14=0 */
538 dcm_writel(CAM_CTL_RGB_DCM, 0xFFFFFE00); /* set bit0~bit8=0 */
539 dcm_writel(CAM_CTL_YUV_DCM, 0xFFFFFFF0); /* set bit0~bit3=0 */
540 dcm_writel(CAM_CTL_CDP_DCM, 0xFFFFFE00); /* set bit0~bit8=0 */
541 dcm_writel(CAM_CTL_DMA_DCM, 0xFFFFFFC0); /* set bit0~bit5=0 */
542
543 dcm_clrl(JPGENC_DCM_CTRL, 0x1); /* clear bit0=0 */
544
545 dcm_setl(VENC_CLK_DCM_CTRL, 0x1); /* ok */
546 dcm_writel(VENC_CLK_CG_CTRL, 0xFFFFFFFF);
547
548 /* LARB2 \84³ ISP, VENC */
549 /* RO, bootup set once status = 1'b0, DCM off setting=N/A */
550 dcm_readl(SMILARB2_DCM_STA);
551 /* RO, bootup set once status = 1'b1, DCM off setting=1'b0 */
552 dcm_readl(SMILARB2_DCM_CON);
553 dcm_setl(SMILARB2_DCM_SET, 0x1<<15); /* set bit15=1 */
554 /* N/A */
555 dcm_readl(SMILARB2_DCM_CON);
556
557 dcm_sta |= ISP_DCM;
558
559 }
560
561 }
562
563 if (type & VDE_DCM) {
564
565 dcm_info("[%s][VDE_DCM ]=0x%08x, subsys_is_on(SYS_VDE)=%d\n",
566 __func__, VDE_DCM, subsys_is_on(SYS_VDE));
567
568 if (subsys_is_on(SYS_VDE)) {
569 dcm_clrl(VDEC_DCM_CON, 0x1); /* clear bit0 */
570
571 /* LARB1 \84³ VDEC */
572 /* RO, bootup set once status = 1'b0, DCM off setting=N/A */
573 dcm_readl(SMILARB1_DCM_STA);
574 /* RO, bootup set once status = 1'b1, DCM off setting=1'b0 */
575 dcm_readl(SMILARB1_DCM_CON);
576 dcm_setl(SMILARB1_DCM_SET, 0x1<<15); /* set bit15=1 */
577 /* N/A */
578 dcm_readl(SMILARB1_DCM_SET);
579
580 dcm_sta |= VDE_DCM;
581 }
582
583 }
584
585 mutex_unlock(&dcm_lock);
586
587 }
588
589 void dcm_disable(unsigned int type)
590 {
591 dcm_info("[%s]type:0x%08x\n", __func__, type);
592
593 mutex_lock(&dcm_lock);
594
595 if (type & CPU_DCM) {
596
597 dcm_info("[%s][CPU_DCM ]=0x%08x\n", __func__, CPU_DCM);
598 dcm_clrl(MCU_BIU_CON, 0x1 << 12); /* set bit12=0 */
599 dcm_clrl(CA7_MISC_CONFIG, 0x1 << 9); /* set bit9=0 */
600 dcm_sta &= ~CPU_DCM;
601 }
602
603 if (type & TOPCKGEN_DCM) {
604
605 dcm_info("[%s][TOPCKGEN_DCM]=0x%08x\n", __func__, TOPCKGEN_DCM);
606 #ifdef DCM_ENABLE_DCM_CFG /* AXI bus dcm, don't need to set by KL Tong */
607 /* default value are all 0, use default value */
608 dcm_clrl(DCM_CFG, (0x1 << 7)); /* set bit7=0 */
609 #endif
610 dcm_setl(CLK_SCP_CFG_0, 0x3FF); /* set bit0~bit9=1, SCP control register 1 */
611 dcm_setl(CLK_SCP_CFG_1, ((0x1 << 4) | 0x1)); /* set bit0=1 and bit4=1, SCP control register 1 */
612 dcm_sta &= ~TOPCKGEN_DCM;
613 }
614
615 if (type & PER_DCM) {
616 dcm_info("[%s][PER_DCM ]=0x%08x\n", __func__, PER_DCM);
617
618 dcm_clrl(PERI_GLOBALCON_DCMCTL, 0x00001F00); /* clear bit8~bit12=0 */
619 dcm_clrl(PERI_GLOBALCON_DCMCTL, 0x000000F3); /* set bit0, bit1, bit4~bit7=0 */
620
621 dcm_setl(PERI_GLOBALCON_DCMDBC, 0x1<<7); /* set bit7=1 */
622 dcm_clrl(PERI_GLOBALCON_DCMDBC, 0x0000007F); /* clear bit0~bit6=0 */
623
624 dcm_clrl(PERI_GLOBALCON_DCMFSEL, 0x00000007); /* clear bit0~bit2 */
625 dcm_clrl(PERI_GLOBALCON_DCMFSEL, 0x00000F00); /* clear bit8~bit11 */
626 dcm_clrl(PERI_GLOBALCON_DCMFSEL, 0x001F0000); /* clear bit16~bit20 */
627
628 /* MSDC module */
629 dcm_setl(MSDC0_IP_DCM, 0xFF800000); /* set bit23~bit31=1 */
630 dcm_setl(MSDC1_IP_DCM, 0xFF800000); /* set bit23~bit31=1 */
631 dcm_setl(MSDC2_IP_DCM, 0xFF800000); /* set bit23~bit31=1 */
632
633
634 /* USB */
635 dcm_setl(PERI_USB0_DCM, 0x00070000); /* set bit16~bit18=1 */
636
637 /* PMIC */
638 dcm_clrl(PMIC_WRAP_DCM_EN, 0x1); /* set bit0=0 */
639
640 /* I2C */
641 dcm_clrl(I2C0_I2CREG_HW_CG_EN, 0x1); /* set bit0=0 */
642 dcm_clrl(I2C1_I2CREG_HW_CG_EN, 0x1); /* set bit0=0 */
643 dcm_clrl(I2C2_I2CREG_HW_CG_EN, 0x1); /* set bit0=0 */
644
645 dcm_sta &= ~PER_DCM;
646 }
647
648 /* Infrasys_dcm */
649 if (type & IFR_DCM) {
650
651 dcm_info("[%s][IFR_DCM ]=0x%08x\n", __func__, IFR_DCM);
652 /* should off DRAMC first than off TOP_DCMCTL */
653 dcm_setl(DRAMC_PD_CTRL, 0x1 << 24); /* set bit24=1 */
654 dcm_clrl(DRAMC_PD_CTRL, 0x1 << 25); /* set bit25=0 */
655
656 dcm_clrl(TOP_DCMCTL, 0x00000006); /* clear bit1, bit2=0, bit0 doesn't need to clear */
657
658 dcm_clrl(INFRA_DCMCTL, 0x00000303); /* set bit0, bit1, bit8, bit9=1, DCM debouncing counter=0 */
659
660 dcm_sta &= ~IFR_DCM;
661
662 }
663
664 if (type & SMI_DCM) {
665 #if SUPPORT_MTEE_SMI_DCM_PROT
666 int iret;
667 #endif /* SUPPORT_MTEE_SMI_DCM_PROT */
668
669 dcm_info("[%s][SMI_DCM ]=0x%08x\n", __func__, SMI_DCM);
670
671 #if SUPPORT_MTEE_SMI_DCM_PROT
672 /* SMI_SECURE_XXX register is protected by MTEE */
673 iret = i4MTEE_SMI_DCM_Ctrl(0);
674 #else
675 /* smi_common */
676 dcm_clrl(SMI_DCM_CONTROL, 0x1); /* set bit0=0 */
677
678 /* RU=read status */
679 dcm_readl(SMI_COMMON_AO_SMI_CON);
680 /* RU=read status */
681 dcm_readl(SMI_COMMON_AO_SMI_CON_SET);
682 dcm_setl(SMI_COMMON_AO_SMI_CON_CLR, 0x4); /* set bit2=1 */
683
684 /* m4u_dcm */
685 dcm_clrl(MMU_DCM, 0x1); /* set bit0=0 */
686 #endif /* SUPPORT_MTEE_SMI_DCM_PROT */
687 dcm_sta &= ~SMI_DCM;
688 }
689
690 if (type & MFG_DCM) {
691
692 dcm_info("[%s][MFG_DCM ]=0x%08x\n", __func__, MFG_DCM);
693
694 dcm_clrl(MFG_DCM_CON_0, 0x8000); /* disable dcm, clear bit 15 */
695
696 dcm_sta &= ~MFG_DCM;
697 }
698
699 if (type & DIS_DCM) {
700
701 dcm_info("[%s][DIS_DCM ]=0x%08x\n", __func__, DIS_DCM);
702
703 dcm_writel(DISP_HW_DCM_DIS0, 0xFFFFFFFF);
704 dcm_writel(DISP_HW_DCM_DIS_SET0, 0xFFFFFFFF);
705 dcm_writel(DISP_HW_DCM_DIS_CLR0, 0x00000000);
706
707 dcm_writel(DISP_HW_DCM_DIS1, 0xFFFFFFFF);
708 dcm_writel(DISP_HW_DCM_DIS_SET1, 0xFFFFFFFF);
709 dcm_writel(DISP_HW_DCM_DIS_CLR1, 0x0);
710
711 /* LARB0 \84³ DISP, MDP */
712 /* RO, bootup set once status = 1'b0, DCM off setting=N/A */
713 dcm_readl(SMILARB0_DCM_STA);
714 /* RO, bootup set once status = 1'b1, DCM off setting=1'b0 */
715 dcm_readl(SMILARB0_DCM_CON);
716 /* N/A */
717 dcm_readl(SMILARB0_DCM_SET);
718 dcm_setl(SMILARB0_DCM_CLR, (0x1 << 15)); /* set bit15=1 */
719
720 dcm_sta &= ~DIS_DCM;
721 }
722
723 if (type & ISP_DCM) {
724
725 dcm_info("[%s][ISP_DCM ]=0x%08x\n", __func__, ISP_DCM);
726
727 dcm_setl(CAM_CTL_RAW_DCM, 0x00007FFF); /* set bit0~bit14=1 */
728 dcm_setl(CAM_CTL_RGB_DCM, 0x000001FF); /* set bit0~bit8=1 */
729 dcm_setl(CAM_CTL_YUV_DCM, 0x0000000F); /* set bit0~bit3=1 */
730 dcm_setl(CAM_CTL_CDP_DCM, 0x000001FF); /* set bit0~bit8=1 */
731 dcm_setl(CAM_CTL_DMA_DCM, 0x0000003F); /* set bit0~bit5=1 */
732
733 dcm_setl(JPGENC_DCM_CTRL, 0x00000001); /* set bit0=1 */
734
735 dcm_writel(VENC_CLK_DCM_CTRL, 0xFFFFFFFE); /* clear bit0 */
736 dcm_writel(VENC_CLK_CG_CTRL, 0x00000000); /* clear bit0~bit31 */
737
738 /* LARB2 \84³ ISP, VENC */
739 /* RO, bootup set once status = 1'b0, DCM off setting=N/A */
740 dcm_readl(SMILARB2_DCM_STA);
741 /* RO, bootup set once status = 1'b1, DCM off setting=1'b0 */
742 dcm_readl(SMILARB2_DCM_CON);
743 /* N/A */
744 dcm_readl(SMILARB2_DCM_SET);
745 dcm_setl(SMILARB2_DCM_CLR, (0x1 << 15)); /* set bit15=1 */
746
747 dcm_sta &= ~ISP_DCM;
748 }
749
750 if (type & VDE_DCM) {
751
752 dcm_info("[%s][VDE_DCM ]=0x%08x\n", __func__, VDE_DCM);
753
754 dcm_setl(VDEC_DCM_CON, 0x1); /* set bit0=1 */
755
756 /* LARB1 \84³ VDEC */
757 /* RO, bootup set once status = 1'b0, DCM off setting=N/A */
758 dcm_readl(SMILARB1_DCM_STA);
759 /* RO, bootup set once status = 1'b1, DCM off setting=1'b0 */
760 dcm_readl(SMILARB1_DCM_CON);
761 /* N/A */
762 dcm_readl(SMILARB1_DCM_SET);
763 dcm_setl(SMILARB1_DCM_CLR, (0x1 << 15)); /* set bit15=1 */
764
765 dcm_sta &= ~VDE_DCM;
766 }
767
768 mutex_unlock(&dcm_lock);
769 }
770
771 void bus_dcm_enable(void)
772 {
773 dcm_writel(DCM_CFG, 0x1 << 7 | 0xF);
774 }
775
776 void bus_dcm_disable(void)
777 {
778 dcm_clrl(DCM_CFG, 0x1 << 7);
779 }
780
781 static unsigned int infra_dcm;
782
783 void disable_infra_dcm(void)
784 {
785 infra_dcm = dcm_readl(INFRA_DCMCTL);
786 dcm_clrl(INFRA_DCMCTL, 0x100);
787 }
788
789 void restore_infra_dcm(void)
790 {
791 dcm_writel(INFRA_DCMCTL, infra_dcm);
792 }
793
794 static unsigned int peri_dcm;
795
796 void disable_peri_dcm(void)
797 {
798 peri_dcm = dcm_readl(PERI_GLOBALCON_DCMCTL);
799 dcm_clrl(PERI_GLOBALCON_DCMCTL, 0x1);
800 }
801
802 void restore_peri_dcm(void)
803 {
804 dcm_writel(PERI_GLOBALCON_DCMCTL, peri_dcm);
805 }
806
807 #define dcm_attr(_name) \
808 static struct kobj_attribute _name##_attr = { \
809 .attr = { \
810 .name = __stringify(_name), \
811 .mode = 0644, \
812 }, \
813 .show = _name##_show, \
814 .store = _name##_store, \
815 }
816
817 static const char *dcm_name[NR_DCMS] = {
818 "CPU_DCM",
819 "IFR_DCM",
820 "PER_DCM",
821 "SMI_DCM",
822 "MFG_DCM",
823 "DIS_DCM",
824 "ISP_DCM",
825 "VDE_DCM",
826 "TOPCKGEN_DCM",
827 };
828
829 static ssize_t dcm_state_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
830 {
831 int len = 0;
832 char *p = buf;
833
834 int i;
835 unsigned int sta;
836
837 p += sprintf(p, "********** dcm_state dump **********\n");
838 mutex_lock(&dcm_lock);
839
840 for (i = 0; i < NR_DCMS; i++) {
841 sta = dcm_sta & (0x1 << i);
842 p += sprintf(p, "[%d][%s]%s\n", i, dcm_name[i], sta ? "on" : "off");
843 }
844
845 mutex_unlock(&dcm_lock);
846
847 p += sprintf(p, "\n********** dcm_state help *********\n");
848 p += sprintf(p, "enable dcm: echo enable mask(dec) > /sys/power/dcm_state\n");
849 p += sprintf(p, "disable dcm: echo disable mask(dec) > /sys/power/dcm_state\n");
850 p += sprintf(p, "dump reg: echo dump mask(dec) > /sys/power/dcm_state\n");
851
852
853 len = p - buf;
854 return len;
855 }
856
857 static ssize_t dcm_state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n)
858 {
859 char cmd[10];
860 unsigned int mask;
861
862 if (sscanf(buf, "%s %x", cmd, &mask) == 2) {
863 mask &= ALL_DCM;
864
865 /*
866 Need to enable MM clock before setting Smi_secure register
867 to avoid system crash while screen is off(screen off with USB cable)
868 */
869 enable_mux(MT_MUX_MM, "DCM");
870
871 if (!strcmp(cmd, "enable")) {
872 dcm_dump_regs(mask);
873 dcm_enable(mask);
874 dcm_dump_regs(mask);
875 } else if (!strcmp(cmd, "disable")) {
876 dcm_dump_regs(mask);
877 dcm_disable(mask);
878 dcm_dump_regs(mask);
879 } else if (!strcmp(cmd, "dump"))
880 dcm_dump_regs(mask);
881
882 disable_mux(MT_MUX_MM, "DCM");
883
884 return n;
885 }
886
887 return -EINVAL;
888 }
889 dcm_attr(dcm_state);
890
891
892 void mt_dcm_init(void)
893 {
894 int err = 0;
895
896 dcm_info("[%s]entry!!, ALL_DCM=%d\n", __func__, ALL_DCM);
897 #if SUPPORT_MTEE_SMI_DCM_PROT
898 /*
899 Note:
900 1. SMI_SECURE_XXX register is protected by MTEE
901 SMI_DCM is enabled by DCM driver in MTEE
902 2. Although initialization sequence for DCM kernel driver and MTEE driver is not guarantee in kernel,
903 it is ok to make status of SMI_DCM to be set to "enable" in DCM kernel driver initialization
904 */
905 dcm_enable(ALL_DCM & (~SMI_DCM));
906 dcm_sta |= SMI_DCM;
907 #else
908 dcm_enable(ALL_DCM);
909 #endif
910
911 err = sysfs_create_file(power_kobj, &dcm_state_attr.attr);
912
913 if (err)
914 dcm_err("[%s]: fail to create sysfs\n", __func__);
915 }