mt_spm_fs.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/kobject.h>
  4. #include <linux/sysfs.h>
  5. #include <linux/string.h>
  6. #include "mt_spm_internal.h"
  7. #include "mt_sleep.h"
  8. /**************************************
  9. * Macro and Inline
  10. **************************************/
  11. #define DEFINE_ATTR_RO(_name) \
  12. static struct kobj_attribute _name##_attr = { \
  13. .attr = { \
  14. .name = #_name, \
  15. .mode = 0444, \
  16. }, \
  17. .show = _name##_show, \
  18. }
  19. #define DEFINE_ATTR_RW(_name) \
  20. static struct kobj_attribute _name##_attr = { \
  21. .attr = { \
  22. .name = #_name, \
  23. .mode = 0644, \
  24. }, \
  25. .show = _name##_show, \
  26. .store = _name##_store, \
  27. }
  28. #define __ATTR_OF(_name) (&_name##_attr.attr)
  29. /**************************************
  30. * xxx_pcm_show Function
  31. **************************************/
  32. #if 0 /* FIXME */
  33. static ssize_t show_pcm_desc(const struct pcm_desc *pcmdesc, char *buf)
  34. {
  35. char *p = buf;
  36. p += sprintf(p, "version = %s\n", pcmdesc->version);
  37. p += sprintf(p, "base = 0x%p\n", pcmdesc->base);
  38. p += sprintf(p, "size = %u\n", pcmdesc->size);
  39. p += sprintf(p, "sess = %u\n", pcmdesc->sess);
  40. p += sprintf(p, "replace = %u\n", pcmdesc->replace);
  41. p += sprintf(p, "vec0 = 0x%x\n", pcmdesc->vec0);
  42. p += sprintf(p, "vec1 = 0x%x\n", pcmdesc->vec1);
  43. p += sprintf(p, "vec2 = 0x%x\n", pcmdesc->vec2);
  44. p += sprintf(p, "vec3 = 0x%x\n", pcmdesc->vec3);
  45. p += sprintf(p, "vec4 = 0x%x\n", pcmdesc->vec4);
  46. p += sprintf(p, "vec5 = 0x%x\n", pcmdesc->vec5);
  47. p += sprintf(p, "vec6 = 0x%x\n", pcmdesc->vec6);
  48. p += sprintf(p, "vec7 = 0x%x\n", pcmdesc->vec7);
  49. BUG_ON(p - buf >= PAGE_SIZE);
  50. return p - buf;
  51. }
  52. static ssize_t suspend_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  53. {
  54. return show_pcm_desc(__spm_suspend.pcmdesc, buf);
  55. }
  56. static ssize_t dpidle_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  57. {
  58. return show_pcm_desc(__spm_dpidle.pcmdesc, buf);
  59. }
  60. static ssize_t sodi3_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  61. {
  62. return show_pcm_desc(__spm_sodi3.pcmdesc, buf);
  63. }
  64. static ssize_t sodi_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  65. {
  66. return show_pcm_desc(__spm_sodi.pcmdesc, buf);
  67. }
  68. static ssize_t mcdi_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  69. {
  70. return show_pcm_desc(__spm_mcdi.pcmdesc, buf);
  71. }
  72. static ssize_t talking_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  73. {
  74. #if 0
  75. return show_pcm_desc(__spm_talking.pcmdesc, buf);
  76. #else
  77. return 0;
  78. #endif
  79. }
  80. static ssize_t ddrdfs_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  81. {
  82. #if 0
  83. return show_pcm_desc(__spm_ddrdfs.pcmdesc, buf);
  84. #else
  85. return 0;
  86. #endif
  87. }
  88. #endif
  89. /**************************************
  90. * xxx_ctrl_show Function
  91. **************************************/
  92. static ssize_t show_pwr_ctrl(const struct pwr_ctrl *pwrctrl, char *buf)
  93. {
  94. char *p = buf;
  95. p += sprintf(p, "pcm_flags = 0x%x\n", pwrctrl->pcm_flags);
  96. p += sprintf(p, "pcm_flags_cust = 0x%x\n", pwrctrl->pcm_flags_cust);
  97. p += sprintf(p, "pcm_reserve = 0x%x\n", pwrctrl->pcm_reserve);
  98. p += sprintf(p, "timer_val = 0x%x\n", pwrctrl->timer_val);
  99. p += sprintf(p, "timer_val_cust = 0x%x\n", pwrctrl->timer_val_cust);
  100. p += sprintf(p, "timer_val_ramp_en = %d\n", pwrctrl->timer_val_ramp_en);
  101. p += sprintf(p, "timer_val_ramp_en_sec = %d\n", pwrctrl->timer_val_ramp_en_sec);
  102. p += sprintf(p, "wake_src = 0x%x\n", pwrctrl->wake_src);
  103. p += sprintf(p, "wake_src_cust = 0x%x\n", pwrctrl->wake_src_cust);
  104. p += sprintf(p, "wake_src_md32 = 0x%x\n", pwrctrl->wake_src_md32);
  105. p += sprintf(p, "r0_ctrl_en = %u\n", pwrctrl->r0_ctrl_en);
  106. p += sprintf(p, "r7_ctrl_en = %u\n", pwrctrl->r7_ctrl_en);
  107. p += sprintf(p, "infra_dcm_lock = %u\n", pwrctrl->infra_dcm_lock);
  108. p += sprintf(p, "wdt_disable = %u\n", pwrctrl->wdt_disable);
  109. p += sprintf(p, "spm_apsrc_req = %u\n", pwrctrl->spm_apsrc_req);
  110. p += sprintf(p, "spm_f26m_req = %u\n", pwrctrl->spm_f26m_req);
  111. p += sprintf(p, "mcusys_idle_mask = %u\n", pwrctrl->mcusys_idle_mask);
  112. p += sprintf(p, "mp1top_idle_mask = %u\n", pwrctrl->mp1top_idle_mask);
  113. p += sprintf(p, "mp0top_idle_mask = %u\n", pwrctrl->mp0top_idle_mask);
  114. p += sprintf(p, "wfi_op = %u\n", pwrctrl->wfi_op);
  115. p += sprintf(p, "mp1_cpu0_wfi_en = %u\n", pwrctrl->mp1_cpu0_wfi_en);
  116. p += sprintf(p, "mp1_cpu1_wfi_en = %u\n", pwrctrl->mp1_cpu1_wfi_en);
  117. p += sprintf(p, "mp1_cpu2_wfi_en = %u\n", pwrctrl->mp1_cpu2_wfi_en);
  118. p += sprintf(p, "mp1_cpu3_wfi_en = %u\n", pwrctrl->mp1_cpu3_wfi_en);
  119. p += sprintf(p, "mp0_cpu0_wfi_en = %u\n", pwrctrl->mp0_cpu0_wfi_en);
  120. p += sprintf(p, "mp0_cpu1_wfi_en = %u\n", pwrctrl->mp0_cpu1_wfi_en);
  121. p += sprintf(p, "mp0_cpu2_wfi_en = %u\n", pwrctrl->mp0_cpu2_wfi_en);
  122. p += sprintf(p, "mp0_cpu3_wfi_en = %u\n", pwrctrl->mp0_cpu3_wfi_en);
  123. p += sprintf(p, "md1_req_mask_b = %u\n", pwrctrl->md1_req_mask_b);
  124. p += sprintf(p, "md2_req_mask_b = %u\n", pwrctrl->md2_req_mask_b);
  125. p += sprintf(p, "md_apsrc0_sel = %u\n", pwrctrl->md_apsrc0_sel);
  126. p += sprintf(p, "md_apsrc1_sel = %u\n", pwrctrl->md_apsrc1_sel);
  127. p += sprintf(p, "conn_apsrc_sel = %u\n", pwrctrl->conn_apsrc_sel);
  128. p += sprintf(p, "md_ddr_dbc_en = %u\n", pwrctrl->md_ddr_dbc_en);
  129. p += sprintf(p, "ccif0_to_ap_mask_b = %u\n", pwrctrl->ccif0_to_ap_mask_b);
  130. p += sprintf(p, "ccif0_to_md_mask_b = %u\n", pwrctrl->ccif0_to_md_mask_b);
  131. p += sprintf(p, "ccif1_to_ap_mask_b = %u\n", pwrctrl->ccif1_to_ap_mask_b);
  132. p += sprintf(p, "ccif1_to_md_mask_b = %u\n", pwrctrl->ccif1_to_md_mask_b);
  133. p += sprintf(p, "lte_mask_b = %u\n", pwrctrl->lte_mask_b);
  134. p += sprintf(p, "ccifmd_md1_event_mask_b = %u\n", pwrctrl->ccifmd_md1_event_mask_b);
  135. p += sprintf(p, "ccifmd_md2_event_mask_b = %u\n", pwrctrl->ccifmd_md2_event_mask_b);
  136. p += sprintf(p, "conn_mask_b = %u\n", pwrctrl->conn_mask_b);
  137. p += sprintf(p, "dsi0_ddr_en_mask_b = %u\n", pwrctrl->dsi0_ddr_en_mask_b);
  138. p += sprintf(p, "dsi1_ddr_en_mask_b = %u\n", pwrctrl->dsi1_ddr_en_mask_b);
  139. p += sprintf(p, "dpi_ddr_en_mask_b = %u\n", pwrctrl->dpi_ddr_en_mask_b);
  140. p += sprintf(p, "isp0_ddr_en_mask_b = %u\n", pwrctrl->isp0_ddr_en_mask_b);
  141. p += sprintf(p, "isp1_ddr_en_mask_b = %u\n", pwrctrl->isp1_ddr_en_mask_b);
  142. p += sprintf(p, "scp_req_mask_b = %u\n", pwrctrl->scp_req_mask_b);
  143. p += sprintf(p, "syspwreq_mask = %u\n", pwrctrl->syspwreq_mask);
  144. p += sprintf(p, "srclkenai_mask = %u\n", pwrctrl->srclkenai_mask);
  145. p += sprintf(p, "gce_req_mask_b = %u\n", pwrctrl->gce_req_mask_b);
  146. p += sprintf(p, "disp_req_mask_b = %u\n", pwrctrl->disp_req_mask_b);
  147. p += sprintf(p, "disp1_req_mask_b = %u\n", pwrctrl->disp1_req_mask_b);
  148. p += sprintf(p, "mfg_req_mask_b = %u\n", pwrctrl->mfg_req_mask_b);
  149. #if defined(CONFIG_ARCH_MT6797)
  150. p += sprintf(p, "disp_od_req_mask_b = %u\n", pwrctrl->disp_od_req_mask_b);
  151. #endif
  152. p += sprintf(p, "param1 = 0x%x\n", pwrctrl->param1);
  153. p += sprintf(p, "param2 = 0x%x\n", pwrctrl->param2);
  154. p += sprintf(p, "param3 = 0x%x\n", pwrctrl->param3);
  155. p += sprintf(p, "dvfs_halt_mask_b = 0x%x\n", pwrctrl->dvfs_halt_mask_b);
  156. p += sprintf(p, "sdio_on_dvfs_req_mask_b = %u\n", pwrctrl->sdio_on_dvfs_req_mask_b);
  157. p += sprintf(p, "cpu_md_dvfs_erq_merge_mask_b = %u\n",
  158. pwrctrl->cpu_md_dvfs_erq_merge_mask_b);
  159. p += sprintf(p, "md1_ddr_en_dvfs_halt_mask_b = %u\n", pwrctrl->md1_ddr_en_dvfs_halt_mask_b);
  160. p += sprintf(p, "md2_ddr_en_dvfs_halt_mask_b = %u\n", pwrctrl->md2_ddr_en_dvfs_halt_mask_b);
  161. p += sprintf(p, "md_srcclkena_0_dvfs_req_mask_b = %u\n",
  162. pwrctrl->md_srcclkena_0_dvfs_req_mask_b);
  163. p += sprintf(p, "md_srcclkena_1_dvfs_req_mask_b = %u\n",
  164. pwrctrl->md_srcclkena_1_dvfs_req_mask_b);
  165. p += sprintf(p, "conn_srcclkena_dvfs_req_mask_b = %u\n",
  166. pwrctrl->conn_srcclkena_dvfs_req_mask_b);
  167. p += sprintf(p, "vsync_dvfs_halt_mask_b = 0x%x\n", pwrctrl->vsync_dvfs_halt_mask_b);
  168. p += sprintf(p, "emi_boost_dvfs_req_mask_b = %u\n", pwrctrl->emi_boost_dvfs_req_mask_b);
  169. p += sprintf(p, "cpu_md_emi_dvfs_req_prot_dis = %u\n",
  170. pwrctrl->cpu_md_emi_dvfs_req_prot_dis);
  171. p += sprintf(p, "emi_bw_dvfs_req_mask = %u\n", pwrctrl->emi_bw_dvfs_req_mask);
  172. p += sprintf(p, "spm_dvfs_req = %u\n", pwrctrl->spm_dvfs_req);
  173. p += sprintf(p, "spm_dvfs_force_down = %u\n", pwrctrl->spm_dvfs_force_down);
  174. p += sprintf(p, "cpu_md_dvfs_sop_force_on = %u\n", pwrctrl->cpu_md_dvfs_sop_force_on);
  175. BUG_ON(p - buf >= PAGE_SIZE);
  176. return p - buf;
  177. }
  178. static ssize_t suspend_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  179. {
  180. return show_pwr_ctrl(__spm_suspend.pwrctrl, buf);
  181. }
  182. #ifndef CONFIG_MTK_FPGA
  183. static ssize_t dpidle_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  184. {
  185. return show_pwr_ctrl(__spm_dpidle.pwrctrl, buf);
  186. }
  187. static ssize_t sodi3_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  188. {
  189. return show_pwr_ctrl(__spm_sodi3.pwrctrl, buf);
  190. }
  191. static ssize_t sodi_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  192. {
  193. return show_pwr_ctrl(__spm_sodi.pwrctrl, buf);
  194. }
  195. static ssize_t mcdi_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  196. {
  197. return 0;
  198. }
  199. #endif
  200. static ssize_t talking_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  201. {
  202. #if 0
  203. return show_pwr_ctrl(__spm_talking.pwrctrl, buf);
  204. #else
  205. return 0;
  206. #endif
  207. }
  208. static ssize_t vcore_dvfs_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  209. {
  210. return show_pwr_ctrl(__spm_vcore_dvfs.pwrctrl, buf);
  211. }
  212. /**************************************
  213. * xxx_ctrl_store Function
  214. **************************************/
  215. static ssize_t store_pwr_ctrl(struct pwr_ctrl *pwrctrl, const char *buf, size_t count)
  216. {
  217. u32 val;
  218. char cmd[32];
  219. if (sscanf(buf, "%31s %x", cmd, &val) != 2)
  220. return -EPERM;
  221. spm_debug("pwr_ctrl: cmd = %s, val = 0x%x\n", cmd, val);
  222. if (!strcmp(cmd, "pcm_flags"))
  223. pwrctrl->pcm_flags = val;
  224. else if (!strcmp(cmd, "pcm_flags_cust"))
  225. pwrctrl->pcm_flags_cust = val;
  226. else if (!strcmp(cmd, "pcm_reserve"))
  227. pwrctrl->pcm_reserve = val;
  228. else if (!strcmp(cmd, "timer_val"))
  229. pwrctrl->timer_val = val;
  230. else if (!strcmp(cmd, "timer_val_cust"))
  231. pwrctrl->timer_val_cust = val;
  232. else if (!strcmp(cmd, "timer_val_ramp_en"))
  233. pwrctrl->timer_val_ramp_en = val;
  234. else if (!strcmp(cmd, "timer_val_ramp_en_sec"))
  235. pwrctrl->timer_val_ramp_en_sec = val;
  236. else if (!strcmp(cmd, "wake_src"))
  237. pwrctrl->wake_src = val;
  238. else if (!strcmp(cmd, "wake_src_cust"))
  239. pwrctrl->wake_src_cust = val;
  240. else if (!strcmp(cmd, "wake_src_md32"))
  241. pwrctrl->wake_src_md32 = val;
  242. else if (!strcmp(cmd, "r0_ctrl_en"))
  243. pwrctrl->r0_ctrl_en = val;
  244. else if (!strcmp(cmd, "r7_ctrl_en"))
  245. pwrctrl->r7_ctrl_en = val;
  246. else if (!strcmp(cmd, "infra_dcm_lock"))
  247. pwrctrl->infra_dcm_lock = val;
  248. else if (!strcmp(cmd, "wdt_disable"))
  249. pwrctrl->wdt_disable = val;
  250. else if (!strcmp(cmd, "spm_apsrc_req"))
  251. pwrctrl->spm_apsrc_req = val;
  252. else if (!strcmp(cmd, "spm_f26m_req"))
  253. pwrctrl->spm_f26m_req = val;
  254. else if (!strcmp(cmd, "spm_lte_req"))
  255. pwrctrl->spm_lte_req = val;
  256. else if (!strcmp(cmd, "spm_infra_req"))
  257. pwrctrl->spm_infra_req = val;
  258. else if (!strcmp(cmd, "spm_vrf18_req"))
  259. pwrctrl->spm_vrf18_req = val;
  260. else if (!strcmp(cmd, "spm_dvfs_req"))
  261. pwrctrl->spm_dvfs_req = val;
  262. else if (!strcmp(cmd, "spm_dvfs_force_down"))
  263. pwrctrl->spm_dvfs_force_down = val;
  264. else if (!strcmp(cmd, "spm_ddren_req"))
  265. pwrctrl->spm_ddren_req = val;
  266. else if (!strcmp(cmd, "spm_flag_keep_csyspwrupack_high"))
  267. pwrctrl->spm_flag_keep_csyspwrupack_high = val;
  268. else if (!strcmp(cmd, "spm_flag_dis_vproc_vsram_dvs"))
  269. pwrctrl->spm_flag_dis_vproc_vsram_dvs = val;
  270. else if (!strcmp(cmd, "spm_flag_run_common_scenario"))
  271. pwrctrl->spm_flag_run_common_scenario = val;
  272. else if (!strcmp(cmd, "cpu_md_dvfs_sop_force_on"))
  273. pwrctrl->cpu_md_dvfs_sop_force_on = val;
  274. else if (!strcmp(cmd, "mcusys_idle_mask"))
  275. pwrctrl->mcusys_idle_mask = val;
  276. else if (!strcmp(cmd, "mp1top_idle_mask"))
  277. pwrctrl->mp1top_idle_mask = val;
  278. else if (!strcmp(cmd, "mp0top_idle_mask"))
  279. pwrctrl->mp0top_idle_mask = val;
  280. else if (!strcmp(cmd, "wfi_op"))
  281. pwrctrl->wfi_op = val;
  282. else if (!strcmp(cmd, "mp1_cpu0_wfi_en"))
  283. pwrctrl->mp1_cpu0_wfi_en = val;
  284. else if (!strcmp(cmd, "mp1_cpu1_wfi_en"))
  285. pwrctrl->mp1_cpu1_wfi_en = val;
  286. else if (!strcmp(cmd, "mp1_cpu2_wfi_en"))
  287. pwrctrl->mp1_cpu2_wfi_en = val;
  288. else if (!strcmp(cmd, "mp1_cpu3_wfi_en"))
  289. pwrctrl->mp1_cpu3_wfi_en = val;
  290. else if (!strcmp(cmd, "mp0_cpu0_wfi_en"))
  291. pwrctrl->mp0_cpu0_wfi_en = val;
  292. else if (!strcmp(cmd, "mp0_cpu1_wfi_en"))
  293. pwrctrl->mp0_cpu1_wfi_en = val;
  294. else if (!strcmp(cmd, "mp0_cpu2_wfi_en"))
  295. pwrctrl->mp0_cpu2_wfi_en = val;
  296. else if (!strcmp(cmd, "mp0_cpu3_wfi_en"))
  297. pwrctrl->mp0_cpu3_wfi_en = val;
  298. else if (!strcmp(cmd, "md1_req_mask_b"))
  299. pwrctrl->md1_req_mask_b = val;
  300. else if (!strcmp(cmd, "md2_req_mask_b"))
  301. pwrctrl->md2_req_mask_b = val;
  302. else if (!strcmp(cmd, "md_apsrc0_sel"))
  303. pwrctrl->md_apsrc0_sel = val;
  304. else if (!strcmp(cmd, "md_apsrc1_sel"))
  305. pwrctrl->md_apsrc1_sel = val;
  306. else if (!strcmp(cmd, "conn_apsrc_sel"))
  307. pwrctrl->conn_apsrc_sel = val;
  308. else if (!strcmp(cmd, "md_ddr_dbc_en"))
  309. pwrctrl->md_ddr_dbc_en = val;
  310. else if (!strcmp(cmd, "ccif0_to_ap_mask_b"))
  311. pwrctrl->ccif0_to_ap_mask_b = val;
  312. else if (!strcmp(cmd, "ccif0_to_md_mask_b"))
  313. pwrctrl->ccif0_to_md_mask_b = val;
  314. else if (!strcmp(cmd, "ccif1_to_ap_mask_b"))
  315. pwrctrl->ccif1_to_ap_mask_b = val;
  316. else if (!strcmp(cmd, "ccif1_to_md_mask_b"))
  317. pwrctrl->ccif1_to_md_mask_b = val;
  318. else if (!strcmp(cmd, "lte_mask_b"))
  319. pwrctrl->lte_mask_b = val;
  320. else if (!strcmp(cmd, "ccifmd_md1_event_mask_b"))
  321. pwrctrl->ccifmd_md1_event_mask_b = val;
  322. else if (!strcmp(cmd, "ccifmd_md2_event_mask_b"))
  323. pwrctrl->ccifmd_md2_event_mask_b = val;
  324. else if (!strcmp(cmd, "vsync_mask_b"))
  325. pwrctrl->vsync_mask_b = val;
  326. else if (!strcmp(cmd, "md_srcclkena_0_infra_mask_b"))
  327. pwrctrl->md_srcclkena_0_infra_mask_b = val;
  328. else if (!strcmp(cmd, "md_srcclkena_1_infra_mask_b"))
  329. pwrctrl->md_srcclkena_1_infra_mask_b = val;
  330. else if (!strcmp(cmd, "conn_srcclkena_infra_mask_b"))
  331. pwrctrl->conn_srcclkena_infra_mask_b = val;
  332. else if (!strcmp(cmd, "md32_srcclkena_infra_mask_b"))
  333. pwrctrl->md32_srcclkena_infra_mask_b = val;
  334. else if (!strcmp(cmd, "srcclkeni_infra_mask_b"))
  335. pwrctrl->srcclkeni_infra_mask_b = val;
  336. else if (!strcmp(cmd, "md_apsrcreq_0_infra_mask_b"))
  337. pwrctrl->md_apsrcreq_0_infra_mask_b = val;
  338. else if (!strcmp(cmd, "md_apsrcreq_1_infra_mask_b"))
  339. pwrctrl->md_apsrcreq_1_infra_mask_b = val;
  340. else if (!strcmp(cmd, "conn_apsrcreq_infra_mask_b"))
  341. pwrctrl->conn_apsrcreq_infra_mask_b = val;
  342. else if (!strcmp(cmd, "md32_apsrcreq_infra_mask_b"))
  343. pwrctrl->md32_apsrcreq_infra_mask_b = val;
  344. else if (!strcmp(cmd, "md_ddr_en_0_mask_b"))
  345. pwrctrl->md_ddr_en_0_mask_b = val;
  346. else if (!strcmp(cmd, "md_ddr_en_1_mask_b"))
  347. pwrctrl->md_ddr_en_1_mask_b = val;
  348. else if (!strcmp(cmd, "md_vrf18_req_0_mask_b"))
  349. pwrctrl->md_vrf18_req_0_mask_b = val;
  350. else if (!strcmp(cmd, "md_vrf18_req_1_mask_b"))
  351. pwrctrl->md_vrf18_req_1_mask_b = val;
  352. else if (!strcmp(cmd, "emi_bw_dvfs_req_mask"))
  353. pwrctrl->emi_bw_dvfs_req_mask = val;
  354. else if (!strcmp(cmd, "md_srcclkena_0_dvfs_req_mask_b"))
  355. pwrctrl->md_srcclkena_0_dvfs_req_mask_b = val;
  356. else if (!strcmp(cmd, "md_srcclkena_1_dvfs_req_mask_b"))
  357. pwrctrl->md_srcclkena_1_dvfs_req_mask_b = val;
  358. else if (!strcmp(cmd, "conn_srcclkena_dvfs_req_mask_b"))
  359. pwrctrl->conn_srcclkena_dvfs_req_mask_b = val;
  360. else if (!strcmp(cmd, "dvfs_halt_mask_b"))
  361. pwrctrl->dvfs_halt_mask_b = val;
  362. else if (!strcmp(cmd, "vdec_req_mask_b"))
  363. pwrctrl->vdec_req_mask_b = val;
  364. else if (!strcmp(cmd, "gce_req_mask_b"))
  365. pwrctrl->gce_req_mask_b = val;
  366. else if (!strcmp(cmd, "cpu_md_dvfs_erq_merge_mask_b"))
  367. pwrctrl->cpu_md_dvfs_erq_merge_mask_b = val;
  368. else if (!strcmp(cmd, "md1_ddr_en_dvfs_halt_mask_b"))
  369. pwrctrl->md1_ddr_en_dvfs_halt_mask_b = val;
  370. else if (!strcmp(cmd, "md2_ddr_en_dvfs_halt_mask_b"))
  371. pwrctrl->md2_ddr_en_dvfs_halt_mask_b = val;
  372. else if (!strcmp(cmd, "vsync_dvfs_halt_mask_b"))
  373. pwrctrl->vsync_dvfs_halt_mask_b = val;
  374. else if (!strcmp(cmd, "conn_ddr_en_mask_b"))
  375. pwrctrl->conn_ddr_en_mask_b = val;
  376. else if (!strcmp(cmd, "disp_req_mask_b"))
  377. pwrctrl->disp_req_mask_b = val;
  378. else if (!strcmp(cmd, "disp1_req_mask_b"))
  379. pwrctrl->disp1_req_mask_b = val;
  380. else if (!strcmp(cmd, "mfg_req_mask_b"))
  381. pwrctrl->mfg_req_mask_b = val;
  382. else if (!strcmp(cmd, "c2k_ps_rccif_wake_mask_b"))
  383. pwrctrl->c2k_ps_rccif_wake_mask_b = val;
  384. else if (!strcmp(cmd, "c2k_l1_rccif_wake_mask_b"))
  385. pwrctrl->c2k_l1_rccif_wake_mask_b = val;
  386. else if (!strcmp(cmd, "ps_c2k_rccif_wake_mask_b"))
  387. pwrctrl->ps_c2k_rccif_wake_mask_b = val;
  388. else if (!strcmp(cmd, "l1_c2k_rccif_wake_mask_b"))
  389. pwrctrl->l1_c2k_rccif_wake_mask_b = val;
  390. else if (!strcmp(cmd, "sdio_on_dvfs_req_mask_b"))
  391. pwrctrl->sdio_on_dvfs_req_mask_b = val;
  392. else if (!strcmp(cmd, "emi_boost_dvfs_req_mask_b"))
  393. pwrctrl->emi_boost_dvfs_req_mask_b = val;
  394. else if (!strcmp(cmd, "cpu_md_emi_dvfs_req_prot_dis"))
  395. pwrctrl->cpu_md_emi_dvfs_req_prot_dis = val;
  396. #if defined(CONFIG_ARCH_MT6797)
  397. else if (!strcmp(cmd, "disp_od_req_mask_b"))
  398. pwrctrl->disp_od_req_mask_b = val;
  399. #endif
  400. else if (!strcmp(cmd, "conn_mask_b"))
  401. pwrctrl->conn_mask_b = val;
  402. else if (!strcmp(cmd, "dsi0_ddr_en_mask_b"))
  403. pwrctrl->dsi0_ddr_en_mask_b = val;
  404. else if (!strcmp(cmd, "dsi1_ddr_en_mask_b"))
  405. pwrctrl->dsi1_ddr_en_mask_b = val;
  406. else if (!strcmp(cmd, "dpi_ddr_en_mask_b"))
  407. pwrctrl->dpi_ddr_en_mask_b = val;
  408. else if (!strcmp(cmd, "isp0_ddr_en_mask_b"))
  409. pwrctrl->isp0_ddr_en_mask_b = val;
  410. else if (!strcmp(cmd, "isp1_ddr_en_mask_b"))
  411. pwrctrl->isp1_ddr_en_mask_b = val;
  412. else if (!strcmp(cmd, "scp_req_mask_b"))
  413. pwrctrl->scp_req_mask_b = val;
  414. else if (!strcmp(cmd, "syspwreq_mask"))
  415. pwrctrl->syspwreq_mask = val;
  416. else if (!strcmp(cmd, "srclkenai_mask"))
  417. pwrctrl->srclkenai_mask = val;
  418. else if (!strcmp(cmd, "param1"))
  419. pwrctrl->param1 = val;
  420. else if (!strcmp(cmd, "param2"))
  421. pwrctrl->param2 = val;
  422. else if (!strcmp(cmd, "param3"))
  423. pwrctrl->param3 = val;
  424. else
  425. return -EINVAL;
  426. return count;
  427. }
  428. static ssize_t suspend_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  429. const char *buf, size_t count)
  430. {
  431. return store_pwr_ctrl(__spm_suspend.pwrctrl, buf, count);
  432. }
  433. #ifndef CONFIG_MTK_FPGA
  434. static ssize_t dpidle_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  435. const char *buf, size_t count)
  436. {
  437. return store_pwr_ctrl(__spm_dpidle.pwrctrl, buf, count);
  438. }
  439. static ssize_t sodi3_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  440. const char *buf, size_t count)
  441. {
  442. return store_pwr_ctrl(__spm_sodi3.pwrctrl, buf, count);
  443. }
  444. static ssize_t sodi_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  445. const char *buf, size_t count)
  446. {
  447. return store_pwr_ctrl(__spm_sodi.pwrctrl, buf, count);
  448. }
  449. static ssize_t mcdi_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  450. const char *buf, size_t count)
  451. {
  452. return 0;
  453. }
  454. #endif
  455. static ssize_t talking_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  456. const char *buf, size_t count)
  457. {
  458. #if 0
  459. return store_pwr_ctrl(__spm_talking.pwrctrl, buf, count);
  460. #else
  461. return 0;
  462. #endif
  463. }
  464. static ssize_t vcore_dvfs_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  465. const char *buf, size_t count)
  466. {
  467. return store_pwr_ctrl(__spm_vcore_dvfs.pwrctrl, buf, count);
  468. }
  469. /**************************************
  470. * ddren_debug_xxx Function
  471. **************************************/
  472. static ssize_t ddren_debug_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  473. {
  474. char *p = buf;
  475. p += sprintf(p, "PCM_REG13_DATA = 0x%x\n", spm_read(PCM_REG13_DATA));
  476. p += sprintf(p, "AP_STANBY_CON = 0x%x\n", spm_read(SPM_AP_STANDBY_CON));
  477. p += sprintf(p, "PCM_DEBUG_CON = 0x%x\n", spm_read(PCM_DEBUG_CON));
  478. p += sprintf(p, "PCM_PASR_DPD_2 = 0x%x\n", spm_read(SPM_PASR_DPD_2));
  479. BUG_ON(p - buf >= PAGE_SIZE);
  480. return p - buf;
  481. }
  482. static ssize_t ddren_debug_store(struct kobject *kobj, struct kobj_attribute *attr,
  483. const char *buf, size_t count)
  484. {
  485. u32 val, con;
  486. char cmd[32];
  487. unsigned long flags;
  488. if (sscanf(buf, "%31s %x", cmd, &val) != 2)
  489. return -EPERM;
  490. spm_debug("ddren_debug: cmd = %s, val = 0x%x\n", cmd, val);
  491. if (!strcmp(cmd, "ddr_en_sel")) {
  492. spin_lock_irqsave(&__spm_lock, flags);
  493. con = spm_read(SPM_AP_STANDBY_CON) & ~MD_DDR_EN_DBC_EN_LSB;
  494. spm_write(SPM_AP_STANDBY_CON, con | (!!val << 18));
  495. spin_unlock_irqrestore(&__spm_lock, flags);
  496. } else if (!strcmp(cmd, "md_ddr_en_out")) {
  497. spin_lock_irqsave(&__spm_lock, flags);
  498. __spm_dbgout_md_ddr_en(val);
  499. spin_unlock_irqrestore(&__spm_lock, flags);
  500. } else if (!strcmp(cmd, "mm_ddr_en_mask")) {
  501. spin_lock_irqsave(&__spm_lock, flags);
  502. spm_write(SPM_PASR_DPD_2, ~val & 0x1f);
  503. spin_unlock_irqrestore(&__spm_lock, flags);
  504. } else {
  505. return -EINVAL;
  506. }
  507. return count;
  508. }
  509. /**************************************
  510. * fm_suspend Function
  511. **************************************/
  512. static ssize_t fm_suspend_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  513. {
  514. char *p = buf;
  515. BUG_ON(p - buf >= PAGE_SIZE);
  516. return p - buf;
  517. }
  518. /**************************************
  519. * auto_suspend_resume_xxx Function
  520. **************************************/
  521. #if 0 /* FIXME */
  522. static ssize_t auto_suspend_resume_show(struct kobject *kobj, struct kobj_attribute *attr,
  523. char *buf)
  524. {
  525. char *p = buf;
  526. u8 i;
  527. p += sprintf(p, "auto_suspend_resume:%d times\n", 10);
  528. for (i = 0; i < 10; i++) {
  529. p += sprintf(p, "[%d]wakeup:0x%x,timer:0x%x,r13:0x%x,event=0x%x,flag=0x%x\n",
  530. __spm_suspend.wakestatus[i].log_index,
  531. __spm_suspend.wakestatus[i].r12,
  532. __spm_suspend.wakestatus[i].r12_ext,
  533. __spm_suspend.wakestatus[i].timer_out,
  534. __spm_suspend.wakestatus[i].r13,
  535. __spm_suspend.wakestatus[i].event_reg,
  536. __spm_suspend.wakestatus[i].debug_flag);
  537. if (0x90100000 != __spm_suspend.wakestatus[i].event_reg)
  538. p += sprintf(p, "SLEEP_ABORT\n");
  539. else if (0xf != (__spm_suspend.wakestatus[i].debug_flag & 0xF))
  540. p += sprintf(p, "NOT_DEEP_SLEEP\n");
  541. else
  542. p += sprintf(p, "SLEEP_PASS\n");
  543. }
  544. slp_set_auto_suspend_wakelock(0);
  545. BUG_ON(p - buf >= PAGE_SIZE);
  546. return p - buf;
  547. }
  548. static ssize_t auto_suspend_resume_store(struct kobject *kobj, struct kobj_attribute *attr,
  549. const char *buf, size_t count)
  550. {
  551. u32 val, pcm_sec;
  552. if (sscanf(buf, "%d %d", &val, &pcm_sec) != 2) {
  553. spm_debug("auto_suspend_resume parameter fail\n");
  554. return -EPERM;
  555. }
  556. spm_debug("auto_suspend_resume val = %d, pcm_sec = %d\n", val, pcm_sec);
  557. __spm_suspend.pwrctrl->timer_val_cust = pcm_sec * 32768;
  558. slp_create_auto_suspend_resume_thread();
  559. slp_start_auto_suspend_resume_timer(val);
  560. return count;
  561. }
  562. #endif /* 0 */
  563. /**************************************
  564. * Init Function
  565. **************************************/
  566. /* DEFINE_ATTR_RO(suspend_pcm); */
  567. /* DEFINE_ATTR_RO(dpidle_pcm); */
  568. /* DEFINE_ATTR_RO(sodi3_pcm); */
  569. /* DEFINE_ATTR_RO(sodi_pcm); */
  570. /* DEFINE_ATTR_RO(mcdi_pcm); */
  571. /* DEFINE_ATTR_RO(talking_pcm); */
  572. /* DEFINE_ATTR_RO(ddrdfs_pcm); */
  573. DEFINE_ATTR_RW(suspend_ctrl);
  574. #ifndef CONFIG_MTK_FPGA
  575. DEFINE_ATTR_RW(dpidle_ctrl);
  576. DEFINE_ATTR_RW(sodi3_ctrl);
  577. DEFINE_ATTR_RW(sodi_ctrl);
  578. DEFINE_ATTR_RW(mcdi_ctrl);
  579. #endif
  580. DEFINE_ATTR_RW(talking_ctrl);
  581. DEFINE_ATTR_RW(vcore_dvfs_ctrl);
  582. DEFINE_ATTR_RW(ddren_debug);
  583. DEFINE_ATTR_RO(fm_suspend);
  584. /* DEFINE_ATTR_RW(auto_suspend_resume); */
  585. static struct attribute *spm_attrs[] = {
  586. /* for spm_lp_scen.pcmdesc */
  587. /* __ATTR_OF(suspend_pcm), */
  588. /* __ATTR_OF(dpidle_pcm), */
  589. /* __ATTR_OF(sodi3_pcm), */
  590. /* __ATTR_OF(sodi_pcm), */
  591. /* __ATTR_OF(mcdi_pcm), */
  592. /* __ATTR_OF(talking_pcm), */
  593. /* __ATTR_OF(vcore_dvfs_pcm), */
  594. /* for spm_lp_scen.pwrctrl */
  595. __ATTR_OF(suspend_ctrl),
  596. #ifndef CONFIG_MTK_FPGA
  597. __ATTR_OF(dpidle_ctrl),
  598. __ATTR_OF(sodi3_ctrl),
  599. __ATTR_OF(sodi_ctrl),
  600. __ATTR_OF(mcdi_ctrl),
  601. #endif
  602. __ATTR_OF(talking_ctrl),
  603. __ATTR_OF(vcore_dvfs_ctrl),
  604. /* other debug interface */
  605. __ATTR_OF(ddren_debug),
  606. __ATTR_OF(fm_suspend),
  607. /* __ATTR_OF(auto_suspend_resume), */
  608. /* must */
  609. NULL,
  610. };
  611. static struct attribute_group spm_attr_group = {
  612. .name = "spm",
  613. .attrs = spm_attrs,
  614. };
  615. int spm_fs_init(void)
  616. {
  617. int r;
  618. /* create /sys/power/spm/xxx */
  619. r = sysfs_create_group(power_kobj, &spm_attr_group);
  620. if (r)
  621. spm_err("FAILED TO CREATE /sys/power/spm (%d)\n", r);
  622. return r;
  623. }
  624. MODULE_DESCRIPTION("SPM-FS Driver v0.1");