Merge tag 'v3.10.55' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / mt_spm_sleep.c
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/string.h>
7 #include <linux/aee.h>
8
9 #include <mach/irqs.h>
10 #include <mach/mt_cirq.h>
11 #include <mach/mt_spm.h>
12 #include <mach/mt_spm_sleep.h>
13 #include <mach/mt_clkmgr.h>
14 #include <mach/mt_dormant.h>
15 #include <mach/wd_api.h>
16 #include <mach/eint.h>
17 #include <mach/mtk_ccci_helper.h>
18
19 /**************************************
20 * only for internal debug
21 **************************************/
22 #ifdef CONFIG_MTK_LDVT
23 #define SPM_PWAKE_EN 0
24 #define SPM_PCMWDT_EN 0
25 #define SPM_BYPASS_SYSPWREQ 1
26 #else
27 #define SPM_PWAKE_EN 1
28 #define SPM_PCMWDT_EN 1
29 #define SPM_BYPASS_SYSPWREQ 0
30 #endif
31
32 #ifndef MTK_ALPS_BOX_SUPPORT
33 /**********************************************************
34 * PCM code for suspend (v34rc10 @ 2013-07-11)
35 **********************************************************/
36 static const u32 __pcm_suspend[] = {
37 0x19c0001f, 0x001c4bd7, 0x1800001f, 0x17cf0f3f, 0x1b80001f, 0x20000000,
38 0x1800001f, 0x17cf0f16, 0x19c0001f, 0x001c4be7, 0xd80002c6, 0x17c07c1f,
39 0x18c0001f, 0x10006234, 0xc0c01260, 0x1200041f, 0x18c0001f, 0x10006240,
40 0xe0e00f16, 0xe0e00f1e, 0xe0e00f0e, 0xe0e00f0f, 0x1b00001f, 0x7fffd7ff,
41 0xf0000000, 0x17c07c1f, 0x1b00001f, 0x3fffc7ff, 0x1b80001f, 0x20000004,
42 0xd80006ac, 0x17c07c1f, 0xd8000566, 0x17c07c1f, 0x18c0001f, 0x10006240,
43 0xe0e00f0f, 0xe0e00f1e, 0xe0e00f12, 0x18c0001f, 0x10006234, 0xc0c01440,
44 0x17c07c1f, 0x1b00001f, 0x3fffcfff, 0x19c0001f, 0x001c6bd7, 0x1800001f,
45 0x17cf0f3f, 0x1800001f, 0x17ff0f3f, 0x19c0001f, 0x001823d7, 0xf0000000,
46 0x17c07c1f, 0x18c0001f, 0x10006294, 0xc0c014e0, 0x17c07c1f, 0x1800001f,
47 0x07cf0f1e, 0x1b80001f, 0x20000a50, 0x1800001f, 0x07ce0f1e, 0x1b80001f,
48 0x20000300, 0x1800001f, 0x078e0f1e, 0x1b80001f, 0x20000300, 0x1800001f,
49 0x038e0f1e, 0x1b80001f, 0x20000300, 0x1800001f, 0x038e0e1e, 0x1800001f,
50 0x038e0e12, 0x1b80001f, 0x200000ed, 0x18c0001f, 0x10006240, 0xe0e00f0d,
51 0x1b80001f, 0x2000000e, 0x19c0001f, 0x000c4ba7, 0x19c0001f, 0x000c4ba5,
52 0xe8208000, 0x10006354, 0xfffffa43, 0x19c0001f, 0x000d4ba5, 0x1b00001f,
53 0xbfffc7ff, 0xf0000000, 0x17c07c1f, 0x1b80001f, 0x20000fdf, 0x8880000d,
54 0x00000024, 0x1b00001f, 0xbfffc7ff, 0xd8001222, 0x17c07c1f, 0x1b00001f,
55 0x3fffc7ff, 0x1b80001f, 0x20000004, 0xd800122c, 0x17c07c1f, 0xe8208000,
56 0x10006354, 0xffffffff, 0x19c0001f, 0x001c4be5, 0x1880001f, 0x10006320,
57 0xc0c017a0, 0xe080000f, 0xd8001223, 0x17c07c1f, 0xe080001f, 0xc0c018c0,
58 0x17c07c1f, 0x18c0001f, 0x10006294, 0xe0f07ff0, 0xe0e00ff0, 0xe0e000f0,
59 0xe8208000, 0x10006294, 0x000f00f0, 0x1800001f, 0x038e0e16, 0x1800001f,
60 0x038e0f16, 0x1800001f, 0x07ce0f16, 0x1800001f, 0x17cf0f16, 0x1b00001f,
61 0x7fffd7ff, 0xf0000000, 0x17c07c1f, 0xe0e00f16, 0x1380201f, 0xe0e00f1e,
62 0x1380201f, 0xe0e00f0e, 0x1b80001f, 0x20000100, 0xe0e00f0f, 0xe0e00f0d,
63 0xe0e00e0d, 0xe0e00c0d, 0xe0e0080d, 0xe0e0000d, 0xf0000000, 0x17c07c1f,
64 0xe0e00f0d, 0xe0e00f1e, 0xe0e00f12, 0xf0000000, 0x17c07c1f, 0xe8208000,
65 0x10006294, 0x000e00f0, 0xe8208000, 0x10006294, 0x000c00f0, 0xe8208000,
66 0x10006294, 0x000800f0, 0xe8208000, 0x10006294, 0x000000f0, 0xe0e008f0,
67 0xe0e00cf0, 0xe0e00ef0, 0xe0e00ff0, 0x1b80001f, 0x20000100, 0xe0f07ff0,
68 0xe0f07f00, 0xf0000000, 0x17c07c1f, 0xa1d08407, 0x1b80001f, 0x200000ed,
69 0x80eab401, 0x1a00001f, 0x10006814, 0xe2000003, 0xf0000000, 0x17c07c1f,
70 0x18c0001f, 0x80000000, 0x1a10001f, 0x10002058, 0x1a80001f, 0x10002058,
71 0xa2000c08, 0xe2800008, 0x1a10001f, 0x1000206c, 0x1a80001f, 0x1000206c,
72 0xa2000c08, 0xe2800008, 0x1a10001f, 0x10002080, 0x1a80001f, 0x10002080,
73 0xa2000c08, 0xe2800008, 0xf0000000, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
74 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
75 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
76 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
77 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
78 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
79 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x1840001f, 0x00000001,
80 0xa1d48407, 0x1990001f, 0x10006400, 0x1a40001f, 0x11008000, 0x1b00001f,
81 0x3fffc7ff, 0x1b80001f, 0xd00f0000, 0x8880000c, 0x3fffc7ff, 0xd8003fc2,
82 0x1140041f, 0xe8208000, 0x10006354, 0xfffffa43, 0xc0c03a80, 0x81471801,
83 0xd80025c5, 0x17c07c1f, 0x89c00007, 0xffffefff, 0x18c0001f, 0x10006200,
84 0xc0c03bc0, 0x12807c1f, 0xe8208000, 0x1000625c, 0x00000001, 0x1b80001f,
85 0x20000080, 0xc0c03bc0, 0x1280041f, 0x18c0001f, 0x10006208, 0xc0c03bc0,
86 0x12807c1f, 0xe8208000, 0x10006248, 0x00000000, 0x1b80001f, 0x20000080,
87 0xc0c03bc0, 0x1280041f, 0xc0c03b20, 0x81879801, 0x1b00001f, 0xffffdfff,
88 0x1b80001f, 0x90010000, 0x8880000c, 0x3fffc7ff, 0xd8003962, 0x17c07c1f,
89 0x8880000c, 0x40000800, 0xd8002602, 0x17c07c1f, 0x19c0001f, 0x00044b25,
90 0x1880001f, 0x10006320, 0xe8208000, 0x10006354, 0xffffffff, 0xc0c017a0,
91 0xe080000f, 0xd8002603, 0x17c07c1f, 0xe8208000, 0x10006310, 0x0b1600f8,
92 0xe080001f, 0x19c0001f, 0x001c4be7, 0x1b80001f, 0x20000030, 0xc0c018c0,
93 0x17c07c1f, 0xd8002ae6, 0x17c07c1f, 0x18c0001f, 0x10006240, 0xc0c01440,
94 0x17c07c1f, 0x18c0001f, 0x10006294, 0xe0f07ff0, 0xe0e00ff0, 0xe0e000f0,
95 0xe8208000, 0x10006294, 0x000f00f0, 0x1800001f, 0x00000036, 0x1800001f,
96 0x00000f36, 0x1800001f, 0x07c00f36, 0x1800001f, 0x17cf0f36, 0xd8002da6,
97 0x17c07c1f, 0x18c0001f, 0x10006234, 0xc0c01440, 0x17c07c1f, 0x19c0001f,
98 0x001c6bd7, 0x1800001f, 0x17cf0f3f, 0x1800001f, 0x17ff0f3f, 0x19c0001f,
99 0x001823d7, 0x1b00001f, 0x3fffcfff, 0x1b80001f, 0x90100000, 0x80c00400,
100 0xd8003003, 0x80980400, 0xd8003302, 0x17c07c1f, 0xd8203782, 0x17c07c1f,
101 0x19c0001f, 0x001c4bd7, 0x1800001f, 0x17cf0f3f, 0x1b80001f, 0x20000000,
102 0x1800001f, 0x17cf0f16, 0x19c0001f, 0x001c4be7, 0xd8003206, 0x17c07c1f,
103 0x18c0001f, 0x10006234, 0xc0c01260, 0x1200041f, 0xd8003306, 0x17c07c1f,
104 0x18c0001f, 0x10006240, 0xe0e00f16, 0xe0e00f1e, 0xe0e00f0e, 0xe0e00f0f,
105 0x18c0001f, 0x10006294, 0xc0c014e0, 0x17c07c1f, 0x19c0001f, 0x001c4ba7,
106 0x1800001f, 0x07cf0f16, 0x1b80001f, 0x20000a50, 0x1800001f, 0x07c00f16,
107 0x1b80001f, 0x20000300, 0x1800001f, 0x04000f16, 0x1b80001f, 0x20000300,
108 0x1800001f, 0x00000f16, 0x1b80001f, 0x20000300, 0x1800001f, 0x00000016,
109 0x10007c1f, 0x1b80001f, 0x2000049c, 0x1b80001f, 0x200000ed, 0x18c0001f,
110 0x10006240, 0xe0e00f0d, 0x1b80001f, 0x2000000e, 0xd0003920, 0x17c07c1f,
111 0x1800001f, 0x03800e12, 0x1b80001f, 0x20000300, 0x1800001f, 0x00000e12,
112 0x1b80001f, 0x20000300, 0x1800001f, 0x00000012, 0x10007c1f, 0x1b80001f,
113 0x2000079e, 0x19c0001f, 0x00054b25, 0xe8208000, 0x10006354, 0xfffffa43,
114 0x19c0001f, 0x00014b25, 0x19c0001f, 0x00014a25, 0xd0003fc0, 0x17c07c1f,
115 0xa1d10407, 0x1b80001f, 0x20000020, 0xf0000000, 0x17c07c1f, 0xa1d40407,
116 0x1391841f, 0xa1d90407, 0xf0000000, 0x17c07c1f, 0xd8003c4a, 0x17c07c1f,
117 0xe2e0006d, 0xe2e0002d, 0xd8203cea, 0x17c07c1f, 0xe2e0002f, 0xe2e0003e,
118 0xe2e00032, 0xf0000000, 0x17c07c1f, 0xd0003fc0, 0x17c07c1f, 0x17c07c1f,
119 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
120 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
121 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
122 0x17c07c1f, 0x17c07c1f, 0xd8004345, 0x17c07c1f, 0x18c0001f, 0x10006208,
123 0x1212841f, 0xc0c04860, 0x12807c1f, 0xe8208000, 0x10006248, 0x00000001,
124 0x1b80001f, 0x20000080, 0xc0c04860, 0x1280041f, 0x18c0001f, 0x10006200,
125 0x1212841f, 0xc0c04860, 0x12807c1f, 0xe8208000, 0x1000625c, 0x00000000,
126 0x1b80001f, 0x20000080, 0xc0c04860, 0x1280041f, 0x19c0001f, 0x00415820,
127 0x1ac0001f, 0x55aa55aa, 0x10007c1f, 0x80cab001, 0x808cb401, 0x80800c02,
128 0xd82044a2, 0x17c07c1f, 0xa1d78407, 0x1240301f, 0xe8208000, 0x100063e0,
129 0x00000001, 0x1b00001f, 0x00202000, 0x1b80001f, 0x80001000, 0x8880000c,
130 0x00200000, 0xd80046c2, 0x17c07c1f, 0xe8208000, 0x100063e0, 0x00000002,
131 0x1b80001f, 0x00001000, 0x809c840d, 0xd8204522, 0x17c07c1f, 0xa1d78407,
132 0x1890001f, 0x10006014, 0x18c0001f, 0x10006014, 0xa0978402, 0xe0c00002,
133 0x1b80001f, 0x00001000, 0xf0000000, 0xd800496a, 0x17c07c1f, 0xe2e00036,
134 0x1380201f, 0xe2e0003e, 0x1380201f, 0xe2e0002e, 0x1380201f, 0xd8204a6a,
135 0x17c07c1f, 0xe2e0006e, 0xe2e0004e, 0xe2e0004c, 0x1b80001f, 0x20000020,
136 0xe2e0004d, 0xf0000000, 0x17c07c1f
137 };
138 static const pcm_desc_t pcm_suspend = {
139 .base = __pcm_suspend,
140 .size = 597,
141 .sess = 3,
142 .vec0 = EVENT_VEC(11, 1, 0, 0), /* 26M-wake event */
143 .vec1 = EVENT_VEC(12, 1, 0, 26), /* 26M-sleep event */
144 .vec2 = EVENT_VEC(30, 1, 0, 55), /* APSRC-wake event */
145 .vec3 = EVENT_VEC(31, 1, 0, 99), /* APSRC-sleep event */
146 };
147 #else
148 /**********************************************************
149 * PCM code for suspend (v34rc10 @ 2013-07-11) int 32K
150 **********************************************************/
151 static const u32 __pcm_suspend[] = {
152 0x19c0001f, 0x001c4bd7, 0x1800001f, 0x17cf0f3e, 0x1b80001f, 0x20000000,
153 0x1800001f, 0x17cf0f16, 0x19c0001f, 0x001c4be7, 0xd8000306, 0x17c07c1f,
154 0x18c0001f, 0x10006234, 0xc0c01360, 0x1200041f, 0x18c0001f, 0x10006240,
155 0xe0e00f16, 0xe0e00f1e, 0xe0e00f0e, 0xe0e00f0f, 0xd0000320, 0x17c07c1f,
156 0xe0e0000d, 0x1b00001f, 0x7fffd7ff, 0xf0000000, 0x17c07c1f, 0x1b00001f,
157 0x3fffc7ff, 0x1b80001f, 0x20000004, 0xd80007ac, 0x17c07c1f, 0xd8000606,
158 0x17c07c1f, 0x18c0001f, 0x10006240, 0xe0e00f0f, 0xe0e00f1e, 0xe0e00f12,
159 0x18c0001f, 0x10006234, 0xc0c01540, 0x17c07c1f, 0xd0000660, 0x17c07c1f,
160 0x18c0001f, 0x10006240, 0xe0e0000f, 0x1b00001f, 0x3fffcfff, 0x19c0001f,
161 0x001c6bd7, 0x1800001f, 0x17cf0f3e, 0x1800001f, 0x17ef0f3e, 0x19c0001f,
162 0x001823d7, 0xf0000000, 0x17c07c1f, 0x18c0001f, 0x10006294, 0xc0c015e0,
163 0x17c07c1f, 0x1800001f, 0x07cf0f1e, 0x1b80001f, 0x20000a50, 0x1800001f,
164 0x07ce0f1e, 0x1b80001f, 0x20000300, 0x1800001f, 0x078e0f1e, 0x1b80001f,
165 0x20000300, 0x1800001f, 0x038e0f1e, 0x1b80001f, 0x20000300, 0x1800001f,
166 0x038e0e1e, 0x1800001f, 0x038e0e12, 0x1b80001f, 0x200000ed, 0x18c0001f,
167 0x10006240, 0xe0e00f0d, 0x1b80001f, 0x2000000e, 0x19c0001f, 0x000c4ba7,
168 0x19c0001f, 0x000c4ba5, 0xe8208000, 0x10006354, 0xfffffa43, 0x19c0001f,
169 0x000d4ba5, 0x1b00001f, 0xbfffc7ff, 0xf0000000, 0x17c07c1f, 0x1b80001f,
170 0x20000fdf, 0x8880000d, 0x00000024, 0x1b00001f, 0xbfffc7ff, 0xd8001322,
171 0x17c07c1f, 0x1b00001f, 0x3fffc7ff, 0x1b80001f, 0x20000004, 0xd800132c,
172 0x17c07c1f, 0xe8208000, 0x10006354, 0xffffffff, 0x19c0001f, 0x001c4be5,
173 0x1880001f, 0x10006320, 0xc0c018a0, 0xe080000f, 0xd8001323, 0x17c07c1f,
174 0xe080001f, 0xc0c019c0, 0x17c07c1f, 0x18c0001f, 0x10006294, 0xe0f07ff0,
175 0xe0e00ff0, 0xe0e000f0, 0xe8208000, 0x10006294, 0x000f00f0, 0x1800001f,
176 0x038e0e16, 0x1800001f, 0x038e0f16, 0x1800001f, 0x07ce0f16, 0x1800001f,
177 0x17cf0f16, 0x1b00001f, 0x7fffd7ff, 0xf0000000, 0x17c07c1f, 0xe0e00f16,
178 0x1380201f, 0xe0e00f1e, 0x1380201f, 0xe0e00f0e, 0x1b80001f, 0x20000100,
179 0xe0e00f0f, 0xe0e00f0d, 0xe0e00e0d, 0xe0e00c0d, 0xe0e0080d, 0xe0e0000d,
180 0xf0000000, 0x17c07c1f, 0xe0e00f0d, 0xe0e00f1e, 0xe0e00f12, 0xf0000000,
181 0x17c07c1f, 0xe8208000, 0x10006294, 0x000e00f0, 0xe8208000, 0x10006294,
182 0x000c00f0, 0xe8208000, 0x10006294, 0x000800f0, 0xe8208000, 0x10006294,
183 0x000000f0, 0xe0e008f0, 0xe0e00cf0, 0xe0e00ef0, 0xe0e00ff0, 0x1b80001f,
184 0x20000100, 0xe0f07ff0, 0xe0f07f00, 0xf0000000, 0x17c07c1f, 0xa1d08407,
185 0x1b80001f, 0x200000ed, 0x80eab401, 0x1a00001f, 0x10006814, 0xe2000003,
186 0xf0000000, 0x17c07c1f, 0x18c0001f, 0x80000000, 0x1a10001f, 0x10002058,
187 0x1a80001f, 0x10002058, 0xa2000c08, 0xe2800008, 0x1a10001f, 0x1000206c,
188 0x1a80001f, 0x1000206c, 0xa2000c08, 0xe2800008, 0x1a10001f, 0x10002080,
189 0x1a80001f, 0x10002080, 0xa2000c08, 0xe2800008, 0xf0000000, 0x17c07c1f,
190 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
191 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
192 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
193 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
194 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x1840001f, 0x00000001,
195 0xa1d48407, 0x1990001f, 0x10006400, 0x1a40001f, 0x11008000, 0x1b00001f,
196 0x3fffc7ff, 0x1b80001f, 0xd00f0000, 0x8880000c, 0x3fffc7ff, 0xd8003fc2,
197 0x1140041f, 0xe8208000, 0x10006354, 0xfffffa43, 0xc0c03b80, 0x81471801,
198 0xd80025c5, 0x17c07c1f, 0x89c00007, 0xffffefff, 0x18c0001f, 0x10006200,
199 0xc0c03cc0, 0x12807c1f, 0xe8208000, 0x1000625c, 0x00000001, 0x1b80001f,
200 0x20000080, 0xc0c03cc0, 0x1280041f, 0x18c0001f, 0x10006208, 0xc0c03cc0,
201 0x12807c1f, 0xe8208000, 0x10006244, 0x00000001, 0x1b80001f, 0x20000080,
202 0xc0c03cc0, 0x1280041f, 0xc0c03c20, 0x81879801, 0x1b00001f, 0xffffdfff,
203 0x1b80001f, 0x90010000, 0x8880000c, 0x3fffc7ff, 0xd8003a62, 0x17c07c1f,
204 0x8880000c, 0x40000800, 0xd8002602, 0x17c07c1f, 0x19c0001f, 0x00044b25,
205 0x1880001f, 0x10006320, 0xe8208000, 0x10006354, 0xffffffff, 0xc0c018a0,
206 0xe080000f, 0xd8002603, 0x17c07c1f, 0xe8208000, 0x10006310, 0x0b1600f8,
207 0xe080001f, 0x19c0001f, 0x001c4be7, 0x1b80001f, 0x20000030, 0xc0c019c0,
208 0x17c07c1f, 0xd8002b26, 0x17c07c1f, 0x18c0001f, 0x10006240, 0xc0c01540,
209 0x17c07c1f, 0xd0002b80, 0x17c07c1f, 0x18c0001f, 0x10006240, 0xe0e0000f,
210 0x18c0001f, 0x10006294, 0xe0f07ff0, 0xe0e00ff0, 0xe0e000f0, 0xe8208000,
211 0x10006294, 0x000f00f0, 0x1800001f, 0x00000036, 0x1800001f, 0x00000f36,
212 0x1800001f, 0x07c00f36, 0x1800001f, 0x17cf0f36, 0xd8002e46, 0x17c07c1f,
213 0x18c0001f, 0x10006234, 0xc0c01540, 0x17c07c1f, 0x19c0001f, 0x001c6bd7,
214 0x1800001f, 0x17cf0f3e, 0x1800001f, 0x17ef0f3e, 0x19c0001f, 0x001823d7,
215 0x1b00001f, 0x3fffcfff, 0x1b80001f, 0x90100000, 0x80c00400, 0xd80030a3,
216 0x80980400, 0xd8003402, 0x17c07c1f, 0xd8203882, 0x17c07c1f, 0x19c0001f,
217 0x001c4bd7, 0x1800001f, 0x17cf0f3e, 0x1b80001f, 0x20000000, 0x1800001f,
218 0x17cf0f16, 0x19c0001f, 0x001c4be7, 0xd80032a6, 0x17c07c1f, 0x18c0001f,
219 0x10006234, 0xc0c01360, 0x1200041f, 0xd80033e6, 0x17c07c1f, 0x18c0001f,
220 0x10006240, 0xe0e00f16, 0xe0e00f1e, 0xe0e00f0e, 0xe0e00f0f, 0xd0003400,
221 0x17c07c1f, 0xe0e0000d, 0x18c0001f, 0x10006294, 0xc0c015e0, 0x17c07c1f,
222 0x19c0001f, 0x001c4ba7, 0x1800001f, 0x07cf0f16, 0x1b80001f, 0x20000a50,
223 0x1800001f, 0x07c00f16, 0x1b80001f, 0x20000300, 0x1800001f, 0x04000f16,
224 0x1b80001f, 0x20000300, 0x1800001f, 0x00000f16, 0x1b80001f, 0x20000300,
225 0x1800001f, 0x00000016, 0x10007c1f, 0x1b80001f, 0x2000049c, 0x1b80001f,
226 0x200000ed, 0x18c0001f, 0x10006240, 0xe0e00f0d, 0x1b80001f, 0x2000000e,
227 0xd0003a20, 0x17c07c1f, 0x1800001f, 0x03800e12, 0x1b80001f, 0x20000300,
228 0x1800001f, 0x00000e12, 0x1b80001f, 0x20000300, 0x1800001f, 0x00000012,
229 0x10007c1f, 0x1b80001f, 0x2000079e, 0x19c0001f, 0x00054b25, 0xe8208000,
230 0x10006354, 0xfffffa43, 0x19c0001f, 0x00014b25, 0x19c0001f, 0x00014a25,
231 0xd0003fc0, 0x17c07c1f, 0xa1d10407, 0x1b80001f, 0x20000020, 0xf0000000,
232 0x17c07c1f, 0xa1d40407, 0x1391841f, 0xa1d90407, 0xf0000000, 0x17c07c1f,
233 0xd8003d4a, 0x17c07c1f, 0xe2e0006d, 0xe2e0002d, 0xd8203dea, 0x17c07c1f,
234 0xe2e0002f, 0xe2e0003e, 0xe2e00032, 0xf0000000, 0x17c07c1f, 0xd0003fc0,
235 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
236 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
237 0x17c07c1f, 0x17c07c1f, 0xd8004345, 0x17c07c1f, 0x18c0001f, 0x10006208,
238 0x1212841f, 0xc0c04860, 0x12807c1f, 0xe8208000, 0x10006244, 0x00000000,
239 0x1b80001f, 0x20000080, 0xc0c04860, 0x1280041f, 0x18c0001f, 0x10006200,
240 0x1212841f, 0xc0c04860, 0x12807c1f, 0xe8208000, 0x1000625c, 0x00000000,
241 0x1b80001f, 0x20000080, 0xc0c04860, 0x1280041f, 0x19c0001f, 0x00415820,
242 0x1ac0001f, 0x55aa55aa, 0x10007c1f, 0x80cab001, 0x808cb401, 0x80800c02,
243 0xd82044a2, 0x17c07c1f, 0xa1d78407, 0x1240301f, 0xe8208000, 0x100063e0,
244 0x00000001, 0x1b00001f, 0x00202000, 0x1b80001f, 0x80001000, 0x8880000c,
245 0x00200000, 0xd80046c2, 0x17c07c1f, 0xe8208000, 0x100063e0, 0x00000002,
246 0x1b80001f, 0x00001000, 0x809c840d, 0xd8204522, 0x17c07c1f, 0xa1d78407,
247 0x1890001f, 0x10006014, 0x18c0001f, 0x10006014, 0xa0978402, 0xe0c00002,
248 0x1b80001f, 0x00001000, 0xf0000000, 0xd800496a, 0x17c07c1f, 0xe2e00036,
249 0x1380201f, 0xe2e0003e, 0x1380201f, 0xe2e0002e, 0x1380201f, 0xd8204a6a,
250 0x17c07c1f, 0xe2e0006e, 0xe2e0004e, 0xe2e0004c, 0x1b80001f, 0x20000020,
251 0xe2e0004d, 0xf0000000, 0x17c07c1f
252 };
253 static const pcm_desc_t pcm_suspend = {
254 .base = __pcm_suspend,
255 .size = 597,
256 .sess = 3,
257 .vec0 = EVENT_VEC(11, 1, 0, 0), /* 26M-wake event */
258 .vec1 = EVENT_VEC(12, 1, 0, 29), /* 26M-sleep event */
259 .vec2 = EVENT_VEC(30, 1, 0, 63), /* APSRC-wake event */
260 .vec3 = EVENT_VEC(31, 1, 0, 107), /* APSRC-sleep event */
261 };
262 #endif
263
264 /**********************************************************
265 * PCM code for deep idle (v17rc4 @ 2014-02-17)
266 **********************************************************/
267 #if (defined(IS_VCORE_USE_6333VCORE) || defined(CONFIG_MTK_PMIC_MT6397)) && !defined(MTK_DVFS_DISABLE_LOW_VOLTAGE_SUPPORT)
268 static const u32 __pcm_dpidle[] = {
269 0x80318400, 0xc0c01580, 0x10c0041f, 0x1800001f, 0x17cf0f16, 0x1b00001f,
270 0x7ffff7ff, 0x18c0001f, 0x10006240, 0xe0e0000d, 0xf0000000, 0x17c07c1f,
271 0x1b00001f, 0x3fffe7ff, 0x1b80001f, 0x20000004, 0xd800040c, 0x17c07c1f,
272 0x18c0001f, 0x10006240, 0xe0e0000f, 0xc0c01580, 0x10c07c1f, 0x1800001f,
273 0x17cf0f36, 0x80c31801, 0xd82003c3, 0x17c07c1f, 0x1800001f, 0x17cf0f3e,
274 0x1b00001f, 0x3fffefff, 0xf0000000, 0x17c07c1f, 0x19c0001f, 0x001c4ba7,
275 0x1b80001f, 0x20000030, 0xe8208000, 0x10006354, 0xfffffbff, 0x1800001f,
276 0x07cf0f16, 0x1b80001f, 0x20000a50, 0x1800001f, 0x07ce0f16, 0x1b80001f,
277 0x20000300, 0x1800001f, 0x078e0f16, 0x1b80001f, 0x20000300, 0x1800001f,
278 0x038e0f16, 0x1b80001f, 0x20000300, 0x1800001f, 0x038e0e16, 0x1800001f,
279 0x038e0e12, 0x19c0001f, 0x000c4ba7, 0x19c0001f, 0x000c4ba5, 0xe8208000,
280 0x10006354, 0xfffffa43, 0x19c0001f, 0x000d4ba5, 0x1b00001f, 0xbfffe7ff,
281 0xf0000000, 0x17c07c1f, 0x1b80001f, 0x20000fdf, 0x8880000d, 0x00000024,
282 0x1b00001f, 0xbfffe7ff, 0xd8000e02, 0x17c07c1f, 0x1b00001f, 0x3fffe7ff,
283 0x1b80001f, 0x20000004, 0xd8000e0c, 0x17c07c1f, 0xe8208000, 0x10006354,
284 0xfffffbff, 0x19c0001f, 0x001c4be5, 0x1880001f, 0x10006320, 0xc0c01460,
285 0xe080000f, 0xd8000e03, 0x17c07c1f, 0xe080001f, 0xc0c01800, 0x17c07c1f,
286 0x1800001f, 0x038e0e16, 0x1800001f, 0x038e0f16, 0x1800001f, 0x07ce0f16,
287 0x1800001f, 0x17cf0f16, 0x1b00001f, 0x7ffff7ff, 0xf0000000, 0x17c07c1f,
288 0xe0e00f16, 0x1380201f, 0xe0e00f1e, 0x1380201f, 0xe0e00f0e, 0x1380201f,
289 0xe0e00f0c, 0xe0e00f0d, 0xe0e00e0d, 0xe0e00c0d, 0xe0e0080d, 0xe0e0000d,
290 0xf0000000, 0x17c07c1f, 0xd800110a, 0x17c07c1f, 0xe2e00036, 0x1380201f,
291 0xe2e0003e, 0x1380201f, 0xe2e0002e, 0x1380201f, 0xd820120a, 0x17c07c1f,
292 0xe2e0006e, 0xe2e0004e, 0xe2e0004c, 0x1b80001f, 0x20000020, 0xe2e0004d,
293 0xf0000000, 0x17c07c1f, 0xd80012ca, 0x17c07c1f, 0xe2e0006d, 0xe2e0002d,
294 0xd820136a, 0x17c07c1f, 0xe2e0002f, 0xe2e0003e, 0xe2e00032, 0xf0000000,
295 0x17c07c1f, 0xa1d10407, 0x1b80001f, 0x20000080, 0x10c07c1f, 0xf0000000,
296 0x17c07c1f, 0xa1d08407, 0x1b80001f, 0x200000ed, 0x80eab401, 0x1a00001f,
297 0x10006814, 0xe2000003, 0xf0000000, 0x17c07c1f, 0x1a00001f, 0x10006604,
298 0xd8001703, 0x17c07c1f, 0xe2200004, 0x1b80001f, 0x2000009e, 0xe2200006,
299 0x1b80001f, 0x2000009e, 0xd82017c3, 0x17c07c1f, 0xe2200005, 0x1b80001f,
300 0x2000009e, 0xe2200007, 0x1b80001f, 0x2000009e, 0xf0000000, 0x17c07c1f,
301 0x18c0001f, 0x80000000, 0x1a10001f, 0x10002058, 0x1a80001f, 0x10002058,
302 0xa2000c08, 0xe2800008, 0x1a10001f, 0x1000206c, 0x1a80001f, 0x1000206c,
303 0xa2000c08, 0xe2800008, 0x1a10001f, 0x10002080, 0x1a80001f, 0x10002080,
304 0xa2000c08, 0xe2800008, 0xf0000000, 0x17c07c1f, 0xa1d40407, 0x1391841f,
305 0xa1d90407, 0xf0000000, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
306 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
307 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
308 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
309 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
310 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
311 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x1840001f, 0x00000001,
312 0xa1d48407, 0x1a40001f, 0x11008000, 0x1b00001f, 0x3fffe7ff, 0x1b80001f,
313 0xd00f0000, 0x8880000c, 0x3fffe7ff, 0xd80037a2, 0x1140041f, 0xe8208000,
314 0x10006354, 0xfffffa43, 0xc0c013a0, 0x17c07c1f, 0x1950001f, 0x10006400,
315 0x80d70405, 0xd80025e3, 0x17c07c1f, 0x89c00007, 0xffffefff, 0x18c0001f,
316 0x10006200, 0xc0c01240, 0x12807c1f, 0xe8208000, 0x1000625c, 0x00000001,
317 0x1b80001f, 0x20000080, 0xc0c01240, 0x1280041f, 0x18c0001f, 0x10006208,
318 0xc0c01240, 0x12807c1f, 0xe8208000, 0x10006248, 0x00000000, 0x1b80001f,
319 0x20000080, 0xc0c01240, 0x1280041f, 0xc0c01ac0, 0x17c07c1f, 0x1b00001f,
320 0xffffffff, 0x1b80001f, 0xd0010000, 0x8880000c, 0x3fffe7ff, 0xd80033e2,
321 0x17c07c1f, 0x8880000c, 0x40000000, 0xd8002622, 0x17c07c1f, 0x8083b401,
322 0xd8002622, 0x17c07c1f, 0x1880001f, 0x10006320, 0x1990001f, 0x10006600,
323 0xe8208000, 0x10006354, 0xfffffbff, 0xc0c01460, 0xe080000f, 0xd8002623,
324 0x17c07c1f, 0xe8208000, 0x10006310, 0x0b1600f8, 0xe080001f, 0x19c0001f,
325 0x001c4be7, 0x1b80001f, 0x20000030, 0xc0c01800, 0x17c07c1f, 0x18c0001f,
326 0x10006240, 0xe0e0000f, 0x1800001f, 0x00000016, 0x1800001f, 0x00000f16,
327 0x1800001f, 0x07c00f16, 0x1800001f, 0x17cf0f16, 0x8080b401, 0xd8002ca2,
328 0x17c07c1f, 0xc0c01580, 0x10c07c1f, 0x80c31801, 0xd8202d43, 0x17c07c1f,
329 0x1800001f, 0x17cf0f1e, 0x1b00001f, 0x3fffefff, 0x1b80001f, 0x90100000,
330 0x80881c01, 0xd8003202, 0x17c07c1f, 0x80318400, 0xc0c01580, 0x10c0041f,
331 0x18c0001f, 0x10006240, 0xe0e0000d, 0x1800001f, 0x07cf0f16, 0x1b80001f,
332 0x20000a50, 0x1800001f, 0x07c00f16, 0x1b80001f, 0x20000300, 0x1800001f,
333 0x04000f16, 0x1b80001f, 0x20000300, 0x1800001f, 0x00000f16, 0x1b80001f,
334 0x20000300, 0x1800001f, 0x00000016, 0x10007c1f, 0x1b80001f, 0x2000049c,
335 0x19c0001f, 0x00044b25, 0xd82033e2, 0x17c07c1f, 0x1800001f, 0x03800e12,
336 0x1b80001f, 0x20000300, 0x1800001f, 0x00000e12, 0x1b80001f, 0x20000300,
337 0x1800001f, 0x00000012, 0x10007c1f, 0x1b80001f, 0x2000079e, 0x19c0001f,
338 0x00054b25, 0x19c0001f, 0x00014b25, 0x19c0001f, 0x00014a25, 0x80d70405,
339 0xd80037a3, 0x17c07c1f, 0x18c0001f, 0x10006208, 0x1212841f, 0xc0c01000,
340 0x12807c1f, 0xe8208000, 0x10006248, 0x00000001, 0x1b80001f, 0x20000080,
341 0xc0c01000, 0x1280041f, 0x18c0001f, 0x10006200, 0xc0c01000, 0x12807c1f,
342 0xe8208000, 0x1000625c, 0x00000000, 0x1b80001f, 0x20000080, 0xc0c01000,
343 0x1280041f, 0x19c0001f, 0x00015820, 0x1ac0001f, 0x55aa55aa, 0x10007c1f,
344 0x80cab001, 0x808cb401, 0x80800c02, 0xd8203902, 0x17c07c1f, 0xa1d78407,
345 0x1240301f, 0xe8208000, 0x100063e0, 0x00000001, 0x1b00001f, 0x00202000,
346 0x1b80001f, 0x80001000, 0x8880000c, 0x00200000, 0xd8003b22, 0x17c07c1f,
347 0xe8208000, 0x100063e0, 0x00000002, 0x1b80001f, 0x00001000, 0x809c840d,
348 0xd8203982, 0x17c07c1f, 0xa1d78407, 0x1890001f, 0x10006014, 0x18c0001f,
349 0x10006014, 0xa0978402, 0xe0c00002, 0x1b80001f, 0x00001000, 0xf0000000
350 };
351 static const pcm_desc_t pcm_dpidle = {
352 .base = __pcm_dpidle,
353 .size = 486,
354 .sess = 2,
355 .vec0 = EVENT_VEC(11, 1, 0, 0), /* 26M-wake event */
356 .vec1 = EVENT_VEC(12, 1, 0, 12), /* 26M-sleep event */
357 .vec2 = EVENT_VEC(30, 1, 0, 34), /* APSRC-wake event */
358 .vec3 = EVENT_VEC(31, 1, 0, 74), /* APSRC-sleep event */
359 };
360 #else
361 static const u32 __pcm_dpidle[] = {
362 0x80318400, 0xc0c014c0, 0x10c0041f, 0x1800001f, 0x17cf0f16, 0x1b00001f,
363 0x7ffff7ff, 0xf0000000, 0x17c07c1f, 0x1b00001f, 0x3fffe7ff, 0x1b80001f,
364 0x20000004, 0xd800034c, 0x17c07c1f, 0xc0c014c0, 0x10c07c1f, 0x1800001f,
365 0x17cf0f36, 0x80c31801, 0xd8200303, 0x17c07c1f, 0x1800001f, 0x17cf0f3e,
366 0x1b00001f, 0x3fffefff, 0xf0000000, 0x17c07c1f, 0x19c0001f, 0x001c4ba7,
367 0x1b80001f, 0x20000030, 0xe8208000, 0x10006354, 0xfffffbff, 0x1800001f,
368 0x07cf0f16, 0x1b80001f, 0x20000a50, 0x1800001f, 0x07ce0f16, 0x1b80001f,
369 0x20000300, 0x1800001f, 0x078e0f16, 0x1b80001f, 0x20000300, 0x1800001f,
370 0x038e0f16, 0x1b80001f, 0x20000300, 0x1800001f, 0x038e0e16, 0x1800001f,
371 0x038e0e12, 0x19c0001f, 0x000c4ba7, 0x19c0001f, 0x000c4ba5, 0xe8208000,
372 0x10006354, 0xfffffa43, 0x19c0001f, 0x000d4ba5, 0x1b00001f, 0xbfffe7ff,
373 0xf0000000, 0x17c07c1f, 0x1b80001f, 0x20000fdf, 0x8880000d, 0x00000024,
374 0x1b00001f, 0xbfffe7ff, 0xd8000d42, 0x17c07c1f, 0x1b00001f, 0x3fffe7ff,
375 0x1b80001f, 0x20000004, 0xd8000d4c, 0x17c07c1f, 0xe8208000, 0x10006354,
376 0xfffffbff, 0x19c0001f, 0x001c4be5, 0x1880001f, 0x10006320, 0xc0c013a0,
377 0xe080000f, 0xd8000d43, 0x17c07c1f, 0xe080001f, 0xc0c01740, 0x17c07c1f,
378 0x1800001f, 0x038e0e16, 0x1800001f, 0x038e0f16, 0x1800001f, 0x07ce0f16,
379 0x1800001f, 0x17cf0f16, 0x1b00001f, 0x7ffff7ff, 0xf0000000, 0x17c07c1f,
380 0xe0e00f16, 0x1380201f, 0xe0e00f1e, 0x1380201f, 0xe0e00f0e, 0x1380201f,
381 0xe0e00f0c, 0xe0e00f0d, 0xe0e00e0d, 0xe0e00c0d, 0xe0e0080d, 0xe0e0000d,
382 0xf0000000, 0x17c07c1f, 0xd800104a, 0x17c07c1f, 0xe2e00036, 0x1380201f,
383 0xe2e0003e, 0x1380201f, 0xe2e0002e, 0x1380201f, 0xd820114a, 0x17c07c1f,
384 0xe2e0006e, 0xe2e0004e, 0xe2e0004c, 0x1b80001f, 0x20000020, 0xe2e0004d,
385 0xf0000000, 0x17c07c1f, 0xd800120a, 0x17c07c1f, 0xe2e0006d, 0xe2e0002d,
386 0xd82012aa, 0x17c07c1f, 0xe2e0002f, 0xe2e0003e, 0xe2e00032, 0xf0000000,
387 0x17c07c1f, 0xa1d10407, 0x1b80001f, 0x20000080, 0x10c07c1f, 0xf0000000,
388 0x17c07c1f, 0xa1d08407, 0x1b80001f, 0x200000ed, 0x80eab401, 0x1a00001f,
389 0x10006814, 0xe2000003, 0xf0000000, 0x17c07c1f, 0x1a00001f, 0x10006604,
390 0xd8001643, 0x17c07c1f, 0xe2200004, 0x1b80001f, 0x20000020, 0xe2200006,
391 0x1b80001f, 0x20000020, 0xd8201703, 0x17c07c1f, 0xe2200005, 0x1b80001f,
392 0x20000020, 0xe2200007, 0x1b80001f, 0x20000020, 0xf0000000, 0x17c07c1f,
393 0x18c0001f, 0x80000000, 0x1a10001f, 0x10002058, 0x1a80001f, 0x10002058,
394 0xa2000c08, 0xe2800008, 0x1a10001f, 0x1000206c, 0x1a80001f, 0x1000206c,
395 0xa2000c08, 0xe2800008, 0x1a10001f, 0x10002080, 0x1a80001f, 0x10002080,
396 0xa2000c08, 0xe2800008, 0xf0000000, 0x17c07c1f, 0xa1d40407, 0x1391841f,
397 0xa1d90407, 0xf0000000, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
398 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
399 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
400 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
401 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
402 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
403 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
404 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x1840001f, 0x00000001,
405 0xa1d48407, 0x1a40001f, 0x11008000, 0x1b00001f, 0x3fffe7ff, 0x1b80001f,
406 0xd00f0000, 0x8880000c, 0x3fffe7ff, 0xd80036e2, 0x1140041f, 0xe8208000,
407 0x10006354, 0xfffffa43, 0xc0c012e0, 0x17c07c1f, 0x1950001f, 0x10006400,
408 0x80d70405, 0xd80025e3, 0x17c07c1f, 0x89c00007, 0xffffefff, 0x18c0001f,
409 0x10006200, 0xc0c01180, 0x12807c1f, 0xe8208000, 0x1000625c, 0x00000001,
410 0x1b80001f, 0x20000080, 0xc0c01180, 0x1280041f, 0x18c0001f, 0x10006208,
411 0xc0c01180, 0x12807c1f, 0xe8208000, 0x10006248, 0x00000000, 0x1b80001f,
412 0x20000080, 0xc0c01180, 0x1280041f, 0xc0c01a00, 0x17c07c1f, 0x1b00001f,
413 0xffffffff, 0x1b80001f, 0xd0010000, 0x8880000c, 0x3fffe7ff, 0xd8003322,
414 0x17c07c1f, 0x8880000c, 0x40000000, 0xd8002622, 0x17c07c1f, 0x8083b401,
415 0xd8002622, 0x17c07c1f, 0x1880001f, 0x10006320, 0x1990001f, 0x10006600,
416 0xe8208000, 0x10006354, 0xfffffbff, 0xc0c013a0, 0xe080000f, 0xd8002623,
417 0x17c07c1f, 0xe8208000, 0x10006310, 0x0b1600f8, 0xe080001f, 0x19c0001f,
418 0x001c4be7, 0x1b80001f, 0x20000030, 0xc0c01740, 0x17c07c1f, 0x1800001f,
419 0x00000016, 0x1800001f, 0x00000f16, 0x1800001f, 0x07c00f16, 0x1800001f,
420 0x17cf0f16, 0x8080b401, 0xd8002c42, 0x17c07c1f, 0xc0c014c0, 0x10c07c1f,
421 0x80c31801, 0xd8202ce3, 0x17c07c1f, 0x1800001f, 0x17cf0f1e, 0x1b00001f,
422 0x3fffefff, 0x1b80001f, 0x90100000, 0x80881c01, 0xd8003142, 0x17c07c1f,
423 0x80318400, 0xc0c014c0, 0x10c0041f, 0x1800001f, 0x07cf0f16, 0x1b80001f,
424 0x20000a50, 0x1800001f, 0x07c00f16, 0x1b80001f, 0x20000300, 0x1800001f,
425 0x04000f16, 0x1b80001f, 0x20000300, 0x1800001f, 0x00000f16, 0x1b80001f,
426 0x20000300, 0x1800001f, 0x00000016, 0x10007c1f, 0x1b80001f, 0x2000049c,
427 0x19c0001f, 0x00044b25, 0xd8203322, 0x17c07c1f, 0x1800001f, 0x03800e12,
428 0x1b80001f, 0x20000300, 0x1800001f, 0x00000e12, 0x1b80001f, 0x20000300,
429 0x1800001f, 0x00000012, 0x10007c1f, 0x1b80001f, 0x2000079e, 0x19c0001f,
430 0x00054b25, 0x19c0001f, 0x00014b25, 0x19c0001f, 0x00014a25, 0x80d70405,
431 0xd80036e3, 0x17c07c1f, 0x18c0001f, 0x10006208, 0x1212841f, 0xc0c00f40,
432 0x12807c1f, 0xe8208000, 0x10006248, 0x00000001, 0x1b80001f, 0x20000080,
433 0xc0c00f40, 0x1280041f, 0x18c0001f, 0x10006200, 0xc0c00f40, 0x12807c1f,
434 0xe8208000, 0x1000625c, 0x00000000, 0x1b80001f, 0x20000080, 0xc0c00f40,
435 0x1280041f, 0x19c0001f, 0x00015820, 0x1ac0001f, 0x55aa55aa, 0x10007c1f,
436 0x80cab001, 0x808cb401, 0x80800c02, 0xd8203842, 0x17c07c1f, 0xa1d78407,
437 0x1240301f, 0xe8208000, 0x100063e0, 0x00000001, 0x1b00001f, 0x00202000,
438 0x1b80001f, 0x80001000, 0x8880000c, 0x00200000, 0xd8003a62, 0x17c07c1f,
439 0xe8208000, 0x100063e0, 0x00000002, 0x1b80001f, 0x00001000, 0x809c840d,
440 0xd82038c2, 0x17c07c1f, 0xa1d78407, 0x1890001f, 0x10006014, 0x18c0001f,
441 0x10006014, 0xa0978402, 0xe0c00002, 0x1b80001f, 0x00001000, 0xf0000000
442 };
443 static const pcm_desc_t pcm_dpidle = {
444 .base = __pcm_dpidle,
445 .size = 480,
446 .sess = 2,
447 .vec0 = EVENT_VEC(11, 1, 0, 0), /* 26M-wake event */
448 .vec1 = EVENT_VEC(12, 1, 0, 9), /* 26M-sleep event */
449 .vec2 = EVENT_VEC(30, 1, 0, 28), /* APSRC-wake event */
450 .vec3 = EVENT_VEC(31, 1, 0, 68), /* APSRC-sleep event */
451 };
452 #endif
453
454
455 /**************************************
456 * SW code for suspend and deep idle
457 **************************************/
458 #define SPM_SYSCLK_SETTLE 128 /* 3.9ms */
459
460 #define WAIT_UART_ACK_TIMES 10 /* 10 * 10us */
461
462 #define SPM_WAKE_PERIOD 600 /* sec */
463
464 #define PCM_WDT_TIMEOUT (30 * 32768) /* 30s */
465 #define PCM_TIMER_MAX_FOR_WDT (0xffffffff - PCM_WDT_TIMEOUT)
466
467 #define WAKE_SRC_FOR_SUSPEND \
468 (WAKE_SRC_KP | WAKE_SRC_EINT | WAKE_SRC_CONN_WDT | WAKE_SRC_IRRX | \
469 WAKE_SRC_CONN | WAKE_SRC_USB_CD | WAKE_SRC_THERM | WAKE_SRC_SYSPWREQ | \
470 WAKE_SRC_ETHERNET)
471
472 #define WAKE_SRC_FOR_DPIDLE \
473 (WAKE_SRC_KP | WAKE_SRC_GPT | WAKE_SRC_EINT | WAKE_SRC_CONN_WDT | \
474 WAKE_SRC_IRRX | WAKE_SRC_CONN | WAKE_SRC_USB_CD | WAKE_SRC_USB_PDN | \
475 WAKE_SRC_AFE | WAKE_SRC_THERM | WAKE_SRC_SYSPWREQ | WAKE_SRC_ETHERNET)
476
477 #define wfi_with_sync() \
478 do { \
479 isb(); \
480 dsb(); \
481 __asm__ __volatile__("wfi" : : : "memory"); \
482 } while (0)
483
484 #define spm_crit2(fmt, args...) \
485 do { \
486 aee_sram_printk(fmt, ##args); \
487 spm_crit(fmt, ##args); \
488 } while (0)
489
490 #define spm_error2(fmt, args...) \
491 do { \
492 aee_sram_printk(fmt, ##args); \
493 spm_error(fmt, ##args); \
494 } while (0)
495
496 typedef struct {
497 u32 debug_reg; /* PCM_REG_DATA_INI */
498 u32 r12; /* PCM_REG12_DATA */
499 u32 raw_sta; /* SLEEP_ISR_RAW_STA */
500 u32 cpu_wake; /* SLEEP_CPU_WAKEUP_EVENT */
501 u32 timer_out; /* PCM_TIMER_OUT */
502 u32 event_reg; /* PCM_EVENT_REG_STA */
503 u32 isr; /* SLEEP_ISR_STATUS */
504 u32 r13; /* PCM_REG13_DATA */
505 } wake_status_t;
506
507 extern int get_dynamic_period(int first_use, int first_wakeup_time, int battery_capacity_level);
508
509 extern int mt_irq_mask_all(struct mtk_irq_mask *mask);
510 extern int mt_irq_mask_restore(struct mtk_irq_mask *mask);
511 extern void mt_irq_unmask_for_sleep(unsigned int irq);
512
513 extern void mtk_uart_restore(void);
514 extern void dump_uart_reg(void);
515
516 extern spinlock_t spm_lock;
517
518 static u32 spm_sleep_wakesrc = WAKE_SRC_FOR_SUSPEND;
519
520 static void spm_set_sysclk_settle(void)
521 {
522 u32 settle;
523
524 /* SYSCLK settle = VTCXO settle time */
525 spm_write(SPM_CLK_SETTLE, SPM_SYSCLK_SETTLE);
526 settle = spm_read(SPM_CLK_SETTLE);
527
528 spm_crit2("settle = %u\n", settle);
529 }
530
531 static void spm_reset_and_init_pcm(void)
532 {
533 u32 con1;
534
535 /* reset PCM */
536 spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_PCM_SW_RESET);
537 spm_write(SPM_PCM_CON0, CON0_CFG_KEY);
538
539 /* init PCM_CON0 (disable event vector) */
540 spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_IM_SLEEP_DVS);
541
542 /* init PCM_CON1 (disable PCM timer but keep PCM WDT setting) */
543 con1 = spm_read(SPM_PCM_CON1) & (CON1_PCM_WDT_WAKE_MODE | CON1_PCM_WDT_EN);
544 spm_write(SPM_PCM_CON1, con1 | CON1_CFG_KEY | CON1_SPM_SRAM_ISO_B |
545 CON1_SPM_SRAM_SLP_B | CON1_IM_NONRP_EN | CON1_MIF_APBEN);
546 }
547
548 /*
549 * pcmdesc: pcm_suspend or pcm_dpidle
550 */
551 static void spm_kick_im_to_fetch(const pcm_desc_t *pcmdesc)
552 {
553 u32 ptr, len, con0;
554
555 /* tell IM where is PCM code (use slave mode if code existed and session <= 2) */
556 ptr = spm_get_base_phys(pcmdesc->base);
557 len = pcmdesc->size - 1;
558 if (spm_read(SPM_PCM_IM_PTR) != ptr || spm_read(SPM_PCM_IM_LEN) != len ||
559 pcmdesc->sess > 2) {
560 spm_write(SPM_PCM_IM_PTR, ptr);
561 spm_write(SPM_PCM_IM_LEN, len);
562 } else {
563 spm_write(SPM_PCM_CON1, spm_read(SPM_PCM_CON1) | CON1_CFG_KEY | CON1_IM_SLAVE);
564 }
565
566 /* kick IM to fetch (only toggle IM_KICK) */
567 con0 = spm_read(SPM_PCM_CON0) & ~(CON0_IM_KICK | CON0_PCM_KICK);
568 spm_write(SPM_PCM_CON0, con0 | CON0_CFG_KEY | CON0_IM_KICK);
569 spm_write(SPM_PCM_CON0, con0 | CON0_CFG_KEY);
570 }
571
572 static int spm_request_uart_to_sleep(void)
573 {
574 u32 val1;
575 int i = 0;
576
577 /* request UART to sleep */
578 val1 = spm_read(SPM_POWER_ON_VAL1);
579 spm_write(SPM_POWER_ON_VAL1, val1 | R7_UART_CLK_OFF_REQ);
580
581 /* wait for UART to ACK */
582 while (!(spm_read(SPM_PCM_REG13_DATA) & R13_UART_CLK_OFF_ACK)) {
583 if (i++ >= WAIT_UART_ACK_TIMES) {
584 spm_write(SPM_POWER_ON_VAL1, val1);
585 spm_error2("CANNOT GET UART SLEEP ACK (0x%x)\n", spm_read(PERI_PDN0_STA));
586 dump_uart_reg();
587 return -EBUSY;
588 }
589 udelay(10);
590 }
591
592 return 0;
593 }
594
595 static void spm_init_pcm_register(void)
596 {
597 /* init r0 with POWER_ON_VAL0 */
598 spm_write(SPM_PCM_REG_DATA_INI, spm_read(SPM_POWER_ON_VAL0));
599 spm_write(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R0);
600 spm_write(SPM_PCM_PWR_IO_EN, 0);
601
602 /* init r7 with POWER_ON_VAL1 */
603 spm_write(SPM_PCM_REG_DATA_INI, spm_read(SPM_POWER_ON_VAL1));
604 spm_write(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R7);
605 spm_write(SPM_PCM_PWR_IO_EN, 0);
606
607 /* clear REG_DATA_INI for PCM after init rX */
608 spm_write(SPM_PCM_REG_DATA_INI, 0);
609 }
610
611 /*
612 * pcmdesc: pcm_suspend or pcm_dpidle
613 */
614 static void spm_init_event_vector(const pcm_desc_t *pcmdesc)
615 {
616 /* init event vector register */
617 spm_write(SPM_PCM_EVENT_VECTOR0, pcmdesc->vec0);
618 spm_write(SPM_PCM_EVENT_VECTOR1, pcmdesc->vec1);
619 spm_write(SPM_PCM_EVENT_VECTOR2, pcmdesc->vec2);
620 spm_write(SPM_PCM_EVENT_VECTOR3, pcmdesc->vec3);
621 spm_write(SPM_PCM_EVENT_VECTOR4, pcmdesc->vec4);
622 spm_write(SPM_PCM_EVENT_VECTOR5, pcmdesc->vec5);
623 spm_write(SPM_PCM_EVENT_VECTOR6, pcmdesc->vec6);
624 spm_write(SPM_PCM_EVENT_VECTOR7, pcmdesc->vec7);
625
626 /* event vector will be enabled by PCM itself */
627 }
628
629 static void spm_set_pwrctl_for_sleep(void)
630 {
631 u32 pwrctl = 0;
632
633 spm_write(SPM_APMCU_PWRCTL, pwrctl);
634
635 spm_write(SPM_AP_STANBY_CON, (0x2 << 19) | /* unmask CONN */
636 (0 << 16) | /* mask DISP and MFG */
637 (0 << 6) | /* check SCU idle */
638 (0 << 5) | /* check L2C idle */
639 (1U << 4)); /* Reduce AND */
640 spm_write(SPM_CORE0_WFI_SEL, 0x1);
641 spm_write(SPM_CORE1_WFI_SEL, 0x1);
642 spm_write(SPM_CORE2_WFI_SEL, 0x1);
643 spm_write(SPM_CORE3_WFI_SEL, 0x1);
644 }
645
646 static void spm_set_pwrctl_for_dpidle(u16 pwrlevel)
647 {
648 u32 pwrctl = 0;
649
650 /* [7:6]=dpidle level, [5:3]=VRF18_CON22 sleep_val, [2:0]=VRF18_CON22 wakeup_val */
651 if (pwrlevel == 0)
652 pwrctl |= (1U << 6);
653 else
654 pwrctl |= (1U << 7);
655
656 spm_write(SPM_APMCU_PWRCTL, pwrctl);
657
658 spm_write(SPM_AP_STANBY_CON, (0x2 << 19) | /* unmask CONN */
659 (0 << 16) | /* mask DISP and MFG */
660 (0 << 6) | /* check SCU idle */
661 (0 << 5) | /* check L2C idle */
662 (1U << 4)); /* Reduce AND */
663 spm_write(SPM_CORE0_WFI_SEL, 0x1);
664 spm_write(SPM_CORE1_WFI_SEL, 0x1);
665 spm_write(SPM_CORE2_WFI_SEL, 0x1);
666 spm_write(SPM_CORE3_WFI_SEL, 0x1);
667 }
668
669 /*
670 * timer_val: PCM timer value (0 = disable)
671 * wake_src : WAKE_SRC_XXX
672 */
673 static void spm_set_wakeup_event(u32 timer_val, u32 wake_src)
674 {
675 u32 isr;
676
677 /* set PCM timer (set to max when disable) */
678 spm_write(SPM_PCM_TIMER_VAL, timer_val ? : PCM_TIMER_MAX_FOR_WDT);
679 spm_write(SPM_PCM_CON1, spm_read(SPM_PCM_CON1) | CON1_CFG_KEY | CON1_PCM_TIMER_EN);
680
681 /* unmask wakeup source */
682 #if SPM_BYPASS_SYSPWREQ
683 wake_src &= ~WAKE_SRC_SYSPWREQ; /* make 26M off when attach ICE */
684 #endif
685 spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, ~wake_src);
686
687 /* unmask SPM ISR (keep TWAM setting) */
688 isr = spm_read(SPM_SLEEP_ISR_MASK) & ISR_TWAM;
689 spm_write(SPM_SLEEP_ISR_MASK, isr | ISRM_PCM_IRQ_AUX);
690 }
691
692 static void spm_kick_pcm_to_run(bool cpu_pdn, bool infra_pdn, bool pcmwdt_en)
693 {
694 u32 clk, con0;
695
696 /* keep CPU or INFRA/DDRPHY power if needed and lock INFRA DCM */
697 clk = spm_read(SPM_CLK_CON) & ~(CC_DISABLE_DORM_PWR | CC_DISABLE_INFRA_PWR);
698 if (!cpu_pdn)
699 clk |= CC_DISABLE_DORM_PWR;
700 if (!infra_pdn)
701 clk |= CC_DISABLE_INFRA_PWR;
702 spm_write(SPM_CLK_CON, clk | CC_LOCK_INFRA_DCM);
703
704 /* init pause request mask for PCM */
705 spm_write(SPM_PCM_MAS_PAUSE_MASK, 0xffffffff);
706
707 /* enable r0 and r7 to control power */
708 spm_write(SPM_PCM_PWR_IO_EN, PCM_PWRIO_EN_R0 | PCM_PWRIO_EN_R7);
709
710 /* SRCLKENA: r7 (PWR_IO_EN[7]=1) */
711 spm_write(SPM_CLK_CON, spm_read(SPM_CLK_CON) | CC_SRCLKENA_MASK);
712
713 /* enable PCM WDT (normal mode) to start count if needed */
714 #if SPM_PCMWDT_EN
715 if (pcmwdt_en) {
716 u32 con1;
717 con1 = spm_read(SPM_PCM_CON1) & ~(CON1_PCM_WDT_WAKE_MODE | CON1_PCM_WDT_EN);
718 spm_write(SPM_PCM_CON1, CON1_CFG_KEY | con1);
719
720 BUG_ON(spm_read(SPM_PCM_TIMER_VAL) > PCM_TIMER_MAX_FOR_WDT);
721 spm_write(SPM_PCM_WDT_TIMER_VAL, spm_read(SPM_PCM_TIMER_VAL) + PCM_WDT_TIMEOUT);
722 spm_write(SPM_PCM_CON1, con1 | CON1_CFG_KEY | CON1_PCM_WDT_EN);
723 }
724 #endif
725
726 /* kick PCM to run (only toggle PCM_KICK) */
727 con0 = spm_read(SPM_PCM_CON0) & ~(CON0_IM_KICK | CON0_PCM_KICK);
728 spm_write(SPM_PCM_CON0, con0 | CON0_CFG_KEY | CON0_PCM_KICK);
729 spm_write(SPM_PCM_CON0, con0 | CON0_CFG_KEY);
730 }
731
732 static void spm_trigger_wfi_for_sleep(bool cpu_pdn, bool infra_pdn)
733 {
734 if (cpu_pdn) {
735 if (!cpu_power_down(SHUTDOWN_MODE)) {
736 switch_to_amp();
737 wfi_with_sync();
738 }
739 switch_to_smp();
740 cpu_check_dormant_abort();
741 } else {
742 wfi_with_sync();
743 }
744
745 if (infra_pdn)
746 mtk_uart_restore();
747 }
748
749 static void spm_trigger_wfi_for_dpidle(bool cpu_pdn)
750 {
751 if (cpu_pdn) {
752 if (!cpu_power_down(DORMANT_MODE)) {
753 switch_to_amp();
754 wfi_with_sync();
755 }
756 switch_to_smp();
757 cpu_check_dormant_abort();
758 } else {
759 wfi_with_sync();
760 }
761 }
762
763 static void spm_get_wakeup_status(wake_status_t *wakesta)
764 {
765 /* get PC value if PCM assert (pause abort) */
766 wakesta->debug_reg = spm_read(SPM_PCM_REG_DATA_INI);
767
768 /* get wakeup event */
769 wakesta->r12 = spm_read(SPM_PCM_REG9_DATA); /* r9 = r12 for pcm_normal */
770 wakesta->raw_sta = spm_read(SPM_SLEEP_ISR_RAW_STA);
771 wakesta->cpu_wake = spm_read(SPM_SLEEP_CPU_WAKEUP_EVENT);
772
773 /* get sleep time */
774 wakesta->timer_out = spm_read(SPM_PCM_TIMER_OUT);
775
776 /* get special pattern (0xf0000 or 0x10000) if sleep abort */
777 wakesta->event_reg = spm_read(SPM_PCM_EVENT_REG_STA);
778
779 /* get ISR status */
780 wakesta->isr = spm_read(SPM_SLEEP_ISR_STATUS);
781
782 /* get MD/CONN and co-clock status */
783 wakesta->r13 = spm_read(SPM_PCM_REG13_DATA);
784 }
785
786 static void spm_clean_after_wakeup(bool pcmwdt_en)
787 {
788 /* disable PCM WDT to stop count if needed */
789 #if SPM_PCMWDT_EN
790 if (pcmwdt_en)
791 spm_write(SPM_PCM_CON1, CON1_CFG_KEY | (spm_read(SPM_PCM_CON1) & ~CON1_PCM_WDT_EN));
792 #endif
793
794 /* PCM has cleared uart_clk_off_req and now clear it in POWER_ON_VAL1 */
795 spm_write(SPM_POWER_ON_VAL1, spm_read(SPM_POWER_ON_VAL1) & ~R7_UART_CLK_OFF_REQ);
796
797 /* SRCLKENA: POWER_ON_VAL1|r7 (PWR_IO_EN[7]=1) */
798 spm_write(SPM_CLK_CON, spm_read(SPM_CLK_CON) & ~CC_SRCLKENA_MASK);
799
800 /* re-enable POWER_ON_VAL0/1 to control power */
801 spm_write(SPM_PCM_PWR_IO_EN, 0);
802
803 /* unlock INFRA DCM */
804 spm_write(SPM_CLK_CON, spm_read(SPM_CLK_CON) & ~CC_LOCK_INFRA_DCM);
805
806 /* clean PCM timer event */
807 spm_write(SPM_PCM_CON1, CON1_CFG_KEY | (spm_read(SPM_PCM_CON1) & ~CON1_PCM_TIMER_EN));
808
809 /* clean CPU wakeup event (pause abort) */
810 spm_write(SPM_SLEEP_CPU_WAKEUP_EVENT, 0);
811
812 /* clean wakeup event raw status (except THERM) */
813 spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, ~WAKE_SRC_THERM);
814
815 /* clean ISR status (except TWAM) */
816 spm_write(SPM_SLEEP_ISR_MASK, spm_read(SPM_SLEEP_ISR_MASK) | ISRM_ALL_EXC_TWAM);
817 spm_write(SPM_SLEEP_ISR_STATUS, ISRC_ALL_EXC_TWAM);
818 spm_write(SPM_PCM_SW_INT_CLEAR, PCM_SW_INT0);
819 }
820
821 static wake_reason_t spm_output_wake_reason(const wake_status_t *wakesta, bool dpidle)
822 {
823 char str[200] = { 0 };
824 wake_reason_t wr = WR_NONE;
825
826 if (wakesta->debug_reg != 0) {
827 spm_error2("PCM ASSERT AND PC = %u (0x%x)(0x%x)\n",
828 wakesta->debug_reg, wakesta->r13, wakesta->event_reg);
829 return WR_PCM_ASSERT;
830 }
831
832 if (dpidle) /* bypass wakeup event check */
833 return WR_WAKE_SRC;
834
835 if((wakesta->event_reg & 0x100000) == 0)
836 {
837 spm_crit2("Sleep Abort!\n");
838 }
839
840 if (wakesta->r12 & (1U << 0)) {
841 if (!(wakesta->isr & ISR_TWAM) && !wakesta->cpu_wake) {
842 strcat(str, "PCM_TIMER ");
843 wr = WR_PCM_TIMER;
844 } else {
845 if (wakesta->isr & ISR_TWAM) {
846 strcat(str, "TWAM ");
847 wr = WR_WAKE_SRC;
848 }
849 if (wakesta->cpu_wake) {
850 strcat(str, "CPU ");
851 wr = WR_WAKE_SRC;
852 }
853 }
854 }
855 if (wakesta->r12 & WAKE_SRC_TS) {
856 strcat(str, "TS ");
857 wr = WR_WAKE_SRC;
858 }
859 if (wakesta->r12 & WAKE_SRC_KP) {
860 strcat(str, "KP ");
861 wr = WR_WAKE_SRC;
862 }
863 if (wakesta->r12 & WAKE_SRC_WDT) {
864 strcat(str, "WDT ");
865 wr = WR_WAKE_SRC;
866 }
867 if (wakesta->r12 & WAKE_SRC_GPT) {
868 strcat(str, "GPT ");
869 wr = WR_WAKE_SRC;
870 }
871 if (wakesta->r12 & WAKE_SRC_EINT) {
872 strcat(str, "EINT ");
873 wr = WR_WAKE_SRC;
874 }
875 if (wakesta->r12 & WAKE_SRC_CONN_WDT) {
876 strcat(str, "CONN_WDT ");
877 wr = WR_WAKE_SRC;
878 }
879 if (wakesta->r12 & WAKE_SRC_CEC) {
880 strcat(str, "CEC ");
881 wr = WR_WAKE_SRC;
882 }
883 if (wakesta->r12 & WAKE_SRC_IRRX) {
884 strcat(str, "IRRX ");
885 wr = WR_WAKE_SRC;
886 }
887 if (wakesta->r12 & WAKE_SRC_LOW_BAT) {
888 strcat(str, "LOW_BAT ");
889 wr = WR_WAKE_SRC;
890 }
891 if (wakesta->r12 & WAKE_SRC_CONN) {
892 strcat(str, "CONN ");
893 wr = WR_WAKE_SRC;
894 }
895 if (wakesta->r12 & (1U << 13)) {
896 strcat(str, "PCM_WDT ");
897 wr = WR_PCM_WDT;
898 }
899 if (wakesta->r12 & WAKE_SRC_USB_CD) {
900 strcat(str, "USB_CD ");
901 wr = WR_WAKE_SRC;
902 }
903 if (wakesta->r12 & WAKE_SRC_USB_PDN) {
904 strcat(str, "USB_PDN ");
905 wr = WR_WAKE_SRC;
906 }
907 if (wakesta->r12 & WAKE_SRC_DBGSYS) {
908 strcat(str, "DBGSYS ");
909 wr = WR_WAKE_SRC;
910 }
911 if (wakesta->r12 & WAKE_SRC_UART0) {
912 strcat(str, "UART0 ");
913 wr = WR_WAKE_SRC;
914 }
915 if (wakesta->r12 & WAKE_SRC_AFE) {
916 strcat(str, "AFE ");
917 wr = WR_WAKE_SRC;
918 }
919 if (wakesta->r12 & WAKE_SRC_THERM) {
920 strcat(str, "THERM ");
921 wr = WR_WAKE_SRC;
922 }
923 if (wakesta->r12 & WAKE_SRC_CIRQ) {
924 strcat(str, "CIRQ ");
925 wr = WR_WAKE_SRC;
926 }
927 if (wakesta->r12 & WAKE_SRC_SYSPWREQ) {
928 strcat(str, "SYSPWREQ ");
929 wr = WR_WAKE_SRC;
930 }
931 if (wakesta->r12 & WAKE_SRC_ETHERNET) {
932 strcat(str, "ETHERNET ");
933 wr = WR_WAKE_SRC;
934 }
935 if (wakesta->r12 & WAKE_SRC_CPU0_IRQ) {
936 strcat(str, "CPU0_IRQ ");
937 wr = WR_WAKE_SRC;
938 }
939 if (wakesta->r12 & WAKE_SRC_CPU1_IRQ) {
940 strcat(str, "CPU1_IRQ ");
941 wr = WR_WAKE_SRC;
942 }
943 if (wakesta->r12 & WAKE_SRC_CPU2_IRQ) {
944 strcat(str, "CPU2_IRQ ");
945 wr = WR_WAKE_SRC;
946 }
947 if (wakesta->r12 & WAKE_SRC_CPU3_IRQ) {
948 strcat(str, "CPU3_IRQ ");
949 wr = WR_WAKE_SRC;
950 }
951 if (wr == WR_NONE) {
952 strcat(str, "UNKNOWN ");
953 wr = WR_UNKNOWN;
954 }
955
956 spm_crit2("wake up by %s(0x%x)(0x%x)(%u)\n",
957 str, wakesta->r12, wakesta->raw_sta, wakesta->timer_out);
958 spm_crit2("event_reg = 0x%x, isr = 0x%x, r13 = 0x%x\n",
959 wakesta->event_reg, wakesta->isr, wakesta->r13);
960
961 if (wakesta->r12 & WAKE_SRC_EINT)
962 mt_eint_print_status();
963
964 return wr;
965 }
966
967 #if SPM_PWAKE_EN
968 static u32 spm_get_wake_period(int pwake_time, wake_reason_t last_wr)
969 {
970 int period = SPM_WAKE_PERIOD;
971
972 #ifndef MTK_ALPS_BOX_SUPPORT
973 if (pwake_time < 0) {
974 /* use FG to get the period of 1% battery decrease */
975 period = get_dynamic_period(last_wr != WR_PCM_TIMER ? 1 : 0, SPM_WAKE_PERIOD, 1);
976 if (period <= 0) {
977 spm_warning("CANNOT GET PERIOD FROM FUEL GAUGE\n");
978 period = SPM_WAKE_PERIOD;
979 }
980 } else {
981 period = pwake_time;
982 spm_crit2("pwake = %d\n", pwake_time);
983 }
984 #else
985 if(pwake_time >= 0) {
986 period = pwake_time;
987 }
988 #endif
989 if (period > 36 * 3600) /* max period is 36.4 hours */
990 period = 36 * 3600;
991
992 return period;
993 }
994 #endif
995
996 /*
997 * wakesrc: WAKE_SRC_XXX
998 * enable : enable or disable @wakesrc
999 * replace: if true, will replace the default setting
1000 */
1001 int spm_set_sleep_wakesrc(u32 wakesrc, bool enable, bool replace)
1002 {
1003 unsigned long flags;
1004
1005 #if 0
1006 if (spm_is_wakesrc_invalid(wakesrc))
1007 return -EINVAL;
1008 #endif
1009
1010 spin_lock_irqsave(&spm_lock, flags);
1011 if (enable) {
1012 if (replace)
1013 spm_sleep_wakesrc = wakesrc;
1014 else
1015 spm_sleep_wakesrc |= wakesrc;
1016 } else {
1017 if (replace)
1018 spm_sleep_wakesrc = 0;
1019 else
1020 spm_sleep_wakesrc &= ~wakesrc;
1021 }
1022 spin_unlock_irqrestore(&spm_lock, flags);
1023
1024 return 0;
1025 }
1026
1027 /*
1028 * cpu_pdn:
1029 * true = CPU shutdown
1030 * false = CPU standby
1031 * infra_pdn:
1032 * true = INFRA/DDRPHY power down
1033 * false = keep INFRA/DDRPHY power
1034 * pwake_time:
1035 * >= 0 = specific wakeup period
1036 */
1037 wake_reason_t spm_go_to_sleep(bool cpu_pdn, bool infra_pdn, int pwake_time)
1038 {
1039 u32 sec = 0;
1040 int wd_ret;
1041 wake_status_t wakesta;
1042 unsigned long flags;
1043 struct mtk_irq_mask mask;
1044 struct wd_api *wd_api;
1045 static wake_reason_t last_wr = WR_NONE;
1046 const pcm_desc_t *pcmdesc = &pcm_suspend;
1047 const bool pcmwdt_en = true;
1048
1049 #if SPM_PWAKE_EN
1050 sec = spm_get_wake_period(pwake_time, last_wr);
1051 #else
1052 if(pwake_time != -1)
1053 sec = pwake_time;
1054 #endif
1055
1056 wd_ret = get_wd_api(&wd_api);
1057 if (!wd_ret)
1058 wd_api->wd_suspend_notify();
1059
1060 spin_lock_irqsave(&spm_lock, flags);
1061 mt_irq_mask_all(&mask);
1062 mt_irq_unmask_for_sleep(MT_SPM_IRQ_ID);
1063 mt_cirq_clone_gic();
1064 mt_cirq_enable();
1065
1066 spm_set_sysclk_settle();
1067
1068 spm_crit2("sec = %u, wakesrc = 0x%x (%u)(%u)\n",
1069 sec, spm_sleep_wakesrc, cpu_pdn, infra_pdn);
1070
1071 spm_reset_and_init_pcm();
1072
1073 spm_kick_im_to_fetch(pcmdesc);
1074
1075 if (spm_request_uart_to_sleep()) {
1076 last_wr = WR_UART_BUSY;
1077 goto RESTORE_IRQ;
1078 }
1079
1080 spm_init_pcm_register();
1081
1082 spm_init_event_vector(pcmdesc);
1083
1084 spm_set_pwrctl_for_sleep();
1085
1086 spm_set_wakeup_event(sec * 32768, spm_sleep_wakesrc);
1087
1088 spm_kick_pcm_to_run(cpu_pdn, infra_pdn, pcmwdt_en);
1089
1090 spm_trigger_wfi_for_sleep(cpu_pdn, infra_pdn);
1091
1092 spm_get_wakeup_status(&wakesta);
1093
1094 spm_clean_after_wakeup(pcmwdt_en);
1095
1096 last_wr = spm_output_wake_reason(&wakesta, false);
1097
1098 RESTORE_IRQ:
1099 mt_cirq_flush();
1100 mt_cirq_disable();
1101 mt_irq_mask_restore(&mask);
1102 spin_unlock_irqrestore(&spm_lock, flags);
1103
1104 //spm_go_to_normal(); /* included in pcm_suspend */
1105
1106 if (!wd_ret)
1107 wd_api->wd_resume_notify();
1108
1109 return last_wr;
1110 }
1111
1112 /*
1113 * cpu_pdn:
1114 * true = CPU dormant
1115 * false = CPU standby
1116 * pwrlevel:
1117 * 0 = AXI is off
1118 * 1 = AXI is 26M
1119 * pwake_time:
1120 * >= 0 = specific wakeup period
1121 */
1122 wake_reason_t spm_go_to_sleep_dpidle(bool cpu_pdn, u16 pwrlevel, int pwake_time)
1123 {
1124 u32 sec = 0;
1125 int wd_ret;
1126 wake_status_t wakesta;
1127 unsigned long flags;
1128 struct mtk_irq_mask mask;
1129 struct wd_api *wd_api;
1130 static wake_reason_t last_wr = WR_NONE;
1131 const pcm_desc_t *pcmdesc = &pcm_dpidle;
1132 const bool pcmwdt_en = false;
1133
1134
1135 #if SPM_PWAKE_EN
1136 sec = spm_get_wake_period(pwake_time, last_wr);
1137 #else
1138 if(pwake_time != -1)
1139 sec = pwake_time;
1140 #endif
1141
1142 wd_ret = get_wd_api(&wd_api);
1143 if (!wd_ret)
1144 wd_api->wd_suspend_notify();
1145
1146 spin_lock_irqsave(&spm_lock, flags);
1147 mt_irq_mask_all(&mask);
1148 mt_irq_unmask_for_sleep(MT_SPM_IRQ_ID);
1149 mt_cirq_clone_gic();
1150 mt_cirq_enable();
1151
1152 spm_crit2("sec = %u, wakesrc = 0x%x [%u][%u]\n",
1153 sec, spm_sleep_wakesrc, cpu_pdn, pwrlevel);
1154
1155 spm_reset_and_init_pcm();
1156
1157 spm_kick_im_to_fetch(pcmdesc);
1158
1159 if (spm_request_uart_to_sleep()) {
1160 last_wr = WR_UART_BUSY;
1161 goto RESTORE_IRQ;
1162 }
1163
1164 spm_init_pcm_register();
1165
1166 spm_init_event_vector(pcmdesc);
1167
1168 spm_set_pwrctl_for_dpidle(pwrlevel);
1169
1170 spm_set_wakeup_event(sec * 32768, spm_sleep_wakesrc);
1171
1172 spm_kick_pcm_to_run(cpu_pdn, false, pcmwdt_en); /* keep INFRA/DDRPHY power */
1173
1174 spm_trigger_wfi_for_dpidle(cpu_pdn);
1175
1176 spm_get_wakeup_status(&wakesta);
1177
1178 spm_clean_after_wakeup(pcmwdt_en);
1179
1180 last_wr = spm_output_wake_reason(&wakesta, false);
1181
1182 RESTORE_IRQ:
1183 mt_cirq_flush();
1184 mt_cirq_disable();
1185 mt_irq_mask_restore(&mask);
1186 spin_unlock_irqrestore(&spm_lock, flags);
1187
1188 if (!wd_ret)
1189 wd_api->wd_resume_notify();
1190
1191 return last_wr;
1192 }
1193
1194 void __attribute__((weak)) spm_dpidle_before_wfi(void)
1195 {
1196 }
1197
1198 void __attribute__((weak)) spm_dpidle_after_wfi(void)
1199 {
1200 }
1201
1202 /*
1203 * cpu_pdn:
1204 * true = CPU dormant
1205 * false = CPU standby
1206 * pwrlevel:
1207 * 0 = AXI is off
1208 * 1 = AXI is 26M
1209 */
1210 wake_reason_t spm_go_to_dpidle(bool cpu_pdn, u16 pwrlevel)
1211 {
1212 wake_status_t wakesta;
1213 unsigned long flags;
1214 struct mtk_irq_mask mask;
1215 wake_reason_t wr = WR_NONE;
1216 const pcm_desc_t *pcmdesc = &pcm_dpidle;
1217 const bool pcmwdt_en = false;
1218
1219 spin_lock_irqsave(&spm_lock, flags);
1220 mt_irq_mask_all(&mask);
1221 mt_irq_unmask_for_sleep(MT_SPM_IRQ_ID);
1222 mt_cirq_clone_gic();
1223 mt_cirq_enable();
1224
1225 spm_reset_and_init_pcm();
1226
1227 spm_kick_im_to_fetch(pcmdesc);
1228
1229 if (spm_request_uart_to_sleep()) {
1230 wr = WR_UART_BUSY;
1231 goto RESTORE_IRQ;
1232 }
1233
1234 spm_init_pcm_register();
1235
1236 spm_init_event_vector(pcmdesc);
1237
1238 spm_set_pwrctl_for_dpidle(pwrlevel);
1239
1240 spm_set_wakeup_event(6553, WAKE_SRC_FOR_DPIDLE);
1241
1242 spm_kick_pcm_to_run(cpu_pdn, false, pcmwdt_en); /* keep INFRA/DDRPHY power */
1243
1244 spm_dpidle_before_wfi();
1245
1246 spm_trigger_wfi_for_dpidle(cpu_pdn);
1247
1248 spm_dpidle_after_wfi();
1249
1250 spm_get_wakeup_status(&wakesta);
1251
1252 spm_clean_after_wakeup(pcmwdt_en);
1253
1254 wr = spm_output_wake_reason(&wakesta, true);
1255
1256 RESTORE_IRQ:
1257 mt_cirq_flush();
1258 mt_cirq_disable();
1259 mt_irq_mask_restore(&mask);
1260 spin_unlock_irqrestore(&spm_lock, flags);
1261
1262 return wr;
1263 }
1264
1265 bool spm_is_conn_sleep(void)
1266 {
1267 return !(spm_read(SPM_PCM_REG13_DATA) & R13_CONN_SRCCLKENI);
1268 }
1269
1270 void spm_output_sleep_option(void)
1271 {
1272 spm_notice("PWAKE_EN:%d, PCMWDT_EN:%d, BYPASS_SYSPWREQ:%d\n",
1273 SPM_PWAKE_EN, SPM_PCMWDT_EN, SPM_BYPASS_SYSPWREQ);
1274 }
1275
1276 MODULE_AUTHOR("YT Lee <yt.lee@mediatek.com>");
1277 MODULE_DESCRIPTION("SPM-Sleep Driver v0.9");