mt_idle.c 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272
  1. #include <linux/init.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/cpu.h>
  5. #include <linux/types.h>
  6. #include <linux/string.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/irq.h>
  9. #include <linux/spinlock.h>
  10. #include <linux/cpumask.h>
  11. #include <linux/stddef.h>
  12. #include <linux/debugfs.h>
  13. #include <linux/seq_file.h>
  14. #include <linux/of.h>
  15. #include <linux/of_address.h>
  16. #include <asm/system_misc.h>
  17. #include <asm/uaccess.h>
  18. #include <mt-plat/sync_write.h>
  19. #include "mt_dcm.h"
  20. #include "mt_ptp.h"
  21. #include <mach/mt_gpt.h>
  22. #if !defined(CONFIG_ARCH_MT6580)
  23. #include <mach/mt_cpuxgpt.h>
  24. #else
  25. #include <mach/mt_clkmgr.h>
  26. #endif
  27. #include <mach/mt_spm_mtcmos_internal.h>
  28. #include "hotplug.h"
  29. #include "mt_cpufreq.h"
  30. #include "mt_idle.h"
  31. #include "mt_spm.h"
  32. #include "mt_spm_idle.h"
  33. #define IDLE_TAG "[Power/swap]"
  34. #define idle_warn(fmt, args...) pr_warn(IDLE_TAG fmt, ##args)
  35. #define idle_dbg(fmt, args...) pr_debug(IDLE_TAG fmt, ##args)
  36. #define idle_warn_log(fmt, args...) { \
  37. if (dpidle_dump_log == DEEPIDLE_LOG_FULL) \
  38. pr_warn(IDLE_TAG fmt, ##args); \
  39. }
  40. #define idle_gpt GPT4
  41. #define idle_readl(addr) __raw_readl(addr)
  42. #define idle_writel(addr, val) mt65xx_reg_sync_writel(val, addr)
  43. #define idle_setl(addr, val) \
  44. mt65xx_reg_sync_writel(idle_readl(addr) | (val), addr)
  45. #define idle_clrl(addr, val) \
  46. mt65xx_reg_sync_writel(idle_readl(addr) & ~(val), addr)
  47. enum mt_idle_mode {
  48. MT_DPIDLE = 0,
  49. MT_SOIDLE,
  50. MT_SLIDLE,
  51. };
  52. #if !defined(CONFIG_ARCH_MT6580)
  53. enum {
  54. CG_INFRA = 0,
  55. CG_PERI = 1,
  56. CG_DISP0 = 2,
  57. CG_DISP1 = 3,
  58. CG_IMAGE = 4,
  59. CG_MFG = 5,
  60. CG_AUDIO = 6,
  61. CG_VDEC0 = 7,
  62. CG_VDEC1 = 8,
  63. CG_VENC = 9,
  64. NR_GRPS = 10,
  65. };
  66. #endif
  67. static unsigned long rgidle_cnt[NR_CPUS] = {0};
  68. static bool mt_idle_chk_golden;
  69. static bool mt_dpidle_chk_golden;
  70. #if defined(CONFIG_MICROTRUST_TEE_SUPPORT)
  71. extern int is_teei_ready(void);
  72. #endif
  73. #define INVALID_GRP_ID(grp) (grp < 0 || grp >= NR_GRPS)
  74. void __attribute__((weak)) bus_dcm_enable(void)
  75. {
  76. }
  77. void __attribute__((weak)) bus_dcm_disable(void)
  78. {
  79. }
  80. void __attribute__((weak)) mt_dcm_topckg_enable(void)
  81. {
  82. }
  83. void __attribute__((weak)) mt_dcm_topckg_disable(void)
  84. {
  85. }
  86. void __attribute__((weak)) tscpu_cancel_thermal_timer(void)
  87. {
  88. }
  89. void __attribute__((weak)) tscpu_start_thermal_timer(void)
  90. {
  91. }
  92. void __attribute__((weak)) mtkts_bts_cancel_thermal_timer(void)
  93. {
  94. }
  95. void __attribute__((weak)) mtkts_btsmdpa_cancel_thermal_timer(void)
  96. {
  97. }
  98. void __attribute__((weak)) mtkts_pmic_cancel_thermal_timer(void)
  99. {
  100. }
  101. void __attribute__((weak)) mtkts_battery_cancel_thermal_timer(void)
  102. {
  103. }
  104. void __attribute__((weak)) mtkts_pa_cancel_thermal_timer(void)
  105. {
  106. }
  107. void __attribute__((weak)) mtkts_wmt_cancel_thermal_timer(void)
  108. {
  109. }
  110. void __attribute__((weak)) mtkts_bts_start_thermal_timer(void)
  111. {
  112. }
  113. void __attribute__((weak)) mtkts_btsmdpa_start_thermal_timer(void)
  114. {
  115. }
  116. void __attribute__((weak)) mtkts_pmic_start_thermal_timer(void)
  117. {
  118. }
  119. void __attribute__((weak)) mtkts_battery_start_thermal_timer(void)
  120. {
  121. }
  122. void __attribute__((weak)) mtkts_pa_start_thermal_timer(void)
  123. {
  124. }
  125. void __attribute__((weak)) mtkts_wmt_start_thermal_timer(void)
  126. {
  127. }
  128. void __attribute__((weak)) mtkts_allts_cancel_ts1_timer(void)
  129. {
  130. }
  131. void __attribute__((weak)) mtkts_allts_cancel_ts2_timer(void)
  132. {
  133. }
  134. void __attribute__((weak)) mtkts_allts_cancel_ts3_timer(void)
  135. {
  136. }
  137. void __attribute__((weak)) mtkts_allts_cancel_ts4_timer(void)
  138. {
  139. }
  140. void __attribute__((weak)) mtkts_allts_cancel_ts5_timer(void)
  141. {
  142. }
  143. void __attribute__((weak)) mtkts_allts_start_ts1_timer(void)
  144. {
  145. }
  146. void __attribute__((weak)) mtkts_allts_start_ts2_timer(void)
  147. {
  148. }
  149. void __attribute__((weak)) mtkts_allts_start_ts3_timer(void)
  150. {
  151. }
  152. void __attribute__((weak)) mtkts_allts_start_ts4_timer(void)
  153. {
  154. }
  155. void __attribute__((weak)) mtkts_allts_start_ts5_timer(void)
  156. {
  157. }
  158. wake_reason_t __attribute__((weak)) spm_go_to_dpidle(u32 spm_flags, u32 spm_data, u32 dump_log)
  159. {
  160. return 0;
  161. }
  162. void __attribute__((weak)) spm_go_to_sodi(u32 spm_flags, u32 spm_data)
  163. {
  164. }
  165. bool __attribute__((weak)) spm_get_sodi_en(void)
  166. {
  167. return false;
  168. }
  169. unsigned long __attribute__((weak)) localtimer_get_counter(void)
  170. {
  171. return 0;
  172. }
  173. int __attribute__((weak)) localtimer_set_next_event(unsigned long evt)
  174. {
  175. return 0;
  176. }
  177. int __attribute__((weak)) hps_del_timer(void)
  178. {
  179. return 0;
  180. }
  181. int __attribute__((weak)) hps_restart_timer(void)
  182. {
  183. return 0;
  184. }
  185. void __attribute__((weak)) MMProfileEnable(int enable)
  186. {
  187. }
  188. void __attribute__((weak)) MMProfileStart(int start)
  189. {
  190. }
  191. void __attribute__((weak)) msdc_clk_status(int *status)
  192. {
  193. *status = 0x1;
  194. }
  195. enum {
  196. IDLE_TYPE_DP = 0,
  197. IDLE_TYPE_SO,
  198. IDLE_TYPE_SL,
  199. IDLE_TYPE_RG,
  200. NR_TYPES
  201. };
  202. enum {
  203. BY_CPU = 0,
  204. BY_CLK,
  205. BY_TMR,
  206. BY_OTH,
  207. BY_VTG,
  208. NR_REASONS
  209. };
  210. #if defined(CONFIG_ARCH_MT6735)
  211. /* Idle handler on/off */
  212. static int idle_switch[NR_TYPES] = {
  213. 1, /* dpidle switch */
  214. #if defined(CONFIG_MTK_DISABLE_SODI)
  215. 0, /* soidle switch */
  216. #else
  217. 1, /* soidle switch */
  218. #endif
  219. 1, /* slidle switch */
  220. 1, /* rgidle switch */
  221. };
  222. static unsigned int dpidle_condition_mask[NR_GRPS] = {
  223. 0x0000008A, /* INFRA: */
  224. 0x37FC1FFD, /* PERI0: */
  225. 0x000FFFFF, /* DISP0: */
  226. 0x0000003C, /* DISP1: */
  227. 0x00000FE1, /* IMAGE: */
  228. 0x00000001, /* MFG: */
  229. 0x00000000, /* AUDIO: */
  230. 0x00000001, /* VDEC0: */
  231. 0x00000001, /* VDEC1: */
  232. 0x00001111, /* VENC: */
  233. };
  234. static unsigned int soidle_condition_mask[NR_GRPS] = {
  235. 0x00000088, /* INFRA: */
  236. 0x37FC0FFC, /* PERI0: */
  237. 0x000033FC, /* DISP0: */
  238. 0x00000030, /* DISP1: */
  239. 0x00000FE1, /* IMAGE: */
  240. 0x00000001, /* MFG: */
  241. 0x00000000, /* AUDIO: */
  242. 0x00000001, /* VDEC0: */
  243. 0x00000001, /* VDEC1: */
  244. 0x00001111, /* VENC: */
  245. };
  246. static unsigned int slidle_condition_mask[NR_GRPS] = {
  247. 0x00000000, /* INFRA: */
  248. 0x07C01000, /* PERI0: */
  249. 0x00000000, /* DISP0: */
  250. 0x00000000, /* DISP1: */
  251. 0x00000000, /* IMAGE: */
  252. 0x00000000, /* MFG: */
  253. 0x00000000, /* AUDIO: */
  254. 0x00000000, /* VDEC0: */
  255. 0x00000000, /* VDEC1: */
  256. 0x00000000, /* VENC: */
  257. };
  258. #elif defined(CONFIG_ARCH_MT6735M)
  259. /* Idle handler on/off */
  260. static int idle_switch[NR_TYPES] = {
  261. 1, /* dpidle switch */
  262. #if defined(CONFIG_MTK_DISABLE_SODI)
  263. 0, /* soidle switch */
  264. #else
  265. 1, /* soidle switch */
  266. #endif
  267. 1, /* slidle switch */
  268. 1, /* rgidle switch */
  269. };
  270. static unsigned int dpidle_condition_mask[NR_GRPS] = {
  271. 0x0000008A, /* INFRA: */
  272. 0x37DA1FFD, /* PERI0: */
  273. 0x000FFFFF, /* DISP0: */
  274. 0x0000003F, /* DISP1: */
  275. 0x00000FE1, /* IMAGE: */
  276. 0x00000001, /* MFG: */
  277. 0x00000000, /* AUDIO: */
  278. 0x00000001, /* VDEC0: */
  279. 0x00000001, /* VDEC1: */
  280. /* VENC: there is no venc */
  281. };
  282. static unsigned int soidle_condition_mask[NR_GRPS] = {
  283. 0x00000088, /* INFRA: */
  284. 0x37DC0FFC, /* PERI0: */
  285. 0x000033FC, /* DISP0: */
  286. 0x00000030, /* DISP1: */
  287. 0x00000FE1, /* IMAGE: */
  288. 0x00000001, /* MFG: */
  289. 0x00000000, /* AUDIO: */
  290. 0x00000001, /* VDEC0: */
  291. 0x00000001, /* VDEC1: */
  292. /* VENC: there is no venc */
  293. };
  294. static unsigned int slidle_condition_mask[NR_GRPS] = {
  295. 0x00000000, /* INFRA: */
  296. 0x07C01000, /* PERI0: */
  297. 0x00000000, /* DISP0: */
  298. 0x00000000, /* DISP1: */
  299. 0x00000000, /* IMAGE: */
  300. 0x00000000, /* MFG: */
  301. 0x00000000, /* AUDIO: */
  302. 0x00000000, /* VDEC0: */
  303. 0x00000000, /* VDEC1: */
  304. /* VENC: there is no venc */
  305. };
  306. #elif defined(CONFIG_ARCH_MT6753)
  307. static int idle_switch[NR_TYPES] = {
  308. 1, /* dpidle switch */
  309. #if defined(CONFIG_MTK_DISABLE_SODI)
  310. 0, /* soidle switch */
  311. #else
  312. 1, /* soidle switch */
  313. #endif
  314. 1, /* slidle switch */
  315. 1, /* rgidle switch */
  316. };
  317. static unsigned int dpidle_condition_mask[NR_GRPS] = {
  318. 0x0000008A, /* INFRA: */
  319. 0x77FC1FFD, /* PERI0: */
  320. 0x002FFFFF, /* DISP0: */
  321. 0x0000003C, /* DISP1: */
  322. 0x00000FE1, /* IMAGE: */
  323. 0x00000001, /* MFG: */
  324. 0x00000000, /* AUDIO: */
  325. 0x00000001, /* VDEC0: */
  326. 0x00000001, /* VDEC1: */
  327. 0x00001111, /* VENC: */
  328. };
  329. static unsigned int soidle_condition_mask[NR_GRPS] = {
  330. 0x00000088, /* INFRA: */
  331. 0x77FC0FFC, /* PERI0: */
  332. 0x000063FC, /* DISP0: */
  333. 0x00000030, /* DISP1: */
  334. 0x00000FE1, /* IMAGE: */
  335. 0x00000001, /* MFG: */
  336. 0x00000000, /* AUDIO: */
  337. 0x00000001, /* VDEC0: */
  338. 0x00000001, /* VDEC1: */
  339. 0x00001111, /* VENC: */
  340. };
  341. static unsigned int slidle_condition_mask[NR_GRPS] = {
  342. 0x00000000, /* INFRA: */
  343. 0x07C01000, /* PERI0: */
  344. 0x00000000, /* DISP0: */
  345. 0x00000000, /* DISP1: */
  346. 0x00000000, /* IMAGE: */
  347. 0x00000000, /* MFG: */
  348. 0x00000000, /* AUDIO: */
  349. 0x00000000, /* VDEC0: */
  350. 0x00000000, /* VDEC1: */
  351. 0x00000000, /* VENC: */
  352. };
  353. #elif defined(CONFIG_ARCH_MT6580)
  354. /*Idle handler on/off*/
  355. static int idle_switch[NR_TYPES] = {
  356. 1, /* dpidle switch */
  357. 1, /* soidle switch */
  358. 0, /* slidle switch */
  359. 1, /* rgidle switch */
  360. };
  361. static unsigned int dpidle_condition_mask[NR_GRPS] = {
  362. 0x00000000, /* CG_MIXED: */
  363. 0x00000000, /* CG_MPLL: */
  364. 0x00000000, /* CG_INFRA_AO: */
  365. 0x00000037, /* CG_CTRL0: */
  366. 0x8089B2FC, /* CG_CTRL1: */
  367. 0x00003F16, /* CG_CTRL2: */
  368. 0x0007EFFF, /* CG_MMSYS0: */
  369. 0x0000000C, /* CG_MMSYS1: */
  370. 0x000003E1, /* CG_IMGSYS: */
  371. 0x00000001, /* CG_MFGSYS: */
  372. 0x00000000, /* CG_AUDIO: */
  373. };
  374. static unsigned int soidle_condition_mask[NR_GRPS] = {
  375. 0x00000000, /* CG_MIXED: */
  376. 0x00000000, /* CG_MPLL: */
  377. 0x00000000, /* CG_INFRA_AO: */
  378. 0x00000026, /* CG_CTRL0: */
  379. 0x8089B2F8, /* CG_CTRL1: */
  380. 0x00003F06, /* CG_CTRL2: */
  381. 0x00000200, /* CG_MMSYS0: */
  382. 0x00000000, /* CG_MMSYS1: */
  383. 0x000003E1, /* CG_IMGSYS: */
  384. 0x00000001, /* CG_MFGSYS: */
  385. 0x00000000, /* CG_AUDIO: */
  386. };
  387. static unsigned int slidle_condition_mask[NR_GRPS] = {
  388. 0xFFFFFFFF, /* CG_MIXED: */
  389. 0xFFFFFFFF, /* CG_MPLL: */
  390. 0xFFFFFFFF, /* CG_INFRA_AO: */
  391. 0xFFFFFFFF, /* CG_CTRL0: */
  392. 0xFFFFFFFF, /* CG_CTRL1: */
  393. 0xFFFFFFFF, /* CG_CTRL2: */
  394. 0xFFFFFFFF, /* CG_MMSYS0: */
  395. 0xFFFFFFFF, /* CG_MMSYS1: */
  396. 0xFFFFFFFF, /* CG_IMGSYS: */
  397. 0xFFFFFFFF, /* CG_MFGSYS: */
  398. 0xFFFFFFFF, /* CG_AUDIO: */
  399. };
  400. #else
  401. #error "Does not support!"
  402. #endif
  403. static const char *idle_name[NR_TYPES] = {
  404. "dpidle",
  405. "soidle",
  406. "slidle",
  407. "rgidle",
  408. };
  409. static const char *reason_name[NR_REASONS] = {
  410. "by_cpu",
  411. "by_clk",
  412. "by_tmr",
  413. "by_oth",
  414. "by_vtg",
  415. };
  416. char cg_group_name[][NR_GRPS] = {
  417. #if !defined(CONFIG_ARCH_MT6580)
  418. "INFRA",
  419. "PERI",
  420. "DISP0",
  421. "DISP1",
  422. "IMAGE",
  423. "MFG",
  424. "AUDIO",
  425. "VDEC0",
  426. "VDEC1",
  427. "VENC",
  428. #else
  429. "MIXED",
  430. "MPLL",
  431. "INFRA_AO",
  432. "CTRL0",
  433. "CTRL1",
  434. "CTRL2",
  435. "MMSYS0",
  436. "MMSYS1",
  437. "IMGSYS",
  438. "MFGSYS",
  439. "AUDIO",
  440. #endif
  441. };
  442. static char log_buf[500];
  443. static char log_buf_2[500];
  444. static unsigned long long idle_block_log_prev_time;
  445. static unsigned int idle_block_log_time_criteria = 5000; /* 5 sec */
  446. static unsigned long long idle_cnt_dump_prev_time;
  447. static unsigned int idle_cnt_dump_criteria = 10000; /* 10 sec */
  448. static bool idle_ratio_en;
  449. static unsigned long long idle_ratio_profile_start_time;
  450. static unsigned long long idle_ratio_profile_duration;
  451. static unsigned long long idle_ratio_start_time[NR_TYPES];
  452. static unsigned long long idle_ratio_value[NR_TYPES];
  453. /* Slow Idle */
  454. static unsigned int slidle_block_mask[NR_GRPS] = {0x0};
  455. static unsigned long slidle_cnt[NR_CPUS] = {0};
  456. static unsigned long slidle_block_cnt[NR_REASONS] = {0};
  457. /* SODI */
  458. static unsigned int soidle_block_mask[NR_GRPS] = {0x0};
  459. static unsigned int soidle_timer_left;
  460. static unsigned int soidle_timer_left2;
  461. #ifndef CONFIG_SMP
  462. static unsigned int soidle_timer_cmp;
  463. #endif
  464. static unsigned int soidle_time_critera = 26000;
  465. static unsigned int soidle_block_time_critera = 30000; /* default 30sec */
  466. static unsigned long soidle_cnt[NR_CPUS] = {0};
  467. static unsigned long soidle_last_cnt[NR_CPUS] = {0};
  468. static unsigned long soidle_block_cnt[NR_CPUS][NR_REASONS] = { {0} };
  469. static unsigned long long soidle_block_prev_time;
  470. static bool soidle_by_pass_cg;
  471. static bool soidle_by_pass_pg;
  472. static int sodi_by_uptime_count;
  473. /* DeepIdle */
  474. static unsigned int dpidle_block_mask[NR_GRPS] = {0x0};
  475. static unsigned int dpidle_timer_left;
  476. static unsigned int dpidle_timer_left2;
  477. #ifndef CONFIG_SMP
  478. static unsigned int dpidle_timer_cmp;
  479. #endif
  480. static unsigned int dpidle_time_critera = 26000;
  481. static unsigned int dpidle_block_time_critera = 30000; /* default 30sec */
  482. static unsigned long dpidle_cnt[NR_CPUS] = {0};
  483. static unsigned long dpidle_last_cnt[NR_CPUS] = {0};
  484. static unsigned long dpidle_block_cnt[NR_REASONS] = {0};
  485. static unsigned long long dpidle_block_prev_time;
  486. static bool dpidle_by_pass_cg;
  487. static bool dpidle_by_pass_pg;
  488. static unsigned int dpidle_dump_log = DEEPIDLE_LOG_REDUCED;
  489. static unsigned int idle_spm_lock;
  490. #define clk_readl(addr) __raw_readl(addr)
  491. #define clk_writel(addr, val) mt_reg_sync_writel(val, addr)
  492. #if !defined(CONFIG_ARCH_MT6580)
  493. static void __iomem *infrasys_base;
  494. static void __iomem *perisys_base;
  495. static void __iomem *audiosys_base;
  496. static void __iomem *mfgsys_base;
  497. static void __iomem *mmsys_base;
  498. static void __iomem *imgsys_base;
  499. static void __iomem *vdecsys_base;
  500. #if !defined(CONFIG_ARCH_MT6735M)
  501. static void __iomem *vencsys_base;
  502. #endif
  503. static void __iomem *cksys_base;
  504. #define INFRA_REG(ofs) (infrasys_base + ofs)
  505. #define PREI_REG(ofs) (perisys_base + ofs)
  506. #define AUDIO_REG(ofs) (audiosys_base + ofs)
  507. #define MFG_REG(ofs) (mfgsys_base + ofs)
  508. #define MM_REG(ofs) (mmsys_base + ofs)
  509. #define IMG_REG(ofs) (imgsys_base + ofs)
  510. #define VDEC_REG(ofs) (vdecsys_base + ofs)
  511. #define VENC_REG(ofs) (vencsys_base + ofs)
  512. #define CKSYS_REG(ofs) (cksys_base + ofs)
  513. #define INFRA_PDN_STA INFRA_REG(0x0048)
  514. #define PERI_PDN0_STA PREI_REG(0x0018)
  515. #define PERI_PDN1_STA PREI_REG(0x001C)
  516. #define AUDIO_TOP_CON0 AUDIO_REG(0x0000)
  517. #define MFG_CG_CON MFG_REG(0)
  518. #define DISP_CG_CON0 MM_REG(0x100)
  519. #define DISP_CG_CON1 MM_REG(0x110)
  520. #define DISP_CG_DUMMY MM_REG(0x894)
  521. #define IMG_CG_CON IMG_REG(0x0000)
  522. #define VDEC_CKEN_SET VDEC_REG(0x0000)
  523. #define LARB_CKEN_SET VDEC_REG(0x0008)
  524. #define VENC_CG_CON VENC_REG(0x0)
  525. #define CLK_CFG_4 CKSYS_REG(0x080)
  526. #define DIS_PWR_STA_MASK BIT(3)
  527. #define MFG_PWR_STA_MASK BIT(4)
  528. #define ISP_PWR_STA_MASK BIT(5)
  529. #define VDE_PWR_STA_MASK BIT(7)
  530. #define VEN_PWR_STA_MASK BIT(8)
  531. #define INFRA_AUDIO_PDN_STA_MASK BIT(5)
  532. enum subsys_id {
  533. SYS_VDE,
  534. SYS_MFG,
  535. SYS_VEN,
  536. SYS_ISP,
  537. SYS_DIS,
  538. NR_SYSS__,
  539. };
  540. static int sys_is_on(enum subsys_id id)
  541. {
  542. u32 pwr_sta_mask[] = {
  543. VDE_PWR_STA_MASK,
  544. MFG_PWR_STA_MASK,
  545. VEN_PWR_STA_MASK,
  546. ISP_PWR_STA_MASK,
  547. DIS_PWR_STA_MASK,
  548. };
  549. u32 mask = pwr_sta_mask[id];
  550. u32 sta = idle_readl(SPM_PWR_STATUS);
  551. u32 sta_s = idle_readl(SPM_PWR_STATUS_2ND);
  552. return (sta & mask) && (sta_s & mask);
  553. }
  554. static void get_all_clock_state(u32 clks[NR_GRPS])
  555. {
  556. int i;
  557. for (i = 0; i < NR_GRPS; i++)
  558. clks[i] = 0;
  559. clks[CG_INFRA] = ~idle_readl(INFRA_PDN_STA); /* INFRA */
  560. clks[CG_PERI] = ~idle_readl(PERI_PDN0_STA); /* PERI */
  561. if (sys_is_on(SYS_DIS)) {
  562. #if defined(CONFIG_ARCH_MT6753)
  563. clks[CG_DISP0] = ~idle_readl(DISP_CG_DUMMY); /* DUMMY */
  564. #else
  565. clks[CG_DISP0] = ~idle_readl(DISP_CG_CON0); /* DISP0 */
  566. #endif
  567. clks[CG_DISP1] = ~idle_readl(DISP_CG_CON1); /* DISP1 */
  568. }
  569. if (sys_is_on(SYS_ISP))
  570. clks[CG_IMAGE] = ~idle_readl(IMG_CG_CON); /* IMAGE */
  571. if (sys_is_on(SYS_MFG))
  572. clks[CG_MFG] = ~idle_readl(MFG_CG_CON); /* MFG */
  573. if (clks[CG_INFRA] & INFRA_AUDIO_PDN_STA_MASK) /* check if infra_audio is on */
  574. clks[CG_AUDIO] = ~idle_readl(AUDIO_TOP_CON0); /* AUDIO */
  575. if (sys_is_on(SYS_VDE)) {
  576. clks[CG_VDEC0] = idle_readl(VDEC_CKEN_SET); /* VDEC0 */
  577. clks[CG_VDEC1] = idle_readl(LARB_CKEN_SET); /* VDEC1 */
  578. }
  579. #if !defined(CONFIG_ARCH_MT6735M)
  580. if (sys_is_on(SYS_VEN))
  581. clks[CG_VENC] = idle_readl(VENC_CG_CON); /* VENC_JPEG */
  582. #endif
  583. }
  584. bool cg_check_idle_can_enter(
  585. unsigned int *condition_mask, unsigned int *block_mask, enum mt_idle_mode mode)
  586. {
  587. int i;
  588. unsigned int sd_mask = 0;
  589. u32 clks[NR_GRPS];
  590. u32 r = 0;
  591. unsigned int sta;
  592. /* SD status */
  593. msdc_clk_status(&sd_mask);
  594. if (sd_mask) {
  595. block_mask[CG_PERI] |= sd_mask;
  596. return false;
  597. }
  598. /* CG status */
  599. get_all_clock_state(clks);
  600. for (i = 0; i < NR_GRPS; i++) {
  601. block_mask[i] = condition_mask[i] & clks[i];
  602. r |= block_mask[i];
  603. }
  604. if (!(r == 0))
  605. return false;
  606. /* MTCMOS status */
  607. sta = idle_readl(SPM_PWR_STATUS);
  608. if (mode == MT_DPIDLE) {
  609. if (!dpidle_by_pass_pg) {
  610. if (sta & (MFG_PWR_STA_MASK |
  611. ISP_PWR_STA_MASK |
  612. VDE_PWR_STA_MASK |
  613. VEN_PWR_STA_MASK |
  614. DIS_PWR_STA_MASK))
  615. return false;
  616. }
  617. } else if (mode == MT_SOIDLE) {
  618. if (!soidle_by_pass_pg) {
  619. if (sta & (MFG_PWR_STA_MASK |
  620. ISP_PWR_STA_MASK |
  621. VDE_PWR_STA_MASK |
  622. VEN_PWR_STA_MASK))
  623. return false;
  624. }
  625. }
  626. return true;
  627. }
  628. static unsigned int clk_cfg_4;
  629. void faudintbus_pll2sq(void)
  630. {
  631. clk_cfg_4 = clk_readl(CLK_CFG_4);
  632. clk_writel(CLK_CFG_4, clk_cfg_4 & 0xFFFFFCFF);
  633. }
  634. void faudintbus_sq2pll(void)
  635. {
  636. clk_writel(CLK_CFG_4, clk_cfg_4);
  637. }
  638. static int __init get_base_from_node(
  639. const struct of_device_id *ids, void __iomem **pbase, int idx, const char *cmp)
  640. {
  641. struct device_node *node;
  642. node = of_find_matching_node(NULL, ids);
  643. if (!node) {
  644. idle_warn("node '%s' not found!\n", cmp);
  645. #if !defined(CONFIG_ARCH_MT6580)
  646. BUG();
  647. #endif
  648. }
  649. *pbase = of_iomap(node, idx);
  650. if (!(*pbase)) {
  651. idle_warn("node '%s' cannot iomap!\n", cmp);
  652. #if !defined(CONFIG_ARCH_MT6580)
  653. BUG();
  654. #endif
  655. }
  656. return 0;
  657. }
  658. static void __init iomap_init(void)
  659. {
  660. static const struct of_device_id infra_ao_ids[] = {
  661. {.compatible = "mediatek,infracfg_ao"},
  662. {.compatible = "mediatek,mt6735-infracfg_ao"},
  663. { /* sentinel */ }
  664. };
  665. static const struct of_device_id pericfg_ids[] = {
  666. {.compatible = "mediatek,pericfg"},
  667. {.compatible = "mediatek,mt6735-pericfg"},
  668. { /* sentinel */ }
  669. };
  670. static const struct of_device_id audio_ids[] = {
  671. {.compatible = "mediatek,audio"},
  672. {.compatible = "mediatek,mt6735-audio"},
  673. { /* sentinel */ }
  674. };
  675. static const struct of_device_id g3d_config_ids[] = {
  676. {.compatible = "mediatek,g3d_config"},
  677. {.compatible = "mediatek,mt6735-g3d_config"},
  678. { /* sentinel */ }
  679. };
  680. static const struct of_device_id mmsys_config_ids[] = {
  681. {.compatible = "mediatek,mmsys_config"},
  682. {.compatible = "mediatek,mt6735-mmsys_config"},
  683. { /* sentinel */ }
  684. };
  685. static const struct of_device_id imgsys_ids[] = {
  686. {.compatible = "mediatek,imgsys"},
  687. {.compatible = "mediatek,mt6735-imgsys"},
  688. { /* sentinel */ }
  689. };
  690. static const struct of_device_id vdec_gcon_ids[] = {
  691. {.compatible = "mediatek,vdec_gcon"},
  692. {.compatible = "mediatek,mt6735-vdec_gcon"},
  693. { /* sentinel */ }
  694. };
  695. #if !defined(CONFIG_ARCH_MT6735M)
  696. static const struct of_device_id venc_gcon_ids[] = {
  697. {.compatible = "mediatek,venc_gcon"},
  698. {.compatible = "mediatek,mt6735-venc_gcon"},
  699. { /* sentinel */ }
  700. };
  701. #endif
  702. static const struct of_device_id cksys_ids[] = {
  703. {.compatible = "mediatek,cksys"},
  704. {.compatible = "mediatek,mt6735-cksys"},
  705. { /* sentinel */ }
  706. };
  707. get_base_from_node(infra_ao_ids, &infrasys_base, 0, "infracfg_ao");
  708. get_base_from_node(pericfg_ids, &perisys_base, 0, "pericfg");
  709. get_base_from_node(audio_ids, &audiosys_base, 0, "audio");
  710. get_base_from_node(g3d_config_ids, &mfgsys_base, 0, "g3d_config");
  711. get_base_from_node(mmsys_config_ids, &mmsys_base, 0, "mmsys_config");
  712. get_base_from_node(imgsys_ids, &imgsys_base, 0, "imgsys");
  713. get_base_from_node(vdec_gcon_ids, &vdecsys_base, 0, "vdec_gcon");
  714. #if !defined(CONFIG_ARCH_MT6735M)
  715. get_base_from_node(venc_gcon_ids, &vencsys_base, 0, "venc_gcon");
  716. #endif
  717. get_base_from_node(cksys_ids, &cksys_base, 0, "cksys");
  718. }
  719. #endif /*!defined(CONFIG_ARCH_MT6580)*/
  720. const char *cg_grp_get_name(int id)
  721. {
  722. BUG_ON(INVALID_GRP_ID(id));
  723. return cg_group_name[id];
  724. }
  725. /* Workaround of static analysis defect*/
  726. int idle_gpt_get_cnt(unsigned int id, unsigned int *ptr)
  727. {
  728. unsigned int val[2] = {0};
  729. int ret = 0;
  730. ret = gpt_get_cnt(id, val);
  731. *ptr = val[0];
  732. return ret;
  733. }
  734. int idle_gpt_get_cmp(unsigned int id, unsigned int *ptr)
  735. {
  736. unsigned int val[2] = {0};
  737. int ret = 0;
  738. ret = gpt_get_cmp(id, val);
  739. *ptr = val[0];
  740. return ret;
  741. }
  742. static long int idle_get_current_time_ms(void)
  743. {
  744. struct timeval t;
  745. do_gettimeofday(&t);
  746. return ((t.tv_sec & 0xFFF) * 1000000 + t.tv_usec) / 1000;
  747. }
  748. static DEFINE_SPINLOCK(idle_spm_spin_lock);
  749. void idle_lock_spm(enum idle_lock_spm_id id)
  750. {
  751. unsigned long flags;
  752. spin_lock_irqsave(&idle_spm_spin_lock, flags);
  753. idle_spm_lock |= (1 << id);
  754. spin_unlock_irqrestore(&idle_spm_spin_lock, flags);
  755. }
  756. void idle_unlock_spm(enum idle_lock_spm_id id)
  757. {
  758. unsigned long flags;
  759. spin_lock_irqsave(&idle_spm_spin_lock, flags);
  760. idle_spm_lock &= ~(1 << id);
  761. spin_unlock_irqrestore(&idle_spm_spin_lock, flags);
  762. }
  763. /*
  764. * SODI part
  765. */
  766. static DEFINE_MUTEX(soidle_locked);
  767. #if !defined(CONFIG_ARCH_MT6580)
  768. static void enable_soidle_by_mask(int grp, unsigned int mask)
  769. {
  770. mutex_lock(&soidle_locked);
  771. soidle_condition_mask[grp] &= ~mask;
  772. mutex_unlock(&soidle_locked);
  773. }
  774. static void disable_soidle_by_mask(int grp, unsigned int mask)
  775. {
  776. mutex_lock(&soidle_locked);
  777. soidle_condition_mask[grp] |= mask;
  778. mutex_unlock(&soidle_locked);
  779. }
  780. #endif
  781. void enable_soidle_by_bit(int id)
  782. {
  783. #if !defined(CONFIG_ARCH_MT6580)
  784. int grp = id / 32;
  785. unsigned int mask = 1U << (id % 32);
  786. BUG_ON(INVALID_GRP_ID(grp));
  787. enable_soidle_by_mask(grp, mask);
  788. #else
  789. unsigned int grp = clk_id_to_grp_id(id);
  790. unsigned int mask = clk_id_to_mask(id);
  791. if ((grp == NR_GRPS) || (mask == NR_GRPS))
  792. idle_warn("[%s]wrong clock id\n", __func__);
  793. else
  794. soidle_condition_mask[grp] &= ~mask;
  795. #endif
  796. }
  797. EXPORT_SYMBOL(enable_soidle_by_bit);
  798. void disable_soidle_by_bit(int id)
  799. {
  800. #if !defined(CONFIG_ARCH_MT6580)
  801. int grp = id / 32;
  802. unsigned int mask = 1U << (id % 32);
  803. BUG_ON(INVALID_GRP_ID(grp));
  804. disable_soidle_by_mask(grp, mask);
  805. #else
  806. unsigned int grp = clk_id_to_grp_id(id);
  807. unsigned int mask = clk_id_to_mask(id);
  808. if ((grp == NR_GRPS) || (mask == NR_GRPS))
  809. idle_warn("[%s]wrong clock id\n", __func__);
  810. else
  811. soidle_condition_mask[grp] |= mask;
  812. #endif
  813. }
  814. EXPORT_SYMBOL(disable_soidle_by_bit);
  815. #if !defined(CONFIG_ARCH_MT6580)
  816. void defeature_soidle_by_display(void)
  817. {
  818. if (idle_switch[IDLE_TYPE_SO] != 0)
  819. {
  820. idle_switch[IDLE_TYPE_SO] = 0;
  821. }
  822. }
  823. EXPORT_SYMBOL(defeature_soidle_by_display);
  824. #endif
  825. static bool soidle_can_enter(int cpu)
  826. {
  827. int reason = NR_REASONS;
  828. unsigned long long soidle_block_curr_time = 0;
  829. bool retval = false;
  830. char *p;
  831. #ifdef CONFIG_SMP
  832. if (!(spm_get_cpu_pwr_status() == CA7_CPU0)) {
  833. reason = BY_CPU;
  834. goto out;
  835. }
  836. #endif
  837. if (idle_spm_lock) {
  838. reason = BY_VTG;
  839. goto out;
  840. }
  841. #if defined(CONFIG_MICROTRUST_TEE_SUPPORT)
  842. if (!is_teei_ready()) {
  843. reason = BY_OTH;
  844. goto out;
  845. }
  846. #endif
  847. /* decide when to enable SODI by display driver */
  848. if (spm_get_sodi_en() == 0) {
  849. reason = BY_OTH;
  850. goto out;
  851. }
  852. if (soidle_by_pass_cg == 0) {
  853. memset(soidle_block_mask, 0, NR_GRPS * sizeof(unsigned int));
  854. #if !defined(CONFIG_ARCH_MT6580)
  855. if (!cg_check_idle_can_enter(soidle_condition_mask, soidle_block_mask, MT_SOIDLE)) {
  856. #else
  857. if (!clkmgr_idle_can_enter(soidle_condition_mask, soidle_block_mask)) {
  858. #endif
  859. reason = BY_CLK;
  860. goto out;
  861. }
  862. }
  863. #ifdef CONFIG_SMP
  864. soidle_timer_left = localtimer_get_counter();
  865. if ((int)soidle_timer_left < soidle_time_critera ||
  866. ((int)soidle_timer_left) < 0) {
  867. reason = BY_TMR;
  868. goto out;
  869. }
  870. #else
  871. gpt_get_cnt(GPT1, &soidle_timer_left);
  872. gpt_get_cmp(GPT1, &soidle_timer_cmp);
  873. if ((soidle_timer_cmp - soidle_timer_left) < soidle_time_critera) {
  874. reason = BY_TMR;
  875. goto out;
  876. }
  877. #endif
  878. if (sodi_by_uptime_count != -1) {
  879. struct timespec uptime;
  880. unsigned long val;
  881. get_monotonic_boottime(&uptime);
  882. val = (unsigned long)uptime.tv_sec;
  883. if (val <= 20) {
  884. sodi_by_uptime_count++;
  885. reason = BY_OTH;
  886. goto out;
  887. } else {
  888. idle_warn("SODI: blocking by uptime count = %d\n", sodi_by_uptime_count);
  889. sodi_by_uptime_count = -1;
  890. }
  891. }
  892. out:
  893. if (reason < NR_REASONS) {
  894. if (soidle_block_prev_time == 0)
  895. soidle_block_prev_time = idle_get_current_time_ms();
  896. soidle_block_curr_time = idle_get_current_time_ms();
  897. if (((soidle_block_curr_time - soidle_block_prev_time) > soidle_block_time_critera)
  898. && ((soidle_block_curr_time - idle_block_log_prev_time) > idle_block_log_time_criteria)) {
  899. if ((smp_processor_id() == 0)) {
  900. int i = 0;
  901. /* soidle,rgidle count */
  902. p = log_buf;
  903. p += sprintf(p, "CNT(soidle,rgidle): ");
  904. for (i = 0; i < nr_cpu_ids; i++)
  905. p += sprintf(p, "[%d] = (%lu,%lu), ", i, soidle_cnt[i], rgidle_cnt[i]);
  906. idle_warn("%s\n", log_buf);
  907. /* block category */
  908. p = log_buf;
  909. p += sprintf(p, "soidle_block_cnt: ");
  910. for (i = 0; i < NR_REASONS; i++)
  911. p += sprintf(p, "[%s] = %lu, ", reason_name[i], soidle_block_cnt[0][i]);
  912. idle_warn("%s\n", log_buf);
  913. p = log_buf;
  914. p += sprintf(p, "soidle_block_mask: ");
  915. for (i = 0; i < NR_GRPS; i++)
  916. p += sprintf(p, "0x%08x, ", soidle_block_mask[i]);
  917. idle_warn("%s\n", log_buf);
  918. memset(soidle_block_cnt, 0, sizeof(soidle_block_cnt));
  919. soidle_block_prev_time = idle_get_current_time_ms();
  920. idle_block_log_prev_time = soidle_block_prev_time;
  921. }
  922. }
  923. soidle_block_cnt[cpu][reason]++;
  924. retval = false;
  925. } else {
  926. soidle_block_prev_time = idle_get_current_time_ms();
  927. retval = true;
  928. }
  929. return retval;
  930. }
  931. void soidle_before_wfi(int cpu)
  932. {
  933. #ifdef CONFIG_SMP
  934. soidle_timer_left2 = localtimer_get_counter();
  935. if ((int)soidle_timer_left2 <= 0) {
  936. /* Trigger idle_gpt Timerout imediately */
  937. gpt_set_cmp(idle_gpt, 1);
  938. } else
  939. gpt_set_cmp(idle_gpt, soidle_timer_left2);
  940. start_gpt(idle_gpt);
  941. #else
  942. gpt_get_cnt(GPT1, &soidle_timer_left2);
  943. #endif
  944. }
  945. void soidle_after_wfi(int cpu)
  946. {
  947. #ifdef CONFIG_SMP
  948. if (gpt_check_and_ack_irq(idle_gpt)) {
  949. localtimer_set_next_event(1);
  950. } else {
  951. /* waked up by other wakeup source */
  952. unsigned int cnt, cmp;
  953. idle_gpt_get_cnt(idle_gpt, &cnt);
  954. idle_gpt_get_cmp(idle_gpt, &cmp);
  955. if (unlikely(cmp < cnt)) {
  956. idle_warn("[%s]GPT%d: counter = %10u, compare = %10u\n", __func__,
  957. idle_gpt + 1, cnt, cmp);
  958. BUG();
  959. }
  960. localtimer_set_next_event(cmp-cnt);
  961. stop_gpt(idle_gpt);
  962. }
  963. #endif
  964. soidle_cnt[cpu]++;
  965. }
  966. /*
  967. * deep idle part
  968. */
  969. static DEFINE_MUTEX(dpidle_locked);
  970. #if !defined(CONFIG_ARCH_MT6580)
  971. static void enable_dpidle_by_mask(int grp, unsigned int mask)
  972. {
  973. mutex_lock(&dpidle_locked);
  974. dpidle_condition_mask[grp] &= ~mask;
  975. mutex_unlock(&dpidle_locked);
  976. }
  977. static void disable_dpidle_by_mask(int grp, unsigned int mask)
  978. {
  979. mutex_lock(&dpidle_locked);
  980. dpidle_condition_mask[grp] |= mask;
  981. mutex_unlock(&dpidle_locked);
  982. }
  983. #endif
  984. void enable_dpidle_by_bit(int id)
  985. {
  986. #if !defined(CONFIG_ARCH_MT6580)
  987. int grp = id / 32;
  988. unsigned int mask = 1U << (id % 32);
  989. BUG_ON(INVALID_GRP_ID(grp));
  990. enable_dpidle_by_mask(grp, mask);
  991. #else
  992. unsigned int grp = clk_id_to_grp_id(id);
  993. unsigned int mask = clk_id_to_mask(id);
  994. if ((grp == NR_GRPS) || (mask == NR_GRPS))
  995. idle_warn("[%s]wrong clock id\n", __func__);
  996. else
  997. dpidle_condition_mask[grp] &= ~mask;
  998. #endif
  999. }
  1000. EXPORT_SYMBOL(enable_dpidle_by_bit);
  1001. void disable_dpidle_by_bit(int id)
  1002. {
  1003. #if !defined(CONFIG_ARCH_MT6580)
  1004. int grp = id / 32;
  1005. unsigned int mask = 1U << (id % 32);
  1006. BUG_ON(INVALID_GRP_ID(grp));
  1007. disable_dpidle_by_mask(grp, mask);
  1008. #else
  1009. unsigned int grp = clk_id_to_grp_id(id);
  1010. unsigned int mask = clk_id_to_mask(id);
  1011. if ((grp == NR_GRPS) || (mask == NR_GRPS))
  1012. idle_warn("[%s]wrong clock id\n", __func__);
  1013. else
  1014. dpidle_condition_mask[grp] |= mask;
  1015. #endif
  1016. }
  1017. EXPORT_SYMBOL(disable_dpidle_by_bit);
  1018. static bool dpidle_can_enter(void)
  1019. {
  1020. int reason = NR_REASONS;
  1021. int i = 0;
  1022. unsigned long long dpidle_block_curr_time = 0;
  1023. bool retval = false;
  1024. char *p;
  1025. #ifdef CONFIG_SMP
  1026. if (!(spm_get_cpu_pwr_status() == CA7_CPU0)) {
  1027. reason = BY_CPU;
  1028. goto out;
  1029. }
  1030. #endif
  1031. if (idle_spm_lock) {
  1032. reason = BY_VTG;
  1033. goto out;
  1034. }
  1035. #if defined(CONFIG_MICROTRUST_TEE_SUPPORT)
  1036. if (!is_teei_ready()) {
  1037. reason = BY_OTH;
  1038. goto out;
  1039. }
  1040. #endif
  1041. if (dpidle_by_pass_cg == 0) {
  1042. memset(dpidle_block_mask, 0, NR_GRPS * sizeof(unsigned int));
  1043. #if !defined(CONFIG_ARCH_MT6580)
  1044. if (!cg_check_idle_can_enter(dpidle_condition_mask, dpidle_block_mask, MT_DPIDLE)) {
  1045. #else
  1046. if (!clkmgr_idle_can_enter(dpidle_condition_mask, dpidle_block_mask)) {
  1047. #endif
  1048. reason = BY_CLK;
  1049. goto out;
  1050. }
  1051. }
  1052. #ifdef CONFIG_SMP
  1053. dpidle_timer_left = localtimer_get_counter();
  1054. if ((int)dpidle_timer_left < dpidle_time_critera ||
  1055. ((int)dpidle_timer_left) < 0) {
  1056. reason = BY_TMR;
  1057. goto out;
  1058. }
  1059. #else
  1060. gpt_get_cnt(GPT1, &dpidle_timer_left);
  1061. gpt_get_cmp(GPT1, &dpidle_timer_cmp);
  1062. if ((dpidle_timer_cmp - dpidle_timer_left) < dpidle_time_critera) {
  1063. reason = BY_TMR;
  1064. goto out;
  1065. }
  1066. #endif
  1067. out:
  1068. if (reason < NR_REASONS) {
  1069. if (dpidle_block_prev_time == 0)
  1070. dpidle_block_prev_time = idle_get_current_time_ms();
  1071. dpidle_block_curr_time = idle_get_current_time_ms();
  1072. if (((dpidle_block_curr_time - dpidle_block_prev_time) > dpidle_block_time_critera)
  1073. && ((dpidle_block_curr_time - idle_block_log_prev_time) > idle_block_log_time_criteria)) {
  1074. if ((smp_processor_id() == 0)) {
  1075. /* dpidle,rgidle count */
  1076. p = log_buf;
  1077. p += sprintf(p, "CNT(dpidle,rgidle): ");
  1078. for (i = 0; i < nr_cpu_ids; i++)
  1079. p += sprintf(p, "[%d] = (%lu,%lu), ", i, dpidle_cnt[i], rgidle_cnt[i]);
  1080. idle_warn("%s\n", log_buf);
  1081. /* block category */
  1082. p = log_buf;
  1083. p += sprintf(p, "dpidle_block_cnt: ");
  1084. for (i = 0; i < NR_REASONS; i++)
  1085. p += sprintf(p, "[%s] = %lu, ", reason_name[i], dpidle_block_cnt[i]);
  1086. idle_warn("%s\n", log_buf);
  1087. p = log_buf;
  1088. p += sprintf(p, "dpidle_block_mask: ");
  1089. for (i = 0; i < NR_GRPS; i++)
  1090. p += sprintf(p, "0x%08x, ", dpidle_block_mask[i]);
  1091. idle_warn("%s\n", log_buf);
  1092. memset(dpidle_block_cnt, 0, sizeof(dpidle_block_cnt));
  1093. dpidle_block_prev_time = idle_get_current_time_ms();
  1094. idle_block_log_prev_time = dpidle_block_prev_time;
  1095. }
  1096. }
  1097. dpidle_block_cnt[reason]++;
  1098. retval = false;
  1099. } else {
  1100. dpidle_block_prev_time = idle_get_current_time_ms();
  1101. retval = true;
  1102. }
  1103. return retval;
  1104. }
  1105. void spm_dpidle_before_wfi(void)
  1106. {
  1107. bus_dcm_enable();
  1108. #if !defined(CONFIG_ARCH_MT6580)
  1109. faudintbus_pll2sq();
  1110. #else
  1111. clkmgr_faudintbus_pll2sq();
  1112. #endif
  1113. #ifdef CONFIG_SMP
  1114. dpidle_timer_left2 = localtimer_get_counter();
  1115. if ((int)dpidle_timer_left2 <= 0) {
  1116. /* Trigger GPT4 Timerout imediately */
  1117. gpt_set_cmp(idle_gpt, 1);
  1118. } else
  1119. gpt_set_cmp(idle_gpt, dpidle_timer_left2);
  1120. start_gpt(idle_gpt);
  1121. #else
  1122. gpt_get_cnt(idle_gpt, &dpidle_timer_left2);
  1123. #endif
  1124. }
  1125. void spm_dpidle_after_wfi(void)
  1126. {
  1127. #ifdef CONFIG_SMP
  1128. /* if (gpt_check_irq(GPT4)) { */
  1129. if (gpt_check_and_ack_irq(idle_gpt)) {
  1130. /* waked up by WAKEUP_GPT */
  1131. localtimer_set_next_event(1);
  1132. } else {
  1133. /* waked up by other wakeup source */
  1134. unsigned int cnt, cmp;
  1135. idle_gpt_get_cnt(idle_gpt, &cnt);
  1136. idle_gpt_get_cmp(idle_gpt, &cmp);
  1137. if (unlikely(cmp < cnt)) {
  1138. idle_warn("[%s]GPT%d: counter = %10u, compare = %10u\n", __func__,
  1139. idle_gpt + 1, cnt, cmp);
  1140. BUG();
  1141. }
  1142. localtimer_set_next_event(cmp-cnt);
  1143. stop_gpt(idle_gpt);
  1144. }
  1145. #endif
  1146. #if !defined(CONFIG_ARCH_MT6580)
  1147. faudintbus_sq2pll();
  1148. #else
  1149. clkmgr_faudintbus_sq2pll();
  1150. #endif
  1151. bus_dcm_disable();
  1152. dpidle_cnt[0]++;
  1153. }
  1154. /*
  1155. * slow idle part
  1156. */
  1157. static DEFINE_MUTEX(slidle_locked);
  1158. static void enable_slidle_by_mask(int grp, unsigned int mask)
  1159. {
  1160. mutex_lock(&slidle_locked);
  1161. slidle_condition_mask[grp] &= ~mask;
  1162. mutex_unlock(&slidle_locked);
  1163. }
  1164. static void disable_slidle_by_mask(int grp, unsigned int mask)
  1165. {
  1166. mutex_lock(&slidle_locked);
  1167. slidle_condition_mask[grp] |= mask;
  1168. mutex_unlock(&slidle_locked);
  1169. }
  1170. void enable_slidle_by_bit(int id)
  1171. {
  1172. int grp = id / 32;
  1173. unsigned int mask = 1U << (id % 32);
  1174. BUG_ON(INVALID_GRP_ID(grp));
  1175. enable_slidle_by_mask(grp, mask);
  1176. }
  1177. EXPORT_SYMBOL(enable_slidle_by_bit);
  1178. void disable_slidle_by_bit(int id)
  1179. {
  1180. int grp = id / 32;
  1181. unsigned int mask = 1U << (id % 32);
  1182. BUG_ON(INVALID_GRP_ID(grp));
  1183. disable_slidle_by_mask(grp, mask);
  1184. }
  1185. EXPORT_SYMBOL(disable_slidle_by_bit);
  1186. static bool slidle_can_enter(void)
  1187. {
  1188. int reason = NR_REASONS;
  1189. if (!(spm_get_cpu_pwr_status() == CA7_CPU0)) {
  1190. reason = BY_CPU;
  1191. goto out;
  1192. }
  1193. memset(slidle_block_mask, 0, NR_GRPS * sizeof(unsigned int));
  1194. #if !defined(CONFIG_ARCH_MT6580)
  1195. if (!cg_check_idle_can_enter(slidle_condition_mask, slidle_block_mask, MT_SLIDLE)) {
  1196. #else
  1197. if (!clkmgr_idle_can_enter(slidle_condition_mask, slidle_block_mask)) {
  1198. #endif
  1199. reason = BY_CLK;
  1200. goto out;
  1201. }
  1202. #if EN_PTP_OD
  1203. if (ptp_data[0]) {
  1204. reason = BY_OTH;
  1205. goto out;
  1206. }
  1207. #endif
  1208. out:
  1209. if (reason < NR_REASONS) {
  1210. slidle_block_cnt[reason]++;
  1211. return false;
  1212. } else {
  1213. return true;
  1214. }
  1215. }
  1216. static void slidle_before_wfi(int cpu)
  1217. {
  1218. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753)
  1219. mt_dcm_topckg_enable();
  1220. #endif
  1221. }
  1222. static void slidle_after_wfi(int cpu)
  1223. {
  1224. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753)
  1225. mt_dcm_topckg_disable();
  1226. slidle_cnt[cpu]++;
  1227. #endif
  1228. }
  1229. static void go_to_slidle(int cpu)
  1230. {
  1231. slidle_before_wfi(cpu);
  1232. mb();
  1233. __asm__ __volatile__("wfi" : : : "memory");
  1234. slidle_after_wfi(cpu);
  1235. }
  1236. /*
  1237. * regular idle part
  1238. */
  1239. static void rgidle_before_wfi(int cpu)
  1240. {
  1241. }
  1242. static void rgidle_after_wfi(int cpu)
  1243. {
  1244. rgidle_cnt[cpu]++;
  1245. }
  1246. static noinline void go_to_rgidle(int cpu)
  1247. {
  1248. rgidle_before_wfi(cpu);
  1249. isb();
  1250. mb();
  1251. __asm__ __volatile__("wfi" : : : "memory");
  1252. rgidle_after_wfi(cpu);
  1253. }
  1254. /*
  1255. * idle task flow part
  1256. */
  1257. static inline void soidle_pre_handler(void)
  1258. {
  1259. hps_del_timer();
  1260. #ifdef CONFIG_THERMAL
  1261. /* cancel thermal hrtimer for power saving */
  1262. tscpu_cancel_thermal_timer();
  1263. mtkts_bts_cancel_thermal_timer();
  1264. mtkts_btsmdpa_cancel_thermal_timer();
  1265. mtkts_pmic_cancel_thermal_timer();
  1266. mtkts_battery_cancel_thermal_timer();
  1267. mtkts_pa_cancel_thermal_timer();
  1268. mtkts_wmt_cancel_thermal_timer();
  1269. mtkts_allts_cancel_ts1_timer();
  1270. mtkts_allts_cancel_ts2_timer();
  1271. mtkts_allts_cancel_ts3_timer();
  1272. mtkts_allts_cancel_ts4_timer();
  1273. mtkts_allts_cancel_ts5_timer();
  1274. #endif
  1275. }
  1276. static inline void soidle_post_handler(void)
  1277. {
  1278. hps_restart_timer();
  1279. #ifdef CONFIG_THERMAL
  1280. /* restart thermal hrtimer for update temp info */
  1281. tscpu_start_thermal_timer();
  1282. mtkts_bts_start_thermal_timer();
  1283. mtkts_btsmdpa_start_thermal_timer();
  1284. mtkts_pmic_start_thermal_timer();
  1285. mtkts_battery_start_thermal_timer();
  1286. mtkts_pa_start_thermal_timer();
  1287. mtkts_wmt_start_thermal_timer();
  1288. mtkts_allts_start_ts1_timer();
  1289. mtkts_allts_start_ts2_timer();
  1290. mtkts_allts_start_ts3_timer();
  1291. mtkts_allts_start_ts4_timer();
  1292. mtkts_allts_start_ts5_timer();
  1293. #endif
  1294. }
  1295. static u32 slp_spm_SODI_flags = {
  1296. 0
  1297. };
  1298. u32 slp_spm_deepidle_flags = {
  1299. 0
  1300. };
  1301. static inline void dpidle_pre_handler(void)
  1302. {
  1303. hps_del_timer();
  1304. #ifdef CONFIG_THERMAL
  1305. /* cancel thermal hrtimer for power saving */
  1306. tscpu_cancel_thermal_timer();
  1307. mtkts_bts_cancel_thermal_timer();
  1308. mtkts_btsmdpa_cancel_thermal_timer();
  1309. mtkts_pmic_cancel_thermal_timer();
  1310. mtkts_battery_cancel_thermal_timer();
  1311. mtkts_pa_cancel_thermal_timer();
  1312. mtkts_wmt_cancel_thermal_timer();
  1313. mtkts_allts_cancel_ts1_timer();
  1314. mtkts_allts_cancel_ts2_timer();
  1315. mtkts_allts_cancel_ts3_timer();
  1316. mtkts_allts_cancel_ts4_timer();
  1317. mtkts_allts_cancel_ts5_timer();
  1318. #endif
  1319. }
  1320. static inline void dpidle_post_handler(void)
  1321. {
  1322. hps_restart_timer();
  1323. #ifdef CONFIG_THERMAL
  1324. /* restart thermal hrtimer for update temp info */
  1325. tscpu_start_thermal_timer();
  1326. mtkts_bts_start_thermal_timer();
  1327. mtkts_btsmdpa_start_thermal_timer();
  1328. mtkts_pmic_start_thermal_timer();
  1329. mtkts_battery_start_thermal_timer();
  1330. mtkts_pa_start_thermal_timer();
  1331. mtkts_wmt_start_thermal_timer();
  1332. mtkts_allts_start_ts1_timer();
  1333. mtkts_allts_start_ts2_timer();
  1334. mtkts_allts_start_ts3_timer();
  1335. mtkts_allts_start_ts4_timer();
  1336. mtkts_allts_start_ts5_timer();
  1337. #endif
  1338. }
  1339. #ifdef SPM_DEEPIDLE_PROFILE_TIME
  1340. unsigned int dpidle_profile[4];
  1341. #endif
  1342. static inline int dpidle_select_handler(int cpu)
  1343. {
  1344. int ret = 0;
  1345. if (idle_switch[IDLE_TYPE_DP]) {
  1346. if (dpidle_can_enter())
  1347. ret = 1;
  1348. }
  1349. return ret;
  1350. }
  1351. static inline int soidle_select_handler(int cpu)
  1352. {
  1353. int ret = 0;
  1354. if (idle_switch[IDLE_TYPE_SO]) {
  1355. if (soidle_can_enter(cpu))
  1356. ret = 1;
  1357. }
  1358. return ret;
  1359. }
  1360. static inline int slidle_select_handler(int cpu)
  1361. {
  1362. int ret = 0;
  1363. if (idle_switch[IDLE_TYPE_SL]) {
  1364. if (slidle_can_enter())
  1365. ret = 1;
  1366. }
  1367. return ret;
  1368. }
  1369. static inline int rgidle_select_handler(int cpu)
  1370. {
  1371. int ret = 0;
  1372. if (idle_switch[IDLE_TYPE_RG])
  1373. ret = 1;
  1374. return ret;
  1375. }
  1376. static int (*idle_select_handlers[NR_TYPES])(int) = {
  1377. dpidle_select_handler,
  1378. soidle_select_handler,
  1379. slidle_select_handler,
  1380. rgidle_select_handler,
  1381. };
  1382. void dump_idle_cnt_in_interval(int cpu)
  1383. {
  1384. int i = 0;
  1385. char *p = log_buf;
  1386. char *p2 = log_buf_2;
  1387. unsigned long long idle_cnt_dump_curr_time = 0;
  1388. bool have_dpidle = false;
  1389. bool have_soidle = false;
  1390. if (idle_cnt_dump_prev_time == 0)
  1391. idle_cnt_dump_prev_time = idle_get_current_time_ms();
  1392. idle_cnt_dump_curr_time = idle_get_current_time_ms();
  1393. if (!(cpu == 0))
  1394. return;
  1395. if (!((idle_cnt_dump_curr_time - idle_cnt_dump_prev_time) > idle_cnt_dump_criteria))
  1396. return;
  1397. /* dump idle count */
  1398. /* deepidle */
  1399. p = log_buf;
  1400. for (i = 0; i < nr_cpu_ids; i++) {
  1401. if ((dpidle_cnt[i] - dpidle_last_cnt[i]) != 0) {
  1402. p += sprintf(p, "[%d] = %lu, ", i, dpidle_cnt[i] - dpidle_last_cnt[i]);
  1403. have_dpidle = true;
  1404. }
  1405. dpidle_last_cnt[i] = dpidle_cnt[i];
  1406. }
  1407. if (have_dpidle)
  1408. p2 += sprintf(p2, "DP: %s --- ", log_buf);
  1409. else
  1410. p2 += sprintf(p2, "DP: No enter --- ");
  1411. /* sodi */
  1412. p = log_buf;
  1413. for (i = 0; i < nr_cpu_ids; i++) {
  1414. if ((soidle_cnt[i] - soidle_last_cnt[i]) != 0) {
  1415. p += sprintf(p, "[%d] = %lu, ", i, soidle_cnt[i] - soidle_last_cnt[i]);
  1416. have_soidle = true;
  1417. }
  1418. soidle_last_cnt[i] = soidle_cnt[i];
  1419. }
  1420. if (have_soidle)
  1421. p2 += sprintf(p2, "SODI: %s --- ", log_buf);
  1422. else
  1423. p2 += sprintf(p2, "SODI: No enter --- ");
  1424. /* dump log */
  1425. idle_warn("%s\n", log_buf_2);
  1426. /* dump idle ratio */
  1427. if (idle_ratio_en) {
  1428. idle_ratio_profile_duration = idle_get_current_time_ms() - idle_ratio_profile_start_time;
  1429. idle_warn("--- CPU 0 idle: %llu, DP = %llu, SO = %llu, SL = %llu, RG = %llu --- (ms)\n",
  1430. idle_ratio_profile_duration,
  1431. idle_ratio_value[IDLE_TYPE_DP],
  1432. idle_ratio_value[IDLE_TYPE_SO],
  1433. idle_ratio_value[IDLE_TYPE_SL],
  1434. idle_ratio_value[IDLE_TYPE_RG]);
  1435. idle_ratio_profile_start_time = idle_get_current_time_ms();
  1436. for (i = 0; i < NR_TYPES; i++)
  1437. idle_ratio_value[i] = 0;
  1438. }
  1439. /* update time base */
  1440. idle_cnt_dump_prev_time = idle_cnt_dump_curr_time;
  1441. }
  1442. inline void idle_ratio_calc_start(int type, int cpu)
  1443. {
  1444. if (type >= 0 && type < NR_TYPES && cpu == 0)
  1445. idle_ratio_start_time[type] = idle_get_current_time_ms();
  1446. }
  1447. inline void idle_ratio_calc_stop(int type, int cpu)
  1448. {
  1449. if (type >= 0 && type < NR_TYPES && cpu == 0)
  1450. idle_ratio_value[type] += (idle_get_current_time_ms() - idle_ratio_start_time[type]);
  1451. }
  1452. int mt_idle_select(int cpu)
  1453. {
  1454. int i = NR_TYPES - 1;
  1455. dump_idle_cnt_in_interval(cpu);
  1456. for (i = 0; i < NR_TYPES; i++) {
  1457. if (idle_select_handlers[i](cpu))
  1458. break;
  1459. }
  1460. return i;
  1461. }
  1462. EXPORT_SYMBOL(mt_idle_select);
  1463. int dpidle_enter(int cpu)
  1464. {
  1465. int ret = 1;
  1466. idle_ratio_calc_start(IDLE_TYPE_DP, cpu);
  1467. dpidle_pre_handler();
  1468. spm_go_to_dpidle(slp_spm_deepidle_flags, 0, dpidle_dump_log);
  1469. dpidle_post_handler();
  1470. idle_ratio_calc_stop(IDLE_TYPE_DP, cpu);
  1471. #ifdef CONFIG_SMP
  1472. idle_warn_log("DP:timer_left=%d, timer_left2=%d, delta=%d\n",
  1473. dpidle_timer_left, dpidle_timer_left2, dpidle_timer_left-dpidle_timer_left2);
  1474. #else
  1475. idle_warn_log("DP:timer_left=%d, timer_left2=%d, delta=%d, timeout val=%d\n",
  1476. dpidle_timer_left,
  1477. dipidle_timer_left2,
  1478. dpidle_timer_left2 - dpidle_timer_left,
  1479. dpidle_timer_cmp - dpidle_timer_left);
  1480. #endif
  1481. #ifdef SPM_DEEPIDLE_PROFILE_TIME
  1482. gpt_get_cnt(SPM_PROFILE_APXGPT, &dpidle_profile[3]);
  1483. idle_warn_log("1:%u, 2:%u, 3:%u, 4:%u\n",
  1484. dpidle_profile[0], dpidle_profile[1], dpidle_profile[2], dpidle_profile[3]);
  1485. #endif
  1486. return ret;
  1487. }
  1488. EXPORT_SYMBOL(dpidle_enter);
  1489. int soidle_enter(int cpu)
  1490. {
  1491. int ret = 1;
  1492. idle_ratio_calc_start(IDLE_TYPE_SO, cpu);
  1493. soidle_pre_handler();
  1494. spm_go_to_sodi(slp_spm_SODI_flags, 0);
  1495. soidle_post_handler();
  1496. idle_ratio_calc_stop(IDLE_TYPE_SO, cpu);
  1497. return ret;
  1498. }
  1499. EXPORT_SYMBOL(soidle_enter);
  1500. int slidle_enter(int cpu)
  1501. {
  1502. int ret = 1;
  1503. idle_ratio_calc_start(IDLE_TYPE_SL, cpu);
  1504. go_to_slidle(cpu);
  1505. idle_ratio_calc_stop(IDLE_TYPE_SL, cpu);
  1506. return ret;
  1507. }
  1508. EXPORT_SYMBOL(slidle_enter);
  1509. int rgidle_enter(int cpu)
  1510. {
  1511. int ret = 1;
  1512. idle_ratio_calc_start(IDLE_TYPE_RG, cpu);
  1513. go_to_rgidle(cpu);
  1514. idle_ratio_calc_stop(IDLE_TYPE_RG, cpu);
  1515. return ret;
  1516. }
  1517. EXPORT_SYMBOL(rgidle_enter);
  1518. void mt_idle_init(void)
  1519. {
  1520. }
  1521. /*
  1522. * debugfs
  1523. */
  1524. static char dbg_buf[2048] = {0};
  1525. static char cmd_buf[512] = {0};
  1526. /*
  1527. * idle_state
  1528. */
  1529. static int _idle_state_open(struct seq_file *s, void *data)
  1530. {
  1531. return 0;
  1532. }
  1533. static int idle_state_open(struct inode *inode, struct file *filp)
  1534. {
  1535. return single_open(filp, _idle_state_open, inode->i_private);
  1536. }
  1537. static ssize_t idle_state_read(struct file *filp,
  1538. char __user *userbuf,
  1539. size_t count,
  1540. loff_t *f_pos)
  1541. {
  1542. int len = 0;
  1543. char *p = dbg_buf;
  1544. int i;
  1545. p += sprintf(p, "********** idle state dump **********\n");
  1546. for (i = 0; i < nr_cpu_ids; i++) {
  1547. p += sprintf(p, "soidle_cnt[%d]=%lu, dpidle_cnt[%d]=%lu, slidle_cnt[%d]=%lu, rgidle_cnt[%d]=%lu\n",
  1548. i, soidle_cnt[i], i, dpidle_cnt[i],
  1549. i, slidle_cnt[i], i, rgidle_cnt[i]);
  1550. }
  1551. p += sprintf(p, "\n********** variables dump **********\n");
  1552. for (i = 0; i < NR_TYPES; i++)
  1553. p += sprintf(p, "%s_switch=%d, ", idle_name[i], idle_switch[i]);
  1554. p += sprintf(p, "\n");
  1555. p += sprintf(p, "idle_ratio_en = %u\n", idle_ratio_en);
  1556. p += sprintf(p, "\n********** idle command help **********\n");
  1557. p += sprintf(p, "status help: cat /sys/kernel/debug/cpuidle/idle_state\n");
  1558. p += sprintf(p, "switch on/off: echo switch mask > /sys/kernel/debug/cpuidle/idle_state\n");
  1559. p += sprintf(p, "idle ratio profile: echo ratio 1/0 > /sys/kernel/debug/cpuidle/idle_state\n");
  1560. p += sprintf(p, "soidle help: cat /sys/kernel/debug/cpuidle/soidle_state\n");
  1561. p += sprintf(p, "dpidle help: cat /sys/kernel/debug/cpuidle/dpidle_state\n");
  1562. p += sprintf(p, "slidle help: cat /sys/kernel/debug/cpuidle/slidle_state\n");
  1563. p += sprintf(p, "rgidle help: cat /sys/kernel/debug/cpuidle/rgidle_state\n");
  1564. len = p - dbg_buf;
  1565. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  1566. }
  1567. static ssize_t idle_state_write(struct file *filp,
  1568. const char __user *userbuf,
  1569. size_t count,
  1570. loff_t *f_pos)
  1571. {
  1572. char cmd[32];
  1573. int idx;
  1574. int param;
  1575. count = min(count, sizeof(cmd_buf) - 1);
  1576. if (copy_from_user(cmd_buf, userbuf, count))
  1577. return -EFAULT;
  1578. cmd_buf[count] = '\0';
  1579. if (sscanf(cmd_buf, "%s %x", cmd, &param) == 2) {
  1580. if (!strcmp(cmd, "switch")) {
  1581. for (idx = 0; idx < NR_TYPES; idx++)
  1582. idle_switch[idx] = (param & (1U << idx)) ? 1 : 0;
  1583. } else if (!strcmp(cmd, "ratio")) {
  1584. idle_ratio_en = param;
  1585. if (idle_ratio_en) {
  1586. idle_ratio_profile_start_time = idle_get_current_time_ms();
  1587. for (idx = 0; idx < NR_TYPES; idx++)
  1588. idle_ratio_value[idx] = 0;
  1589. }
  1590. }
  1591. return count;
  1592. }
  1593. return -EINVAL;
  1594. }
  1595. static const struct file_operations idle_state_fops = {
  1596. .open = idle_state_open,
  1597. .read = idle_state_read,
  1598. .write = idle_state_write,
  1599. .llseek = seq_lseek,
  1600. .release = single_release,
  1601. };
  1602. /*
  1603. * dpidle_state
  1604. */
  1605. static int _dpidle_state_open(struct seq_file *s, void *data)
  1606. {
  1607. return 0;
  1608. }
  1609. static int dpidle_state_open(struct inode *inode, struct file *filp)
  1610. {
  1611. return single_open(filp, _dpidle_state_open, inode->i_private);
  1612. }
  1613. static ssize_t dpidle_state_read(struct file *filp, char __user *userbuf, size_t count, loff_t *f_pos)
  1614. {
  1615. int len = 0;
  1616. char *p = dbg_buf;
  1617. int i;
  1618. p += sprintf(p, "*********** deep idle state ************\n");
  1619. p += sprintf(p, "dpidle_time_critera=%u\n", dpidle_time_critera);
  1620. for (i = 0; i < NR_REASONS; i++) {
  1621. p += sprintf(p, "[%d]dpidle_block_cnt[%s]=%lu\n", i, reason_name[i],
  1622. dpidle_block_cnt[i]);
  1623. }
  1624. p += sprintf(p, "\n");
  1625. for (i = 0; i < NR_GRPS; i++) {
  1626. p += sprintf(p, "[%02d]dpidle_condition_mask[%-8s]=0x%08x\t\tdpidle_block_mask[%-8s]=0x%08x\n", i,
  1627. cg_grp_get_name(i), dpidle_condition_mask[i],
  1628. cg_grp_get_name(i), dpidle_block_mask[i]);
  1629. }
  1630. p += sprintf(p, "dpidle_bypass_cg=%u\n", dpidle_by_pass_cg);
  1631. p += sprintf(p, "dpidle_by_pass_pg=%u\n", dpidle_by_pass_pg);
  1632. p += sprintf(p, "dpidle_dump_log = %u\n", dpidle_dump_log);
  1633. p += sprintf(p, "(0: None, 1: Reduced, 2: Full\n");
  1634. p += sprintf(p, "\n*********** dpidle command help ************\n");
  1635. p += sprintf(p, "dpidle help: cat /sys/kernel/debug/cpuidle/dpidle_state\n");
  1636. p += sprintf(p, "switch on/off: echo [dpidle] 1/0 > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1637. p += sprintf(p, "cpupdn on/off: echo cpupdn 1/0 > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1638. p += sprintf(p, "en_dp_by_bit: echo enable id > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1639. p += sprintf(p, "dis_dp_by_bit: echo disable id > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1640. p += sprintf(p, "modify tm_cri: echo time value(dec) > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1641. p += sprintf(p, "bypass cg: echo bypass 1/0 > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1642. len = p - dbg_buf;
  1643. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  1644. }
  1645. static ssize_t dpidle_state_write(struct file *filp,
  1646. const char __user *userbuf,
  1647. size_t count,
  1648. loff_t *f_pos)
  1649. {
  1650. char cmd[32];
  1651. int param;
  1652. count = min(count, sizeof(cmd_buf) - 1);
  1653. if (copy_from_user(cmd_buf, userbuf, count))
  1654. return -EFAULT;
  1655. cmd_buf[count] = '\0';
  1656. if (sscanf(cmd_buf, "%s %d", cmd, &param) == 2) {
  1657. if (!strcmp(cmd, "dpidle"))
  1658. idle_switch[IDLE_TYPE_DP] = param;
  1659. else if (!strcmp(cmd, "enable"))
  1660. enable_dpidle_by_bit(param);
  1661. else if (!strcmp(cmd, "disable"))
  1662. disable_dpidle_by_bit(param);
  1663. else if (!strcmp(cmd, "time"))
  1664. dpidle_time_critera = param;
  1665. else if (!strcmp(cmd, "bypass")) {
  1666. dpidle_by_pass_cg = param;
  1667. idle_warn("bypass = %d\n", dpidle_by_pass_cg);
  1668. } else if (!strcmp(cmd, "bypass_pg")) {
  1669. dpidle_by_pass_pg = param;
  1670. idle_warn("bypass_pg = %d\n", dpidle_by_pass_pg);
  1671. } else if (!strcmp(cmd, "log"))
  1672. dpidle_dump_log = param;
  1673. return count;
  1674. } else if (!kstrtoint(cmd_buf, 10, &param)) {
  1675. idle_switch[IDLE_TYPE_DP] = param;
  1676. return count;
  1677. }
  1678. return -EINVAL;
  1679. }
  1680. static const struct file_operations dpidle_state_fops = {
  1681. .open = dpidle_state_open,
  1682. .read = dpidle_state_read,
  1683. .write = dpidle_state_write,
  1684. .llseek = seq_lseek,
  1685. .release = single_release,
  1686. };
  1687. /*
  1688. * soidle_state
  1689. */
  1690. static int _soidle_state_open(struct seq_file *s, void *data)
  1691. {
  1692. return 0;
  1693. }
  1694. static int soidle_state_open(struct inode *inode, struct file *filp)
  1695. {
  1696. return single_open(filp, _soidle_state_open, inode->i_private);
  1697. }
  1698. static ssize_t soidle_state_read(struct file *filp, char __user *userbuf, size_t count, loff_t *f_pos)
  1699. {
  1700. int len = 0;
  1701. char *p = dbg_buf;
  1702. int i;
  1703. p += sprintf(p, "*********** deep idle state ************\n");
  1704. p += sprintf(p, "soidle_time_critera=%u\n", soidle_time_critera);
  1705. for (i = 0; i < NR_REASONS; i++) {
  1706. p += sprintf(p, "[%d]soidle_block_cnt[%s]=%lu\n", i, reason_name[i],
  1707. soidle_block_cnt[0][i]);
  1708. }
  1709. p += sprintf(p, "\n");
  1710. for (i = 0; i < NR_GRPS; i++) {
  1711. p += sprintf(p, "[%02d]soidle_condition_mask[%-8s]=0x%08x\t\tsoidle_block_mask[%-8s]=0x%08x\n", i,
  1712. cg_grp_get_name(i), soidle_condition_mask[i],
  1713. cg_grp_get_name(i), soidle_block_mask[i]);
  1714. }
  1715. p += sprintf(p, "soidle_bypass_cg=%u\n", soidle_by_pass_cg);
  1716. p += sprintf(p, "soidle_by_pass_pg=%u\n", soidle_by_pass_pg);
  1717. p += sprintf(p, "\n*********** soidle command help ************\n");
  1718. p += sprintf(p, "soidle help: cat /sys/kernel/debug/cpuidle/soidle_state\n");
  1719. p += sprintf(p, "switch on/off: echo [soidle] 1/0 > /sys/kernel/debug/cpuidle/soidle_state\n");
  1720. p += sprintf(p, "cpupdn on/off: echo cpupdn 1/0 > /sys/kernel/debug/cpuidle/soidle_state\n");
  1721. p += sprintf(p, "en_dp_by_bit: echo enable id > /sys/kernel/debug/cpuidle/soidle_state\n");
  1722. p += sprintf(p, "dis_dp_by_bit: echo disable id > /sys/kernel/debug/cpuidle/soidle_state\n");
  1723. p += sprintf(p, "modify tm_cri: echo time value(dec) > /sys/kernel/debug/cpuidle/soidle_state\n");
  1724. p += sprintf(p, "bypass cg: echo bypass 1/0 > /sys/kernel/debug/cpuidle/soidle_state\n");
  1725. len = p - dbg_buf;
  1726. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  1727. }
  1728. static ssize_t soidle_state_write(struct file *filp,
  1729. const char __user *userbuf,
  1730. size_t count,
  1731. loff_t *f_pos)
  1732. {
  1733. char cmd[32];
  1734. int param;
  1735. count = min(count, sizeof(cmd_buf) - 1);
  1736. if (copy_from_user(cmd_buf, userbuf, count))
  1737. return -EFAULT;
  1738. cmd_buf[count] = '\0';
  1739. if (sscanf(cmd_buf, "%s %d", cmd, &param) == 2) {
  1740. if (!strcmp(cmd, "soidle"))
  1741. idle_switch[IDLE_TYPE_SO] = param;
  1742. else if (!strcmp(cmd, "enable"))
  1743. enable_soidle_by_bit(param);
  1744. else if (!strcmp(cmd, "disable"))
  1745. disable_soidle_by_bit(param);
  1746. else if (!strcmp(cmd, "time"))
  1747. soidle_time_critera = param;
  1748. else if (!strcmp(cmd, "bypass")) {
  1749. soidle_by_pass_cg = param;
  1750. idle_warn("bypass = %d\n", soidle_by_pass_cg);
  1751. } else if (!strcmp(cmd, "bypass_pg")) {
  1752. soidle_by_pass_pg = param;
  1753. idle_warn("bypass_pg = %d\n", soidle_by_pass_pg);
  1754. }
  1755. return count;
  1756. } else if (!kstrtoint(cmd_buf, 10, &param)) {
  1757. idle_switch[IDLE_TYPE_SO] = param;
  1758. return count;
  1759. }
  1760. return -EINVAL;
  1761. }
  1762. static const struct file_operations soidle_state_fops = {
  1763. .open = soidle_state_open,
  1764. .read = soidle_state_read,
  1765. .write = soidle_state_write,
  1766. .llseek = seq_lseek,
  1767. .release = single_release,
  1768. };
  1769. /*
  1770. * slidle_state
  1771. */
  1772. static int _slidle_state_open(struct seq_file *s, void *data)
  1773. {
  1774. return 0;
  1775. }
  1776. static int slidle_state_open(struct inode *inode, struct file *filp)
  1777. {
  1778. return single_open(filp, _slidle_state_open, inode->i_private);
  1779. }
  1780. static ssize_t slidle_state_read(struct file *filp, char __user *userbuf, size_t count, loff_t *f_pos)
  1781. {
  1782. int len = 0;
  1783. char *p = dbg_buf;
  1784. int i;
  1785. p += sprintf(p, "*********** slow idle state ************\n");
  1786. for (i = 0; i < NR_REASONS; i++) {
  1787. p += sprintf(p, "[%d]slidle_block_cnt[%s]=%lu\n",
  1788. i, reason_name[i], slidle_block_cnt[i]);
  1789. }
  1790. p += sprintf(p, "\n");
  1791. for (i = 0; i < NR_GRPS; i++) {
  1792. p += sprintf(p, "[%02d]slidle_condition_mask[%-8s]=0x%08x\t\tslidle_block_mask[%-8s]=0x%08x\n", i,
  1793. cg_grp_get_name(i), slidle_condition_mask[i],
  1794. cg_grp_get_name(i), slidle_block_mask[i]);
  1795. }
  1796. p += sprintf(p, "\n********** slidle command help **********\n");
  1797. p += sprintf(p, "slidle help: cat /sys/kernel/debug/cpuidle/slidle_state\n");
  1798. p += sprintf(p, "switch on/off: echo [slidle] 1/0 > /sys/kernel/debug/cpuidle/slidle_state\n");
  1799. len = p - dbg_buf;
  1800. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  1801. }
  1802. static ssize_t slidle_state_write(struct file *filp, const char __user *userbuf,
  1803. size_t count, loff_t *f_pos)
  1804. {
  1805. char cmd[32];
  1806. int param;
  1807. count = min(count, sizeof(cmd_buf) - 1);
  1808. if (copy_from_user(cmd_buf, userbuf, count))
  1809. return -EFAULT;
  1810. cmd_buf[count] = '\0';
  1811. if (sscanf(userbuf, "%s %d", cmd, &param) == 2) {
  1812. if (!strcmp(cmd, "slidle"))
  1813. idle_switch[IDLE_TYPE_SL] = param;
  1814. else if (!strcmp(cmd, "enable"))
  1815. enable_slidle_by_bit(param);
  1816. else if (!strcmp(cmd, "disable"))
  1817. disable_slidle_by_bit(param);
  1818. return count;
  1819. } else if (!kstrtoint(cmd_buf, 10, &param)) {
  1820. idle_switch[IDLE_TYPE_SL] = param;
  1821. return count;
  1822. }
  1823. return -EINVAL;
  1824. }
  1825. static const struct file_operations slidle_state_fops = {
  1826. .open = slidle_state_open,
  1827. .read = slidle_state_read,
  1828. .write = slidle_state_write,
  1829. .llseek = seq_lseek,
  1830. .release = single_release,
  1831. };
  1832. static struct dentry *root_entry;
  1833. static int mt_cpuidle_debugfs_init(void)
  1834. {
  1835. /* Initialize debugfs */
  1836. root_entry = debugfs_create_dir("cpuidle", NULL);
  1837. if (!root_entry) {
  1838. idle_warn("Can not create debugfs `dpidle_state`\n");
  1839. return 1;
  1840. }
  1841. debugfs_create_file("idle_state", 0644, root_entry, NULL, &idle_state_fops);
  1842. debugfs_create_file("dpidle_state", 0644, root_entry, NULL, &dpidle_state_fops);
  1843. debugfs_create_file("soidle_state", 0644, root_entry, NULL, &soidle_state_fops);
  1844. debugfs_create_file("slidle_state", 0644, root_entry, NULL,
  1845. &slidle_state_fops);
  1846. return 0;
  1847. }
  1848. void mt_cpuidle_framework_init(void)
  1849. {
  1850. int err = 0;
  1851. #if !defined(CONFIG_ARCH_MT6580)
  1852. int i = 0;
  1853. #endif
  1854. idle_dbg("[%s]entry!!\n", __func__);
  1855. err = request_gpt(idle_gpt, GPT_ONE_SHOT, GPT_CLK_SRC_SYS, GPT_CLK_DIV_1,
  1856. 0, NULL, GPT_NOAUTOEN);
  1857. if (err)
  1858. idle_warn("[%s]fail to request GPT%d\n", __func__, idle_gpt + 1);
  1859. err = 0;
  1860. #if !defined(CONFIG_ARCH_MT6580)
  1861. for (i = 0; i < num_possible_cpus(); i++)
  1862. err |= cpu_xgpt_register_timer(i, NULL);
  1863. #else
  1864. /* TODO: cpu_xgpt_register_timer() has not been ported to mach/mt_cpuxgpt.h */
  1865. #endif
  1866. if (err)
  1867. idle_warn("[%s]fail to request cpuxgpt\n", __func__);
  1868. #if !defined(CONFIG_ARCH_MT6580)
  1869. iomap_init();
  1870. #endif
  1871. mt_cpuidle_debugfs_init();
  1872. }
  1873. EXPORT_SYMBOL(mt_cpuidle_framework_init);
  1874. module_param(mt_idle_chk_golden, bool, 0644);
  1875. module_param(mt_dpidle_chk_golden, bool, 0644);