mt_spm_dpidle.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/spinlock.h>
  5. #include <linux/delay.h>
  6. #include <linux/of_fdt.h>
  7. #ifdef CONFIG_OF
  8. #include <linux/of.h>
  9. #include <linux/of_irq.h>
  10. #include <linux/of_address.h>
  11. #endif
  12. #include <mach/irqs.h>
  13. #include <mach/mt_secure_api.h>
  14. #if defined(CONFIG_MTK_SYS_CIRQ)
  15. #include <mt-plat/mt_cirq.h>
  16. #endif
  17. #include "mt_spm_idle.h"
  18. #include "mt_cpuidle.h"
  19. #ifdef CONFIG_MTK_WD_KICKER
  20. #include <mach/wd_api.h>
  21. #endif
  22. #include <mach/mt_gpt.h>
  23. #include <mt-plat/mt_ccci_common.h>
  24. #include "mt_spm_misc.h"
  25. #include <mt-plat/upmu_common.h>
  26. #include "mt_spm_dpidle.h"
  27. #include "mt_spm_internal.h"
  28. #include "mt_spm_pmic_wrap.h"
  29. #include <mt-plat/mt_io.h>
  30. /*
  31. * only for internal debug
  32. */
  33. #define DPIDLE_TAG "[DP] "
  34. #define dpidle_dbg(fmt, args...) pr_debug(DPIDLE_TAG fmt, ##args)
  35. #define SPM_BYPASS_SYSPWREQ 0
  36. #define WAKE_SRC_FOR_MD32 0
  37. #define I2C_CHANNEL 2
  38. #define spm_is_wakesrc_invalid(wakesrc) (!!((u32)(wakesrc) & 0xc0003803))
  39. #define CA70_BUS_CONFIG 0xF020002C /* (CA7MCUCFG_BASE + 0x1C) - 0x1020011c */
  40. #define CA71_BUS_CONFIG 0xF020022C /* (CA7MCUCFG_BASE + 0x1C) - 0x1020011c */
  41. #ifdef CONFIG_MTK_RAM_CONSOLE
  42. #define SPM_AEE_RR_REC 1
  43. #else
  44. #define SPM_AEE_RR_REC 0
  45. #endif
  46. #define SPM_USE_TWAM_DEBUG 0
  47. #define DPIDLE_LOG_PRINT_TIMEOUT_CRITERIA 20
  48. #define DPIDLE_LOG_DISCARD_CRITERIA 5000 /* ms */
  49. #define reg_read(addr) __raw_readl(IOMEM(addr))
  50. #if defined(CONFIG_OF)
  51. #define MCUCFG_NODE "mediatek,mcucfg"
  52. static unsigned long mcucfg_base;
  53. static unsigned long mcucfg_phys_base;
  54. #undef MCUCFG_BASE
  55. #define MCUCFG_BASE (mcucfg_base)
  56. #else /* #if defined (CONFIG_OF) */
  57. #undef MCUCFG_BASE
  58. #define MCUCFG_BASE 0xF0200000 /* 0x1020_0000 */
  59. #endif /* #if defined (CONFIG_OF) */
  60. /* MCUCFG registers */
  61. #define MP0_AXI_CONFIG (MCUCFG_BASE + 0x2C)
  62. #define MP0_AXI_CONFIG_PHYS (mcucfg_phys_base + 0x2C)
  63. #define MP1_AXI_CONFIG (MCUCFG_BASE + 0x22C)
  64. #define MP1_AXI_CONFIG_PHYS (mcucfg_phys_base + 0x22C)
  65. #define MP2_AXI_CONFIG (MCUCFG_BASE + 0x20C)
  66. #define MP2_AXI_CONFIG_PHYS (mcucfg_phys_base + 0x20C)
  67. #define ACINACTM (1 << 4)
  68. #define ACINACTM_MP2 (0x11)
  69. #if defined(CONFIG_ARM_PSCI) || defined(CONFIG_MTK_PSCI)
  70. #include <mach/mt_secure_api.h>
  71. #define MCUSYS_SMC_WRITE(addr, val) mcusys_smc_write_phy(addr##_PHYS, val)
  72. #else
  73. #define MCUSYS_SMC_WRITE(addr, val) mcusys_smc_write(addr, val)
  74. #endif
  75. #if SPM_AEE_RR_REC
  76. enum spm_deepidle_step {
  77. SPM_DEEPIDLE_ENTER = 0x00000001,
  78. SPM_DEEPIDLE_ENTER_UART_SLEEP = 0x00000003,
  79. SPM_DEEPIDLE_ENTER_WFI = 0x000000ff,
  80. SPM_DEEPIDLE_LEAVE_WFI = 0x000001ff,
  81. SPM_DEEPIDLE_ENTER_UART_AWAKE = 0x000003ff,
  82. SPM_DEEPIDLE_LEAVE = 0x000007ff
  83. };
  84. #endif
  85. /* please put firmware to vendor/mediatek/proprietary/hardware/spm/mtxxxx/ */
  86. #if 0
  87. /**********************************************************
  88. * PCM code for deep idle
  89. **********************************************************/
  90. static const u32 dpidle_binary[] = {
  91. 0x81f48407, 0x80328400, 0x80318400, 0xe8208000, 0x10006354, 0xffff1fff,
  92. 0xe8208000, 0x10001108, 0x00000000, 0x1b80001f, 0x20000034, 0xe8208000,
  93. 0x10006b04, 0x00000000, 0xc28032c0, 0x1290041f, 0x1b00001f, 0x7ffcf7ff,
  94. 0xf0000000, 0x17c07c1f, 0x1b00001f, 0x3ffce7ff, 0x1b80001f, 0x20000004,
  95. 0xd820038c, 0x17c07c1f, 0xd0000620, 0x17c07c1f, 0xe8208000, 0x10001108,
  96. 0x00000002, 0x1b80001f, 0x20000034, 0xe8208000, 0x10006354, 0xffffffff,
  97. 0xe8208000, 0x10006b04, 0x00000001, 0xc28032c0, 0x1290841f, 0xa0118400,
  98. 0xa0128400, 0xe8208000, 0x10006b04, 0x00000004, 0x1b00001f, 0x3ffcefff,
  99. 0xa1d48407, 0xf0000000, 0x17c07c1f, 0x81489801, 0xd80007c5, 0x17c07c1f,
  100. 0x81419801, 0xd80007c5, 0x17c07c1f, 0x1a00001f, 0x10006604, 0xe2200004,
  101. 0xc0c033c0, 0x10807c1f, 0x81411801, 0xd80009e5, 0x17c07c1f, 0x18c0001f,
  102. 0x1000f644, 0x1910001f, 0x1000f644, 0xa1140404, 0xe0c00004, 0x1b80001f,
  103. 0x20000208, 0x18c0001f, 0x10006240, 0xe0e00016, 0xe0e0001e, 0xe0e0000e,
  104. 0xe0e0000f, 0x81481801, 0xd8200d25, 0x17c07c1f, 0x18c0001f, 0x10004828,
  105. 0x1910001f, 0x10004828, 0x89000004, 0x3fffffff, 0xe0c00004, 0x18c0001f,
  106. 0x100041dc, 0x1910001f, 0x100041dc, 0x89000004, 0x3fffffff, 0xe0c00004,
  107. 0x18c0001f, 0x1000f63c, 0x1910001f, 0x1000f63c, 0x89000004, 0xfffffff9,
  108. 0xe0c00004, 0xc28032c0, 0x1294841f, 0x803e0400, 0x1b80001f, 0x20000050,
  109. 0x803e8400, 0x803f0400, 0x803f8400, 0x1b80001f, 0x20000208, 0x803d0400,
  110. 0x1b80001f, 0x20000034, 0x80380400, 0xa01d8400, 0x1b80001f, 0x20000034,
  111. 0x803d8400, 0x803b0400, 0x1b80001f, 0x20000158, 0x81481801, 0xd8201005,
  112. 0x17c07c1f, 0xa01d8400, 0x80340400, 0x81481801, 0xd8201145, 0x17c07c1f,
  113. 0x18c0001f, 0x1000f698, 0x1910001f, 0x1000f698, 0xa1120404, 0xe0c00004,
  114. 0x80310400, 0x81481801, 0xd8201265, 0x17c07c1f, 0xe8208000, 0x10000044,
  115. 0x00000200, 0xd00012c0, 0x17c07c1f, 0xe8208000, 0x10000044, 0x00000100,
  116. 0xe8208000, 0x10000004, 0x00000002, 0x1b80001f, 0x20000068, 0x1b80001f,
  117. 0x2000000a, 0x81481801, 0xd82017a5, 0x17c07c1f, 0x18c0001f, 0x1000f640,
  118. 0x1910001f, 0x1000f640, 0x81200404, 0xe0c00004, 0xa1000404, 0xe0c00004,
  119. 0x18c0001f, 0x10004828, 0x1910001f, 0x10004828, 0xa9000004, 0xc0000000,
  120. 0xe0c00004, 0x18c0001f, 0x100041dc, 0x1910001f, 0x100041dc, 0xa9000004,
  121. 0xc0000000, 0xe0c00004, 0x18c0001f, 0x1000f63c, 0x1910001f, 0x1000f63c,
  122. 0xa9000004, 0x00000006, 0xe0c00004, 0x18c0001f, 0x10006240, 0xe0e0000d,
  123. 0x81fa0407, 0x18c0001f, 0x100040f4, 0x1910001f, 0x100040f4, 0xa11c8404,
  124. 0xe0c00004, 0x813c8404, 0xe0c00004, 0x1b80001f, 0x20000100, 0x81f08407,
  125. 0xe8208000, 0x10006354, 0xfff01b47, 0xa1d80407, 0xa1dc0407, 0xa1de8407,
  126. 0xa1df0407, 0xc28032c0, 0x1291041f, 0x1b00001f, 0xbffce7ff, 0xf0000000,
  127. 0x17c07c1f, 0x1b80001f, 0x20000fdf, 0x1a50001f, 0x10006608, 0x80c9a401,
  128. 0x810aa401, 0x10918c1f, 0xa0939002, 0x80ca2401, 0x810ba401, 0xa09c0c02,
  129. 0xa0979002, 0x8080080d, 0xd8201e42, 0x17c07c1f, 0x1b00001f, 0x3ffce7ff,
  130. 0x1b80001f, 0x20000004, 0xd80027ec, 0x17c07c1f, 0x1b00001f, 0xbffce7ff,
  131. 0xd00027e0, 0x17c07c1f, 0x81f80407, 0x81fc0407, 0x81fe8407, 0x81ff0407,
  132. 0x1880001f, 0x10006320, 0xc0c02b60, 0xe080000f, 0xd8001d03, 0x17c07c1f,
  133. 0xe080001f, 0xa1da0407, 0x81481801, 0xd82020c5, 0x17c07c1f, 0xe8208000,
  134. 0x10000048, 0x00000300, 0xd0002120, 0x17c07c1f, 0xe8208000, 0x10000048,
  135. 0x00000100, 0xe8208000, 0x10000004, 0x00000002, 0x1b80001f, 0x20000068,
  136. 0xa0110400, 0x81481801, 0xd8202325, 0x17c07c1f, 0x18c0001f, 0x1000f698,
  137. 0x1910001f, 0x1000f698, 0x81320404, 0xe0c00004, 0x803d8400, 0xa0140400,
  138. 0xa01b0400, 0xa0180400, 0xa01d0400, 0xa01f8400, 0xa01f0400, 0xa01e8400,
  139. 0xa01e0400, 0x1b80001f, 0x20000104, 0x81411801, 0xd8002605, 0x17c07c1f,
  140. 0x18c0001f, 0x10006240, 0xc0c02aa0, 0x17c07c1f, 0x18c0001f, 0x1000f644,
  141. 0x1910001f, 0x1000f644, 0x81340404, 0xe0c00004, 0x81489801, 0xd8002765,
  142. 0x17c07c1f, 0x81419801, 0xd8002765, 0x17c07c1f, 0x1a00001f, 0x10006604,
  143. 0xe2200005, 0xc0c033c0, 0x10807c1f, 0xc28032c0, 0x1291841f, 0x1b00001f,
  144. 0x7ffcf7ff, 0xf0000000, 0x17c07c1f, 0x1900001f, 0x10006830, 0xe1000003,
  145. 0xf0000000, 0x17c07c1f, 0xe0f07f16, 0x1380201f, 0xe0f07f1e, 0x1380201f,
  146. 0xe0f07f0e, 0x1b80001f, 0x20000104, 0xe0f07f0c, 0xe0f07f0d, 0xe0f07e0d,
  147. 0xe0f07c0d, 0xe0f0780d, 0xe0f0700d, 0xf0000000, 0x17c07c1f, 0xe0f07f0d,
  148. 0xe0f07f0f, 0xe0f07f1e, 0xe0f07f12, 0xf0000000, 0x17c07c1f, 0xa1d08407,
  149. 0x1b80001f, 0x20000080, 0x80eab401, 0x1a00001f, 0x10006814, 0xe2000003,
  150. 0xf0000000, 0x17c07c1f, 0x81429801, 0xd8002e45, 0x17c07c1f, 0x18c0001f,
  151. 0x65930005, 0x1900001f, 0x10006830, 0xe1000003, 0xe8208000, 0x10006834,
  152. 0x00000000, 0xe8208000, 0x10006834, 0x00000001, 0xf0000000, 0x17c07c1f,
  153. 0xa1d10407, 0x1b80001f, 0x20000020, 0xf0000000, 0x17c07c1f, 0xa1d00407,
  154. 0x1b80001f, 0x20000100, 0x80ea3401, 0x1a00001f, 0x10006814, 0xe2000003,
  155. 0xf0000000, 0x17c07c1f, 0xe0e0000f, 0xe0e0000e, 0xe0e0001e, 0xe0e00012,
  156. 0xf0000000, 0x17c07c1f, 0xd800324a, 0x17c07c1f, 0xe0e00016, 0xe0e0001e,
  157. 0x1380201f, 0xe0e0001f, 0xe0e0001d, 0xe0e0000d, 0xd0003280, 0x17c07c1f,
  158. 0xe0e03301, 0xe0e03101, 0xf0000000, 0x17c07c1f, 0x18c0001f, 0x10006b6c,
  159. 0x1910001f, 0x10006b6c, 0xa1002804, 0xe0c00004, 0xf0000000, 0x17c07c1f,
  160. 0x18d0001f, 0x10006604, 0x10cf8c1f, 0xd82033c3, 0x17c07c1f, 0xf0000000,
  161. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  162. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  163. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  164. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  165. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  166. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  167. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  168. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  169. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  170. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  171. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  172. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  173. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  174. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  175. 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
  176. 0x17c07c1f, 0x17c07c1f, 0x1840001f, 0x00000001, 0x1990001f, 0x10006b08,
  177. 0xe8208000, 0x10006b6c, 0x00000000, 0x1b00001f, 0x2ffce7ff, 0x1b80001f,
  178. 0x500f0000, 0xe8208000, 0x10006354, 0xfff01b47, 0xc0c02e80, 0x81401801,
  179. 0xd8004765, 0x17c07c1f, 0x81f60407, 0x18c0001f, 0x10006200, 0xc0c063c0,
  180. 0x12807c1f, 0xe8208000, 0x1000625c, 0x00000001, 0x1890001f, 0x1000625c,
  181. 0x81040801, 0xd8204344, 0x17c07c1f, 0xc0c063c0, 0x1280041f, 0x18c0001f,
  182. 0x10006208, 0xc0c063c0, 0x12807c1f, 0x1b80001f, 0x20000003, 0xe8208000,
  183. 0x10006248, 0x00000000, 0x1890001f, 0x10006248, 0x81040801, 0xd8004544,
  184. 0x17c07c1f, 0xc0c063c0, 0x1280041f, 0x18c0001f, 0x10006290, 0xe0e0004f,
  185. 0xc0c063c0, 0x1280041f, 0xe8208000, 0x10006404, 0x00003101, 0xc28032c0,
  186. 0x1292041f, 0x1b00001f, 0x2ffce7ff, 0x1b80001f, 0x30000004, 0x8880000c,
  187. 0x2ffce7ff, 0xd8005dc2, 0x17c07c1f, 0xe8208000, 0x10006294, 0x0003ffff,
  188. 0x18c0001f, 0x10006294, 0xe0e03fff, 0xe0e003ff, 0x81449801, 0xd8004c65,
  189. 0x17c07c1f, 0x1a00001f, 0x10006604, 0xe2200006, 0xc0c033c0, 0x17c07c1f,
  190. 0x1a00001f, 0x10006604, 0x81491801, 0xd8004c05, 0x17c07c1f, 0xc28032c0,
  191. 0x1294041f, 0xe2200003, 0xc0c06820, 0x12807c1f, 0xc0c033c0, 0x17c07c1f,
  192. 0xd0004c60, 0x17c07c1f, 0xe2200003, 0xc0c033c0, 0x17c07c1f, 0x81489801,
  193. 0xd8204f45, 0x17c07c1f, 0x81419801, 0xd8004f45, 0x17c07c1f, 0x1a00001f,
  194. 0x10006604, 0xe2200000, 0xc0c033c0, 0x17c07c1f, 0xc0c06c00, 0x17c07c1f,
  195. 0xe2200001, 0xc0c033c0, 0x17c07c1f, 0xc0c06c00, 0x17c07c1f, 0xe2200005,
  196. 0xc0c033c0, 0x17c07c1f, 0xc0c06c00, 0x17c07c1f, 0xc0c06760, 0x17c07c1f,
  197. 0xa1d38407, 0xa1d98407, 0xa0108400, 0xa0120400, 0xa0148400, 0xa0150400,
  198. 0xa0158400, 0xa01b8400, 0xa01c0400, 0xa01c8400, 0xa0188400, 0xa0190400,
  199. 0xa0198400, 0xe8208000, 0x10006310, 0x0b1600f8, 0x1b00001f, 0xbffce7ff,
  200. 0x1b80001f, 0x90100000, 0x1240301f, 0x80c28001, 0xc8c00003, 0x17c07c1f,
  201. 0x80c10001, 0xc8c00663, 0x17c07c1f, 0x1b00001f, 0x2ffce7ff, 0x18c0001f,
  202. 0x10006294, 0xe0e007fe, 0xe0e00ffc, 0xe0e01ff8, 0xe0e03ff0, 0xe0e03fe0,
  203. 0xe0e03fc0, 0x1b80001f, 0x20000020, 0xe8208000, 0x10006294, 0x0003ffc0,
  204. 0xe8208000, 0x10006294, 0x0003fc00, 0x80388400, 0x80390400, 0x80398400,
  205. 0x1b80001f, 0x20000300, 0x803b8400, 0x803c0400, 0x803c8400, 0x1b80001f,
  206. 0x20000300, 0x80348400, 0x80350400, 0x80358400, 0x1b80001f, 0x20000104,
  207. 0x80308400, 0x80320400, 0x81f38407, 0x81f98407, 0x81f90407, 0x81f40407,
  208. 0x81489801, 0xd8205aa5, 0x17c07c1f, 0x81419801, 0xd8005aa5, 0x17c07c1f,
  209. 0x1a00001f, 0x10006604, 0xe2200001, 0xc0c033c0, 0x17c07c1f, 0xc0c06c00,
  210. 0x17c07c1f, 0xe2200000, 0xc0c033c0, 0x17c07c1f, 0xc0c06c00, 0x17c07c1f,
  211. 0xe2200004, 0xc0c033c0, 0x17c07c1f, 0xc0c06c00, 0x17c07c1f, 0x81449801,
  212. 0xd8005dc5, 0x17c07c1f, 0x1a00001f, 0x10006604, 0x81491801, 0xd8005c85,
  213. 0x17c07c1f, 0xe2200002, 0xc0c06820, 0x1280041f, 0xc0c033c0, 0x17c07c1f,
  214. 0xd0005ce0, 0x17c07c1f, 0xe2200002, 0xc0c033c0, 0x17c07c1f, 0x1a00001f,
  215. 0x10006604, 0xe2200007, 0xc0c033c0, 0x17c07c1f, 0x1b80001f, 0x200016a8,
  216. 0x81401801, 0xd8006325, 0x17c07c1f, 0xe8208000, 0x10006404, 0x00000101,
  217. 0x18c0001f, 0x10006290, 0x1212841f, 0xc0c06540, 0x12807c1f, 0xc0c06540,
  218. 0x1280041f, 0x18c0001f, 0x10006208, 0x1212841f, 0xc0c06540, 0x12807c1f,
  219. 0xe8208000, 0x10006248, 0x00000001, 0x1890001f, 0x10006248, 0x81040801,
  220. 0xd8206064, 0x17c07c1f, 0xc0c06540, 0x1280041f, 0x18c0001f, 0x10006200,
  221. 0x1212841f, 0xc0c06540, 0x12807c1f, 0xe8208000, 0x1000625c, 0x00000000,
  222. 0x1890001f, 0x1000625c, 0x81040801, 0xd8006244, 0x17c07c1f, 0xc0c06540,
  223. 0x1280041f, 0x19c0001f, 0x61415820, 0x1ac0001f, 0x55aa55aa, 0xf0000000,
  224. 0xd800646a, 0x17c07c1f, 0xe2e0004f, 0xe2e0006f, 0xe2e0002f, 0xd820650a,
  225. 0x17c07c1f, 0xe2e0002e, 0xe2e0003e, 0xe2e00032, 0xf0000000, 0x17c07c1f,
  226. 0xd800660a, 0x17c07c1f, 0xe2e00036, 0xe2e0003e, 0x1380201f, 0xe2e0003c,
  227. 0xd820672a, 0x17c07c1f, 0x1380201f, 0xe2e0007c, 0x1b80001f, 0x20000003,
  228. 0xe2e0005c, 0xe2e0004c, 0xe2e0004d, 0xf0000000, 0x17c07c1f, 0xa1d40407,
  229. 0x1391841f, 0xa1d90407, 0x1392841f, 0xf0000000, 0x17c07c1f, 0xe8208000,
  230. 0x10059c14, 0x00000002, 0xe8208000, 0x10059c20, 0x00000001, 0xe8208000,
  231. 0x10059c04, 0x000000d6, 0x1a00001f, 0x10059c00, 0xd8206aea, 0x17c07c1f,
  232. 0xe2200088, 0xe2200002, 0xe8208000, 0x10059c24, 0x00000001, 0x1b80001f,
  233. 0x20000158, 0xd0006bc0, 0x17c07c1f, 0xe2200088, 0xe2200000, 0xe8208000,
  234. 0x10059c24, 0x00000001, 0x1b80001f, 0x20000158, 0xf0000000, 0x17c07c1f,
  235. 0x1880001f, 0x0000001d, 0x814a1801, 0xd8006e65, 0x17c07c1f, 0x81499801,
  236. 0xd8006f65, 0x17c07c1f, 0x814a9801, 0xd8007065, 0x17c07c1f, 0x18d0001f,
  237. 0x40000000, 0x18d0001f, 0x40000000, 0xd8006d62, 0x00a00402, 0xd0007160,
  238. 0x17c07c1f, 0x18d0001f, 0x40000000, 0x18d0001f, 0x80000000, 0xd8006e62,
  239. 0x00a00402, 0xd0007160, 0x17c07c1f, 0x18d0001f, 0x40000000, 0x18d0001f,
  240. 0x60000000, 0xd8006f62, 0x00a00402, 0xd0007160, 0x17c07c1f, 0x18d0001f,
  241. 0x40000000, 0x18d0001f, 0xc0000000, 0xd8007062, 0x00a00402, 0xd0007160,
  242. 0x17c07c1f, 0xf0000000, 0x17c07c1f
  243. };
  244. static struct pcm_desc dpidle_pcm = {
  245. .version = "pcm_deepidle_v19.15_20140731-exp1-no_6311_low_power_mode",
  246. .base = dpidle_binary,
  247. .size = 909,
  248. .sess = 2,
  249. .replace = 0,
  250. .vec0 = EVENT_VEC(11, 1, 0, 0), /* FUNC_26M_WAKEUP */
  251. .vec1 = EVENT_VEC(12, 1, 0, 20), /* FUNC_26M_SLEEP */
  252. .vec2 = EVENT_VEC(30, 1, 0, 51), /* FUNC_APSRC_WAKEUP */
  253. .vec3 = EVENT_VEC(31, 1, 0, 217), /* FUNC_APSRC_SLEEP */
  254. };
  255. #endif
  256. static struct pwr_ctrl dpidle_ctrl = {
  257. .wake_src = WAKE_SRC_FOR_DPIDLE,
  258. .wake_src_md32 = WAKE_SRC_FOR_MD32,
  259. .r0_ctrl_en = 1,
  260. .r7_ctrl_en = 1,
  261. .infra_dcm_lock = 1,
  262. .wfi_op = WFI_OP_AND,
  263. /* SPM_AP_STANDBY_CON */
  264. .mp0top_idle_mask = 0,
  265. .mp1top_idle_mask = 0,
  266. .mcusys_idle_mask = 0,
  267. .md_ddr_dbc_en = 0,
  268. .md1_req_mask_b = 1,
  269. .md2_req_mask_b = 0,
  270. #if defined(CONFIG_ARCH_MT6755)
  271. .scp_req_mask_b = 0, /* bit 21 */
  272. #elif defined(CONFIG_ARCH_MT6797)
  273. .scp_req_mask_b = 1, /* bit 21 */
  274. #endif
  275. .lte_mask_b = 0,
  276. .md_apsrc1_sel = 0,
  277. .md_apsrc0_sel = 0,
  278. .conn_mask_b = 1,
  279. .conn_apsrc_sel = 0,
  280. /* SPM_SRC_REQ */
  281. .spm_apsrc_req = 0,
  282. .spm_f26m_req = 0,
  283. .spm_lte_req = 0,
  284. .spm_infra_req = 0,
  285. .spm_vrf18_req = 0,
  286. .spm_dvfs_req = 0,
  287. .spm_dvfs_force_down = 0,
  288. .spm_ddren_req = 0,
  289. .cpu_md_dvfs_sop_force_on = 0,
  290. /* SPM_SRC_MASK */
  291. .ccif0_to_md_mask_b = 1,
  292. .ccif0_to_ap_mask_b = 1,
  293. .ccif1_to_md_mask_b = 1,
  294. .ccif1_to_ap_mask_b = 1,
  295. .ccifmd_md1_event_mask_b = 1,
  296. .ccifmd_md2_event_mask_b = 1,
  297. .vsync_mask_b = 0, /* 5bit */
  298. .md_srcclkena_0_infra_mask_b = 0,
  299. .md_srcclkena_1_infra_mask_b = 0,
  300. .conn_srcclkena_infra_mask_b = 0,
  301. .md32_srcclkena_infra_mask_b = 0,
  302. .srcclkeni_infra_mask_b = 0,
  303. .md_apsrcreq_0_infra_mask_b = 1,
  304. .md_apsrcreq_1_infra_mask_b = 0,
  305. .conn_apsrcreq_infra_mask_b = 1,
  306. #if defined(CONFIG_ARCH_MT6755)
  307. .md32_apsrcreq_infra_mask_b = 0,
  308. #elif defined(CONFIG_ARCH_MT6797)
  309. .md32_apsrcreq_infra_mask_b = 1,
  310. #endif
  311. .md_ddr_en_0_mask_b = 1,
  312. .md_ddr_en_1_mask_b = 0,
  313. .md_vrf18_req_0_mask_b = 1,
  314. .md_vrf18_req_1_mask_b = 0,
  315. .emi_bw_dvfs_req_mask = 1,
  316. .md_srcclkena_0_dvfs_req_mask_b = 0,
  317. .md_srcclkena_1_dvfs_req_mask_b = 0,
  318. .conn_srcclkena_dvfs_req_mask_b = 0,
  319. /* SPM_SRC2_MASK */
  320. .dvfs_halt_mask_b = 0x1f, /* 5bit */
  321. .vdec_req_mask_b = 0,
  322. .gce_req_mask_b = 0,
  323. .cpu_md_dvfs_erq_merge_mask_b = 0,
  324. .md1_ddr_en_dvfs_halt_mask_b = 0,
  325. .md2_ddr_en_dvfs_halt_mask_b = 0,
  326. .vsync_dvfs_halt_mask_b = 0, /* 5bit */
  327. .conn_ddr_en_mask_b = 1,
  328. .disp_req_mask_b = 0,
  329. .disp1_req_mask_b = 0,
  330. .mfg_req_mask_b = 0,
  331. .c2k_ps_rccif_wake_mask_b = 1,
  332. .c2k_l1_rccif_wake_mask_b = 1,
  333. .ps_c2k_rccif_wake_mask_b = 1,
  334. .l1_c2k_rccif_wake_mask_b = 1,
  335. .sdio_on_dvfs_req_mask_b = 0,
  336. .emi_boost_dvfs_req_mask_b = 0,
  337. .cpu_md_emi_dvfs_req_prot_dis = 0,
  338. #if defined(CONFIG_ARCH_MT6797)
  339. .disp_od_req_mask_b = 0, /* bit 27, set 0 for deepidle */
  340. #endif
  341. /* SPM_CLK_CON */
  342. .srclkenai_mask = 1,
  343. .mp1_cpu0_wfi_en = 1,
  344. .mp1_cpu1_wfi_en = 1,
  345. .mp1_cpu2_wfi_en = 1,
  346. .mp1_cpu3_wfi_en = 1,
  347. .mp0_cpu0_wfi_en = 1,
  348. .mp0_cpu1_wfi_en = 1,
  349. .mp0_cpu2_wfi_en = 1,
  350. .mp0_cpu3_wfi_en = 1,
  351. #if SPM_BYPASS_SYSPWREQ
  352. .syspwreq_mask = 1,
  353. #endif
  354. };
  355. struct spm_lp_scen __spm_dpidle = {
  356. /* .pcmdesc = &dpidle_pcm, */
  357. .pwrctrl = &dpidle_ctrl,
  358. };
  359. static unsigned int dpidle_log_discard_cnt;
  360. static unsigned int dpidle_log_print_prev_time;
  361. static void spm_trigger_wfi_for_dpidle(struct pwr_ctrl *pwrctrl)
  362. {
  363. u32 v0, v1;
  364. #if defined(CONFIG_ARCH_MT6797)
  365. u32 v2;
  366. #endif
  367. if (is_cpu_pdn(pwrctrl->pcm_flags)) {
  368. mt_cpu_dormant(CPU_DEEPIDLE_MODE);
  369. } else {
  370. /* backup MPx_AXI_CONFIG */
  371. v0 = reg_read(MP0_AXI_CONFIG);
  372. v1 = reg_read(MP1_AXI_CONFIG);
  373. #if defined(CONFIG_ARCH_MT6797)
  374. v2 = reg_read(MP2_AXI_CONFIG);
  375. MCUSYS_SMC_WRITE(MP2_AXI_CONFIG, v2 | ACINACTM_MP2);
  376. #endif
  377. /* disable snoop function */
  378. MCUSYS_SMC_WRITE(MP0_AXI_CONFIG, v0 | ACINACTM);
  379. MCUSYS_SMC_WRITE(MP1_AXI_CONFIG, v1 | ACINACTM);
  380. #if defined(CONFIG_ARCH_MT6797)
  381. v2 = reg_read(MP2_AXI_CONFIG);
  382. MCUSYS_SMC_WRITE(MP2_AXI_CONFIG, v2 | ACINACTM_MP2);
  383. #endif
  384. dpidle_dbg("enter legacy WFI, MP0_AXI_CONFIG=0x%x, MP1_AXI_CONFIG=0x%x\n",
  385. reg_read(MP0_AXI_CONFIG), reg_read(MP1_AXI_CONFIG));
  386. wfi_with_sync();
  387. /* restore MP0_AXI_CONFIG */
  388. MCUSYS_SMC_WRITE(MP0_AXI_CONFIG, v0);
  389. MCUSYS_SMC_WRITE(MP1_AXI_CONFIG, v1);
  390. #if defined(CONFIG_ARCH_MT6797)
  391. MCUSYS_SMC_WRITE(MP2_AXI_CONFIG, v2);
  392. #endif
  393. dpidle_dbg("exit legacy WFI, MP0_AXI_CONFIG=0x%x, MP1_AXI_CONFIG=0x%x\n",
  394. reg_read(MP0_AXI_CONFIG), reg_read(MP1_AXI_CONFIG));
  395. }
  396. }
  397. /*
  398. * wakesrc: WAKE_SRC_XXX
  399. * enable : enable or disable @wakesrc
  400. * replace: if true, will replace the default setting
  401. */
  402. int spm_set_dpidle_wakesrc(u32 wakesrc, bool enable, bool replace)
  403. {
  404. unsigned long flags;
  405. if (spm_is_wakesrc_invalid(wakesrc))
  406. return -EINVAL;
  407. spin_lock_irqsave(&__spm_lock, flags);
  408. if (enable) {
  409. if (replace)
  410. __spm_dpidle.pwrctrl->wake_src = wakesrc;
  411. else
  412. __spm_dpidle.pwrctrl->wake_src |= wakesrc;
  413. } else {
  414. if (replace)
  415. __spm_dpidle.pwrctrl->wake_src = 0;
  416. else
  417. __spm_dpidle.pwrctrl->wake_src &= ~wakesrc;
  418. }
  419. spin_unlock_irqrestore(&__spm_lock, flags);
  420. return 0;
  421. }
  422. static wake_reason_t spm_output_wake_reason(struct wake_status *wakesta, struct pcm_desc *pcmdesc, u32 dump_log)
  423. {
  424. wake_reason_t wr = WR_NONE;
  425. unsigned long int dpidle_log_print_curr_time = 0;
  426. bool log_print = false;
  427. if (dump_log == DEEPIDLE_LOG_FULL) {
  428. wr = __spm_output_wake_reason(wakesta, pcmdesc, false);
  429. } else if (dump_log == DEEPIDLE_LOG_REDUCED) {
  430. /* Determine print SPM log or not */
  431. dpidle_log_print_curr_time = spm_get_current_time_ms();
  432. if (wakesta->assert_pc != 0)
  433. log_print = true;
  434. /* Not wakeup by GPT */
  435. else if ((wakesta->r12 & (0x1 << 4)) == 0)
  436. log_print = true;
  437. else if (wakesta->timer_out <= DPIDLE_LOG_PRINT_TIMEOUT_CRITERIA)
  438. log_print = true;
  439. else if ((dpidle_log_print_curr_time - dpidle_log_print_prev_time) > DPIDLE_LOG_DISCARD_CRITERIA)
  440. log_print = true;
  441. /* Print SPM log */
  442. if (log_print == true) {
  443. dpidle_dbg("dpidle_log_discard_cnt = %d\n", dpidle_log_discard_cnt);
  444. wr = __spm_output_wake_reason(wakesta, pcmdesc, false);
  445. dpidle_log_print_prev_time = dpidle_log_print_curr_time;
  446. dpidle_log_discard_cnt = 0;
  447. } else {
  448. dpidle_log_discard_cnt++;
  449. wr = WR_NONE;
  450. }
  451. }
  452. #ifdef CONFIG_MTK_ECCCI_DRIVER
  453. if (wakesta->r12 & WAKE_SRC_R12_CLDMA_EVENT_B)
  454. exec_ccci_kern_func_by_md_id(0, ID_GET_MD_WAKEUP_SRC, NULL, 0);
  455. #endif
  456. return wr;
  457. }
  458. wake_reason_t spm_go_to_dpidle(u32 spm_flags, u32 spm_data, u32 dump_log)
  459. {
  460. struct wake_status wakesta;
  461. unsigned long flags;
  462. struct mtk_irq_mask mask;
  463. wake_reason_t wr = WR_NONE;
  464. /* struct pcm_desc *pcmdesc = __spm_dpidle.pcmdesc; */
  465. struct pcm_desc *pcmdesc;
  466. struct pwr_ctrl *pwrctrl = __spm_dpidle.pwrctrl;
  467. u32 cpu = spm_data;
  468. #if SPM_AEE_RR_REC
  469. aee_rr_rec_deepidle_val(SPM_DEEPIDLE_ENTER);
  470. #endif
  471. if (dyna_load_pcm[DYNA_LOAD_PCM_DEEPIDLE + cpu / 4].ready)
  472. pcmdesc = &(dyna_load_pcm[DYNA_LOAD_PCM_DEEPIDLE + cpu / 4].desc);
  473. else
  474. BUG();
  475. update_pwrctrl_pcm_flags(&spm_flags);
  476. set_pwrctrl_pcm_flags(pwrctrl, spm_flags);
  477. spm_dpidle_before_wfi(cpu);
  478. lockdep_off();
  479. spin_lock_irqsave(&__spm_lock, flags);
  480. mt_irq_mask_all(&mask);
  481. mt_irq_unmask_for_sleep(SPM_IRQ0_ID);
  482. #if defined(CONFIG_MTK_SYS_CIRQ)
  483. mt_cirq_clone_gic();
  484. mt_cirq_enable();
  485. #endif
  486. #if SPM_AEE_RR_REC
  487. aee_rr_rec_deepidle_val(SPM_DEEPIDLE_ENTER_UART_SLEEP);
  488. #endif
  489. if (request_uart_to_sleep()) {
  490. wr = WR_UART_BUSY;
  491. goto RESTORE_IRQ;
  492. }
  493. __spm_reset_and_init_pcm(pcmdesc);
  494. __spm_kick_im_to_fetch(pcmdesc);
  495. __spm_init_pcm_register();
  496. __spm_init_event_vector(pcmdesc);
  497. __spm_check_md_pdn_power_control(pwrctrl);
  498. __spm_sync_vcore_dvfs_power_control(pwrctrl, __spm_vcore_dvfs.pwrctrl);
  499. __spm_set_power_control(pwrctrl);
  500. __spm_set_wakeup_event(pwrctrl);
  501. spm_dpidle_pre_process();
  502. __spm_kick_pcm_to_run(pwrctrl);
  503. #if SPM_AEE_RR_REC
  504. aee_rr_rec_deepidle_val(SPM_DEEPIDLE_ENTER_WFI);
  505. #endif
  506. #ifdef SPM_DEEPIDLE_PROFILE_TIME
  507. gpt_get_cnt(SPM_PROFILE_APXGPT, &dpidle_profile[1]);
  508. #endif
  509. spm_trigger_wfi_for_dpidle(pwrctrl);
  510. #ifdef SPM_DEEPIDLE_PROFILE_TIME
  511. gpt_get_cnt(SPM_PROFILE_APXGPT, &dpidle_profile[2]);
  512. #endif
  513. #if SPM_AEE_RR_REC
  514. aee_rr_rec_deepidle_val(SPM_DEEPIDLE_LEAVE_WFI);
  515. #endif
  516. spm_dpidle_post_process();
  517. __spm_get_wakeup_status(&wakesta);
  518. __spm_clean_after_wakeup();
  519. #if SPM_AEE_RR_REC
  520. aee_rr_rec_deepidle_val(SPM_DEEPIDLE_ENTER_UART_AWAKE);
  521. #endif
  522. request_uart_to_wakeup();
  523. wr = spm_output_wake_reason(&wakesta, pcmdesc, dump_log);
  524. RESTORE_IRQ:
  525. #if defined(CONFIG_MTK_SYS_CIRQ)
  526. mt_cirq_flush();
  527. mt_cirq_disable();
  528. #endif
  529. mt_irq_mask_restore(&mask);
  530. spin_unlock_irqrestore(&__spm_lock, flags);
  531. lockdep_on();
  532. spm_dpidle_after_wfi(cpu, wakesta.debug_flag);
  533. #if SPM_AEE_RR_REC
  534. aee_rr_rec_deepidle_val(0);
  535. #endif
  536. return wr;
  537. }
  538. /*
  539. * cpu_pdn:
  540. * true = CPU dormant
  541. * false = CPU standby
  542. * pwrlevel:
  543. * 0 = AXI is off
  544. * 1 = AXI is 26M
  545. * pwake_time:
  546. * >= 0 = specific wakeup period
  547. */
  548. wake_reason_t spm_go_to_sleep_dpidle(u32 spm_flags, u32 spm_data)
  549. {
  550. u32 sec = 0;
  551. u32 dpidle_timer_val = 0;
  552. u32 dpidle_wake_src = 0;
  553. struct wake_status wakesta;
  554. unsigned long flags;
  555. struct mtk_irq_mask mask;
  556. #ifdef CONFIG_MTK_WD_KICKER
  557. struct wd_api *wd_api;
  558. int wd_ret;
  559. #endif
  560. static wake_reason_t last_wr = WR_NONE;
  561. /* struct pcm_desc *pcmdesc = __spm_dpidle.pcmdesc; */
  562. struct pcm_desc *pcmdesc;
  563. struct pwr_ctrl *pwrctrl = __spm_dpidle.pwrctrl;
  564. int cpu = smp_processor_id();
  565. if (dyna_load_pcm[DYNA_LOAD_PCM_DEEPIDLE + cpu / 4].ready)
  566. pcmdesc = &(dyna_load_pcm[DYNA_LOAD_PCM_DEEPIDLE + cpu / 4].desc);
  567. else
  568. BUG();
  569. /* backup original dpidle setting */
  570. dpidle_timer_val = pwrctrl->timer_val;
  571. dpidle_wake_src = pwrctrl->wake_src;
  572. update_pwrctrl_pcm_flags(&spm_flags);
  573. set_pwrctrl_pcm_flags(pwrctrl, spm_flags);
  574. spm_dpidle_before_wfi(cpu);
  575. #if 0
  576. #if SPM_PWAKE_EN
  577. sec = spm_get_wake_period(-1 /* FIXME */, last_wr);
  578. #endif
  579. #endif
  580. pwrctrl->timer_val = sec * 32768;
  581. /* FIXME */
  582. /* pwrctrl->wake_src = spm_get_sleep_wakesrc(); */
  583. #ifdef CONFIG_MTK_WD_KICKER
  584. wd_ret = get_wd_api(&wd_api);
  585. if (!wd_ret)
  586. wd_api->wd_suspend_notify();
  587. #endif
  588. spin_lock_irqsave(&__spm_lock, flags);
  589. mt_irq_mask_all(&mask);
  590. mt_irq_unmask_for_sleep(SPM_IRQ0_ID);
  591. #if defined(CONFIG_MTK_SYS_CIRQ)
  592. mt_cirq_clone_gic();
  593. mt_cirq_enable();
  594. #endif
  595. spm_crit2("sleep_deepidle, sec = %u, wakesrc = 0x%x [%u]\n",
  596. sec, pwrctrl->wake_src, is_cpu_pdn(pwrctrl->pcm_flags));
  597. if (request_uart_to_sleep()) {
  598. last_wr = WR_UART_BUSY;
  599. goto RESTORE_IRQ;
  600. }
  601. __spm_reset_and_init_pcm(pcmdesc);
  602. __spm_kick_im_to_fetch(pcmdesc);
  603. __spm_init_pcm_register();
  604. __spm_init_event_vector(pcmdesc);
  605. __spm_sync_vcore_dvfs_power_control(pwrctrl, __spm_vcore_dvfs.pwrctrl);
  606. __spm_set_power_control(pwrctrl);
  607. __spm_set_wakeup_event(pwrctrl);
  608. spm_dpidle_pre_process();
  609. __spm_kick_pcm_to_run(pwrctrl);
  610. spm_trigger_wfi_for_dpidle(pwrctrl);
  611. spm_dpidle_post_process();
  612. __spm_get_wakeup_status(&wakesta);
  613. __spm_clean_after_wakeup();
  614. request_uart_to_wakeup();
  615. last_wr = __spm_output_wake_reason(&wakesta, pcmdesc, true);
  616. RESTORE_IRQ:
  617. #if defined(CONFIG_MTK_SYS_CIRQ)
  618. mt_cirq_flush();
  619. mt_cirq_disable();
  620. #endif
  621. mt_irq_mask_restore(&mask);
  622. spin_unlock_irqrestore(&__spm_lock, flags);
  623. #ifdef CONFIG_MTK_WD_KICKER
  624. if (!wd_ret)
  625. wd_api->wd_resume_notify();
  626. #endif
  627. spm_dpidle_after_wfi(cpu, wakesta.debug_flag);
  628. /* restore original dpidle setting */
  629. pwrctrl->timer_val = dpidle_timer_val;
  630. pwrctrl->wake_src = dpidle_wake_src;
  631. return last_wr;
  632. }
  633. void spm_deepidle_init(void)
  634. {
  635. #if defined(CONFIG_OF)
  636. struct device_node *node;
  637. struct resource r;
  638. /* mcucfg */
  639. node = of_find_compatible_node(NULL, NULL, MCUCFG_NODE);
  640. if (!node) {
  641. pr_err("error: cannot find node " MCUCFG_NODE);
  642. goto mcucfg_exit;
  643. }
  644. if (of_address_to_resource(node, 0, &r)) {
  645. pr_err("error: cannot get phys addr" MCUCFG_NODE);
  646. goto mcucfg_exit;
  647. }
  648. mcucfg_phys_base = r.start;
  649. mcucfg_base = (unsigned long)of_iomap(node, 0);
  650. if (!mcucfg_base) {
  651. pr_err("error: cannot iomap " MCUCFG_NODE);
  652. goto mcucfg_exit;
  653. }
  654. dpidle_dbg("mcucfg_base = 0x%u\n", (unsigned int)mcucfg_base);
  655. spm_deepidle_chip_init();
  656. mcucfg_exit:
  657. dpidle_dbg("spm_deepidle_init\n");
  658. #endif
  659. }
  660. MODULE_DESCRIPTION("SPM-DPIdle Driver v0.1");