mt_idle.c 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880
  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/debugfs.h>
  12. #include <linux/seq_file.h>
  13. #include <linux/of.h>
  14. #include <linux/of_address.h>
  15. #include <linux/irqchip/mt-gic.h>
  16. #include <asm/system_misc.h>
  17. #include <mt-plat/sync_write.h>
  18. #include <mach/mt_gpt.h>
  19. #include <mach/mt_cpuxgpt.h>
  20. #include "mt_spm.h"
  21. #include "mt_spm_idle.h"
  22. #include "hotplug.h"
  23. #include "mt_cpufreq.h"
  24. #ifdef CONFIG_THERMAL
  25. #include <mach/mt_thermal.h>
  26. #endif
  27. #include "mt_idle.h"
  28. #include "mt_idle_internal.h"
  29. #include <mach/mt_spm_mtcmos_internal.h>
  30. #include "mt_spm_reg.h"
  31. #include "mt_cpufreq_hybrid.h"
  32. #include <asm/uaccess.h>
  33. #ifdef CONFIG_CPU_ISOLATION
  34. #include <linux/cpumask.h>
  35. #include <mt-plat/aee.h>
  36. #include <mach/mt_hotplug_strategy_internal.h>
  37. #endif
  38. #if defined(CONFIG_ARCH_MT6755)
  39. #define FEATURE_ENABLE_SODI2P5
  40. #endif
  41. /*
  42. * MCDI DVT IPI Test and GPT test
  43. * GPT need to modify mt_idle.c and mt_spm_mcdi.c
  44. */
  45. #define MCDI_DVT_IPI 0 /*0:disable, 1: enable : mt_idle.c , mt_spm_mcdi.c and mt_cpuidle.c mt_cpuidle.c */
  46. #define MCDI_DVT_CPUxGPT 0 /*0:disable, 1: enable : GPT need to modify mt_idle.c and mt_spm_mcdi.c mt_cpuidle.c */
  47. #if ((MCDI_DVT_IPI) || (MCDI_DVT_CPUxGPT))
  48. #include <linux/delay.h>
  49. #endif
  50. #define IDLE_TAG "Power/swap"
  51. #define spm_emerg(fmt, args...) pr_emerg(IDLE_TAG fmt, ##args)
  52. #define spm_alert(fmt, args...) pr_alert(IDLE_TAG fmt, ##args)
  53. #define spm_crit(fmt, args...) pr_crit(IDLE_TAG fmt, ##args)
  54. #define idle_err(fmt, args...) pr_err(IDLE_TAG fmt, ##args)
  55. #define idle_warn(fmt, args...) pr_warn(IDLE_TAG fmt, ##args)
  56. #define spm_notice(fmt, args...) pr_notice(IDLE_TAG fmt, ##args)
  57. #define idle_info(fmt, args...) pr_debug(IDLE_TAG fmt, ##args)
  58. #define idle_ver(fmt, args...) pr_debug(IDLE_TAG fmt, ##args)
  59. #define idle_dbg(fmt, args...) pr_debug(IDLE_TAG fmt, ##args)
  60. #define idle_warn_log(fmt, args...) { \
  61. if (dpidle_dump_log == DEEPIDLE_LOG_FULL) \
  62. pr_warn(IDLE_TAG fmt, ##args); \
  63. }
  64. #define idle_gpt GPT4
  65. #define idle_writel(addr, val) \
  66. mt65xx_reg_sync_writel(val, addr)
  67. #define idle_setl(addr, val) \
  68. mt65xx_reg_sync_writel(idle_readl(addr) | (val), addr)
  69. #define idle_clrl(addr, val) \
  70. mt65xx_reg_sync_writel(idle_readl(addr) & ~(val), addr)
  71. #ifdef CONFIG_CPU_ISOLATION
  72. #define AEE_WARNING_BY_ISO 10
  73. #endif
  74. static unsigned long rgidle_cnt[NR_CPUS] = { 0 };
  75. static bool mt_idle_chk_golden;
  76. static bool mt_dpidle_chk_golden;
  77. #ifdef CONFIG_HYBRID_CPU_DVFS
  78. static bool mt_dvfsp_paused_by_idle;
  79. #endif
  80. #define NR_CMD_BUF 128
  81. /* FIXME: early porting */
  82. #if 1
  83. void __attribute__((weak))
  84. bus_dcm_enable(void)
  85. {
  86. /* FIXME: early porting */
  87. }
  88. void __attribute__((weak))
  89. bus_dcm_disable(void)
  90. {
  91. /* FIXME: early porting */
  92. }
  93. unsigned int __attribute__((weak))
  94. mt_get_clk_mem_sel(void)
  95. {
  96. return 1;
  97. }
  98. void __attribute__((weak))
  99. tscpu_cancel_thermal_timer(void)
  100. {
  101. }
  102. void __attribute__((weak))
  103. tscpu_start_thermal_timer(void)
  104. {
  105. /* FIXME: early porting */
  106. }
  107. void __attribute__((weak)) mtkts_bts_cancel_thermal_timer(void)
  108. {
  109. }
  110. void __attribute__((weak)) mtkts_btsmdpa_cancel_thermal_timer(void)
  111. {
  112. }
  113. void __attribute__((weak)) mtkts_pmic_cancel_thermal_timer(void)
  114. {
  115. }
  116. void __attribute__((weak)) mtkts_battery_cancel_thermal_timer(void)
  117. {
  118. }
  119. void __attribute__((weak)) mtkts_pa_cancel_thermal_timer(void)
  120. {
  121. }
  122. void __attribute__((weak)) mtkts_wmt_cancel_thermal_timer(void)
  123. {
  124. }
  125. void __attribute__((weak)) mtkts_bts_start_thermal_timer(void)
  126. {
  127. }
  128. void __attribute__((weak)) mtkts_btsmdpa_start_thermal_timer(void)
  129. {
  130. }
  131. void __attribute__((weak)) mtkts_pmic_start_thermal_timer(void)
  132. {
  133. }
  134. void __attribute__((weak)) mtkts_battery_start_thermal_timer(void)
  135. {
  136. }
  137. void __attribute__((weak)) mtkts_pa_start_thermal_timer(void)
  138. {
  139. }
  140. void __attribute__((weak)) mtkts_wmt_start_thermal_timer(void)
  141. {
  142. }
  143. void __attribute__((weak)) mtkts_allts_cancel_ts1_timer(void)
  144. {
  145. }
  146. void __attribute__((weak)) mtkts_allts_cancel_ts2_timer(void)
  147. {
  148. }
  149. void __attribute__((weak)) mtkts_allts_cancel_ts3_timer(void)
  150. {
  151. }
  152. void __attribute__((weak)) mtkts_allts_cancel_ts4_timer(void)
  153. {
  154. }
  155. void __attribute__((weak)) mtkts_allts_cancel_ts5_timer(void)
  156. {
  157. }
  158. void __attribute__((weak)) mtkts_allts_start_ts1_timer(void)
  159. {
  160. }
  161. void __attribute__((weak)) mtkts_allts_start_ts2_timer(void)
  162. {
  163. }
  164. void __attribute__((weak)) mtkts_allts_start_ts3_timer(void)
  165. {
  166. }
  167. void __attribute__((weak)) mtkts_allts_start_ts4_timer(void)
  168. {
  169. }
  170. void __attribute__((weak)) mtkts_allts_start_ts5_timer(void)
  171. {
  172. }
  173. bool __attribute__((weak)) mtk_gpu_sodi_entry(void)
  174. {
  175. return false;
  176. }
  177. bool __attribute__((weak)) mtk_gpu_sodi_exit(void)
  178. {
  179. return false;
  180. }
  181. bool __attribute__((weak)) spm_mcdi_can_enter(void)
  182. {
  183. return false;
  184. }
  185. bool __attribute__((weak)) spm_get_sodi3_en(void)
  186. {
  187. return false;
  188. }
  189. bool __attribute__((weak)) spm_get_sodi_en(void)
  190. {
  191. return false;
  192. }
  193. int __attribute__((weak)) hps_del_timer(void)
  194. {
  195. return 0;
  196. }
  197. int __attribute__((weak)) hps_restart_timer(void)
  198. {
  199. return 0;
  200. }
  201. void __attribute__((weak)) msdc_clk_status(int *status)
  202. {
  203. *status = 0x1;
  204. }
  205. wake_reason_t __attribute__((weak)) spm_go_to_dpidle(u32 spm_flags, u32 spm_data, u32 sodi_flags)
  206. {
  207. return WR_UNKNOWN;
  208. }
  209. void __attribute__((weak)) spm_enable_sodi(bool en)
  210. {
  211. }
  212. void __attribute__((weak)) spm_sodi_mempll_pwr_mode(bool pwr_mode)
  213. {
  214. }
  215. wake_reason_t __attribute__((weak)) spm_go_to_sodi3(u32 spm_flags, u32 spm_data, u32 sodi_flags)
  216. {
  217. return WR_UNKNOWN;
  218. }
  219. wake_reason_t __attribute__((weak)) spm_go_to_sodi(u32 spm_flags, u32 spm_data, u32 sodi_flags)
  220. {
  221. return WR_UNKNOWN;
  222. }
  223. bool __attribute__((weak)) go_to_mcidle(int cpu)
  224. {
  225. return false;
  226. }
  227. void __attribute__((weak)) spm_mcdi_switch_on_off(enum spm_mcdi_lock_id id, int mcdi_en)
  228. {
  229. }
  230. unsigned long __attribute__((weak)) localtimer_get_counter(void)
  231. {
  232. return 0;
  233. }
  234. int __attribute__((weak)) localtimer_set_next_event(unsigned long evt)
  235. {
  236. return 0;
  237. }
  238. #endif
  239. static char log_buf[500];
  240. static char log_buf_2[500];
  241. static unsigned long long idle_block_log_prev_time;
  242. static unsigned int idle_block_log_time_criteria = 5000; /* 5 sec */
  243. static unsigned long long idle_cnt_dump_prev_time;
  244. static unsigned int idle_cnt_dump_criteria = 10000; /* 10 sec */
  245. static bool idle_ratio_en;
  246. static unsigned long long idle_ratio_profile_start_time;
  247. static unsigned long long idle_ratio_profile_duration;
  248. static unsigned long long idle_ratio_start_time[NR_TYPES];
  249. static unsigned long long idle_ratio_value[NR_TYPES];
  250. /* Slow Idle */
  251. static unsigned int slidle_block_mask[NR_GRPS] = {0x0};
  252. static unsigned long slidle_cnt[NR_CPUS] = {0};
  253. static unsigned long slidle_block_cnt[NR_REASONS] = {0};
  254. /* SODI3 */
  255. static unsigned int soidle3_pll_block_mask[NR_PLLS] = {0x0};
  256. static unsigned int soidle3_block_mask[NR_GRPS] = {0x0};
  257. static unsigned int soidle3_timer_left;
  258. static unsigned int soidle3_timer_left2;
  259. #ifndef CONFIG_SMP
  260. static unsigned int soidle3_timer_cmp;
  261. #endif
  262. static unsigned int soidle3_time_critera = 65000; /* 5ms */
  263. static unsigned int soidle3_block_time_critera = 30000; /* 30sec */
  264. static unsigned long soidle3_cnt[NR_CPUS] = {0};
  265. static unsigned long soidle3_last_cnt[NR_CPUS] = {0};
  266. static unsigned long soidle3_block_cnt[NR_REASONS] = {0};
  267. static unsigned long long soidle3_block_prev_time;
  268. static bool soidle3_by_pass_cg;
  269. static bool soidle3_by_pass_pll;
  270. static bool soidle3_by_pass_en;
  271. static u32 sodi3_flags = SODI_FLAG_REDUCE_LOG|SODI_FLAG_V3;
  272. #ifdef SPM_SODI3_PROFILE_TIME
  273. unsigned int soidle3_profile[4];
  274. #endif
  275. /* SODI */
  276. static unsigned int soidle_block_mask[NR_GRPS] = {0x0};
  277. static unsigned int soidle_timer_left;
  278. static unsigned int soidle_timer_left2;
  279. #ifndef CONFIG_SMP
  280. static unsigned int soidle_timer_cmp;
  281. #endif
  282. static unsigned int soidle_time_critera = 26000; /* 2ms */
  283. static unsigned int soidle_block_time_critera = 30000; /* 30sec */
  284. static unsigned long soidle_cnt[NR_CPUS] = {0};
  285. static unsigned long soidle_last_cnt[NR_CPUS] = {0};
  286. static unsigned long soidle_block_cnt[NR_REASONS] = {0};
  287. static unsigned long long soidle_block_prev_time;
  288. static bool soidle_by_pass_cg;
  289. bool soidle_by_pass_pg;
  290. static bool soidle_by_pass_en;
  291. static u32 sodi_flags = SODI_FLAG_REDUCE_LOG;
  292. static u32 sodi_fw = SODI_FW_LPM;
  293. #ifdef SPM_SODI_PROFILE_TIME
  294. unsigned int soidle_profile[4];
  295. #endif
  296. /* DeepIdle */
  297. static unsigned int dpidle_block_mask[NR_GRPS] = {0x0};
  298. static unsigned int dpidle_timer_left;
  299. static unsigned int dpidle_timer_left2;
  300. #ifndef CONFIG_SMP
  301. static unsigned int dpidle_timer_cmp;
  302. #endif
  303. static unsigned int dpidle_time_critera = 26000;
  304. static unsigned int dpidle_block_time_critera = 30000; /* default 30sec */
  305. static unsigned long dpidle_cnt[NR_CPUS] = {0};
  306. static unsigned long dpidle_last_cnt[NR_CPUS] = {0};
  307. static unsigned long dpidle_f26m_cnt[NR_CPUS] = {0};
  308. static unsigned long dpidle_block_cnt[NR_REASONS] = {0};
  309. static unsigned long long dpidle_block_prev_time;
  310. static bool dpidle_by_pass_cg;
  311. bool dpidle_by_pass_pg;
  312. static unsigned int dpidle_dump_log = DEEPIDLE_LOG_REDUCED;
  313. /* MCDI */
  314. static unsigned int mcidle_timer_left[NR_CPUS];
  315. static unsigned int mcidle_timer_left2[NR_CPUS];
  316. static unsigned int mcidle_time_critera = 39000; /* 3ms */
  317. static unsigned long mcidle_cnt[NR_CPUS] = { 0 };
  318. static unsigned long mcidle_block_cnt[NR_CPUS][NR_REASONS] = { {0}, {0} };
  319. u64 mcidle_timer_before_wfi[NR_CPUS];
  320. static unsigned int idle_spm_lock;
  321. /* Workaround of static analysis defect*/
  322. int idle_gpt_get_cnt(unsigned int id, unsigned int *ptr)
  323. {
  324. unsigned int val[2] = {0};
  325. int ret = 0;
  326. ret = gpt_get_cnt(id, val);
  327. *ptr = val[0];
  328. return ret;
  329. }
  330. int idle_gpt_get_cmp(unsigned int id, unsigned int *ptr)
  331. {
  332. unsigned int val[2] = {0};
  333. int ret = 0;
  334. ret = gpt_get_cmp(id, val);
  335. *ptr = val[0];
  336. return ret;
  337. }
  338. long int idle_get_current_time_ms(void)
  339. {
  340. struct timeval t;
  341. do_gettimeofday(&t);
  342. return ((t.tv_sec & 0xFFF) * 1000000 + t.tv_usec) / 1000;
  343. }
  344. static DEFINE_SPINLOCK(idle_spm_spin_lock);
  345. void idle_lock_spm(enum idle_lock_spm_id id)
  346. {
  347. unsigned long flags;
  348. spin_lock_irqsave(&idle_spm_spin_lock, flags);
  349. idle_spm_lock |= (1 << id);
  350. spin_unlock_irqrestore(&idle_spm_spin_lock, flags);
  351. }
  352. void idle_unlock_spm(enum idle_lock_spm_id id)
  353. {
  354. unsigned long flags;
  355. spin_lock_irqsave(&idle_spm_spin_lock, flags);
  356. idle_spm_lock &= ~(1 << id);
  357. spin_unlock_irqrestore(&idle_spm_spin_lock, flags);
  358. }
  359. #ifdef CONFIG_CPU_ISOLATION
  360. bool is_cpus_offline_or_isolated(cpumask_var_t mask)
  361. {
  362. cpumask_var_t tmp_mask;
  363. /* remove offline CPUs from mask */
  364. cpumask_andnot(tmp_mask, mask, cpu_online_mask);
  365. /* remove isolated CPUs from mask */
  366. cpumask_andnot(tmp_mask, tmp_mask, cpu_isolate_mask);
  367. return cpumask_empty(tmp_mask);
  368. }
  369. #endif
  370. /************************************************
  371. * SODI3 part
  372. ************************************************/
  373. static DEFINE_MUTEX(soidle3_locked);
  374. static void enable_soidle3_by_mask(int grp, unsigned int mask)
  375. {
  376. mutex_lock(&soidle3_locked);
  377. soidle3_condition_mask[grp] &= ~mask;
  378. mutex_unlock(&soidle3_locked);
  379. }
  380. static void disable_soidle3_by_mask(int grp, unsigned int mask)
  381. {
  382. mutex_lock(&soidle3_locked);
  383. soidle3_condition_mask[grp] |= mask;
  384. mutex_unlock(&soidle3_locked);
  385. }
  386. void enable_soidle3_by_bit(int id)
  387. {
  388. int grp = id / 32;
  389. unsigned int mask = 1U << (id % 32);
  390. BUG_ON(INVALID_GRP_ID(grp));
  391. enable_soidle3_by_mask(grp, mask);
  392. }
  393. EXPORT_SYMBOL(enable_soidle3_by_bit);
  394. void disable_soidle3_by_bit(int id)
  395. {
  396. int grp = id / 32;
  397. unsigned int mask = 1U << (id % 32);
  398. BUG_ON(INVALID_GRP_ID(grp));
  399. disable_soidle3_by_mask(grp, mask);
  400. }
  401. EXPORT_SYMBOL(disable_soidle3_by_bit);
  402. #define clk_readl(addr) DRV_Reg32(addr)
  403. #define clk_writel(addr, val) mt_reg_sync_writel(val, addr)
  404. static unsigned int clk_cfg_4;
  405. void faudintbus_pll2sq(void)
  406. {
  407. clk_cfg_4 = clk_readl(CLK_CFG_4);
  408. clk_writel(CLK_CFG_4, clk_cfg_4 & 0xFCFFFFFF);
  409. clk_writel(CLK_CFG_UPDATE, 1U << 18);
  410. }
  411. void faudintbus_sq2pll(void)
  412. {
  413. clk_writel(CLK_CFG_4, clk_cfg_4);
  414. clk_writel(CLK_CFG_UPDATE, 1U << 18);
  415. }
  416. bool soidle3_can_enter(int cpu)
  417. {
  418. int reason = NR_REASONS;
  419. int i;
  420. unsigned long long soidle3_block_curr_time = 0;
  421. unsigned int cpu_pwr_stat = 0;
  422. #ifdef CONFIG_CPU_ISOLATION
  423. cpumask_var_t tmp_mask;
  424. static int prev_reason = -1;
  425. static int by_iso_count;
  426. #endif
  427. char *p;
  428. bool ret = false;
  429. if (!is_disp_pwm_rosc()) {
  430. reason = BY_PWM;
  431. goto out;
  432. }
  433. if (!spm_load_firmware_status()) {
  434. reason = BY_FRM;
  435. goto out;
  436. }
  437. #ifdef CONFIG_SMP
  438. cpu_pwr_stat = spm_get_cpu_pwr_status();
  439. if (!((cpu_pwr_stat == CPU_0) || (cpu_pwr_stat == CPU_4))) {
  440. reason = BY_CPU;
  441. #ifdef CONFIG_CPU_ISOLATION
  442. if ((cpu % 4) == 0) {
  443. cpumask_complement(tmp_mask, cpumask_of(cpu));
  444. if (is_cpus_offline_or_isolated(tmp_mask)) {
  445. /* ISOLATION, blocking reason *maybe* rewrite by others */
  446. reason = BY_ISO;
  447. } else {
  448. /* MULTI-CORE, skip remainder checking */
  449. goto out;
  450. }
  451. }
  452. #else
  453. goto out;
  454. #endif
  455. }
  456. #endif
  457. if (cpu % 4) {
  458. reason = BY_CPU;
  459. goto out;
  460. }
  461. if (idle_spm_lock) {
  462. reason = BY_VTG;
  463. goto out;
  464. }
  465. if (soidle3_by_pass_en == 0) {
  466. if ((spm_get_sodi_en() == 0) || (spm_get_sodi3_en() == 0)) {
  467. /* if SODI is disabled, SODI3 is also disabled */
  468. reason = BY_OTH;
  469. goto out;
  470. }
  471. }
  472. if (soidle3_by_pass_pll == 0) {
  473. if (!pll_check_idle_can_enter(soidle3_pll_condition_mask, soidle3_pll_block_mask)) {
  474. reason = BY_PLL;
  475. goto out;
  476. }
  477. }
  478. if (soidle3_by_pass_cg == 0) {
  479. memset(soidle3_block_mask, 0, NR_GRPS * sizeof(unsigned int));
  480. if (!cg_check_idle_can_enter(soidle3_condition_mask, soidle3_block_mask, MT_SOIDLE)) {
  481. reason = BY_CLK;
  482. goto out;
  483. }
  484. }
  485. #ifdef CONFIG_CPU_ISOLATION
  486. if (reason == BY_ISO) {
  487. /* blocking reason is BY_ISO, notify hotplug API */
  488. hps_ctxt.wake_up_by_fasthotplug = 1;
  489. hps_task_wakeup_nolock();
  490. goto out;
  491. }
  492. #endif
  493. #ifdef CONFIG_SMP
  494. soidle3_timer_left = localtimer_get_counter();
  495. if ((int)soidle3_timer_left < soidle3_time_critera ||
  496. ((int)soidle3_timer_left) < 0) {
  497. reason = BY_TMR;
  498. goto out;
  499. }
  500. #else
  501. gpt_get_cnt(GPT1, &soidle3_timer_left);
  502. gpt_get_cmp(GPT1, &soidle3_timer_cmp);
  503. if ((soidle3_timer_cmp - soidle3_timer_left) < soidle3_time_critera) {
  504. reason = BY_TMR;
  505. goto out;
  506. }
  507. #endif
  508. #ifdef CONFIG_HYBRID_CPU_DVFS
  509. /* Try to pause DVFSP, xxidle will be blocked if DVFSP can NOT be paused */
  510. if (cpuhvfs_pause_dvfsp_running(PAUSE_IDLE) != 0) {
  511. reason = BY_DVFSP;
  512. goto out;
  513. }
  514. mt_dvfsp_paused_by_idle = true;
  515. #endif
  516. if (soidle3_by_pass_cg == 0) {
  517. /* Check if I2C-appm gated since DVFSP will control it */
  518. if (!cg_i2c_appm_check_idle_can_enter(soidle3_block_mask)) {
  519. #ifdef CONFIG_HYBRID_CPU_DVFS
  520. cpuhvfs_unpause_dvfsp_to_run(PAUSE_IDLE);
  521. mt_dvfsp_paused_by_idle = false;
  522. #endif
  523. reason = BY_CLK;
  524. goto out;
  525. }
  526. }
  527. out:
  528. #ifdef CONFIG_CPU_ISOLATION
  529. if (reason == BY_ISO && prev_reason == BY_ISO) {
  530. if (by_iso_count++ > AEE_WARNING_BY_ISO) {
  531. by_iso_count = 0;
  532. aee_kernel_warning("!!!! SODI3 is blocking by CPU_ISOLATION !!!!\n");
  533. }
  534. } else {
  535. by_iso_count = 0;
  536. }
  537. prev_reason = reason;
  538. #endif
  539. if (reason < NR_REASONS) {
  540. if (soidle3_block_prev_time == 0)
  541. soidle3_block_prev_time = idle_get_current_time_ms();
  542. soidle3_block_curr_time = idle_get_current_time_ms();
  543. if (((soidle3_block_curr_time - soidle3_block_prev_time) > soidle3_block_time_critera)
  544. && ((soidle3_block_curr_time - idle_block_log_prev_time) > idle_block_log_time_criteria)) {
  545. if ((cpu % 4) == 0) {
  546. /* soidle3,rgidle count */
  547. p = log_buf;
  548. p += sprintf(p, "CNT(soidle3,rgidle): ");
  549. for (i = 0; i < nr_cpu_ids; i++)
  550. p += sprintf(p, "[%d] = (%lu,%lu), ", i, soidle3_cnt[i], rgidle_cnt[i]);
  551. idle_warn("%s\n", log_buf);
  552. /* block category */
  553. p = log_buf;
  554. p += sprintf(p, "soidle3_block_cnt: ");
  555. for (i = 0; i < NR_REASONS; i++)
  556. p += sprintf(p, "[%s] = %lu, ", reason_name[i], soidle3_block_cnt[i]);
  557. idle_warn("%s\n", log_buf);
  558. p = log_buf;
  559. p += sprintf(p, "soidle3_block_mask: ");
  560. for (i = 0; i < NR_GRPS; i++)
  561. p += sprintf(p, "0x%08x, ", soidle3_block_mask[i]);
  562. idle_warn("%s\n", log_buf);
  563. memset(soidle3_block_cnt, 0, sizeof(soidle3_block_cnt));
  564. soidle3_block_prev_time = idle_get_current_time_ms();
  565. idle_block_log_prev_time = soidle3_block_prev_time;
  566. }
  567. }
  568. soidle3_block_cnt[reason]++;
  569. ret = false;
  570. } else {
  571. soidle3_block_prev_time = idle_get_current_time_ms();
  572. ret = true;
  573. }
  574. return ret;
  575. }
  576. void soidle3_before_wfi(int cpu)
  577. {
  578. #ifdef CONFIG_SMP
  579. soidle3_timer_left2 = localtimer_get_counter();
  580. if ((int)soidle3_timer_left2 <= 0)
  581. gpt_set_cmp(idle_gpt, 1); /* Trigger idle_gpt Timerout imediately */
  582. else
  583. gpt_set_cmp(idle_gpt, div_u64(soidle3_timer_left2, 406.25));
  584. gpt_set_clk(idle_gpt, GPT_CLK_SRC_RTC, GPT_CLK_DIV_1);
  585. start_gpt(idle_gpt);
  586. #else
  587. gpt_get_cnt(GPT1, &soidle3_timer_left2);
  588. #endif
  589. }
  590. void soidle3_after_wfi(int cpu)
  591. {
  592. #ifdef CONFIG_SMP
  593. if (gpt_check_and_ack_irq(idle_gpt)) {
  594. localtimer_set_next_event(1);
  595. gpt_set_clk(idle_gpt, GPT_CLK_SRC_SYS, GPT_CLK_DIV_1);
  596. } else {
  597. /* waked up by other wakeup source */
  598. unsigned int cnt, cmp;
  599. gpt_get_cnt(idle_gpt, &cnt);
  600. gpt_get_cmp(idle_gpt, &cmp);
  601. if (unlikely(cmp < cnt)) {
  602. idle_err("[%s]GPT%d: counter = %10u, compare = %10u\n",
  603. __func__, idle_gpt + 1, cnt, cmp);
  604. BUG();
  605. }
  606. localtimer_set_next_event((cmp-cnt) * 1625 / 4);
  607. gpt_set_clk(idle_gpt, GPT_CLK_SRC_SYS, GPT_CLK_DIV_1);
  608. stop_gpt(idle_gpt);
  609. }
  610. #endif
  611. #ifdef CONFIG_HYBRID_CPU_DVFS
  612. if (mt_dvfsp_paused_by_idle) {
  613. cpuhvfs_unpause_dvfsp_to_run(PAUSE_IDLE);
  614. mt_dvfsp_paused_by_idle = false;
  615. }
  616. #endif
  617. soidle3_cnt[cpu]++;
  618. }
  619. /************************************************
  620. * SODI part
  621. ************************************************/
  622. static DEFINE_MUTEX(soidle_locked);
  623. static void enable_soidle_by_mask(int grp, unsigned int mask)
  624. {
  625. mutex_lock(&soidle_locked);
  626. soidle_condition_mask[grp] &= ~mask;
  627. mutex_unlock(&soidle_locked);
  628. }
  629. static void disable_soidle_by_mask(int grp, unsigned int mask)
  630. {
  631. mutex_lock(&soidle_locked);
  632. soidle_condition_mask[grp] |= mask;
  633. mutex_unlock(&soidle_locked);
  634. }
  635. void enable_soidle_by_bit(int id)
  636. {
  637. int grp = id / 32;
  638. unsigned int mask = 1U << (id % 32);
  639. BUG_ON(INVALID_GRP_ID(grp));
  640. enable_soidle_by_mask(grp, mask);
  641. /* enable the settings for SODI3 at the same time */
  642. enable_soidle3_by_mask(grp, mask);
  643. }
  644. EXPORT_SYMBOL(enable_soidle_by_bit);
  645. void disable_soidle_by_bit(int id)
  646. {
  647. int grp = id / 32;
  648. unsigned int mask = 1U << (id % 32);
  649. BUG_ON(INVALID_GRP_ID(grp));
  650. disable_soidle_by_mask(grp, mask);
  651. /* disable the settings for SODI3 at the same time */
  652. disable_soidle3_by_mask(grp, mask);
  653. }
  654. EXPORT_SYMBOL(disable_soidle_by_bit);
  655. bool soidle_can_enter(int cpu)
  656. {
  657. int reason = NR_REASONS;
  658. int i;
  659. unsigned long long soidle_block_curr_time = 0;
  660. unsigned int cpu_pwr_stat = 0;
  661. #ifdef CONFIG_CPU_ISOLATION
  662. cpumask_var_t tmp_mask;
  663. static int prev_reason = -1;
  664. static int by_iso_count;
  665. #endif
  666. char *p;
  667. bool ret = false;
  668. if (!spm_load_firmware_status()) {
  669. reason = BY_FRM;
  670. goto out;
  671. }
  672. #ifdef CONFIG_SMP
  673. cpu_pwr_stat = spm_get_cpu_pwr_status();
  674. if (!((cpu_pwr_stat == CPU_0) || (cpu_pwr_stat == CPU_4))) {
  675. reason = BY_CPU;
  676. #ifdef CONFIG_CPU_ISOLATION
  677. if ((cpu % 4) == 0) {
  678. cpumask_complement(tmp_mask, cpumask_of(cpu));
  679. if (is_cpus_offline_or_isolated(tmp_mask)) {
  680. /* ISOLATION, blocking reason *maybe* rewrite by others */
  681. reason = BY_ISO;
  682. } else {
  683. /* MULTI-CORE, skip remainder checking */
  684. goto out;
  685. }
  686. }
  687. #else
  688. goto out;
  689. #endif
  690. }
  691. #endif
  692. if (cpu % 4) {
  693. reason = BY_CPU;
  694. goto out;
  695. }
  696. if (idle_spm_lock) {
  697. reason = BY_VTG;
  698. goto out;
  699. }
  700. if (soidle_by_pass_en == 0) {
  701. if (spm_get_sodi_en() == 0) {
  702. reason = BY_OTH;
  703. goto out;
  704. }
  705. }
  706. if (soidle_by_pass_cg == 0) {
  707. memset(soidle_block_mask, 0, NR_GRPS * sizeof(unsigned int));
  708. if (!cg_check_idle_can_enter(soidle_condition_mask, soidle_block_mask, MT_SOIDLE)) {
  709. reason = BY_CLK;
  710. goto out;
  711. }
  712. }
  713. #ifdef CONFIG_CPU_ISOLATION
  714. if (reason == BY_ISO) {
  715. /* blocking reason is BY_ISO, notify hotplug API */
  716. hps_ctxt.wake_up_by_fasthotplug = 1;
  717. hps_task_wakeup_nolock();
  718. goto out;
  719. }
  720. #endif
  721. #ifdef CONFIG_SMP
  722. soidle_timer_left = localtimer_get_counter();
  723. if ((int)soidle_timer_left < soidle_time_critera ||
  724. ((int)soidle_timer_left) < 0) {
  725. reason = BY_TMR;
  726. goto out;
  727. }
  728. #else
  729. gpt_get_cnt(GPT1, &soidle_timer_left);
  730. gpt_get_cmp(GPT1, &soidle_timer_cmp);
  731. if ((soidle_timer_cmp - soidle_timer_left) < soidle_time_critera) {
  732. reason = BY_TMR;
  733. goto out;
  734. }
  735. #endif
  736. #ifdef CONFIG_HYBRID_CPU_DVFS
  737. /* Try to pause DVFSP, xxidle will be blocked if DVFSP can NOT be paused */
  738. if (cpuhvfs_pause_dvfsp_running(PAUSE_IDLE) != 0) {
  739. reason = BY_DVFSP;
  740. goto out;
  741. }
  742. mt_dvfsp_paused_by_idle = true;
  743. #endif
  744. if (soidle_by_pass_cg == 0) {
  745. /* Check if I2C-appm gated since DVFSP will control it */
  746. if (!cg_i2c_appm_check_idle_can_enter(soidle_block_mask)) {
  747. #ifdef CONFIG_HYBRID_CPU_DVFS
  748. cpuhvfs_unpause_dvfsp_to_run(PAUSE_IDLE);
  749. mt_dvfsp_paused_by_idle = false;
  750. #endif
  751. reason = BY_CLK;
  752. goto out;
  753. }
  754. }
  755. out:
  756. #ifdef CONFIG_CPU_ISOLATION
  757. if (reason == BY_ISO && prev_reason == BY_ISO) {
  758. if (by_iso_count++ > AEE_WARNING_BY_ISO) {
  759. by_iso_count = 0;
  760. aee_kernel_warning("!!!! SODI is blocking by CPU_ISOLATION !!!!\n");
  761. }
  762. } else {
  763. by_iso_count = 0;
  764. }
  765. prev_reason = reason;
  766. #endif
  767. if (reason < NR_REASONS) {
  768. if (soidle_block_prev_time == 0)
  769. soidle_block_prev_time = idle_get_current_time_ms();
  770. soidle_block_curr_time = idle_get_current_time_ms();
  771. if (((soidle_block_curr_time - soidle_block_prev_time) > soidle_block_time_critera)
  772. && ((soidle_block_curr_time - idle_block_log_prev_time) > idle_block_log_time_criteria)) {
  773. if ((cpu % 4) == 0) {
  774. /* soidle,rgidle count */
  775. p = log_buf;
  776. p += sprintf(p, "CNT(soidle,rgidle): ");
  777. for (i = 0; i < nr_cpu_ids; i++)
  778. p += sprintf(p, "[%d] = (%lu,%lu), ", i, soidle_cnt[i], rgidle_cnt[i]);
  779. idle_warn("%s\n", log_buf);
  780. /* block category */
  781. p = log_buf;
  782. p += sprintf(p, "soidle_block_cnt: ");
  783. for (i = 0; i < NR_REASONS; i++)
  784. p += sprintf(p, "[%s] = %lu, ", reason_name[i], soidle_block_cnt[i]);
  785. idle_warn("%s\n", log_buf);
  786. p = log_buf;
  787. p += sprintf(p, "soidle_block_mask: ");
  788. for (i = 0; i < NR_GRPS; i++)
  789. p += sprintf(p, "0x%08x, ", soidle_block_mask[i]);
  790. idle_warn("%s\n", log_buf);
  791. memset(soidle_block_cnt, 0, sizeof(soidle_block_cnt));
  792. soidle_block_prev_time = idle_get_current_time_ms();
  793. idle_block_log_prev_time = soidle_block_prev_time;
  794. }
  795. }
  796. soidle_block_cnt[reason]++;
  797. ret = false;
  798. } else {
  799. soidle_block_prev_time = idle_get_current_time_ms();
  800. ret = true;
  801. }
  802. return ret;
  803. }
  804. void soidle_before_wfi(int cpu)
  805. {
  806. #ifdef FEATURE_ENABLE_SODI2P5
  807. faudintbus_pll2sq();
  808. #endif
  809. #ifdef CONFIG_SMP
  810. soidle_timer_left2 = localtimer_get_counter();
  811. if ((int)soidle_timer_left2 <= 0)
  812. gpt_set_cmp(idle_gpt, 1); /* Trigger idle_gpt Timerout imediately */
  813. else
  814. gpt_set_cmp(idle_gpt, soidle_timer_left2);
  815. start_gpt(idle_gpt);
  816. #else
  817. gpt_get_cnt(GPT1, &soidle_timer_left2);
  818. #endif
  819. }
  820. void soidle_after_wfi(int cpu)
  821. {
  822. #ifdef CONFIG_SMP
  823. if (gpt_check_and_ack_irq(idle_gpt)) {
  824. localtimer_set_next_event(1);
  825. } else {
  826. /* waked up by other wakeup source */
  827. unsigned int cnt, cmp;
  828. idle_gpt_get_cnt(idle_gpt, &cnt);
  829. idle_gpt_get_cmp(idle_gpt, &cmp);
  830. if (unlikely(cmp < cnt)) {
  831. idle_err("[%s]GPT%d: counter = %10u, compare = %10u\n",
  832. __func__, idle_gpt + 1, cnt, cmp);
  833. BUG();
  834. }
  835. localtimer_set_next_event(cmp - cnt);
  836. stop_gpt(idle_gpt);
  837. }
  838. #endif
  839. #ifdef FEATURE_ENABLE_SODI2P5
  840. faudintbus_sq2pll();
  841. #endif
  842. #ifdef CONFIG_HYBRID_CPU_DVFS
  843. if (mt_dvfsp_paused_by_idle) {
  844. cpuhvfs_unpause_dvfsp_to_run(PAUSE_IDLE);
  845. mt_dvfsp_paused_by_idle = false;
  846. }
  847. #endif
  848. soidle_cnt[cpu]++;
  849. }
  850. /************************************************
  851. * multi-core idle part
  852. ************************************************/
  853. static DEFINE_MUTEX(mcidle_locked);
  854. bool mcidle_can_enter(int cpu)
  855. {
  856. int reason = NR_REASONS;
  857. #ifdef CONFIG_ARM64
  858. if (num_online_cpus() == 1) {
  859. reason = BY_CPU;
  860. goto mcidle_out;
  861. }
  862. #else
  863. if (num_online_cpus() == 1) {
  864. reason = BY_CPU;
  865. goto mcidle_out;
  866. }
  867. #endif
  868. if (spm_mcdi_can_enter() == 0) {
  869. reason = BY_OTH;
  870. goto mcidle_out;
  871. }
  872. #ifdef CONFIG_CPU_ISOLATION
  873. if (CPU_STATE_NEED_MCDI == per_cpu(cpu_isolation_state, cpu) && !cpu_isolation_disable_mcdi)
  874. goto mcidle_out;
  875. else {
  876. reason = BY_ISO;
  877. goto mcidle_out;
  878. }
  879. #elif ((!MCDI_DVT_IPI) && (!MCDI_DVT_CPUxGPT))
  880. mcidle_timer_left[cpu] = localtimer_get_counter();
  881. if (mcidle_timer_left[cpu] < mcidle_time_critera || ((int)mcidle_timer_left[cpu]) < 0) {
  882. reason = BY_TMR;
  883. goto mcidle_out;
  884. }
  885. #endif
  886. mcidle_out:
  887. if (reason < NR_REASONS) {
  888. mcidle_block_cnt[cpu][reason]++;
  889. return false;
  890. }
  891. return true;
  892. }
  893. bool spm_mcdi_xgpt_timeout[NR_CPUS];
  894. void mcidle_before_wfi(int cpu)
  895. {
  896. #if (!MCDI_DVT_IPI)
  897. u64 set_count = 0;
  898. spm_mcdi_xgpt_timeout[cpu] = 0;
  899. #if (MCDI_DVT_CPUxGPT)
  900. localtimer_set_next_event(130000000);
  901. mcidle_timer_left2[cpu] = 65000000;
  902. #else
  903. mcidle_timer_left2[cpu] = localtimer_get_counter();
  904. #endif
  905. mcidle_timer_before_wfi[cpu] = localtimer_get_phy_count();
  906. set_count = mcidle_timer_before_wfi[cpu] + (int)mcidle_timer_left2[cpu];
  907. cpu_xgpt_set_cmp(cpu, set_count);
  908. #elif (MCDI_DVT_IPI)
  909. /* localtimer_set_next_event(130000000); */
  910. /* printk("delay local timer next event"); */
  911. #endif
  912. }
  913. int mcdi_xgpt_wakeup_cnt[NR_CPUS];
  914. void mcidle_after_wfi(int cpu)
  915. {
  916. #if (!MCDI_DVT_IPI)
  917. u64 cmp;
  918. cpu_xgpt_irq_dis(cpu); /* ack cpuxgpt, api need refine from Weiqi */
  919. #if (!MCDI_DVT_CPUxGPT)
  920. cmp = (localtimer_get_phy_count() - mcidle_timer_before_wfi[cpu]);
  921. if (cmp < (int)mcidle_timer_left2[cpu])
  922. localtimer_set_next_event(mcidle_timer_left2[cpu] - cmp);
  923. else
  924. localtimer_set_next_event(1);
  925. #endif
  926. #endif
  927. }
  928. /************************************************
  929. * deep idle part
  930. ************************************************/
  931. static DEFINE_MUTEX(dpidle_locked);
  932. static void enable_dpidle_by_mask(int grp, unsigned int mask)
  933. {
  934. mutex_lock(&dpidle_locked);
  935. dpidle_condition_mask[grp] &= ~mask;
  936. mutex_unlock(&dpidle_locked);
  937. }
  938. static void disable_dpidle_by_mask(int grp, unsigned int mask)
  939. {
  940. mutex_lock(&dpidle_locked);
  941. dpidle_condition_mask[grp] |= mask;
  942. mutex_unlock(&dpidle_locked);
  943. }
  944. void enable_dpidle_by_bit(int id)
  945. {
  946. int grp = id / 32;
  947. unsigned int mask = 1U << (id % 32);
  948. BUG_ON(INVALID_GRP_ID(grp));
  949. enable_dpidle_by_mask(grp, mask);
  950. }
  951. EXPORT_SYMBOL(enable_dpidle_by_bit);
  952. void disable_dpidle_by_bit(int id)
  953. {
  954. int grp = id / 32;
  955. unsigned int mask = 1U << (id % 32);
  956. BUG_ON(INVALID_GRP_ID(grp));
  957. disable_dpidle_by_mask(grp, mask);
  958. }
  959. EXPORT_SYMBOL(disable_dpidle_by_bit);
  960. static bool dpidle_can_enter(int cpu)
  961. {
  962. int reason = NR_REASONS;
  963. int i = 0;
  964. unsigned long long dpidle_block_curr_time = 0;
  965. unsigned int cpu_pwr_stat = 0;
  966. #ifdef CONFIG_CPU_ISOLATION
  967. cpumask_var_t tmp_mask;
  968. static int prev_reason = -1;
  969. static int by_iso_count;
  970. #endif
  971. char *p;
  972. bool ret = false;
  973. if (!spm_load_firmware_status()) {
  974. reason = BY_FRM;
  975. goto out;
  976. }
  977. /* TODO: check if mt_cpufreq_earlysuspend_status_get() should be used */
  978. #if 0
  979. if (dpidle_by_pass_cg == 0) {
  980. if (!mt_cpufreq_earlysuspend_status_get()) {
  981. reason = BY_VTG;
  982. goto out;
  983. }
  984. }
  985. #endif
  986. #ifdef CONFIG_SMP
  987. cpu_pwr_stat = spm_get_cpu_pwr_status();
  988. if (!((cpu_pwr_stat == CPU_0) || (cpu_pwr_stat == CPU_4))) {
  989. reason = BY_CPU;
  990. #ifdef CONFIG_CPU_ISOLATION
  991. if ((cpu % 4) == 0) {
  992. cpumask_complement(tmp_mask, cpumask_of(cpu));
  993. if (is_cpus_offline_or_isolated(tmp_mask)) {
  994. /* ISOLATION, blocking reason *maybe* rewrite by others */
  995. reason = BY_ISO;
  996. } else {
  997. /* MULTI-CORE, skip remainder checking */
  998. goto out;
  999. }
  1000. }
  1001. #else
  1002. goto out;
  1003. #endif
  1004. }
  1005. #endif
  1006. if (cpu % 4) {
  1007. reason = BY_CPU;
  1008. goto out;
  1009. }
  1010. if (idle_spm_lock) {
  1011. reason = BY_VTG;
  1012. goto out;
  1013. }
  1014. if (dpidle_by_pass_cg == 0) {
  1015. memset(dpidle_block_mask, 0, NR_GRPS * sizeof(unsigned int));
  1016. if (!cg_check_idle_can_enter(dpidle_condition_mask, dpidle_block_mask, MT_DPIDLE)) {
  1017. reason = BY_CLK;
  1018. goto out;
  1019. }
  1020. }
  1021. #ifdef CONFIG_CPU_ISOLATION
  1022. if (reason == BY_ISO) {
  1023. /* blocking reason is BY_ISO, notify hotplug API */
  1024. hps_ctxt.wake_up_by_fasthotplug = 1;
  1025. hps_task_wakeup_nolock();
  1026. goto out;
  1027. }
  1028. #endif
  1029. #ifdef CONFIG_SMP
  1030. dpidle_timer_left = localtimer_get_counter();
  1031. if ((int)dpidle_timer_left < dpidle_time_critera ||
  1032. ((int)dpidle_timer_left) < 0) {
  1033. reason = BY_TMR;
  1034. goto out;
  1035. }
  1036. #else
  1037. gpt_get_cnt(GPT1, &dpidle_timer_left);
  1038. gpt_get_cmp(GPT1, &dpidle_timer_cmp);
  1039. if ((dpidle_timer_cmp-dpidle_timer_left) < dpidle_time_critera) {
  1040. reason = BY_TMR;
  1041. goto out;
  1042. }
  1043. #endif
  1044. #ifdef CONFIG_HYBRID_CPU_DVFS
  1045. /* Try to pause DVFSP, xxidle will be blocked if DVFSP can NOT be paused */
  1046. if (cpuhvfs_pause_dvfsp_running(PAUSE_IDLE) != 0) {
  1047. reason = BY_DVFSP;
  1048. goto out;
  1049. }
  1050. mt_dvfsp_paused_by_idle = true;
  1051. #endif
  1052. if (dpidle_by_pass_cg == 0) {
  1053. /* Check if I2C-appm gated since DVFSP will control it */
  1054. if (!cg_i2c_appm_check_idle_can_enter(dpidle_block_mask)) {
  1055. #ifdef CONFIG_HYBRID_CPU_DVFS
  1056. cpuhvfs_unpause_dvfsp_to_run(PAUSE_IDLE);
  1057. mt_dvfsp_paused_by_idle = false;
  1058. #endif
  1059. reason = BY_CLK;
  1060. goto out;
  1061. }
  1062. }
  1063. out:
  1064. #ifdef CONFIG_CPU_ISOLATION
  1065. if (reason == BY_ISO && prev_reason == BY_ISO) {
  1066. if (by_iso_count++ > AEE_WARNING_BY_ISO) {
  1067. by_iso_count = 0;
  1068. aee_kernel_warning("!!!! deep idle is blocking by CPU_ISOLATION !!!!\n");
  1069. }
  1070. } else {
  1071. by_iso_count = 0;
  1072. }
  1073. prev_reason = reason;
  1074. #endif
  1075. if (reason < NR_REASONS) {
  1076. if (dpidle_block_prev_time == 0)
  1077. dpidle_block_prev_time = idle_get_current_time_ms();
  1078. dpidle_block_curr_time = idle_get_current_time_ms();
  1079. if (((dpidle_block_curr_time - dpidle_block_prev_time) > dpidle_block_time_critera)
  1080. && ((dpidle_block_curr_time - idle_block_log_prev_time) > idle_block_log_time_criteria)) {
  1081. if ((cpu % 4) == 0) {
  1082. /* dpidle,rgidle count */
  1083. p = log_buf;
  1084. p += sprintf(p, "CNT(dpidle,rgidle): ");
  1085. for (i = 0; i < nr_cpu_ids; i++)
  1086. p += sprintf(p, "[%d] = (%lu,%lu), ", i, dpidle_cnt[i], rgidle_cnt[i]);
  1087. idle_warn("%s\n", log_buf);
  1088. /* block category */
  1089. p = log_buf;
  1090. p += sprintf(p, "dpidle_block_cnt: ");
  1091. for (i = 0; i < NR_REASONS; i++)
  1092. p += sprintf(p, "[%s] = %lu, ", reason_name[i], dpidle_block_cnt[i]);
  1093. idle_warn("%s\n", log_buf);
  1094. p = log_buf;
  1095. p += sprintf(p, "dpidle_block_mask: ");
  1096. for (i = 0; i < NR_GRPS; i++)
  1097. p += sprintf(p, "0x%08x, ", dpidle_block_mask[i]);
  1098. idle_warn("%s\n", log_buf);
  1099. memset(dpidle_block_cnt, 0, sizeof(dpidle_block_cnt));
  1100. dpidle_block_prev_time = idle_get_current_time_ms();
  1101. idle_block_log_prev_time = dpidle_block_prev_time;
  1102. }
  1103. }
  1104. dpidle_block_cnt[reason]++;
  1105. ret = false;
  1106. } else {
  1107. dpidle_block_prev_time = idle_get_current_time_ms();
  1108. ret = true;
  1109. }
  1110. return ret;
  1111. }
  1112. void spm_dpidle_before_wfi(int cpu)
  1113. {
  1114. if (TRUE == mt_dpidle_chk_golden) {
  1115. /* FIXME: */
  1116. #if 0
  1117. mt_power_gs_dump_dpidle();
  1118. #endif
  1119. }
  1120. bus_dcm_enable();
  1121. faudintbus_pll2sq();
  1122. /* clkmux_sel(MT_MUX_AUDINTBUS, 0, "Deepidle"); //select 26M */
  1123. #ifdef CONFIG_SMP
  1124. dpidle_timer_left2 = localtimer_get_counter();
  1125. if ((int)dpidle_timer_left2 <= 0)
  1126. gpt_set_cmp(idle_gpt, 1); /* Trigger GPT4 Timeout imediately */
  1127. else
  1128. gpt_set_cmp(idle_gpt, dpidle_timer_left2);
  1129. start_gpt(idle_gpt);
  1130. #else
  1131. gpt_get_cnt(idle_gpt, &dpidle_timer_left2);
  1132. #endif
  1133. }
  1134. void spm_dpidle_after_wfi(int cpu, u32 spm_debug_flag)
  1135. {
  1136. #ifdef CONFIG_SMP
  1137. /* if (gpt_check_irq(GPT4)) { */
  1138. if (gpt_check_and_ack_irq(idle_gpt)) {
  1139. /* waked up by WAKEUP_GPT */
  1140. localtimer_set_next_event(1);
  1141. } else {
  1142. /* waked up by other wakeup source */
  1143. unsigned int cnt, cmp;
  1144. idle_gpt_get_cnt(idle_gpt, &cnt);
  1145. idle_gpt_get_cmp(idle_gpt, &cmp);
  1146. if (unlikely(cmp < cnt)) {
  1147. idle_err("[%s]GPT%d: counter = %10u, compare = %10u\n", __func__,
  1148. idle_gpt + 1, cnt, cmp);
  1149. BUG();
  1150. }
  1151. localtimer_set_next_event(cmp - cnt);
  1152. stop_gpt(idle_gpt);
  1153. /* GPT_ClearCount(WAKEUP_GPT); */
  1154. }
  1155. #endif
  1156. /* clkmux_sel(MT_MUX_AUDINTBUS, 1, "Deepidle"); //mainpll */
  1157. faudintbus_sq2pll();
  1158. bus_dcm_disable();
  1159. #ifdef CONFIG_HYBRID_CPU_DVFS
  1160. if (mt_dvfsp_paused_by_idle) {
  1161. cpuhvfs_unpause_dvfsp_to_run(PAUSE_IDLE);
  1162. mt_dvfsp_paused_by_idle = false;
  1163. }
  1164. #endif
  1165. dpidle_cnt[cpu]++;
  1166. if ((spm_debug_flag & (SPM_DBG_DEBUG_IDX_26M_WAKE | SPM_DBG_DEBUG_IDX_26M_SLEEP))
  1167. == (SPM_DBG_DEBUG_IDX_26M_WAKE | SPM_DBG_DEBUG_IDX_26M_SLEEP))
  1168. dpidle_f26m_cnt[cpu]++;
  1169. }
  1170. /************************************************
  1171. * slow idle part
  1172. ************************************************/
  1173. static DEFINE_MUTEX(slidle_locked);
  1174. static void enable_slidle_by_mask(int grp, unsigned int mask)
  1175. {
  1176. mutex_lock(&slidle_locked);
  1177. slidle_condition_mask[grp] &= ~mask;
  1178. mutex_unlock(&slidle_locked);
  1179. }
  1180. static void disable_slidle_by_mask(int grp, unsigned int mask)
  1181. {
  1182. mutex_lock(&slidle_locked);
  1183. slidle_condition_mask[grp] |= mask;
  1184. mutex_unlock(&slidle_locked);
  1185. }
  1186. void enable_slidle_by_bit(int id)
  1187. {
  1188. int grp = id / 32;
  1189. unsigned int mask = 1U << (id % 32);
  1190. BUG_ON(INVALID_GRP_ID(grp));
  1191. enable_slidle_by_mask(grp, mask);
  1192. }
  1193. EXPORT_SYMBOL(enable_slidle_by_bit);
  1194. void disable_slidle_by_bit(int id)
  1195. {
  1196. int grp = id / 32;
  1197. unsigned int mask = 1U << (id % 32);
  1198. BUG_ON(INVALID_GRP_ID(grp));
  1199. disable_slidle_by_mask(grp, mask);
  1200. }
  1201. EXPORT_SYMBOL(disable_slidle_by_bit);
  1202. static bool slidle_can_enter(void)
  1203. {
  1204. int reason = NR_REASONS;
  1205. unsigned int cpu_pwr_stat = 0;
  1206. cpu_pwr_stat = spm_get_cpu_pwr_status();
  1207. if (!((cpu_pwr_stat == CPU_0) || (cpu_pwr_stat == CPU_4))) {
  1208. reason = BY_CPU;
  1209. goto out;
  1210. }
  1211. memset(slidle_block_mask, 0, NR_GRPS * sizeof(unsigned int));
  1212. if (!cg_check_idle_can_enter(slidle_condition_mask, slidle_block_mask, MT_SLIDLE)) {
  1213. reason = BY_CLK;
  1214. goto out;
  1215. }
  1216. out:
  1217. if (reason < NR_REASONS) {
  1218. slidle_block_cnt[reason]++;
  1219. return false;
  1220. } else {
  1221. return true;
  1222. }
  1223. }
  1224. static void slidle_before_wfi(int cpu)
  1225. {
  1226. /* struct mtk_irq_mask mask; */
  1227. bus_dcm_enable();
  1228. }
  1229. static void slidle_after_wfi(int cpu)
  1230. {
  1231. bus_dcm_disable();
  1232. slidle_cnt[cpu]++;
  1233. }
  1234. static void go_to_slidle(int cpu)
  1235. {
  1236. slidle_before_wfi(cpu);
  1237. mb();
  1238. __asm__ __volatile__("wfi" : : : "memory");
  1239. slidle_after_wfi(cpu);
  1240. }
  1241. /************************************************
  1242. * regular idle part
  1243. ************************************************/
  1244. static void rgidle_before_wfi(int cpu)
  1245. {
  1246. }
  1247. static void rgidle_after_wfi(int cpu)
  1248. {
  1249. rgidle_cnt[cpu]++;
  1250. }
  1251. static noinline void go_to_rgidle(int cpu)
  1252. {
  1253. rgidle_before_wfi(cpu);
  1254. isb();
  1255. mb();
  1256. __asm__ __volatile__("wfi" : : : "memory");
  1257. rgidle_after_wfi(cpu);
  1258. }
  1259. /************************************************
  1260. * idle task flow part
  1261. ************************************************/
  1262. static inline void soidle_pre_handler(void)
  1263. {
  1264. hps_del_timer();
  1265. #ifndef CONFIG_MTK_FPGA
  1266. /* stop Mali dvfs_callback timer */
  1267. if (!mtk_gpu_sodi_entry())
  1268. idle_warn("not stop GPU timer in SODI\n");
  1269. #endif
  1270. #ifdef CONFIG_THERMAL
  1271. /* cancel thermal hrtimer for power saving */
  1272. tscpu_cancel_thermal_timer();
  1273. /* cancel thermal timer/workqueues for power saving */
  1274. mtkts_bts_cancel_thermal_timer();
  1275. mtkts_btsmdpa_cancel_thermal_timer();
  1276. mtkts_pmic_cancel_thermal_timer();
  1277. mtkts_battery_cancel_thermal_timer();
  1278. mtkts_pa_cancel_thermal_timer();
  1279. mtkts_wmt_cancel_thermal_timer();
  1280. mtkts_allts_cancel_ts1_timer();
  1281. mtkts_allts_cancel_ts2_timer();
  1282. mtkts_allts_cancel_ts3_timer();
  1283. mtkts_allts_cancel_ts4_timer();
  1284. mtkts_allts_cancel_ts5_timer();
  1285. #endif
  1286. }
  1287. static inline void soidle_post_handler(void)
  1288. {
  1289. hps_restart_timer();
  1290. #ifndef CONFIG_MTK_FPGA
  1291. /* restart Mali dvfs_callback timer */
  1292. if (!mtk_gpu_sodi_exit())
  1293. idle_warn("not restart GPU timer outside SODI\n");
  1294. #endif
  1295. #ifdef CONFIG_THERMAL
  1296. /* restart thermal hrtimer for update temp info */
  1297. tscpu_start_thermal_timer();
  1298. /* restart thermal timer/workqueues */
  1299. mtkts_bts_start_thermal_timer();
  1300. mtkts_btsmdpa_start_thermal_timer();
  1301. mtkts_pmic_start_thermal_timer();
  1302. mtkts_battery_start_thermal_timer();
  1303. mtkts_pa_start_thermal_timer();
  1304. mtkts_wmt_start_thermal_timer();
  1305. mtkts_allts_start_ts1_timer();
  1306. mtkts_allts_start_ts2_timer();
  1307. mtkts_allts_start_ts3_timer();
  1308. mtkts_allts_start_ts4_timer();
  1309. mtkts_allts_start_ts5_timer();
  1310. #endif
  1311. }
  1312. /*
  1313. * xxidle_handler return 1 if enter and exit the low power state
  1314. */
  1315. static u32 slp_spm_SODI3_flags = {
  1316. SPM_FLAG_ENABLE_SODI3 |
  1317. #ifdef FEATURE_ENABLE_SODI2P5
  1318. SPM_FLAG_DIS_SRCCLKEN_LOW |
  1319. #endif
  1320. #ifdef CONFIG_MTK_ICUSB_SUPPORT
  1321. SPM_FLAG_DIS_INFRA_PDN |
  1322. #endif
  1323. SPM_FLAG_DIS_SYSRAM_SLEEP
  1324. };
  1325. static u32 slp_spm_SODI_flags = {
  1326. #ifdef FEATURE_ENABLE_SODI2P5
  1327. SPM_FLAG_ENABLE_SODI3 |
  1328. SPM_FLAG_DIS_SRCCLKEN_LOW |
  1329. #endif
  1330. #ifdef CONFIG_MTK_ICUSB_SUPPORT
  1331. SPM_FLAG_DIS_INFRA_PDN |
  1332. #endif
  1333. SPM_FLAG_DIS_SYSRAM_SLEEP
  1334. };
  1335. #define LEGACY_SLEEP 0
  1336. u32 slp_spm_deepidle_flags = {
  1337. #if LEGACY_SLEEP
  1338. SPM_FLAG_DIS_CPU_PDN |
  1339. #ifdef CONFIG_MTK_ICUSB_SUPPORT
  1340. SPM_FLAG_DIS_INFRA_PDN |
  1341. #endif
  1342. SPM_FLAG_DIS_VPROC_VSRAM_DVS
  1343. #else
  1344. #ifdef CONFIG_MTK_ICUSB_SUPPORT
  1345. SPM_FLAG_DIS_INFRA_PDN
  1346. #else
  1347. 0
  1348. #endif
  1349. #endif
  1350. };
  1351. static inline void dpidle_pre_handler(void)
  1352. {
  1353. hps_del_timer();
  1354. #ifndef CONFIG_MTK_FPGA
  1355. #ifdef CONFIG_THERMAL
  1356. /* cancel thermal hrtimer for power saving */
  1357. tscpu_cancel_thermal_timer();
  1358. /* cancel thermal timer/workqueues for power saving */
  1359. mtkts_bts_cancel_thermal_timer();
  1360. mtkts_btsmdpa_cancel_thermal_timer();
  1361. mtkts_pmic_cancel_thermal_timer();
  1362. mtkts_battery_cancel_thermal_timer();
  1363. mtkts_pa_cancel_thermal_timer();
  1364. mtkts_wmt_cancel_thermal_timer();
  1365. mtkts_allts_cancel_ts1_timer();
  1366. mtkts_allts_cancel_ts2_timer();
  1367. mtkts_allts_cancel_ts3_timer();
  1368. mtkts_allts_cancel_ts4_timer();
  1369. mtkts_allts_cancel_ts5_timer();
  1370. #endif
  1371. #endif
  1372. }
  1373. static inline void dpidle_post_handler(void)
  1374. {
  1375. hps_restart_timer();
  1376. #ifndef CONFIG_MTK_FPGA
  1377. #ifdef CONFIG_THERMAL
  1378. /* restart thermal hrtimer for update temp info */
  1379. tscpu_start_thermal_timer();
  1380. /* restart thermal timer/workqueues */
  1381. mtkts_bts_start_thermal_timer();
  1382. mtkts_btsmdpa_start_thermal_timer();
  1383. mtkts_pmic_start_thermal_timer();
  1384. mtkts_battery_start_thermal_timer();
  1385. mtkts_pa_start_thermal_timer();
  1386. mtkts_wmt_start_thermal_timer();
  1387. mtkts_allts_start_ts1_timer();
  1388. mtkts_allts_start_ts2_timer();
  1389. mtkts_allts_start_ts3_timer();
  1390. mtkts_allts_start_ts4_timer();
  1391. mtkts_allts_start_ts5_timer();
  1392. #endif
  1393. #endif
  1394. }
  1395. #ifdef SPM_DEEPIDLE_PROFILE_TIME
  1396. unsigned int dpidle_profile[4];
  1397. #endif
  1398. static inline int dpidle_select_handler(int cpu)
  1399. {
  1400. int ret = 0;
  1401. if (idle_switch[IDLE_TYPE_DP]) {
  1402. if (dpidle_can_enter(cpu))
  1403. ret = 1;
  1404. }
  1405. return ret;
  1406. }
  1407. static inline int soidle3_select_handler(int cpu)
  1408. {
  1409. int ret = 0;
  1410. if (idle_switch[IDLE_TYPE_SO3]) {
  1411. #ifdef SPM_SODI3_PROFILE_TIME
  1412. gpt_get_cnt(SPM_SODI3_PROFILE_APXGPT, &soidle3_profile[0]);
  1413. #endif
  1414. if (soidle3_can_enter(cpu))
  1415. ret = 1;
  1416. }
  1417. return ret;
  1418. }
  1419. static inline int soidle_select_handler(int cpu)
  1420. {
  1421. int ret = 0;
  1422. if (idle_switch[IDLE_TYPE_SO]) {
  1423. #ifdef SPM_SODI_PROFILE_TIME
  1424. gpt_get_cnt(SPM_SODI_PROFILE_APXGPT, &soidle_profile[0]);
  1425. #endif
  1426. if (soidle_can_enter(cpu))
  1427. ret = 1;
  1428. }
  1429. return ret;
  1430. }
  1431. static inline int mcidle_select_handler(int cpu)
  1432. {
  1433. int ret = 0;
  1434. if (idle_switch[IDLE_TYPE_MC]) {
  1435. if (mcidle_can_enter(cpu))
  1436. ret = 1;
  1437. }
  1438. return ret;
  1439. }
  1440. static inline int slidle_select_handler(int cpu)
  1441. {
  1442. int ret = 0;
  1443. if (idle_switch[IDLE_TYPE_SL]) {
  1444. if (slidle_can_enter())
  1445. ret = 1;
  1446. }
  1447. return ret;
  1448. }
  1449. static inline int rgidle_select_handler(int cpu)
  1450. {
  1451. int ret = 0;
  1452. if (idle_switch[IDLE_TYPE_RG])
  1453. ret = 1;
  1454. return ret;
  1455. }
  1456. static int (*idle_select_handlers[NR_TYPES]) (int) = {
  1457. dpidle_select_handler,
  1458. soidle3_select_handler,
  1459. soidle_select_handler,
  1460. mcidle_select_handler,
  1461. slidle_select_handler,
  1462. rgidle_select_handler,
  1463. };
  1464. void dump_idle_cnt_in_interval(int cpu)
  1465. {
  1466. int i = 0;
  1467. char *p = log_buf;
  1468. char *p2 = log_buf_2;
  1469. unsigned long long idle_cnt_dump_curr_time = 0;
  1470. bool have_dpidle = false;
  1471. bool have_soidle3 = false;
  1472. bool have_soidle = false;
  1473. if (idle_cnt_dump_prev_time == 0)
  1474. idle_cnt_dump_prev_time = idle_get_current_time_ms();
  1475. idle_cnt_dump_curr_time = idle_get_current_time_ms();
  1476. if (!(cpu == 0 || cpu == 4))
  1477. return;
  1478. if (!((idle_cnt_dump_curr_time - idle_cnt_dump_prev_time) > idle_cnt_dump_criteria))
  1479. return;
  1480. /* dump idle count */
  1481. /* deepidle */
  1482. p = log_buf;
  1483. for (i = 0; i < nr_cpu_ids; i++) {
  1484. if ((dpidle_cnt[i] - dpidle_last_cnt[i]) != 0) {
  1485. p += sprintf(p, "[%d] = %lu, ", i, dpidle_cnt[i] - dpidle_last_cnt[i]);
  1486. have_dpidle = true;
  1487. }
  1488. dpidle_last_cnt[i] = dpidle_cnt[i];
  1489. }
  1490. if (have_dpidle)
  1491. p2 += sprintf(p2, "DP: %s --- ", log_buf);
  1492. else
  1493. p2 += sprintf(p2, "DP: No enter --- ");
  1494. /* sodi3 */
  1495. p = log_buf;
  1496. for (i = 0; i < nr_cpu_ids; i++) {
  1497. if ((soidle3_cnt[i] - soidle3_last_cnt[i]) != 0) {
  1498. p += sprintf(p, "[%d] = %lu, ", i, soidle3_cnt[i] - soidle3_last_cnt[i]);
  1499. have_soidle3 = true;
  1500. }
  1501. soidle3_last_cnt[i] = soidle3_cnt[i];
  1502. }
  1503. if (have_soidle3)
  1504. p2 += sprintf(p2, "SODI3: %s --- ", log_buf);
  1505. else
  1506. p2 += sprintf(p2, "SODI3: No enter --- ");
  1507. /* sodi3 */
  1508. p = log_buf;
  1509. for (i = 0; i < nr_cpu_ids; i++) {
  1510. if ((soidle_cnt[i] - soidle_last_cnt[i]) != 0) {
  1511. p += sprintf(p, "[%d] = %lu, ", i, soidle_cnt[i] - soidle_last_cnt[i]);
  1512. have_soidle = true;
  1513. }
  1514. soidle_last_cnt[i] = soidle_cnt[i];
  1515. }
  1516. if (have_soidle)
  1517. p2 += sprintf(p2, "SODI: %s --- ", log_buf);
  1518. else
  1519. p2 += sprintf(p2, "SODI: No enter --- ");
  1520. /* dump log */
  1521. idle_warn("%s\n", log_buf_2);
  1522. /* dump idle ratio */
  1523. if (idle_ratio_en) {
  1524. idle_ratio_profile_duration = idle_get_current_time_ms() - idle_ratio_profile_start_time;
  1525. idle_warn("--- CPU 0 idle: %llu, DP = %llu, SO3 = %llu, SO = %llu, RG = %llu --- (ms)\n",
  1526. idle_ratio_profile_duration,
  1527. idle_ratio_value[IDLE_TYPE_DP],
  1528. idle_ratio_value[IDLE_TYPE_SO3],
  1529. idle_ratio_value[IDLE_TYPE_SO],
  1530. idle_ratio_value[IDLE_TYPE_RG]);
  1531. idle_ratio_profile_start_time = idle_get_current_time_ms();
  1532. for (i = 0; i < NR_TYPES; i++)
  1533. idle_ratio_value[i] = 0;
  1534. }
  1535. /* update time base */
  1536. idle_cnt_dump_prev_time = idle_cnt_dump_curr_time;
  1537. }
  1538. inline void idle_ratio_calc_start(int type, int cpu)
  1539. {
  1540. if (type >= 0 && type < NR_TYPES && cpu == 0)
  1541. idle_ratio_start_time[type] = idle_get_current_time_ms();
  1542. }
  1543. inline void idle_ratio_calc_stop(int type, int cpu)
  1544. {
  1545. if (type >= 0 && type < NR_TYPES && cpu == 0)
  1546. idle_ratio_value[type] += (idle_get_current_time_ms() - idle_ratio_start_time[type]);
  1547. }
  1548. int mt_idle_select(int cpu)
  1549. {
  1550. int i = NR_TYPES - 1;
  1551. dump_idle_cnt_in_interval(cpu);
  1552. for (i = 0; i < NR_TYPES; i++) {
  1553. if (idle_select_handlers[i] (cpu))
  1554. break;
  1555. }
  1556. /* FIXME: return the corresponding idle state after verification successed */
  1557. return i;
  1558. }
  1559. int dpidle_enter(int cpu)
  1560. {
  1561. int ret = IDLE_TYPE_DP;
  1562. idle_ratio_calc_start(IDLE_TYPE_DP, cpu);
  1563. dpidle_pre_handler();
  1564. #ifndef CONFIG_MTK_FPGA
  1565. spm_go_to_dpidle(slp_spm_deepidle_flags, (u32)cpu, dpidle_dump_log);
  1566. #endif
  1567. dpidle_post_handler();
  1568. idle_ratio_calc_stop(IDLE_TYPE_DP, cpu);
  1569. #ifdef CONFIG_SMP
  1570. idle_warn_log("DP:timer_left=%d, timer_left2=%d, delta=%d\n",
  1571. dpidle_timer_left, dpidle_timer_left2, dpidle_timer_left-dpidle_timer_left2);
  1572. #else
  1573. idle_warn_log("DP:timer_left=%d, timer_left2=%d, delta=%d, timeout val=%d\n",
  1574. dpidle_timer_left,
  1575. dipidle_timer_left2,
  1576. dpidle_timer_left2 - dpidle_timer_left,
  1577. dpidle_timer_cmp - dpidle_timer_left);
  1578. #endif
  1579. #ifdef SPM_DEEPIDLE_PROFILE_TIME
  1580. gpt_get_cnt(SPM_PROFILE_APXGPT, &dpidle_profile[3]);
  1581. idle_warn_log("1:%u, 2:%u, 3:%u, 4:%u\n",
  1582. dpidle_profile[0], dpidle_profile[1], dpidle_profile[2], dpidle_profile[3]);
  1583. #endif
  1584. return ret;
  1585. }
  1586. EXPORT_SYMBOL(dpidle_enter);
  1587. int soidle3_enter(int cpu)
  1588. {
  1589. int ret = IDLE_TYPE_SO3;
  1590. unsigned long long soidle3_time = 0;
  1591. static unsigned long long soidle3_residency;
  1592. if (sodi3_flags & SODI_FLAG_RESIDENCY)
  1593. soidle3_time = idle_get_current_time_ms();
  1594. idle_ratio_calc_start(IDLE_TYPE_SO3, cpu);
  1595. soidle_pre_handler();
  1596. if (is_auxadc_released())
  1597. slp_spm_SODI3_flags |= SPM_FLAG_DIS_SRCCLKEN_LOW;
  1598. else
  1599. slp_spm_SODI3_flags &= ~SPM_FLAG_DIS_SRCCLKEN_LOW;
  1600. #ifdef DEFAULT_MMP_ENABLE
  1601. MMProfileLogEx(sodi_mmp_get_events()->sodi_enable, MMProfileFlagStart, 0, 0);
  1602. #endif /* DEFAULT_MMP_ENABLE */
  1603. spm_go_to_sodi3(slp_spm_SODI3_flags, (u32)cpu, sodi3_flags);
  1604. #ifdef DEFAULT_MMP_ENABLE
  1605. MMProfileLogEx(sodi_mmp_get_events()->sodi_enable, MMProfileFlagEnd, 0, spm_read(SPM_PASR_DPD_3));
  1606. #endif /* DEFAULT_MMP_ENABLE */
  1607. soidle_post_handler();
  1608. idle_ratio_calc_stop(IDLE_TYPE_SO3, cpu);
  1609. if (sodi3_flags & SODI_FLAG_RESIDENCY) {
  1610. soidle3_residency += idle_get_current_time_ms() - soidle3_time;
  1611. idle_dbg("SO3: soidle3_residency = %llu\n", soidle3_residency);
  1612. #ifdef CONFIG_SMP
  1613. idle_ver("SO3:timer_left=%d, timer_left2=%d, delta=%d\n",
  1614. soidle3_timer_left, soidle3_timer_left2, soidle3_timer_left - soidle3_timer_left2);
  1615. #else
  1616. idle_ver("SO3:timer_left=%d, timer_left2=%d, delta=%d,timeout val=%d\n",
  1617. soidle3_timer_left, soidle3_timer_left2,
  1618. soidle3_timer_left2 - soidle3_timer_left,
  1619. soidle3_timer_cmp - soidle3_timer_left);
  1620. #endif
  1621. }
  1622. #ifdef SPM_SODI3_PROFILE_TIME
  1623. gpt_get_cnt(SPM_SODI3_PROFILE_APXGPT, &soidle3_profile[3]);
  1624. idle_ver("SODI3: cpu_freq:%u, 1=>2:%u, 2=>3:%u, 3=>4:%u\n",
  1625. mt_cpufreq_get_cur_freq(0), soidle3_profile[1] - soidle3_profile[0],
  1626. soidle3_profile[2] - soidle3_profile[1],
  1627. soidle3_profile[3] - soidle3_profile[2]);
  1628. #endif
  1629. return ret;
  1630. }
  1631. EXPORT_SYMBOL(soidle3_enter);
  1632. int soidle_enter(int cpu)
  1633. {
  1634. int ret = IDLE_TYPE_SO;
  1635. unsigned long long soidle_time = 0;
  1636. static unsigned long long soidle_residency;
  1637. if (sodi_flags & SODI_FLAG_RESIDENCY)
  1638. soidle_time = idle_get_current_time_ms();
  1639. idle_ratio_calc_start(IDLE_TYPE_SO, cpu);
  1640. soidle_pre_handler();
  1641. #ifdef DEFAULT_MMP_ENABLE
  1642. MMProfileLogEx(sodi_mmp_get_events()->sodi_enable, MMProfileFlagStart, 0, 0);
  1643. #endif /* DEFAULT_MMP_ENABLE */
  1644. spm_go_to_sodi(slp_spm_SODI_flags, (u32)cpu, sodi_flags);
  1645. #ifdef DEFAULT_MMP_ENABLE
  1646. MMProfileLogEx(sodi_mmp_get_events()->sodi_enable, MMProfileFlagEnd, 0, spm_read(SPM_PASR_DPD_3));
  1647. #endif /* DEFAULT_MMP_ENABLE */
  1648. soidle_post_handler();
  1649. idle_ratio_calc_stop(IDLE_TYPE_SO, cpu);
  1650. if (sodi_flags & SODI_FLAG_RESIDENCY) {
  1651. soidle_residency += idle_get_current_time_ms() - soidle_time;
  1652. idle_dbg("SO: soidle_residency = %llu\n", soidle_residency);
  1653. #ifdef CONFIG_SMP
  1654. idle_ver("SO:timer_left=%d, timer_left2=%d, delta=%d\n",
  1655. soidle_timer_left, soidle_timer_left2, soidle_timer_left - soidle_timer_left2);
  1656. #else
  1657. idle_ver("SO:timer_left=%d, timer_left2=%d, delta=%d,timeout val=%d\n",
  1658. soidle_timer_left, soidle_timer_left2,
  1659. soidle_timer_left2 - soidle_timer_left,
  1660. soidle_timer_cmp - soidle_timer_left);
  1661. #endif
  1662. }
  1663. #ifdef SPM_SODI_PROFILE_TIME
  1664. gpt_get_cnt(SPM_SODI_PROFILE_APXGPT, &soidle_profile[3]);
  1665. idle_ver("SODI: cpu_freq:%u, 1=>2:%u, 2=>3:%u, 3=>4:%u\n",
  1666. mt_cpufreq_get_cur_freq(0), soidle_profile[1] - soidle_profile[0],
  1667. soidle_profile[2] - soidle_profile[1],
  1668. soidle_profile[3] - soidle_profile[2]);
  1669. #endif
  1670. return ret;
  1671. }
  1672. EXPORT_SYMBOL(soidle_enter);
  1673. int mcidle_enter(int cpu)
  1674. {
  1675. int ret = IDLE_TYPE_MC;
  1676. #ifndef CONFIG_MTK_FPGA
  1677. go_to_mcidle(cpu);
  1678. mcidle_cnt[cpu] += 1;
  1679. #endif
  1680. return ret;
  1681. }
  1682. EXPORT_SYMBOL(mcidle_enter);
  1683. int slidle_enter(int cpu)
  1684. {
  1685. int ret = IDLE_TYPE_SL;
  1686. go_to_slidle(cpu);
  1687. return ret;
  1688. }
  1689. EXPORT_SYMBOL(slidle_enter);
  1690. int rgidle_enter(int cpu)
  1691. {
  1692. int ret = IDLE_TYPE_RG;
  1693. idle_ratio_calc_start(IDLE_TYPE_RG, cpu);
  1694. go_to_rgidle(cpu);
  1695. idle_ratio_calc_stop(IDLE_TYPE_RG, cpu);
  1696. return ret;
  1697. }
  1698. EXPORT_SYMBOL(rgidle_enter);
  1699. static int mcdi_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
  1700. {
  1701. if (!idle_switch[IDLE_TYPE_MC])
  1702. return NOTIFY_OK;
  1703. switch (action) {
  1704. case CPU_UP_PREPARE:
  1705. case CPU_UP_PREPARE_FROZEN:
  1706. if (num_online_cpus() == 1)
  1707. spm_mcdi_switch_on_off(SPM_MCDI_EARLY_SUSPEND, 1);
  1708. break;
  1709. #ifdef CONFIG_HOTPLUG_CPU
  1710. case CPU_DYING:
  1711. case CPU_DYING_FROZEN:
  1712. break;
  1713. case CPU_DEAD:
  1714. case CPU_DEAD_FROZEN:
  1715. if (num_online_cpus() == 1)
  1716. spm_mcdi_switch_on_off(SPM_MCDI_EARLY_SUSPEND, 0);
  1717. break;
  1718. #endif
  1719. default:
  1720. break;
  1721. }
  1722. return NOTIFY_OK;
  1723. }
  1724. static struct notifier_block mcdi_nb = {
  1725. .notifier_call = mcdi_cpu_notify,
  1726. };
  1727. void mt_idle_init(void)
  1728. {
  1729. register_cpu_notifier(&mcdi_nb);
  1730. }
  1731. /***************************/
  1732. /* debugfs */
  1733. /***************************/
  1734. static char dbg_buf[4096] = { 0 };
  1735. static char cmd_buf[512] = { 0 };
  1736. /* idle_state */
  1737. static int _idle_state_open(struct seq_file *s, void *data)
  1738. {
  1739. return 0;
  1740. }
  1741. static int idle_state_open(struct inode *inode, struct file *filp)
  1742. {
  1743. return single_open(filp, _idle_state_open, inode->i_private);
  1744. }
  1745. static ssize_t idle_state_read(struct file *filp,
  1746. char __user *userbuf, size_t count, loff_t *f_pos)
  1747. {
  1748. int len = 0;
  1749. char *p = dbg_buf;
  1750. int i;
  1751. p += sprintf(p, "********** idle state dump **********\n");
  1752. for (i = 0; i < nr_cpu_ids; i++) {
  1753. p += sprintf(p, "dpidle_cnt[%d]=%lu, dpidle_26m[%d]=%lu, soidle3_cnt[%d]=%lu, soidle_cnt[%d]=%lu, ",
  1754. i, dpidle_cnt[i], i, dpidle_f26m_cnt[i], i, soidle3_cnt[i], i, soidle_cnt[i]);
  1755. p += sprintf(p, "mcidle_cnt[%d]=%lu, slidle_cnt[%d]=%lu, rgidle_cnt[%d]=%lu\n",
  1756. i, mcidle_cnt[i], i, slidle_cnt[i], i, rgidle_cnt[i]);
  1757. }
  1758. p += sprintf(p, "\n********** variables dump **********\n");
  1759. for (i = 0; i < NR_TYPES; i++)
  1760. p += sprintf(p, "%s_switch=%d, ", idle_name[i], idle_switch[i]);
  1761. p += sprintf(p, "\n");
  1762. p += sprintf(p, "idle_ratio_en = %u\n", idle_ratio_en);
  1763. p += sprintf(p, "\n********** idle command help **********\n");
  1764. p += sprintf(p, "status help: cat /sys/kernel/debug/cpuidle/idle_state\n");
  1765. p += sprintf(p, "switch on/off: echo switch mask > /sys/kernel/debug/cpuidle/idle_state\n");
  1766. p += sprintf(p, "idle ratio profile: echo ratio 1/0 > /sys/kernel/debug/cpuidle/idle_state\n");
  1767. p += sprintf(p, "soidle3 help: cat /sys/kernel/debug/cpuidle/soidle3_state\n");
  1768. p += sprintf(p, "soidle help: cat /sys/kernel/debug/cpuidle/soidle_state\n");
  1769. p += sprintf(p, "dpidle help: cat /sys/kernel/debug/cpuidle/dpidle_state\n");
  1770. p += sprintf(p, "mcidle help: cat /sys/kernel/debug/cpuidle/mcidle_state\n");
  1771. p += sprintf(p, "slidle help: cat /sys/kernel/debug/cpuidle/slidle_state\n");
  1772. p += sprintf(p, "rgidle help: cat /sys/kernel/debug/cpuidle/rgidle_state\n");
  1773. len = p - dbg_buf;
  1774. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  1775. }
  1776. static ssize_t idle_state_write(struct file *filp,
  1777. const char __user *userbuf, size_t count, loff_t *f_pos)
  1778. {
  1779. char cmd[NR_CMD_BUF];
  1780. int idx;
  1781. int param;
  1782. count = min(count, sizeof(cmd_buf) - 1);
  1783. if (copy_from_user(cmd_buf, userbuf, count))
  1784. return -EFAULT;
  1785. cmd_buf[count] = '\0';
  1786. if (sscanf(cmd_buf, "%s %x", cmd, &param) == 2) {
  1787. if (!strcmp(cmd, "switch")) {
  1788. for (idx = 0; idx < NR_TYPES; idx++)
  1789. idle_switch[idx] = (param & (1U << idx)) ? 1 : 0;
  1790. } else if (!strcmp(cmd, "ratio")) {
  1791. idle_ratio_en = param;
  1792. if (idle_ratio_en) {
  1793. idle_ratio_profile_start_time = idle_get_current_time_ms();
  1794. for (idx = 0; idx < NR_TYPES; idx++)
  1795. idle_ratio_value[idx] = 0;
  1796. }
  1797. }
  1798. return count;
  1799. }
  1800. return -EINVAL;
  1801. }
  1802. static const struct file_operations idle_state_fops = {
  1803. .open = idle_state_open,
  1804. .read = idle_state_read,
  1805. .write = idle_state_write,
  1806. .llseek = seq_lseek,
  1807. .release = single_release,
  1808. };
  1809. /* mcidle_state */
  1810. static int _mcidle_state_open(struct seq_file *s, void *data)
  1811. {
  1812. return 0;
  1813. }
  1814. static int mcidle_state_open(struct inode *inode, struct file *filp)
  1815. {
  1816. return single_open(filp, _mcidle_state_open, inode->i_private);
  1817. }
  1818. static ssize_t mcidle_state_read(struct file *filp, char __user *userbuf, size_t count, loff_t *f_pos)
  1819. {
  1820. int len = 0;
  1821. char *p = dbg_buf;
  1822. int cpus, reason;
  1823. p += sprintf(p, "*********** deep idle state ************\n");
  1824. p += sprintf(p, "mcidle_time_critera=%u\n", mcidle_time_critera);
  1825. for (cpus = 0; cpus < nr_cpu_ids; cpus++) {
  1826. p += sprintf(p, "cpu:%d\n", cpus);
  1827. for (reason = 0; reason < NR_REASONS; reason++) {
  1828. p += sprintf(p, "[%d]mcidle_block_cnt[%s]=%lu\n", reason,
  1829. reason_name[reason], mcidle_block_cnt[cpus][reason]);
  1830. }
  1831. p += sprintf(p, "\n");
  1832. }
  1833. p += sprintf(p, "\n********** mcidle command help **********\n");
  1834. p += sprintf(p, "mcidle help: cat /sys/kernel/debug/cpuidle/mcidle_state\n");
  1835. p += sprintf(p, "switch on/off: echo [mcidle] 1/0 > /sys/kernel/debug/cpuidle/mcidle_state\n");
  1836. p += sprintf(p, "modify tm_cri: echo time value(dec) > /sys/kernel/debug/cpuidle/mcidle_state\n");
  1837. len = p - dbg_buf;
  1838. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  1839. }
  1840. static ssize_t mcidle_state_write(struct file *filp,
  1841. const char __user *userbuf,
  1842. size_t count,
  1843. loff_t *f_pos)
  1844. {
  1845. char cmd[NR_CMD_BUF];
  1846. int param;
  1847. count = min(count, sizeof(cmd_buf) - 1);
  1848. if (copy_from_user(cmd_buf, userbuf, count))
  1849. return -EFAULT;
  1850. cmd_buf[count] = '\0';
  1851. if (sscanf(cmd_buf, "%s %d", cmd, &param) == 2) {
  1852. if (!strcmp(cmd, "mcidle"))
  1853. idle_switch[IDLE_TYPE_MC] = param;
  1854. else if (!strcmp(cmd, "time"))
  1855. mcidle_time_critera = param;
  1856. return count;
  1857. } else if (!kstrtoint(cmd_buf, 10, &param) == 1) {
  1858. idle_switch[IDLE_TYPE_MC] = param;
  1859. return count;
  1860. }
  1861. return -EINVAL;
  1862. }
  1863. static const struct file_operations mcidle_state_fops = {
  1864. .open = mcidle_state_open,
  1865. .read = mcidle_state_read,
  1866. .write = mcidle_state_write,
  1867. .llseek = seq_lseek,
  1868. .release = single_release,
  1869. };
  1870. /* dpidle_state */
  1871. static int _dpidle_state_open(struct seq_file *s, void *data)
  1872. {
  1873. return 0;
  1874. }
  1875. static int dpidle_state_open(struct inode *inode, struct file *filp)
  1876. {
  1877. return single_open(filp, _dpidle_state_open, inode->i_private);
  1878. }
  1879. static ssize_t dpidle_state_read(struct file *filp, char __user *userbuf, size_t count, loff_t *f_pos)
  1880. {
  1881. int len = 0;
  1882. char *p = dbg_buf;
  1883. int i;
  1884. int k;
  1885. p += sprintf(p, "*********** deep idle state ************\n");
  1886. p += sprintf(p, "dpidle_time_critera=%u\n", dpidle_time_critera);
  1887. for (i = 0; i < NR_REASONS; i++) {
  1888. p += sprintf(p, "[%d]dpidle_block_cnt[%s]=%lu\n", i, reason_name[i],
  1889. dpidle_block_cnt[i]);
  1890. }
  1891. p += sprintf(p, "\n");
  1892. for (i = 0; i < NR_GRPS; i++) {
  1893. p += sprintf(p, "[%02d]dpidle_condition_mask[%-8s]=0x%08x\t\tdpidle_block_mask[%-8s]=0x%08x\n", i,
  1894. cg_grp_get_name(i), dpidle_condition_mask[i],
  1895. cg_grp_get_name(i), dpidle_block_mask[i]);
  1896. }
  1897. for (i = 0; i < NR_GRPS; i++) {
  1898. p += sprintf(p, "[%-8s]\n", cg_grp_get_name(i));
  1899. for (k = 0; k < 32; k++) {
  1900. if (dpidle_blocking_stat[i][k] != 0)
  1901. p += sprintf(p, "%-2d: %d\n", k, dpidle_blocking_stat[i][k]);
  1902. }
  1903. }
  1904. for (i = 0; i < NR_GRPS; i++)
  1905. for (k = 0; k < 32; k++)
  1906. dpidle_blocking_stat[i][k] = 0;
  1907. p += sprintf(p, "dpidle_by_pass_cg=%u\n", dpidle_by_pass_cg);
  1908. p += sprintf(p, "dpidle_by_pass_pg=%u\n", dpidle_by_pass_pg);
  1909. p += sprintf(p, "dpidle_dump_log = %u\n", dpidle_dump_log);
  1910. p += sprintf(p, "(0: None, 1: Reduced, 2: Full\n");
  1911. p += sprintf(p, "\n*********** dpidle command help ************\n");
  1912. p += sprintf(p, "dpidle help: cat /sys/kernel/debug/cpuidle/dpidle_state\n");
  1913. p += sprintf(p, "switch on/off: echo [dpidle] 1/0 > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1914. p += sprintf(p, "cpupdn on/off: echo cpupdn 1/0 > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1915. p += sprintf(p, "en_dp_by_bit: echo enable id > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1916. p += sprintf(p, "dis_dp_by_bit: echo disable id > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1917. p += sprintf(p, "modify tm_cri: echo time value(dec) > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1918. p += sprintf(p, "bypass cg: echo bypass 1/0 > /sys/kernel/debug/cpuidle/dpidle_state\n");
  1919. len = p - dbg_buf;
  1920. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  1921. }
  1922. static ssize_t dpidle_state_write(struct file *filp,
  1923. const char __user *userbuf,
  1924. size_t count,
  1925. loff_t *f_pos)
  1926. {
  1927. char cmd[NR_CMD_BUF];
  1928. int param;
  1929. count = min(count, sizeof(cmd_buf) - 1);
  1930. if (copy_from_user(cmd_buf, userbuf, count))
  1931. return -EFAULT;
  1932. cmd_buf[count] = '\0';
  1933. if (sscanf(cmd_buf, "%s %d", cmd, &param) == 2) {
  1934. if (!strcmp(cmd, "dpidle"))
  1935. idle_switch[IDLE_TYPE_DP] = param;
  1936. else if (!strcmp(cmd, "enable"))
  1937. enable_dpidle_by_bit(param);
  1938. else if (!strcmp(cmd, "disable"))
  1939. disable_dpidle_by_bit(param);
  1940. else if (!strcmp(cmd, "time"))
  1941. dpidle_time_critera = param;
  1942. else if (!strcmp(cmd, "bypass"))
  1943. dpidle_by_pass_cg = param;
  1944. else if (!strcmp(cmd, "bypass_pg")) {
  1945. dpidle_by_pass_pg = param;
  1946. idle_warn("bypass_pg = %d\n", dpidle_by_pass_pg);
  1947. } else if (!strcmp(cmd, "log"))
  1948. dpidle_dump_log = param;
  1949. return count;
  1950. } else if (!kstrtoint(cmd_buf, 10, &param) == 1) {
  1951. idle_switch[IDLE_TYPE_DP] = param;
  1952. return count;
  1953. }
  1954. return -EINVAL;
  1955. }
  1956. static const struct file_operations dpidle_state_fops = {
  1957. .open = dpidle_state_open,
  1958. .read = dpidle_state_read,
  1959. .write = dpidle_state_write,
  1960. .llseek = seq_lseek,
  1961. .release = single_release,
  1962. };
  1963. /* soidle3_state */
  1964. static int _soidle3_state_open(struct seq_file *s, void *data)
  1965. {
  1966. return 0;
  1967. }
  1968. static int soidle3_state_open(struct inode *inode, struct file *filp)
  1969. {
  1970. return single_open(filp, _soidle3_state_open, inode->i_private);
  1971. }
  1972. static ssize_t soidle3_state_read(struct file *filp, char __user *userbuf, size_t count, loff_t *f_pos)
  1973. {
  1974. int len = 0;
  1975. char *p = dbg_buf;
  1976. int i;
  1977. p += sprintf(p, "*********** soidle3 state ************\n");
  1978. p += sprintf(p, "soidle3_time_critera=%u\n", soidle3_time_critera);
  1979. for (i = 0; i < NR_REASONS; i++) {
  1980. p += sprintf(p,
  1981. "[%d]soidle3_block_cnt[%s]=%lu\n",
  1982. i, reason_name[i], soidle3_block_cnt[i]);
  1983. }
  1984. p += sprintf(p, "\n");
  1985. for (i = 0; i < NR_PLLS; i++) {
  1986. p += sprintf(p,
  1987. "[%02d]soidle3_pll_condition_mask[%-8s]=0x%08x\t\tsoidle3_pll_block_mask[%-8s]=0x%08x\n",
  1988. i,
  1989. pll_grp_get_name(i), soidle3_pll_condition_mask[i],
  1990. pll_grp_get_name(i), soidle3_pll_block_mask[i]);
  1991. }
  1992. p += sprintf(p, "\n");
  1993. for (i = 0; i < NR_GRPS; i++) {
  1994. p += sprintf(p,
  1995. "[%02d]soidle3_condition_mask[%-8s]=0x%08x\t\tsoidle3_block_mask[%-8s]=0x%08x\n",
  1996. i,
  1997. cg_grp_get_name(i), soidle3_condition_mask[i],
  1998. cg_grp_get_name(i), soidle3_block_mask[i]);
  1999. }
  2000. p += sprintf(p, "soidle3_bypass_pll=%u\n", soidle3_by_pass_pll);
  2001. p += sprintf(p, "soidle3_bypass_cg=%u\n", soidle3_by_pass_cg);
  2002. p += sprintf(p, "soidle3_bypass_en=%u\n", soidle3_by_pass_en);
  2003. p += sprintf(p, "sodi3_flags=0x%x\n", sodi3_flags);
  2004. p += sprintf(p, "\n*********** soidle3 command help ************\n");
  2005. p += sprintf(p, "soidle3 help: cat /sys/kernel/debug/cpuidle/soidle3_state\n");
  2006. p += sprintf(p, "switch on/off: echo [soidle3] 1/0 > /sys/kernel/debug/cpuidle/soidle3_state\n");
  2007. p += sprintf(p, "cpupdn on/off: echo cpupdn 1/0 > /sys/kernel/debug/cpuidle/soidle3_state\n");
  2008. p += sprintf(p, "en_dp_by_bit: echo enable id > /sys/kernel/debug/cpuidle/soidle3_state\n");
  2009. p += sprintf(p, "dis_dp_by_bit: echo disable id > /sys/kernel/debug/cpuidle/soidle3_state\n");
  2010. p += sprintf(p, "modify tm_cri: echo time value(dec) > /sys/kernel/debug/cpuidle/soidle3_state\n");
  2011. p += sprintf(p, "bypass pll: echo bypass_pll 1/0 > /sys/kernel/debug/cpuidle/soidle3_state\n");
  2012. p += sprintf(p, "bypass cg: echo bypass 1/0 > /sys/kernel/debug/cpuidle/soidle3_state\n");
  2013. p += sprintf(p, "bypass en: echo bypass_en 1/0 > /sys/kernel/debug/cpuidle/soidle3_state\n");
  2014. len = p - dbg_buf;
  2015. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  2016. }
  2017. static ssize_t soidle3_state_write(struct file *filp,
  2018. const char __user *userbuf,
  2019. size_t count,
  2020. loff_t *f_pos)
  2021. {
  2022. char cmd[NR_CMD_BUF];
  2023. int param;
  2024. count = min(count, sizeof(cmd_buf) - 1);
  2025. if (copy_from_user(cmd_buf, userbuf, count))
  2026. return -EFAULT;
  2027. cmd_buf[count] = '\0';
  2028. if (sscanf(cmd_buf, "%s %d", cmd, &param) == 2) {
  2029. if (!strcmp(cmd, "soidle3"))
  2030. idle_switch[IDLE_TYPE_SO3] = param;
  2031. else if (!strcmp(cmd, "enable"))
  2032. enable_soidle3_by_bit(param);
  2033. else if (!strcmp(cmd, "disable"))
  2034. disable_soidle3_by_bit(param);
  2035. else if (!strcmp(cmd, "time"))
  2036. soidle3_time_critera = param;
  2037. else if (!strcmp(cmd, "bypass_pll")) {
  2038. soidle3_by_pass_pll = param;
  2039. idle_dbg("bypass_pll = %d\n", soidle3_by_pass_pll);
  2040. } else if (!strcmp(cmd, "bypass")) {
  2041. soidle3_by_pass_cg = param;
  2042. idle_dbg("bypass = %d\n", soidle3_by_pass_cg);
  2043. } else if (!strcmp(cmd, "bypass_en")) {
  2044. soidle3_by_pass_en = param;
  2045. idle_dbg("bypass_en = %d\n", soidle3_by_pass_en);
  2046. } else if (!strcmp(cmd, "sodi3_flags")) {
  2047. sodi3_flags = param;
  2048. idle_dbg("sodi3_flags = 0x%x\n", sodi3_flags);
  2049. }
  2050. return count;
  2051. } else if (!kstrtoint(cmd_buf, 10, &param) == 1) {
  2052. idle_switch[IDLE_TYPE_SO3] = param;
  2053. return count;
  2054. }
  2055. return -EINVAL;
  2056. }
  2057. static const struct file_operations soidle3_state_fops = {
  2058. .open = soidle3_state_open,
  2059. .read = soidle3_state_read,
  2060. .write = soidle3_state_write,
  2061. .llseek = seq_lseek,
  2062. .release = single_release,
  2063. };
  2064. /* soidle_state */
  2065. static int _soidle_state_open(struct seq_file *s, void *data)
  2066. {
  2067. return 0;
  2068. }
  2069. static int soidle_state_open(struct inode *inode, struct file *filp)
  2070. {
  2071. return single_open(filp, _soidle_state_open, inode->i_private);
  2072. }
  2073. static ssize_t soidle_state_read(struct file *filp, char __user *userbuf, size_t count, loff_t *f_pos)
  2074. {
  2075. int len = 0;
  2076. char *p = dbg_buf;
  2077. int i;
  2078. p += sprintf(p, "*********** soidle state ************\n");
  2079. p += sprintf(p, "soidle_time_critera=%u\n", soidle_time_critera);
  2080. for (i = 0; i < NR_REASONS; i++) {
  2081. p += sprintf(p,
  2082. "[%d]soidle_block_cnt[%s]=%lu\n",
  2083. i, reason_name[i], soidle_block_cnt[i]);
  2084. }
  2085. p += sprintf(p, "\n");
  2086. for (i = 0; i < NR_GRPS; i++) {
  2087. p += sprintf(p,
  2088. "[%02d]soidle_condition_mask[%-8s]=0x%08x\t\tsoidle_block_mask[%-8s]=0x%08x\n",
  2089. i,
  2090. cg_grp_get_name(i), soidle_condition_mask[i],
  2091. cg_grp_get_name(i), soidle_block_mask[i]);
  2092. }
  2093. p += sprintf(p, "soidle_bypass_cg=%u\n", soidle_by_pass_cg);
  2094. p += sprintf(p, "soidle_by_pass_pg=%u\n", soidle_by_pass_pg);
  2095. p += sprintf(p, "soidle_bypass_en=%u\n", soidle_by_pass_en);
  2096. p += sprintf(p, "sodi_flags=0x%x\n", sodi_flags);
  2097. p += sprintf(p, "sodi_fw=0x%x\n", sodi_fw);
  2098. p += sprintf(p, "\n*********** soidle command help ************\n");
  2099. p += sprintf(p, "soidle help: cat /sys/kernel/debug/cpuidle/soidle_state\n");
  2100. p += sprintf(p, "switch on/off: echo [soidle] 1/0 > /sys/kernel/debug/cpuidle/soidle_state\n");
  2101. p += sprintf(p, "cpupdn on/off: echo cpupdn 1/0 > /sys/kernel/debug/cpuidle/soidle_state\n");
  2102. p += sprintf(p, "en_dp_by_bit: echo enable id > /sys/kernel/debug/cpuidle/soidle_state\n");
  2103. p += sprintf(p, "dis_dp_by_bit: echo disable id > /sys/kernel/debug/cpuidle/soidle_state\n");
  2104. p += sprintf(p, "modify tm_cri: echo time value(dec) > /sys/kernel/debug/cpuidle/soidle_state\n");
  2105. p += sprintf(p, "bypass cg: echo bypass 1/0 > /sys/kernel/debug/cpuidle/soidle_state\n");
  2106. p += sprintf(p, "bypass en: echo bypass_en 1/0 > /sys/kernel/debug/cpuidle/soidle_state\n");
  2107. len = p - dbg_buf;
  2108. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  2109. }
  2110. static ssize_t soidle_state_write(struct file *filp,
  2111. const char __user *userbuf,
  2112. size_t count,
  2113. loff_t *f_pos)
  2114. {
  2115. char cmd[NR_CMD_BUF];
  2116. int param;
  2117. count = min(count, sizeof(cmd_buf) - 1);
  2118. if (copy_from_user(cmd_buf, userbuf, count))
  2119. return -EFAULT;
  2120. cmd_buf[count] = '\0';
  2121. if (sscanf(cmd_buf, "%s %d", cmd, &param) == 2) {
  2122. if (!strcmp(cmd, "soidle"))
  2123. idle_switch[IDLE_TYPE_SO] = param;
  2124. else if (!strcmp(cmd, "enable"))
  2125. enable_soidle_by_bit(param);
  2126. else if (!strcmp(cmd, "disable"))
  2127. disable_soidle_by_bit(param);
  2128. else if (!strcmp(cmd, "time"))
  2129. soidle_time_critera = param;
  2130. else if (!strcmp(cmd, "bypass")) {
  2131. soidle_by_pass_cg = param;
  2132. idle_dbg("bypass = %d\n", soidle_by_pass_cg);
  2133. } else if (!strcmp(cmd, "bypass_pg")) {
  2134. soidle_by_pass_pg = param;
  2135. idle_warn("bypass_pg = %d\n", soidle_by_pass_pg);
  2136. } else if (!strcmp(cmd, "bypass_en")) {
  2137. soidle_by_pass_en = param;
  2138. idle_dbg("bypass_en = %d\n", soidle_by_pass_en);
  2139. } else if (!strcmp(cmd, "sodi_flags")) {
  2140. sodi_flags = param;
  2141. idle_dbg("sodi_flags = 0x%x\n", sodi_flags);
  2142. } else if (!strcmp(cmd, "sodi_fw")) {
  2143. sodi_fw = param;
  2144. #if defined(CONFIG_ARCH_MT6797)
  2145. set_sodi_fw_mode(sodi_fw);
  2146. #endif
  2147. idle_dbg("sodi_fw = 0x%x\n", sodi_fw);
  2148. }
  2149. return count;
  2150. } else if (!kstrtoint(cmd_buf, 10, &param) == 1) {
  2151. idle_switch[IDLE_TYPE_SO] = param;
  2152. return count;
  2153. }
  2154. return -EINVAL;
  2155. }
  2156. static const struct file_operations soidle_state_fops = {
  2157. .open = soidle_state_open,
  2158. .read = soidle_state_read,
  2159. .write = soidle_state_write,
  2160. .llseek = seq_lseek,
  2161. .release = single_release,
  2162. };
  2163. /* slidle_state */
  2164. static int _slidle_state_open(struct seq_file *s, void *data)
  2165. {
  2166. return 0;
  2167. }
  2168. static int slidle_state_open(struct inode *inode, struct file *filp)
  2169. {
  2170. return single_open(filp, _slidle_state_open, inode->i_private);
  2171. }
  2172. static ssize_t slidle_state_read(struct file *filp, char __user *userbuf, size_t count,
  2173. loff_t *f_pos)
  2174. {
  2175. int len = 0;
  2176. char *p = dbg_buf;
  2177. int i;
  2178. p += sprintf(p, "*********** slow idle state ************\n");
  2179. for (i = 0; i < NR_REASONS; i++) {
  2180. p += sprintf(p, "[%d]slidle_block_cnt[%s]=%lu\n",
  2181. i, reason_name[i], slidle_block_cnt[i]);
  2182. }
  2183. p += sprintf(p, "\n");
  2184. for (i = 0; i < NR_GRPS; i++) {
  2185. p += sprintf(p,
  2186. "[%02d]slidle_condition_mask[%-8s]=0x%08x\t\tslidle_block_mask[%-8s]=0x%08x\n",
  2187. i, cg_grp_get_name(i), slidle_condition_mask[i], cg_grp_get_name(i),
  2188. slidle_block_mask[i]);
  2189. }
  2190. p += sprintf(p, "\n********** slidle command help **********\n");
  2191. p += sprintf(p, "slidle help: cat /sys/kernel/debug/cpuidle/slidle_state\n");
  2192. p += sprintf(p,
  2193. "switch on/off: echo [slidle] 1/0 > /sys/kernel/debug/cpuidle/slidle_state\n");
  2194. len = p - dbg_buf;
  2195. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  2196. }
  2197. static ssize_t slidle_state_write(struct file *filp, const char __user *userbuf,
  2198. size_t count, loff_t *f_pos)
  2199. {
  2200. char cmd[NR_CMD_BUF];
  2201. int param;
  2202. count = min(count, sizeof(cmd_buf) - 1);
  2203. if (copy_from_user(cmd_buf, userbuf, count))
  2204. return -EFAULT;
  2205. cmd_buf[count] = '\0';
  2206. if (sscanf(userbuf, "%s %d", cmd, &param) == 2) {
  2207. if (!strcmp(cmd, "slidle"))
  2208. idle_switch[IDLE_TYPE_SL] = param;
  2209. else if (!strcmp(cmd, "enable"))
  2210. enable_slidle_by_bit(param);
  2211. else if (!strcmp(cmd, "disable"))
  2212. disable_slidle_by_bit(param);
  2213. return count;
  2214. } else if (!kstrtoint(userbuf, 10, &param) == 1) {
  2215. idle_switch[IDLE_TYPE_SL] = param;
  2216. return count;
  2217. }
  2218. return -EINVAL;
  2219. }
  2220. static const struct file_operations slidle_state_fops = {
  2221. .open = slidle_state_open,
  2222. .read = slidle_state_read,
  2223. .write = slidle_state_write,
  2224. .llseek = seq_lseek,
  2225. .release = single_release,
  2226. };
  2227. /* CG/PLL/MTCMOS register dump */
  2228. static int _reg_dump_open(struct seq_file *s, void *data)
  2229. {
  2230. return 0;
  2231. }
  2232. static int reg_dump_open(struct inode *inode, struct file *filp)
  2233. {
  2234. return single_open(filp, _reg_dump_open, inode->i_private);
  2235. }
  2236. static ssize_t reg_dump_read(struct file *filp, char __user *userbuf, size_t count, loff_t *f_pos)
  2237. {
  2238. int len = 0;
  2239. char *p = dbg_buf;
  2240. p += sprintf(p, "SPM_PWR_STATUS = 0x%08x\n", idle_readl(SPM_PWR_STATUS));
  2241. p += sprintf(p, "SPM_MFG_PWR_CON = 0x%08x\n", idle_readl(SPM_MFG_PWR_CON));
  2242. p += sprintf(p, "SPM_ISP_PWR_CON = 0x%08x\n", idle_readl(SPM_ISP_PWR_CON));
  2243. p += sprintf(p, "SPM_VDE_PWR_CON = 0x%08x\n", idle_readl(SPM_VDE_PWR_CON));
  2244. p += sprintf(p, "SPM_VEN_PWR_CON = 0x%08x\n", idle_readl(SPM_VEN_PWR_CON));
  2245. p += sprintf(p, "DISP_CG_CON0 = 0x%08x\n", idle_readl(DISP_CG_CON0));
  2246. p += sprintf(p, "DISP_CG_CON1 = 0x%08x\n", idle_readl(DISP_CG_CON1));
  2247. p += sprintf(p, "MFG_CG_CON = 0x%08x\n", idle_readl(MFG_CG_CON));
  2248. p += sprintf(p, "IMG_CG_CON = 0x%08x\n", idle_readl(IMG_CG_CON));
  2249. p += sprintf(p, "VDEC_CG_CON_0 = 0x%08x\n", idle_readl(VDEC_CG_CON_0));
  2250. p += sprintf(p, "VDEC_CG_CON_1 = 0x%08x\n", idle_readl(VDEC_CG_CON_1));
  2251. p += sprintf(p, "VENCSYS_CG_CON = 0x%08x\n", idle_readl(VENCSYS_CG_CON));
  2252. /* INFRA CG*/
  2253. p += sprintf(p, "INFRA_SW_CG_0_STA = 0x%08x\n", idle_readl(INFRA_SW_CG_0_STA));
  2254. p += sprintf(p, "INFRA_SW_CG_1_STA = 0x%08x\n", idle_readl(INFRA_SW_CG_1_STA));
  2255. p += sprintf(p, "INFRA_SW_CG_2_STA = 0x%08x\n", idle_readl(INFRA_SW_CG_2_STA));
  2256. /* PLL */
  2257. p += sprintf(p, "=== PLL ====\n");
  2258. p += sprintf(p, "MAINPLL_CON0 = 0x%08x\n", idle_readl(MAINPLL_CON0));
  2259. p += sprintf(p, "UNIVPLL_CON0 = 0x%08x\n", idle_readl(UNIVPLL_CON0));
  2260. p += sprintf(p, "MSDCPLL_CON0 = 0x%08x\n", idle_readl(MSDCPLL_CON0));
  2261. p += sprintf(p, "TVDPLL_CON0 = 0x%08x\n", idle_readl(TVDPLL_CON0));
  2262. p += sprintf(p, "APLL1_CON0 = 0x%08x\n", idle_readl(APLL1_CON0));
  2263. p += sprintf(p, "APLL2_CON0 = 0x%08x\n", idle_readl(APLL2_CON0));
  2264. #if defined(CONFIG_ARCH_MT6755)
  2265. p += sprintf(p, "ARMCA15PLL_CON0 = 0x%08x\n", idle_readl(ARMCA15PLL_CON0));
  2266. p += sprintf(p, "ARMCA7PLL_CON0 = 0x%08x\n", idle_readl(ARMCA7PLL_CON0));
  2267. p += sprintf(p, "MMPLL_CON0 = 0x%08x\n", idle_readl(MMPLL_CON0));
  2268. p += sprintf(p, "VENCPLL_CON0 = 0x%08x\n", idle_readl(VENCPLL_CON0));
  2269. #elif defined(CONFIG_ARCH_MT6797)
  2270. p += sprintf(p, "MFGPLL_CON0 = 0x%08x\n", idle_readl(MFGPLL_CON0));
  2271. p += sprintf(p, "IMGPLL_CON0 = 0x%08x\n", idle_readl(IMGPLL_CON0));
  2272. p += sprintf(p, "MPLL_CON0 = 0x%08x\n", idle_readl(MPLL_CON0));
  2273. p += sprintf(p, "CODECPLL_CON0 = 0x%08x\n", idle_readl(CODECPLL_CON0));
  2274. p += sprintf(p, "MDPLL1_CON0 = 0x%08x\n", idle_readl(MDPLL1_CON0));
  2275. p += sprintf(p, "VDECPLL_CON0 = 0x%08x\n", idle_readl(VDECPLL_CON0));
  2276. #endif
  2277. /* MTCMOS */
  2278. p += sprintf(p, "=== MTCMOS ====\n");
  2279. p += sprintf(p, "SPM_ISP_PWR_CON = 0x%08x\n", idle_readl(SPM_ISP_PWR_CON));
  2280. p += sprintf(p, "SPM_MFG_PWR_CON = 0x%08x\n", idle_readl(SPM_MFG_PWR_CON));
  2281. p += sprintf(p, "SPM_MFGAYSNC_PWR_CON = 0x%08x\n", idle_readl(SPM_MFG_PWR_CON - 0x4));
  2282. p += sprintf(p, "SPM_VDE_PWR_CON = 0x%08x\n", idle_readl(SPM_VDE_PWR_CON));
  2283. p += sprintf(p, "SPM_VEN_PWR_CON = 0x%08x\n", idle_readl(SPM_VEN_PWR_CON));
  2284. p += sprintf(p, "SPM_DIS_PWR_CON = 0x%08x\n", idle_readl(SPM_DIS_PWR_CON));
  2285. p += sprintf(p, "SPM_AUDIO_PWR_CON = 0x%08x\n", idle_readl(SPM_AUDIO_PWR_CON));
  2286. p += sprintf(p, "SPM_MD1_PWR_CON = 0x%08x\n", idle_readl(SPM_MD1_PWR_CON));
  2287. /* p += sprintf(p, "SPM_MD2_PWR_CON = 0x%08x\n", idle_readl(SPM_MD2_PWR_CON));*/
  2288. p += sprintf(p, "SPM_C2K_PWR_CON = 0x%08x\n", idle_readl(SPM_C2K_PWR_CON));
  2289. p += sprintf(p, "SPM_CONN_PWR_CON = 0x%08x\n", idle_readl(SPM_CONN_PWR_CON));
  2290. p += sprintf(p, "SPM_MDSYS_INTF_INFRA_PWR_CON = 0x%08x\n", idle_readl(SPM_MDSYS_INTF_INFRA_PWR_CON));
  2291. len = p - dbg_buf;
  2292. return simple_read_from_buffer(userbuf, count, f_pos, dbg_buf, len);
  2293. }
  2294. static ssize_t reg_dump_write(struct file *filp,
  2295. const char __user *userbuf,
  2296. size_t count,
  2297. loff_t *f_pos)
  2298. {
  2299. count = min(count, sizeof(cmd_buf) - 1);
  2300. return count;
  2301. }
  2302. static const struct file_operations reg_dump_fops = {
  2303. .open = reg_dump_open,
  2304. .read = reg_dump_read,
  2305. .write = reg_dump_write,
  2306. .llseek = seq_lseek,
  2307. .release = single_release,
  2308. };
  2309. /* debugfs entry */
  2310. static struct dentry *root_entry;
  2311. static int mt_cpuidle_debugfs_init(void)
  2312. {
  2313. /* TODO: check if debugfs_create_file() failed */
  2314. /* Initialize debugfs */
  2315. root_entry = debugfs_create_dir("cpuidle", NULL);
  2316. if (!root_entry) {
  2317. idle_err("Can not create debugfs `dpidle_state`\n");
  2318. return 1;
  2319. }
  2320. debugfs_create_file("idle_state", 0644, root_entry, NULL, &idle_state_fops);
  2321. debugfs_create_file("dpidle_state", 0644, root_entry, NULL, &dpidle_state_fops);
  2322. debugfs_create_file("soidle3_state", 0644, root_entry, NULL, &soidle3_state_fops);
  2323. debugfs_create_file("soidle_state", 0644, root_entry, NULL, &soidle_state_fops);
  2324. debugfs_create_file("mcidle_state", 0644, root_entry, NULL, &mcidle_state_fops);
  2325. debugfs_create_file("slidle_state", 0644, root_entry, NULL, &slidle_state_fops);
  2326. debugfs_create_file("reg_dump", 0644, root_entry, NULL, &reg_dump_fops);
  2327. return 0;
  2328. }
  2329. void mt_cpuidle_framework_init(void)
  2330. {
  2331. int err = 0;
  2332. int i = 0;
  2333. idle_ver("[%s]entry!!\n", __func__);
  2334. err = request_gpt(idle_gpt, GPT_ONE_SHOT, GPT_CLK_SRC_SYS, GPT_CLK_DIV_1,
  2335. 0, NULL, GPT_NOAUTOEN);
  2336. if (err)
  2337. idle_warn("[%s]fail to request GPT%d\n", __func__, idle_gpt + 1);
  2338. err = 0;
  2339. for (i = 0; i < num_possible_cpus(); i++)
  2340. err |= cpu_xgpt_register_timer(i, NULL);
  2341. if (err)
  2342. idle_warn("[%s]fail to request cpuxgpt\n", __func__);
  2343. iomap_init();
  2344. mt_cpuidle_debugfs_init();
  2345. #if defined(CONFIG_ARCH_MT6797)
  2346. set_sodi_fw_mode(sodi_fw);
  2347. #endif
  2348. }
  2349. EXPORT_SYMBOL(mt_cpuidle_framework_init);
  2350. module_param(mt_idle_chk_golden, bool, 0644);
  2351. module_param(mt_dpidle_chk_golden, bool, 0644);