mt_dcm.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #if defined(__KERNEL__)
  32. #include <linux/init.h>
  33. #include <linux/export.h>
  34. #include <linux/module.h>
  35. #include <linux/kernel.h>
  36. #include <linux/cpumask.h>
  37. #include <linux/cpu.h>
  38. #include <linux/bug.h>
  39. #include <linux/ratelimit.h>
  40. #include <mt-plat/mtk_io.h>
  41. #include <mt-plat/sync_write.h>
  42. #include <mach/mtk_secure_api.h>
  43. #include <linux/of.h>
  44. #include <linux/of_address.h>
  45. #include <mtk_dramc.h>
  46. #include <mt-plat/mtk_chip.h>
  47. #include <mtk_devinfo.h>
  48. #else /* !__KERNEL__ */
  49. #ifdef __CTP__
  50. #include <sync_write.h>
  51. #include <common.h>
  52. #include "efuse.h"
  53. #else /* LK */
  54. #include <debug.h>
  55. #include <stdlib.h>
  56. #include <string.h>
  57. #include <arch/arm.h>
  58. #include <arch/arm/mmu.h>
  59. #include <arch/ops.h>
  60. #include <target/board.h>
  61. #include <platform/mt_reg_base.h>
  62. #include <platform/mt_typedefs.h>
  63. #include <platform/sync_write.h>
  64. #include <platform/boot_mode.h>
  65. #include <platform/sec_devinfo.h>
  66. #endif
  67. #endif
  68. #include "mt_dcm.h"
  69. #include "mt_dcm_autogen.h"
  70. /* #define DCM_DEFAULT_ALL_OFF */
  71. #if defined(__KERNEL__)
  72. #if defined(CONFIG_OF)
  73. unsigned long dcm_topckgen_base;
  74. unsigned long dcm_mcucfg_base;
  75. unsigned long dcm_mcucfg_phys_base;
  76. unsigned long dcm_dramc_ch0_top0_base;
  77. unsigned long dcm_dramc_ch0_top1_base;
  78. unsigned long dcm_dramc_ch0_top3_base;
  79. unsigned long dcm_dramc_ch1_top0_base;
  80. unsigned long dcm_dramc_ch1_top1_base;
  81. unsigned long dcm_dramc_ch1_top3_base;
  82. unsigned long dcm_emi_base;
  83. unsigned long dcm_infracfg_ao_base;
  84. unsigned long dcm_cci_base;
  85. unsigned long dcm_cci_phys_base;
  86. #define MCUCFG_NODE "mediatek,mcucfg"
  87. #define INFRACFG_AO_NODE "mediatek,infracfg_ao"
  88. #define TOPCKGEN_NODE "mediatek,topckgen"
  89. #define DRAMC_CH0_TOP0_NODE "mediatek,dramc_ch0_top0"
  90. #define DRAMC_CH0_TOP1_NODE "mediatek,dramc_ch0_top1"
  91. #define DRAMC_CH0_TOP3_NODE "mediatek,dramc_ch0_top3"
  92. #define DRAMC_CH1_TOP0_NODE "mediatek,dramc_ch1_top0"
  93. #define DRAMC_CH1_TOP1_NODE "mediatek,dramc_ch1_top1"
  94. #define DRAMC_CH1_TOP3_NODE "mediatek,dramc_ch1_top3"
  95. #define EMI_NODE "mediatek,emi"
  96. #define CCI_NODE "mediatek,cci400"
  97. #endif /* #if defined(CONFIG_OF) */
  98. #endif /* defined(__KERNEL__) */
  99. #if !defined(__KERNEL__) /* for CTP */
  100. #define KERN_WARNING
  101. #define KERN_NOTICE
  102. #define KERN_CONT
  103. #define printk(fmt, args...) dbg_print(fmt, ##args)
  104. #define late_initcall(a)
  105. #define DEFINE_MUTEX(a)
  106. #define mutex_lock(a)
  107. #define mutex_unlock(a)
  108. #define IOMEM(a) (a)
  109. #ifdef __CTP__
  110. #define __raw_readl(a) (*(volatile unsigned long*)(a))
  111. /* #define dsb() do { __asm__ __volatile__ ("dsb\n\t"); } while(0) */
  112. #define mt_reg_sync_writel(val, addr) ({ *(unsigned long *)(addr) = val; dsb(); })
  113. #define unlikely(a) (a)
  114. /* message send by smc */
  115. #define dcm_smc_msg_send(msg) do {;} while(0)
  116. #else /* LK */
  117. extern unsigned long mt_secure_call(unsigned long, unsigned long, unsigned long, unsigned long);
  118. #define MTK_SIP_KERNEL_MCSI_A_WRITE 0x82000289
  119. #define MTK_SIP_KERNEL_MCSI_A_READ 0x8200028A
  120. #define mcsi_a_smc_read_phy(addr) \
  121. mt_secure_call(MTK_SIP_KERNEL_MCSI_A_READ, addr, 0, 0)
  122. #define mcsi_a_smc_write_phy(addr, val) \
  123. mt_secure_call(MTK_SIP_KERNEL_MCSI_A_WRITE, addr, val, 0)
  124. /* message send by smc */
  125. #define MTK_SIP_KERNEL_DCM 0x82000230
  126. #define dcm_smc_msg_send(msg) \
  127. mt_secure_call(MTK_SIP_KERNEL_DCM, msg, 0, 0)
  128. #define __raw_readl(addr) DRV_Reg32(addr)
  129. #endif
  130. /* #define BUG() do { __asm__ __volatile__ ("dsb\n\t"); } while (1) */
  131. /* #define BUG_ON(exp) do { if (exp) BUG(); } while (0) */
  132. #else /* defined(__KERNEL__) */
  133. #define USING_PR_LOG
  134. #define dcm_smc_msg_send(msg) dcm_smc_msg(msg)
  135. #endif /* !defined(__KERNEL__) */
  136. #ifdef USING_PR_LOG /* __KERNEL__ */
  137. #define TAG "[Power/dcm] "
  138. /* #define DCM_ENABLE_DCM_CFG */
  139. #define dcm_err(fmt, args...) pr_err(TAG fmt, ##args)
  140. #define dcm_warn(fmt, args...) pr_warn(TAG fmt, ##args)
  141. #define dcm_warn_limit(fmt, args...) pr_warn_ratelimited(TAG fmt, ##args)
  142. #define dcm_info(fmt, args...) pr_notice(TAG fmt, ##args)
  143. #define dcm_dbg(fmt, args...) \
  144. do { \
  145. if (dcm_debug) \
  146. pr_warn(TAG fmt, ##args); \
  147. } while (0)
  148. #define dcm_ver(fmt, args...) pr_debug(TAG fmt, ##args)
  149. #else /* !USING_PR_LOG: CTP/LK */
  150. #ifdef __CTP__
  151. #define TAG "[Power/dcm] "
  152. #undef pr_debug
  153. #define pr_debug printk
  154. #define dcm_err(fmt, args...) \
  155. do { \
  156. pr_debug(KERN_ERR TAG); \
  157. pr_debug(KERN_CONT fmt, ##args); \
  158. } while (0)
  159. #define dcm_warn(fmt, args...) \
  160. do { \
  161. pr_debug(KERN_WARNING TAG); \
  162. pr_debug(KERN_CONT fmt, ##args); \
  163. } while (0)
  164. #define dcm_warn_limit(fmt, args...) \
  165. do { \
  166. pr_debug(KERN_WARNING TAG); \
  167. pr_debug(KERN_CONT fmt, ##args); \
  168. } while (0)
  169. #define dcm_info(fmt, args...) \
  170. do { \
  171. pr_debug(KERN_NOTICE TAG); \
  172. pr_debug(KERN_CONT fmt, ##args); \
  173. } while (0)
  174. #define dcm_dbg(fmt, args...) \
  175. do { \
  176. pr_debug(KERN_INFO TAG); \
  177. pr_debug(KERN_CONT fmt, ##args); \
  178. } while (0)
  179. #define dcm_ver(fmt, args...) \
  180. do { \
  181. pr_debug(KERN_DEBUG TAG); \
  182. pr_debug(KERN_CONT fmt, ##args); \
  183. } while (0)
  184. #else /* LK */
  185. #define dcm_err(fmt, args...) dprintf(CRITICAL, fmt, ##args)
  186. #define dcm_warn(fmt, args...) dprintf(CRITICAL, fmt, ##args)
  187. #define dcm_warn_limit(fmt, args...) dprintf(CRITICAL, fmt, ##args)
  188. #define dcm_info(fmt, args...) dprintf(INFO, fmt, ##args)
  189. #define dcm_dbg(fmt, args...) dprintf(SPEW, fmt, ##args)
  190. #define dcm_ver(fmt, args...) dprintf(SPEW, fmt, ##args)
  191. #endif
  192. #endif
  193. /** macro **/
  194. #define and(v, a) ((v) & (a))
  195. #define or(v, o) ((v) | (o))
  196. #define aor(v, a, o) (((v) & (a)) | (o))
  197. #define reg_read(addr) __raw_readl(IOMEM(addr))
  198. #define reg_write(addr, val) mt_reg_sync_writel((val), ((void *)addr))
  199. #if defined(__KERNEL__) /* for KERNEL */
  200. #if defined(CONFIG_ARM_PSCI) || defined(CONFIG_MTK_PSCI)
  201. #define MCUSYS_SMC_WRITE(addr, val) mcusys_smc_write_phy(addr##_PHYS, val)
  202. #define MCSI_A_SMC_WRITE(addr, val) mcsi_a_smc_write_phy(addr##_PHYS, val)
  203. #define MCSI_A_SMC_READ(addr) mcsi_a_smc_read_phy(addr##_PHYS)
  204. #else
  205. #define MCUSYS_SMC_WRITE(addr, val) mcusys_smc_write(addr, val)
  206. #define MCSI_A_SMC_WRITE(addr, val) reg_write(addr, val)
  207. #define MCSI_A_SMC_READ(addr) reg_read(addr)
  208. #endif
  209. #else /* !defined(__KERNEL__), for CTP */
  210. #ifdef __CTP__
  211. #define MCUSYS_SMC_WRITE(addr, val) reg_write(addr, val)
  212. #define MCSI_A_SMC_WRITE(addr, val) reg_write(addr, val)
  213. #define MCSI_A_SMC_READ(addr) reg_read(addr)
  214. #else /* __LK__ */
  215. #define MCUSYS_SMC_WRITE(addr, val) reg_write(addr, val)
  216. #define MCSI_A_SMC_WRITE(addr, val) mcsi_a_smc_write_phy(addr##_PHYS, val)
  217. #define MCSI_A_SMC_READ(addr) mcsi_a_smc_read_phy(addr##_PHYS)
  218. #endif /* ifdef __CTP__ */
  219. #endif /* defined(__KERNEL__) */
  220. #ifdef USING_PR_LOG
  221. #define REG_DUMP(addr) dcm_info("%-30s(0x%08lx): 0x%08x\n", #addr, addr, reg_read(addr))
  222. #define SECURE_REG_DUMP(addr) dcm_info("%-30s(0x%08lx): 0x%08x\n", #addr, addr, mcsi_a_smc_read_phy(addr##_PHYS))
  223. #else
  224. #ifdef __CTP__
  225. #define REG_DUMP(addr) dcm_info("%s(0x%X): 0x%X\n", #addr, addr, reg_read(addr))
  226. #define SECURE_REG_DUMP(addr) dcm_info("%s(0x%X): 0x%X\n", #addr, addr, reg_read(addr))
  227. #else /* __LK__ */
  228. #define REG_DUMP(addr) dcm_info("%-30s(0x%08lx): 0x%08x\n", #addr, addr, reg_read(addr))
  229. #define SECURE_REG_DUMP(addr) dcm_info("%-30s(0x%08lx): 0x%08x\n", #addr, addr, mcsi_a_smc_read_phy(addr##_PHYS))
  230. #endif /* ifdef __CTP__ */
  231. #endif
  232. /** global **/
  233. #if defined(__KERNEL__)
  234. static DEFINE_MUTEX(dcm_lock);
  235. #endif
  236. static short dcm_initiated = DCM_NOT_INIT;
  237. static short dcm_debug;
  238. static unsigned int all_dcm_type = (ARMCORE_DCM_TYPE | MCUSYS_DCM_TYPE | INFRA_DCM_TYPE |
  239. PERI_DCM_TYPE | EMI_DCM_TYPE | DRAMC_DCM_TYPE | DDRPHY_DCM_TYPE |
  240. STALL_DCM_TYPE);
  241. static unsigned int init_dcm_type = (ARMCORE_DCM_TYPE | MCUSYS_DCM_TYPE | INFRA_DCM_TYPE |
  242. PERI_DCM_TYPE | STALL_DCM_TYPE);
  243. static unsigned int enhance_dcm_type;
  244. /*****************************************
  245. * following is implementation per DCM module.
  246. * 1. per-DCM function is 1-argu with ON/OFF/MODE option.
  247. *****************************************/
  248. typedef int (*DCM_FUNC)(int);
  249. typedef void (*DCM_PRESET_FUNC)(void);
  250. int dcm_armcore(ENUM_ARMCORE_DCM mode)
  251. {
  252. if (mode == ARMCORE_DCM_MODE1) {
  253. dcm_infracfg_ao_mcu_armpll_bus_mode1(mode);
  254. dcm_infracfg_ao_mcu_armpll_ca7l_mode1(mode);
  255. dcm_infracfg_ao_mcu_armpll_ca7ll_mode1(mode);
  256. } else if (mode == ARMCORE_DCM_MODE2) {
  257. dcm_infracfg_ao_mcu_armpll_bus_mode2(mode);
  258. dcm_infracfg_ao_mcu_armpll_ca7l_mode2(mode);
  259. dcm_infracfg_ao_mcu_armpll_ca7ll_mode2(mode);
  260. } else {
  261. dcm_infracfg_ao_mcu_armpll_bus_mode2(mode);
  262. dcm_infracfg_ao_mcu_armpll_ca7l_mode2(mode);
  263. dcm_infracfg_ao_mcu_armpll_ca7ll_mode2(mode);
  264. }
  265. return 0;
  266. }
  267. int dcm_infra(ENUM_INFRA_DCM on)
  268. {
  269. /* ASSERT_INFRA_DCMCTL(); */
  270. dcm_infracfg_ao_dcm_infra_bus(on);
  271. dcm_infracfg_ao_p2p_rxclk_ctrl(on);
  272. dcm_infracfg_ao_infra_md_fmem(on);
  273. /* dcm_infracfg_ao_dcm_mem_ctrl(on); Controlled by DRAMC driver in preloader */
  274. /* dcm_infracfg_ao_dcm_dfs_mem_ctrl(on); No used, removed from infra-ao */
  275. return 0;
  276. }
  277. int dcm_infra_dbc(int cnt)
  278. {
  279. #if 0
  280. reg_write(INFRA_BUS_DCM_CTRL, aor(reg_read(INFRA_BUS_DCM_CTRL),
  281. ~(0x1f << 15), (cnt << 15)));
  282. #endif
  283. return 0;
  284. }
  285. /*
  286. * input argument
  287. * 0: 1/1
  288. * 1: 1/2
  289. * 2: 1/4
  290. * 3: 1/8
  291. * 4: 1/16
  292. * 5: 1/32
  293. * default: 0, 0
  294. */
  295. int dcm_infra_rate(unsigned int fsel, unsigned int sfsel)
  296. {
  297. #if 0
  298. WARN_ON(fsel > 5 || sfsel > 5);
  299. fsel = 0x10 >> fsel;
  300. sfsel = 0x10 >> sfsel;
  301. reg_write(INFRA_BUS_DCM_CTRL, aor(reg_read(INFRA_BUS_DCM_CTRL),
  302. ~INFRA_BUS_DCM_CTRL_SEL_MASK,
  303. ((fsel << 5) | (sfsel << 10))));
  304. #endif
  305. return 0;
  306. }
  307. int dcm_peri(ENUM_PERI_DCM on)
  308. {
  309. dcm_infracfg_ao_dcm_peri_bus(on);
  310. return 0;
  311. }
  312. int dcm_peri_dbc(int cnt)
  313. {
  314. #if 0
  315. reg_write(PERI_BUS_DCM_CTRL, aor(reg_read(PERI_BUS_DCM_CTRL),
  316. ~(0x1f << 15),
  317. (cnt << 15)));
  318. #endif
  319. return 0;
  320. }
  321. /*
  322. * input argument
  323. * 0: 1/1
  324. * 1: 1/2
  325. * 2: 1/4
  326. * 3: 1/8
  327. * 4: 1/16
  328. * 5: 1/32
  329. * default: 0, 0
  330. */
  331. int dcm_peri_rate(unsigned int fsel, unsigned int sfsel)
  332. {
  333. #if 0
  334. WARN_ON(fsel > 5 || sfsel > 5);
  335. fsel = 0x10 >> fsel;
  336. sfsel = 0x10 >> sfsel;
  337. reg_write(PERI_BUS_DCM_CTRL, aor(reg_read(PERI_BUS_DCM_CTRL),
  338. ~PERI_DCM_SEL_MASK,
  339. ((fsel << 5) | (sfsel << 10))));
  340. #endif
  341. return 0;
  342. }
  343. int dcm_mcusys(ENUM_MCUSYS_DCM on)
  344. {
  345. /* Bypass for ICE cannot attach issue */
  346. /* dcm_mp0_cpucfg_dcm_mcu_bus(on); */
  347. /* dcm_mp1_cpucfg_dcm_mcu_bus(on); */
  348. dcm_mcu_misccfg_dcm_mcu_bus(on);
  349. dcm_mcu_misccfg_cci_sync_dcm(on);
  350. dcm_mcu_misccfg_mp0_sync_dcm(on);
  351. dcm_mcu_misccfg_mp1_sync_dcm(on);
  352. dcm_mcsi_a(on);
  353. return 0;
  354. }
  355. int dcm_mcusys_cci_stall(ENUM_MCUSYS_DCM on)
  356. {
  357. return 0;
  358. }
  359. int dcm_mcusys_sync_dcm(ENUM_MCUSYS_DCM on)
  360. {
  361. return 0;
  362. }
  363. int dcm_dramc_ao(ENUM_DRAMC_AO_DCM on)
  364. {
  365. dcm_dramc_ch0_top1_dcm_dramc_ch0_pd_ctrl(on);
  366. dcm_chn0_emi_dcm_emi_group(on);
  367. dcm_dramc_ch1_top1_dcm_dramc_ch1_pd_ctrl(on);
  368. dcm_chn1_emi_dcm_emi_group(on);
  369. return 0;
  370. }
  371. int dcm_ddrphy(ENUM_DDRPHY_DCM on)
  372. {
  373. dcm_dramc_ch0_top0_ddrphy(on);
  374. dcm_dramc_ch1_top0_ddrphy(on);
  375. return 0;
  376. }
  377. int dcm_emi(ENUM_EMI_DCM on)
  378. {
  379. dcm_emi_dcm_emi_group(on);
  380. return 0;
  381. }
  382. int dcm_stall_enhance(ENUM_STALL_DCM on)
  383. {
  384. dcm_mcu_misccfg_stall_dcm_enhance(on);
  385. return 0;
  386. }
  387. int dcm_stall_preset(void)
  388. {
  389. if (enhance_dcm_type & STALL_DCM_TYPE)
  390. dcm_stall_enhance(DCM_ON);
  391. return 0;
  392. }
  393. int dcm_stall(ENUM_STALL_DCM on)
  394. {
  395. dcm_mcu_misccfg_mp0_stall_dcm(on);
  396. dcm_mcu_misccfg_mp1_stall_dcm(on);
  397. return 0;
  398. }
  399. int dcm_gic_sync(ENUM_GIC_SYNC_DCM on)
  400. {
  401. dcm_mcu_misccfg_gic_sync_dcm(on);
  402. return 0;
  403. }
  404. int dcm_last_core(ENUM_LAST_CORE_DCM on)
  405. {
  406. dcm_mcu_misccfg_mp0_last_core_dcm(on);
  407. dcm_mcu_misccfg_mp1_last_core_dcm(on);
  408. return 0;
  409. }
  410. int dcm_rgu(ENUM_RGU_DCM on)
  411. {
  412. dcm_mcu_misccfg_mp0_rgu_dcm(on);
  413. dcm_mcu_misccfg_mp1_rgu_dcm(on);
  414. return 0;
  415. }
  416. /*****************************************************/
  417. typedef struct _dcm {
  418. int current_state;
  419. int saved_state;
  420. int disable_refcnt;
  421. int default_state;
  422. DCM_FUNC func;
  423. DCM_PRESET_FUNC preset_func;
  424. int typeid;
  425. char *name;
  426. } DCM;
  427. static DCM dcm_array[NR_DCM_TYPE] = {
  428. {
  429. .typeid = ARMCORE_DCM_TYPE,
  430. .name = "ARMCORE_DCM",
  431. .func = (DCM_FUNC) dcm_armcore,
  432. .current_state = ARMCORE_DCM_MODE1,
  433. .default_state = ARMCORE_DCM_MODE1,
  434. .disable_refcnt = 0,
  435. },
  436. {
  437. .typeid = MCUSYS_DCM_TYPE,
  438. .name = "MCUSYS_DCM",
  439. .func = (DCM_FUNC) dcm_mcusys,
  440. .current_state = MCUSYS_DCM_ON,
  441. .default_state = MCUSYS_DCM_ON,
  442. .disable_refcnt = 0,
  443. },
  444. {
  445. .typeid = INFRA_DCM_TYPE,
  446. .name = "INFRA_DCM",
  447. .func = (DCM_FUNC) dcm_infra,
  448. /*.preset_func = (DCM_PRESET_FUNC) dcm_infra_preset,*/
  449. .current_state = INFRA_DCM_ON,
  450. .default_state = INFRA_DCM_ON,
  451. .disable_refcnt = 0,
  452. },
  453. {
  454. .typeid = PERI_DCM_TYPE,
  455. .name = "PERI_DCM",
  456. .func = (DCM_FUNC) dcm_peri,
  457. /*.preset_func = (DCM_PRESET_FUNC) dcm_peri_preset,*/
  458. .current_state = PERI_DCM_ON,
  459. .default_state = PERI_DCM_ON,
  460. .disable_refcnt = 0,
  461. },
  462. {
  463. .typeid = EMI_DCM_TYPE,
  464. .name = "EMI_DCM",
  465. .func = (DCM_FUNC) dcm_emi,
  466. .current_state = EMI_DCM_ON,
  467. .default_state = EMI_DCM_ON,
  468. .disable_refcnt = 0,
  469. },
  470. {
  471. .typeid = DRAMC_DCM_TYPE,
  472. .name = "DRAMC_DCM",
  473. .func = (DCM_FUNC) dcm_dramc_ao,
  474. .current_state = DRAMC_AO_DCM_ON,
  475. .default_state = DRAMC_AO_DCM_ON,
  476. .disable_refcnt = 0,
  477. },
  478. {
  479. .typeid = DDRPHY_DCM_TYPE,
  480. .name = "DDRPHY_DCM",
  481. .func = (DCM_FUNC) dcm_ddrphy,
  482. .current_state = DDRPHY_DCM_ON,
  483. .default_state = DDRPHY_DCM_ON,
  484. .disable_refcnt = 0,
  485. },
  486. {
  487. .typeid = STALL_DCM_TYPE,
  488. .name = "STALL_DCM",
  489. .func = (DCM_FUNC) dcm_stall,
  490. .preset_func = (DCM_PRESET_FUNC) dcm_stall_preset,
  491. .current_state = STALL_DCM_ON,
  492. .default_state = STALL_DCM_ON,
  493. .disable_refcnt = 0,
  494. },
  495. {
  496. .typeid = GIC_SYNC_DCM_TYPE,
  497. .name = "GIC_SYNC_DCM",
  498. .func = (DCM_FUNC) dcm_gic_sync,
  499. .current_state = GIC_SYNC_DCM_ON,
  500. .default_state = GIC_SYNC_DCM_ON,
  501. .disable_refcnt = 0,
  502. },
  503. {
  504. .typeid = LAST_CORE_DCM_TYPE,
  505. .name = "LAST_CORE_DCM",
  506. .func = (DCM_FUNC) dcm_last_core,
  507. .current_state = LAST_CORE_DCM_ON,
  508. .default_state = LAST_CORE_DCM_ON,
  509. .disable_refcnt = 0,
  510. },
  511. {
  512. .typeid = RGU_DCM_TYPE,
  513. .name = "RGU_DCM",
  514. .func = (DCM_FUNC) dcm_rgu,
  515. .current_state = RGU_DCM_ON,
  516. .default_state = RGU_DCM_ON,
  517. .disable_refcnt = 0,
  518. },
  519. };
  520. /*****************************************
  521. * DCM driver will provide regular APIs :
  522. * 1. dcm_restore(type) to recovery CURRENT_STATE before any power-off reset.
  523. * 2. dcm_set_default(type) to reset as cold-power-on init state.
  524. * 3. dcm_disable(type) to disable all dcm.
  525. * 4. dcm_set_state(type) to set dcm state.
  526. * 5. dcm_dump_state(type) to show CURRENT_STATE.
  527. * 6. /sys/power/dcm_state interface: 'restore', 'disable', 'dump', 'set'. 4 commands.
  528. *
  529. * spsecified APIs for workaround:
  530. * 1. (definitely no workaround now)
  531. *****************************************/
  532. void dcm_set_default(unsigned int type)
  533. {
  534. int i;
  535. DCM *dcm;
  536. #ifndef ENABLE_DCM_IN_LK
  537. #ifdef USING_PR_LOG
  538. dcm_warn("[%s]type:0x%08x, init_dcm_type=0x%x\n", __func__, type, init_dcm_type);
  539. #endif
  540. #else
  541. #ifdef USING_PR_LOG
  542. dcm_warn("[%s]type:0x%08x, init_dcm_type=0x%x, INIT_DCM_TYPE_BY_K=0x%x\n",
  543. __func__, type, init_dcm_type, INIT_DCM_TYPE_BY_K);
  544. #endif
  545. #endif
  546. mutex_lock(&dcm_lock);
  547. for (i = 0, dcm = &dcm_array[0]; i < NR_DCM_TYPE; i++, dcm++) {
  548. if (type & dcm->typeid) {
  549. dcm->saved_state = dcm->default_state;
  550. dcm->current_state = dcm->default_state;
  551. dcm->disable_refcnt = 0;
  552. #ifdef ENABLE_DCM_IN_LK
  553. if (INIT_DCM_TYPE_BY_K & dcm->typeid) {
  554. #endif
  555. if (dcm->preset_func)
  556. dcm->preset_func();
  557. dcm->func(dcm->current_state);
  558. #ifdef ENABLE_DCM_IN_LK
  559. }
  560. #endif
  561. #ifdef USING_PR_LOG
  562. dcm_info("[%16s 0x%08x] current state:%d (%d)\n",
  563. dcm->name, dcm->typeid, dcm->current_state,
  564. dcm->disable_refcnt);
  565. #endif
  566. }
  567. }
  568. dcm_smc_msg_send(init_dcm_type);
  569. mutex_unlock(&dcm_lock);
  570. }
  571. void dcm_set_state(unsigned int type, int state)
  572. {
  573. int i;
  574. DCM *dcm;
  575. unsigned int init_dcm_type_pre = init_dcm_type;
  576. #ifdef USING_PR_LOG
  577. dcm_warn("[%s]type:0x%08x, set:%d, init_dcm_type_pre=0x%X\n",
  578. __func__, type, state, init_dcm_type_pre);
  579. #endif
  580. mutex_lock(&dcm_lock);
  581. for (i = 0, dcm = &dcm_array[0]; type && (i < NR_DCM_TYPE); i++, dcm++) {
  582. if (type & dcm->typeid) {
  583. type &= ~(dcm->typeid);
  584. dcm->saved_state = state;
  585. if (dcm->disable_refcnt == 0) {
  586. if (state)
  587. init_dcm_type |= dcm->typeid;
  588. else
  589. init_dcm_type &= ~(dcm->typeid);
  590. dcm->current_state = state;
  591. dcm->func(dcm->current_state);
  592. }
  593. #ifdef USING_PR_LOG
  594. dcm_info("[%16s 0x%08x] current state:%d (%d)\n",
  595. dcm->name, dcm->typeid, dcm->current_state,
  596. dcm->disable_refcnt);
  597. #endif
  598. }
  599. }
  600. if (init_dcm_type_pre != init_dcm_type) {
  601. dcm_warn("[%s]type:0x%X, set:%d, init_dcm_type=0x%X->0x%X\n",
  602. __func__, type, state, init_dcm_type_pre, init_dcm_type);
  603. dcm_smc_msg_send(init_dcm_type);
  604. }
  605. mutex_unlock(&dcm_lock);
  606. }
  607. void dcm_disable(unsigned int type)
  608. {
  609. int i;
  610. DCM *dcm;
  611. unsigned int init_dcm_type_pre = init_dcm_type;
  612. #ifdef USING_PR_LOG
  613. dcm_warn("[%s]type:0x%08x, init_dcm_type_pre=0x%X\n",
  614. __func__, type, init_dcm_type_pre);
  615. #endif
  616. mutex_lock(&dcm_lock);
  617. for (i = 0, dcm = &dcm_array[0]; type && (i < NR_DCM_TYPE); i++, dcm++) {
  618. if (type & dcm->typeid) {
  619. type &= ~(dcm->typeid);
  620. dcm->current_state = DCM_OFF;
  621. if (dcm->disable_refcnt++ == 0)
  622. init_dcm_type &= ~(dcm->typeid);
  623. dcm->func(dcm->current_state);
  624. #ifdef USING_PR_LOG
  625. dcm_info("[%16s 0x%08x] current state:%d (%d)\n",
  626. dcm->name, dcm->typeid, dcm->current_state,
  627. dcm->disable_refcnt);
  628. #endif
  629. }
  630. }
  631. if (init_dcm_type_pre != init_dcm_type) {
  632. dcm_warn("[%s]type:0x%X, init_dcm_type=0x%X->0x%X\n",
  633. __func__, type, init_dcm_type_pre, init_dcm_type);
  634. dcm_smc_msg_send(init_dcm_type);
  635. }
  636. mutex_unlock(&dcm_lock);
  637. }
  638. void dcm_restore(unsigned int type)
  639. {
  640. int i;
  641. DCM *dcm;
  642. unsigned int init_dcm_type_pre = init_dcm_type;
  643. #ifdef USING_PR_LOG
  644. dcm_warn("[%s]type:0x%08x, init_dcm_type_pre=0x%X\n",
  645. __func__, type, init_dcm_type_pre);
  646. #endif
  647. mutex_lock(&dcm_lock);
  648. for (i = 0, dcm = &dcm_array[0]; type && (i < NR_DCM_TYPE); i++, dcm++) {
  649. if (type & dcm->typeid) {
  650. type &= ~(dcm->typeid);
  651. if (dcm->disable_refcnt > 0)
  652. dcm->disable_refcnt--;
  653. if (dcm->disable_refcnt == 0) {
  654. if (dcm->saved_state)
  655. init_dcm_type |= dcm->typeid;
  656. else
  657. init_dcm_type &= ~(dcm->typeid);
  658. dcm->current_state = dcm->saved_state;
  659. dcm->func(dcm->current_state);
  660. }
  661. #ifdef USING_PR_LOG
  662. dcm_info("[%16s 0x%08x] current state:%d (%d)\n",
  663. dcm->name, dcm->typeid, dcm->current_state,
  664. dcm->disable_refcnt);
  665. #endif
  666. }
  667. }
  668. if (init_dcm_type_pre != init_dcm_type) {
  669. dcm_warn("[%s]type:0x%X, init_dcm_type=0x%X->0x%X\n",
  670. __func__, type, init_dcm_type_pre, init_dcm_type);
  671. dcm_smc_msg_send(init_dcm_type);
  672. }
  673. mutex_unlock(&dcm_lock);
  674. }
  675. void dcm_dump_state(int type)
  676. {
  677. int i;
  678. DCM *dcm;
  679. dcm_info("\n******** dcm dump state *********\n");
  680. for (i = 0, dcm = &dcm_array[0]; i < NR_DCM_TYPE; i++, dcm++) {
  681. if (type & dcm->typeid) {
  682. #ifdef USING_PR_LOG
  683. dcm_info("[%-16s 0x%08x] current state:%d (%d)\n",
  684. dcm->name, dcm->typeid, dcm->current_state,
  685. dcm->disable_refcnt);
  686. #endif
  687. }
  688. }
  689. }
  690. void dcm_dump_regs(void)
  691. {
  692. dcm_info("\n******** dcm dump register *********\n");
  693. REG_DUMP(INFRA_TOPCKGEN_DCMCTL);
  694. REG_DUMP(INFRA_BUS_DCM_CTRL);
  695. REG_DUMP(PERI_BUS_DCM_CTRL);
  696. REG_DUMP(MEM_DCM_CTRL);
  697. REG_DUMP(DFS_MEM_DCM_CTRL);
  698. REG_DUMP(INFRA_MISC);
  699. REG_DUMP(MP0_DBG_PWR_CTRL);
  700. REG_DUMP(MP1_DBG_PWR_CTRL);
  701. REG_DUMP(L2C_SRAM_CTRL);
  702. REG_DUMP(CCI_CLK_CTRL);
  703. REG_DUMP(BUS_FABRIC_DCM_CTRL);
  704. REG_DUMP(CCI_ADB400_DCM_CONFIG);
  705. REG_DUMP(SYNC_DCM_CONFIG);
  706. REG_DUMP(SYNC_DCM_CLUSTER_CONFIG);
  707. REG_DUMP(BIG_DBG_PWR_CTRL);
  708. REG_DUMP(EMI_CONM);
  709. REG_DUMP(EMI_CONN);
  710. REG_DUMP(DRAMC_CH0_TOP0_MISC_CG_CTRL0);
  711. REG_DUMP(DRAMC_CH0_TOP0_MISC_CG_CTRL2);
  712. REG_DUMP(DRAMC_CH0_TOP1_DRAMC_PD_CTRL);
  713. REG_DUMP(DRAMC_CH0_TOP1_CLKAR);
  714. REG_DUMP(CHN0_EMI_CHN_EMI_CONB);
  715. REG_DUMP(DRAMC_CH1_TOP0_MISC_CG_CTRL0);
  716. REG_DUMP(DRAMC_CH1_TOP0_MISC_CG_CTRL2);
  717. REG_DUMP(DRAMC_CH1_TOP1_DRAMC_PD_CTRL);
  718. REG_DUMP(DRAMC_CH1_TOP1_CLKAR);
  719. REG_DUMP(CHN1_EMI_CHN_EMI_CONB);
  720. SECURE_REG_DUMP(MCSI_A_DCM);
  721. if (init_dcm_type & LAST_CORE_DCM_TYPE) {
  722. REG_DUMP(MP0_LAST_CORE_DCM);
  723. REG_DUMP(MP1_LAST_CORE_DCM);
  724. }
  725. if (init_dcm_type & GIC_SYNC_DCM_TYPE)
  726. REG_DUMP(GIC_SYNC_DCM_CFG);
  727. if (init_dcm_type & RGU_DCM_TYPE) {
  728. REG_DUMP(MP0_RGU_DCM_CONFIG);
  729. REG_DUMP(MP1_RGU_DCM_CONFIG);
  730. }
  731. }
  732. #if defined(CONFIG_PM)
  733. static ssize_t dcm_state_show(struct kobject *kobj, struct kobj_attribute *attr,
  734. char *buf)
  735. {
  736. int len = 0;
  737. char *p = buf;
  738. int i;
  739. DCM *dcm;
  740. if (dcm_initiated != DCM_INIT_SUCCESS) {
  741. dcm_warn_limit("error: due to dcm init fail\n");
  742. return len;
  743. }
  744. /* dcm_dump_state(all_dcm_type); */
  745. len += snprintf(buf+len, PAGE_SIZE-len,
  746. "\n******** dcm dump state *********\n");
  747. for (i = 0, dcm = &dcm_array[0]; i < NR_DCM_TYPE; i++, dcm++)
  748. len += snprintf(buf+len, PAGE_SIZE-len,
  749. "[%-16s 0x%08x] current state:%d (%d)\n",
  750. dcm->name, dcm->typeid, dcm->current_state,
  751. dcm->disable_refcnt);
  752. len += snprintf(buf+len, PAGE_SIZE-len,
  753. "\n********** dcm_state help *********\n");
  754. len += snprintf(buf+len, PAGE_SIZE-len,
  755. "set: echo set [mask] [mode] > /sys/power/dcm_state\n");
  756. len += snprintf(buf+len, PAGE_SIZE-len,
  757. "disable: echo disable [mask] > /sys/power/dcm_state\n");
  758. len += snprintf(buf+len, PAGE_SIZE-len,
  759. "restore: echo restore [mask] > /sys/power/dcm_state\n");
  760. len += snprintf(buf+len, PAGE_SIZE-len,
  761. "dump: echo dump [mask] > /sys/power/dcm_state\n");
  762. len += snprintf(buf+len, PAGE_SIZE-len,
  763. "***** [mask] is hexl bit mask of dcm;\n");
  764. len += snprintf(buf+len, PAGE_SIZE-len,
  765. "***** [mode] is type of DCM to set and retained\n");
  766. return len;
  767. }
  768. #define MCUSYS_STALL_DCM_MP0_WR_DEL_SEL_MASK (0x1F << 0)
  769. #define MCUSYS_STALL_DCM_MP1_WR_DEL_SEL_MASK (0x1F << 8)
  770. static int dcm_convert_stall_wr_del_sel(unsigned int val)
  771. {
  772. if (val < 0 || val > 0x1F)
  773. return 0;
  774. else
  775. return val;
  776. }
  777. int dcm_set_stall_wr_del_sel(unsigned int mp0, unsigned int mp1)
  778. {
  779. mutex_lock(&dcm_lock);
  780. reg_write(SYNC_DCM_CLUSTER_CONFIG,
  781. aor(reg_read(SYNC_DCM_CLUSTER_CONFIG),
  782. ~(MCUSYS_STALL_DCM_MP0_WR_DEL_SEL_MASK |
  783. MCUSYS_STALL_DCM_MP1_WR_DEL_SEL_MASK),
  784. ((dcm_convert_stall_wr_del_sel(mp0) << 0) |
  785. (dcm_convert_stall_wr_del_sel(mp1) << 8))));
  786. mutex_unlock(&dcm_lock);
  787. return 0;
  788. }
  789. static ssize_t dcm_state_store(struct kobject *kobj,
  790. struct kobj_attribute *attr, const char *buf,
  791. size_t n)
  792. {
  793. char cmd[16];
  794. unsigned int mask, init_dcm_type_pre;
  795. unsigned int mp0, mp1;
  796. int ret, mode;
  797. if (dcm_initiated != DCM_INIT_SUCCESS) {
  798. dcm_warn_limit("error: due to dcm init fail\n");
  799. return -EINVAL;
  800. }
  801. if (sscanf(buf, "%15s %x", cmd, &mask) == 2) {
  802. mask &= all_dcm_type;
  803. if (!strcmp(cmd, "restore")) {
  804. /* dcm_dump_regs(); */
  805. dcm_restore(mask);
  806. /* dcm_dump_regs(); */
  807. } else if (!strcmp(cmd, "disable")) {
  808. /* dcm_dump_regs(); */
  809. dcm_disable(mask);
  810. /* dcm_dump_regs(); */
  811. } else if (!strcmp(cmd, "dump")) {
  812. dcm_dump_state(mask);
  813. dcm_dump_regs();
  814. } else if (!strcmp(cmd, "debug")) {
  815. init_dcm_type_pre = init_dcm_type;
  816. switch (mask) {
  817. case 0:
  818. dcm_debug = 0;
  819. break;
  820. case 1:
  821. dcm_debug = 1;
  822. break;
  823. case 4:
  824. enhance_dcm_type |= STALL_DCM_TYPE;
  825. dcm_stall(DCM_OFF);
  826. dcm_stall_enhance(DCM_ON);
  827. stall(DCM_ON);
  828. dcm_warn("stall_dcm_enhance is enabled\n");
  829. break;
  830. case 5:
  831. enhance_dcm_type |= (GIC_SYNC_DCM_TYPE | RGU_DCM_TYPE);
  832. init_dcm_type |= (GIC_SYNC_DCM_TYPE | RGU_DCM_TYPE);
  833. dcm_gic_sync(DCM_ON);
  834. dcm_rgu(DCM_ON);
  835. dcm_warn("gic_sync_dcm and rgu_dcm is enabled\n");
  836. break;
  837. case 6:
  838. enhance_dcm_type |= LAST_CORE_DCM_TYPE;
  839. init_dcm_type |= LAST_CORE_DCM_TYPE;
  840. dcm_last_core(DCM_ON);
  841. dcm_warn("last_core_dcm is enabled\n");
  842. break;
  843. default:
  844. break;
  845. }
  846. if (init_dcm_type_pre != init_dcm_type) {
  847. all_dcm_type |= enhance_dcm_type;
  848. dcm_warn("init_dcm_type=0x%X->0x%X\n",
  849. init_dcm_type_pre, init_dcm_type);
  850. dcm_smc_msg_send(init_dcm_type);
  851. }
  852. } else if (!strcmp(cmd, "set_stall_sel")) {
  853. if (sscanf(buf, "%15s %x %x", cmd, &mp0, &mp1) == 3) {
  854. dcm_set_stall_wr_del_sel(mp0, mp1);
  855. }
  856. } else if (!strcmp(cmd, "set")) {
  857. if (sscanf(buf, "%15s %x %d", cmd, &mask, &mode) == 3) {
  858. mask &= all_dcm_type;
  859. dcm_set_state(mask, mode);
  860. /* Log for stallDCM switching in Performance/Normal mode */
  861. if (mask & 0x80) {
  862. if (mode)
  863. dcm_info("stall dcm is enabled for Default(Normal) mode started\n");
  864. else
  865. dcm_info("stall dcm is disabled for Performance(Sports) mode started\n");
  866. }
  867. }
  868. } else {
  869. dcm_info("SORRY, do not support your command: %s\n", cmd);
  870. }
  871. ret = n;
  872. } else {
  873. dcm_info("SORRY, do not support your command.\n");
  874. ret = -EINVAL;
  875. }
  876. return ret;
  877. }
  878. static struct kobj_attribute dcm_state_attr = {
  879. .attr = {
  880. .name = "dcm_state",
  881. .mode = 0644,
  882. },
  883. .show = dcm_state_show,
  884. .store = dcm_state_store,
  885. };
  886. #endif /* #if defined (CONFIG_PM) */
  887. #if defined(CONFIG_OF)
  888. static int mt_dcm_dts_map(void)
  889. {
  890. struct device_node *node;
  891. struct resource r;
  892. /* topckgen */
  893. node = of_find_compatible_node(NULL, NULL, TOPCKGEN_NODE);
  894. if (!node) {
  895. dcm_info("error: cannot find node " TOPCKGEN_NODE);
  896. goto dcm_error;
  897. }
  898. dcm_topckgen_base = (unsigned long)of_iomap(node, 0);
  899. if (!dcm_topckgen_base) {
  900. dcm_info("error: cannot iomap " TOPCKGEN_NODE);
  901. goto dcm_error;
  902. }
  903. /* mcucfg */
  904. node = of_find_compatible_node(NULL, NULL, MCUCFG_NODE);
  905. if (!node) {
  906. dcm_info("error: cannot find node " MCUCFG_NODE);
  907. goto dcm_error;
  908. }
  909. if (of_address_to_resource(node, 0, &r)) {
  910. dcm_info("error: cannot get phys addr" MCUCFG_NODE);
  911. goto dcm_error;
  912. }
  913. dcm_mcucfg_phys_base = r.start;
  914. dcm_mcucfg_base = (unsigned long)of_iomap(node, 0);
  915. if (!dcm_mcucfg_base) {
  916. dcm_info("error: cannot iomap " MCUCFG_NODE);
  917. goto dcm_error;
  918. }
  919. /* dramc_ch0_top0 */
  920. node = of_find_compatible_node(NULL, NULL, DRAMC_CH0_TOP0_NODE);
  921. if (!node) {
  922. dcm_info("error: cannot find node " DRAMC_CH0_TOP0_NODE);
  923. goto dcm_error;
  924. }
  925. dcm_dramc_ch0_top0_base = (unsigned long)of_iomap(node, 0);
  926. if (!dcm_dramc_ch0_top0_base) {
  927. dcm_info("error: cannot iomap " DRAMC_CH0_TOP0_NODE);
  928. goto dcm_error;
  929. }
  930. /* dramc_ch0_top1 */
  931. node = of_find_compatible_node(NULL, NULL, DRAMC_CH0_TOP1_NODE);
  932. if (!node) {
  933. dcm_info("error: cannot find node " DRAMC_CH0_TOP1_NODE);
  934. goto dcm_error;
  935. }
  936. dcm_dramc_ch0_top1_base = (unsigned long)of_iomap(node, 0);
  937. if (!dcm_dramc_ch0_top1_base) {
  938. dcm_info("error: cannot iomap " DRAMC_CH0_TOP1_NODE);
  939. goto dcm_error;
  940. }
  941. /* dramc_ch0_top3 */
  942. node = of_find_compatible_node(NULL, NULL, DRAMC_CH0_TOP3_NODE);
  943. if (!node) {
  944. dcm_info("error: cannot find node " DRAMC_CH0_TOP3_NODE);
  945. goto dcm_error;
  946. }
  947. dcm_dramc_ch0_top3_base = (unsigned long)of_iomap(node, 0);
  948. if (!dcm_dramc_ch0_top3_base) {
  949. dcm_info("error: cannot iomap " DRAMC_CH0_TOP3_NODE);
  950. goto dcm_error;
  951. }
  952. /* dramc_ch1_top0 */
  953. node = of_find_compatible_node(NULL, NULL, DRAMC_CH1_TOP0_NODE);
  954. if (!node) {
  955. dcm_info("error: cannot find node " DRAMC_CH1_TOP0_NODE);
  956. goto dcm_error;
  957. }
  958. dcm_dramc_ch1_top0_base = (unsigned long)of_iomap(node, 0);
  959. if (!dcm_dramc_ch1_top0_base) {
  960. dcm_info("error: cannot iomap " DRAMC_CH1_TOP0_NODE);
  961. goto dcm_error;
  962. }
  963. /* dramc_ch1_top1 */
  964. node = of_find_compatible_node(NULL, NULL, DRAMC_CH1_TOP1_NODE);
  965. if (!node) {
  966. dcm_info("error: cannot find node " DRAMC_CH1_TOP1_NODE);
  967. goto dcm_error;
  968. }
  969. dcm_dramc_ch1_top1_base = (unsigned long)of_iomap(node, 0);
  970. if (!dcm_dramc_ch1_top1_base) {
  971. dcm_info("error: cannot iomap " DRAMC_CH1_TOP1_NODE);
  972. goto dcm_error;
  973. }
  974. /* dramc_ch1_top3 */
  975. node = of_find_compatible_node(NULL, NULL, DRAMC_CH1_TOP3_NODE);
  976. if (!node) {
  977. dcm_info("error: cannot find node " DRAMC_CH1_TOP3_NODE);
  978. goto dcm_error;
  979. }
  980. dcm_dramc_ch1_top3_base = (unsigned long)of_iomap(node, 0);
  981. if (!dcm_dramc_ch1_top3_base) {
  982. dcm_info("error: cannot iomap " DRAMC_CH1_TOP3_NODE);
  983. goto dcm_error;
  984. }
  985. /* emi */
  986. node = of_find_compatible_node(NULL, NULL, EMI_NODE);
  987. if (!node) {
  988. dcm_info("error: cannot find node " EMI_NODE);
  989. goto dcm_error;
  990. }
  991. dcm_emi_base = (unsigned long)of_iomap(node, 0);
  992. if (!dcm_emi_base) {
  993. dcm_info("error: cannot iomap " EMI_NODE);
  994. goto dcm_error;
  995. }
  996. /* infracfg_ao */
  997. node = of_find_compatible_node(NULL, NULL, INFRACFG_AO_NODE);
  998. if (!node) {
  999. dcm_info("error: cannot find node " INFRACFG_AO_NODE);
  1000. goto dcm_error;
  1001. }
  1002. dcm_infracfg_ao_base = (unsigned long)of_iomap(node, 0);
  1003. if (!dcm_infracfg_ao_base) {
  1004. dcm_info("error: cannot iomap " INFRACFG_AO_NODE);
  1005. goto dcm_error;
  1006. }
  1007. /* cci (mcsi-a) */
  1008. node = of_find_compatible_node(NULL, NULL, CCI_NODE);
  1009. if (!node) {
  1010. dcm_info("error: cannot find node " CCI_NODE);
  1011. goto dcm_error;
  1012. }
  1013. if (of_address_to_resource(node, 0, &r)) {
  1014. dcm_info("error: cannot get phys addr" CCI_NODE);
  1015. goto dcm_error;
  1016. }
  1017. dcm_cci_phys_base = r.start;
  1018. dcm_cci_base = (unsigned long)of_iomap(node, 0);
  1019. if (!dcm_cci_base) {
  1020. dcm_info("error: cannot iomap " CCI_NODE);
  1021. goto dcm_error;
  1022. }
  1023. return 0;
  1024. dcm_error:
  1025. WARN_ON(true);
  1026. return DCM_INIT_FAIL;
  1027. }
  1028. #else
  1029. static int mt_dcm_dts_map(void)
  1030. {
  1031. return 0;
  1032. }
  1033. #endif
  1034. int mt_dcm_init(void)
  1035. {
  1036. #ifdef __CTP__
  1037. unsigned int segment;
  1038. #else /* LK and Kernel */
  1039. u32 segment;
  1040. #endif
  1041. /* if the dcm_initiated equals DCM_INIT_SUCCESS or DCM_INIT_FAIL, then return */
  1042. if (dcm_initiated)
  1043. return dcm_initiated;
  1044. if (mt_dcm_dts_map() == DCM_INIT_FAIL) {
  1045. dcm_initiated = DCM_INIT_FAIL;
  1046. return dcm_initiated;
  1047. }
  1048. segment = (get_devinfo_with_index(30) & 0x000000E0) >> 5; /* 0x10206054 */
  1049. /* deprecated */
  1050. #if 0
  1051. #ifdef __CTP__
  1052. hw_ver = get_chip_hwver();
  1053. #else /* Kernel and LK */
  1054. hw_ver = mt_get_chip_hw_ver();
  1055. #endif
  1056. if (hw_ver >= 0xCB00) {
  1057. feature = get_devinfo_with_index(50); /* 0x10206580 */
  1058. if ((feature >> 21) & 0x1) {
  1059. init_dcm_type |= (GIC_SYNC_DCM_TYPE | RGU_DCM_TYPE);
  1060. enhance_dcm_type |= (GIC_SYNC_DCM_TYPE | RGU_DCM_TYPE);
  1061. }
  1062. if ((feature >> 22) & 0x1)
  1063. enhance_dcm_type |= STALL_DCM_TYPE;
  1064. if ((segment == 0x1) && ((feature >> 23) & 0x1)) {
  1065. init_dcm_type |= LAST_CORE_DCM_TYPE;
  1066. enhance_dcm_type |= LAST_CORE_DCM_TYPE;
  1067. }
  1068. all_dcm_type |= enhance_dcm_type;
  1069. }
  1070. #else
  1071. if (segment == 0x3 || segment == 0x7) {
  1072. enhance_dcm_type |= STALL_DCM_TYPE;
  1073. all_dcm_type |= enhance_dcm_type;
  1074. }
  1075. #endif
  1076. #if !defined(DCM_DEFAULT_ALL_OFF)
  1077. /** enable all dcm **/
  1078. dcm_set_default(init_dcm_type);
  1079. #else /* #if !defined (DCM_DEFAULT_ALL_OFF) */
  1080. dcm_set_state(all_dcm_type, DCM_OFF);
  1081. #endif /* #if !defined (DCM_DEFAULT_ALL_OFF) */
  1082. dcm_dump_regs();
  1083. #if defined(CONFIG_PM)
  1084. {
  1085. int err = 0;
  1086. err = sysfs_create_file(power_kobj, &dcm_state_attr.attr);
  1087. if (err)
  1088. dcm_err("[%s]: fail to create sysfs\n", __func__);
  1089. }
  1090. #if defined(DCM_DEBUG_MON)
  1091. {
  1092. int err = 0;
  1093. err = sysfs_create_file(power_kobj, &dcm_debug_mon_attr.attr);
  1094. if (err)
  1095. dcm_err("[%s]: fail to create sysfs\n", __func__);
  1096. }
  1097. #endif /* #if defined (DCM_DEBUG_MON) */
  1098. #endif /* #if defined (CONFIG_PM) */
  1099. dcm_initiated = DCM_INIT_SUCCESS;
  1100. return 0;
  1101. }
  1102. late_initcall(mt_dcm_init);
  1103. /**** public APIs *****/
  1104. void mt_dcm_disable(void)
  1105. {
  1106. if (dcm_initiated != DCM_INIT_SUCCESS)
  1107. dcm_warn_limit("error: due to dcm init fail\n");
  1108. else
  1109. dcm_disable(all_dcm_type);
  1110. }
  1111. void mt_dcm_restore(void)
  1112. {
  1113. if (dcm_initiated != DCM_INIT_SUCCESS)
  1114. dcm_warn_limit("error: due to dcm init fail\n");
  1115. else
  1116. dcm_restore(all_dcm_type);
  1117. }
  1118. unsigned int sync_dcm_convert_freq2div(unsigned int freq)
  1119. {
  1120. unsigned int div = 0;
  1121. if (freq < 65)
  1122. return 0;
  1123. /* max divided ratio = Floor (CPU Frequency / 5 * system timer Frequency) */
  1124. div = freq / 65;
  1125. if (div > 31)
  1126. return 31;
  1127. return div;
  1128. }
  1129. #define MCUCFG_SYNC_DCM_TOGMASK ((0x1 << 6) | (0x1 << 14) | (0x1 << 22))
  1130. #define MCUCFG_SYNC_DCM_CCI_TOGMASK (0x1 << 6)
  1131. #define MCUCFG_SYNC_DCM_MP0_TOGMASK (0x1 << 14)
  1132. #define MCUCFG_SYNC_DCM_MP1_TOGMASK (0x1 << 22)
  1133. #define MCUCFG_SYNC_DCM_TOG1 ((0x1 << 6) | (0x1 << 14) | (0x1 << 22))
  1134. #define MCUCFG_SYNC_DCM_CCI_TOG1 MCUCFG_SYNC_DCM_CCI_TOGMASK
  1135. #define MCUCFG_SYNC_DCM_MP0_TOG1 MCUCFG_SYNC_DCM_MP0_TOGMASK
  1136. #define MCUCFG_SYNC_DCM_MP1_TOG1 MCUCFG_SYNC_DCM_MP1_TOGMASK
  1137. #define MCUCFG_SYNC_DCM_TOG0 ((0x0 << 6) | (0x0 << 14) | (0x0 << 22))
  1138. #define MCUCFG_SYNC_DCM_CCI_TOG0 (0x0 << 6)
  1139. #define MCUCFG_SYNC_DCM_MP0_TOG0 (0x0 << 14)
  1140. #define MCUCFG_SYNC_DCM_MP1_TOG0 (0x0 << 22)
  1141. #define MCUCFG_SYNC_DCM_SEL_MASK ((0x1F << 1) | (0x1F << 9) | (0x1F << 17))
  1142. #define MCUCFG_SYNC_DCM_SEL_CCI_MASK ((0x1F << 1))
  1143. #define MCUCFG_SYNC_DCM_SEL_MP0_MASK ((0x1F << 9))
  1144. #define MCUCFG_SYNC_DCM_SEL_MP1_MASK ((0x1F << 17))
  1145. /* unit of frequency is MHz */
  1146. int sync_dcm_set_cpu_freq(unsigned int cci, unsigned int mp0, unsigned int mp1)
  1147. {
  1148. #if 1
  1149. sync_dcm_set_cci_freq(cci);
  1150. sync_dcm_set_mp0_freq(mp0);
  1151. sync_dcm_set_mp1_freq(mp1);
  1152. #else
  1153. if (dcm_initiated != DCM_INIT_SUCCESS) {
  1154. dcm_warn_limit("error: due to dcm init fail\n");
  1155. return -1;
  1156. }
  1157. /* set xxx_sync_dcm_div and xxx_sync_dcm_tog as 0 first */
  1158. /* set xxx_sync_dcm_tog as 1 */
  1159. reg_write(SYNC_DCM_CONFIG,
  1160. aor(reg_read(SYNC_DCM_CONFIG),
  1161. ~MCUCFG_SYNC_DCM_SEL_MASK,
  1162. ((sync_dcm_convert_freq2div(cci) << 1) |
  1163. (sync_dcm_convert_freq2div(mp0) << 9) |
  1164. (sync_dcm_convert_freq2div(mp1) << 17))));
  1165. reg_write(SYNC_DCM_CONFIG,
  1166. aor(reg_read(SYNC_DCM_CONFIG),
  1167. ~MCUCFG_SYNC_DCM_TOGMASK,
  1168. MCUCFG_SYNC_DCM_TOG0));
  1169. reg_write(SYNC_DCM_CONFIG,
  1170. aor(reg_read(SYNC_DCM_CONFIG),
  1171. ~MCUCFG_SYNC_DCM_TOGMASK,
  1172. MCUCFG_SYNC_DCM_TOG1));
  1173. dcm_dbg("%s: SYNC_DCM_CONFIG=0x%08x, cci=%u/%u,%u, mp0=%u/%u,%u, mp1=%u/%u,%u\n",
  1174. __func__, reg_read(SYNC_DCM_CONFIG), cci,
  1175. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 1)) >> 1),
  1176. sync_dcm_convert_freq2div(cci), mp0,
  1177. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 9)) >> 9),
  1178. sync_dcm_convert_freq2div(mp0), mp1,
  1179. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 17)) >> 17),
  1180. sync_dcm_convert_freq2div(mp1));
  1181. #endif
  1182. return 0;
  1183. }
  1184. int sync_dcm_set_cpu_div(unsigned int cci, unsigned int mp0, unsigned int mp1)
  1185. {
  1186. if (cci > 31 || mp0 > 31 || mp1 > 31)
  1187. return -1;
  1188. if (dcm_initiated != DCM_INIT_SUCCESS) {
  1189. dcm_warn_limit("error: due to dcm init fail\n");
  1190. return -1;
  1191. }
  1192. /* set xxx_sync_dcm_div and xxx_sync_dcm_tog as 0 first */
  1193. /* set xxx_sync_dcm_tog as 1 */
  1194. reg_write(SYNC_DCM_CONFIG,
  1195. aor(reg_read(SYNC_DCM_CONFIG),
  1196. ~MCUCFG_SYNC_DCM_SEL_MASK,
  1197. ((cci << 1) |
  1198. (mp0 << 9) |
  1199. (mp1 << 17))));
  1200. reg_write(SYNC_DCM_CONFIG,
  1201. aor(reg_read(SYNC_DCM_CONFIG),
  1202. ~MCUCFG_SYNC_DCM_TOGMASK,
  1203. MCUCFG_SYNC_DCM_TOG0));
  1204. reg_write(SYNC_DCM_CONFIG,
  1205. aor(reg_read(SYNC_DCM_CONFIG),
  1206. ~MCUCFG_SYNC_DCM_TOGMASK,
  1207. MCUCFG_SYNC_DCM_TOG1));
  1208. dcm_dbg("%s: SYNC_DCM_CONFIG=0x%08x, cci=%u/%u, mp0=%u/%u, mp1=%u/%u\n",
  1209. __func__, reg_read(SYNC_DCM_CONFIG), cci,
  1210. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 1)) >> 1), mp0,
  1211. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 9)) >> 9), mp1,
  1212. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 17)) >> 17));
  1213. return 0;
  1214. }
  1215. int sync_dcm_set_cci_freq(unsigned int cci)
  1216. {
  1217. if (dcm_initiated != DCM_INIT_SUCCESS) {
  1218. dcm_warn_limit("error: due to dcm init fail\n");
  1219. return -1;
  1220. }
  1221. /* set xxx_sync_dcm_div and xxx_sync_dcm_tog as 0 first */
  1222. /* set xxx_sync_dcm_tog as 1 */
  1223. reg_write(SYNC_DCM_CONFIG,
  1224. aor(reg_read(SYNC_DCM_CONFIG),
  1225. ~MCUCFG_SYNC_DCM_SEL_CCI_MASK,
  1226. sync_dcm_convert_freq2div(cci) << 1));
  1227. reg_write(SYNC_DCM_CONFIG,
  1228. aor(reg_read(SYNC_DCM_CONFIG),
  1229. ~MCUCFG_SYNC_DCM_CCI_TOGMASK,
  1230. MCUCFG_SYNC_DCM_CCI_TOG0));
  1231. reg_write(SYNC_DCM_CONFIG,
  1232. aor(reg_read(SYNC_DCM_CONFIG),
  1233. ~MCUCFG_SYNC_DCM_CCI_TOGMASK,
  1234. MCUCFG_SYNC_DCM_CCI_TOG1));
  1235. dcm_dbg("%s: SYNC_DCM_CONFIG=0x%08x, cci=%u, cci_div_sel=%u,%u\n",
  1236. __func__, reg_read(SYNC_DCM_CONFIG), cci,
  1237. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 1)) >> 1),
  1238. sync_dcm_convert_freq2div(cci));
  1239. return 0;
  1240. }
  1241. int sync_dcm_set_mp0_freq(unsigned int mp0)
  1242. {
  1243. if (dcm_initiated != DCM_INIT_SUCCESS) {
  1244. dcm_warn_limit("error: due to dcm init fail\n");
  1245. return -1;
  1246. }
  1247. /* set xxx_sync_dcm_div and xxx_sync_dcm_tog as 0 first */
  1248. /* set xxx_sync_dcm_tog as 1 */
  1249. reg_write(SYNC_DCM_CONFIG,
  1250. aor(reg_read(SYNC_DCM_CONFIG),
  1251. ~MCUCFG_SYNC_DCM_SEL_MP0_MASK,
  1252. sync_dcm_convert_freq2div(mp0) << 9));
  1253. reg_write(SYNC_DCM_CONFIG,
  1254. aor(reg_read(SYNC_DCM_CONFIG),
  1255. ~MCUCFG_SYNC_DCM_MP0_TOGMASK,
  1256. MCUCFG_SYNC_DCM_MP0_TOG0));
  1257. reg_write(SYNC_DCM_CONFIG,
  1258. aor(reg_read(SYNC_DCM_CONFIG),
  1259. ~MCUCFG_SYNC_DCM_MP0_TOGMASK,
  1260. MCUCFG_SYNC_DCM_MP0_TOG1));
  1261. dcm_dbg("%s: SYNC_DCM_CONFIG=0x%08x, mp0=%u, mp0_div_sel=%u,%u\n",
  1262. __func__, reg_read(SYNC_DCM_CONFIG), mp0,
  1263. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 9)) >> 9),
  1264. sync_dcm_convert_freq2div(mp0));
  1265. return 0;
  1266. }
  1267. int sync_dcm_set_mp1_freq(unsigned int mp1)
  1268. {
  1269. if (dcm_initiated != DCM_INIT_SUCCESS) {
  1270. dcm_warn_limit("error: due to dcm init fail\n");
  1271. return -1;
  1272. }
  1273. /* set xxx_sync_dcm_div and xxx_sync_dcm_tog as 0 first */
  1274. /* set xxx_sync_dcm_tog as 1 */
  1275. reg_write(SYNC_DCM_CONFIG,
  1276. aor(reg_read(SYNC_DCM_CONFIG),
  1277. ~MCUCFG_SYNC_DCM_SEL_MP1_MASK,
  1278. sync_dcm_convert_freq2div(mp1) << 17));
  1279. reg_write(SYNC_DCM_CONFIG,
  1280. aor(reg_read(SYNC_DCM_CONFIG),
  1281. ~MCUCFG_SYNC_DCM_MP1_TOGMASK,
  1282. MCUCFG_SYNC_DCM_MP1_TOG0));
  1283. reg_write(SYNC_DCM_CONFIG,
  1284. aor(reg_read(SYNC_DCM_CONFIG),
  1285. ~MCUCFG_SYNC_DCM_MP1_TOGMASK,
  1286. MCUCFG_SYNC_DCM_MP1_TOG1));
  1287. dcm_dbg("%s: SYNC_DCM_CONFIG=0x%08x, mp1=%u, mp1_div_sel=%u,%u\n",
  1288. __func__, reg_read(SYNC_DCM_CONFIG), mp1,
  1289. (and(reg_read(SYNC_DCM_CONFIG), (0x1F << 17)) >> 17),
  1290. sync_dcm_convert_freq2div(mp1));
  1291. return 0;
  1292. }
  1293. /* mt_dcm_topckg_disable/enable is used for slow idle */
  1294. void mt_dcm_topckg_disable(void)
  1295. {
  1296. #if 0
  1297. #if !defined(DCM_DEFAULT_ALL_OFF)
  1298. reg_write(TOPCKG_DCM_CFG, aor(reg_read(TOPCKG_DCM_CFG),
  1299. ~TOPCKG_DCM_CFG_QMASK, TOPCKG_DCM_CFG_QOFF));
  1300. #endif /* #if !defined (DCM_DEFAULT_ALL_OFF) */
  1301. #endif /* 0 */
  1302. }
  1303. /* mt_dcm_topckg_disable/enable is used for slow idle */
  1304. void mt_dcm_topckg_enable(void)
  1305. {
  1306. #if 0
  1307. #if !defined(DCM_DEFAULT_ALL_OFF)
  1308. if (dcm_array[TOPCKG_DCM].current_state != DCM_OFF) {
  1309. reg_write(TOPCKG_DCM_CFG, aor(reg_read(TOPCKG_DCM_CFG),
  1310. ~TOPCKG_DCM_CFG_QMASK, TOPCKG_DCM_CFG_QON));
  1311. }
  1312. #endif /* #if !defined (DCM_DEFAULT_ALL_OFF) */
  1313. #endif /* 0 */
  1314. }
  1315. void mt_dcm_topck_off(void)
  1316. {
  1317. #if 0
  1318. if (dcm_initiated != DCM_INIT_SUCCESS)
  1319. dcm_warn_limit("error: due to dcm init fail\n");
  1320. else
  1321. dcm_set_state(TOPCKG_DCM_TYPE, DCM_OFF);
  1322. #endif /* 0 */
  1323. }
  1324. void mt_dcm_topck_on(void)
  1325. {
  1326. #if 0
  1327. if (dcm_initiated != DCM_INIT_SUCCESS)
  1328. dcm_warn_limit("error: due to dcm init fail\n");
  1329. else
  1330. dcm_set_state(TOPCKG_DCM_TYPE, DCM_ON);
  1331. #endif /* 0 */
  1332. }
  1333. void mt_dcm_peri_off(void)
  1334. {
  1335. }
  1336. void mt_dcm_peri_on(void)
  1337. {
  1338. }