Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /* |
2 | * This program is free software; you can redistribute it and/or modify | |
3 | * it under the terms of the GNU General Public License as published by | |
4 | * the Free Software Foundation; either version 2 of the License, or | |
5 | * (at your option) any later version. | |
6 | */ | |
7 | ||
8 | #include <linux/kernel.h> | |
9 | #include <linux/module.h> | |
10 | #include <linux/sched.h> | |
11 | #include <linux/init.h> | |
12 | #include <linux/cpu.h> | |
13 | #include <linux/cpufreq.h> | |
14 | #include <linux/delay.h> | |
15 | #include <linux/slab.h> | |
16 | #include <linux/proc_fs.h> | |
17 | #include <linux/miscdevice.h> | |
18 | #include <linux/platform_device.h> | |
19 | #include <linux/earlysuspend.h> | |
20 | #include <linux/spinlock.h> | |
21 | #include <linux/kthread.h> | |
22 | #include <linux/hrtimer.h> | |
23 | #include <linux/ktime.h> | |
24 | #include <linux/xlog.h> | |
25 | #include <linux/jiffies.h> | |
26 | #include <linux/version.h> | |
27 | #include <linux/seq_file.h> | |
28 | ||
29 | #include <asm/system.h> | |
30 | #include <asm/uaccess.h> | |
31 | ||
32 | #include "mach/mt_freqhopping.h" | |
33 | #include "mach/mt_typedefs.h" | |
34 | #include "mach/mt_clkmgr.h" | |
35 | #include "mach/mt_cpufreq.h" | |
36 | #include "mach/sync_write.h" | |
37 | #include "mach/pmic_mt6323_sw.h" | |
38 | ||
39 | /************************************************** | |
40 | * enable for DVFS random test | |
41 | ***************************************************/ | |
42 | //#define MT_DVFS_RANDOM_TEST | |
43 | ||
44 | /************************************************** | |
45 | * CPU stress test | |
46 | ***************************************************/ | |
47 | //#define CPUSTRESS_TURBO | |
48 | //#define CPUSTRESS_VPROC_1_15V | |
49 | //#define CPUSTRESS_VPROC_1_25V_GPU_500MHZ_1BUCK | |
50 | ||
51 | /************************************************** | |
52 | * If MT6333/MT6397 supported, VPROC could support lower than 1.15V | |
53 | * MTK_DVFS_DISABLE_LOW_VOLTAGE_SUPPORT only for phone_v1 | |
54 | ***************************************************/ | |
55 | #if (defined(IS_VCORE_USE_6333VCORE) || defined(CONFIG_MTK_PMIC_MT6397)) && !defined(MTK_DVFS_DISABLE_LOW_VOLTAGE_SUPPORT) | |
56 | #define MT_DVFS_LOW_VOLTAGE_SUPPORT | |
57 | #endif | |
58 | ||
59 | /************************************************** | |
60 | * enable this option to adjust buck voltage | |
61 | ***************************************************/ | |
62 | #define MT_BUCK_ADJUST | |
63 | ||
64 | /************************************************** | |
65 | * enable this option to use hopping control | |
66 | ***************************************************/ | |
67 | #define MT_CPUFREQ_FHCTL | |
68 | #define FHCTL_CHANGE_FREQ (1000000) //KHz /* If cross 1GHz when DFS, not used FHCTL. */ | |
69 | ||
70 | /************************************************** | |
71 | * Define register write function | |
72 | ***************************************************/ | |
73 | #define mt_cpufreq_reg_write(val, addr) mt65xx_reg_sync_writel((val), ((void *)addr)) | |
74 | ||
75 | /************************************************** | |
76 | * Change min sample rate in hotplug governor | |
77 | ***************************************************/ | |
78 | #if 0 //#ifdef MTK_SDIOAUTOK_SUPPORT //Check MT8127 timing result | |
79 | #define CPUFREQ_SDIO_TRANSFER | |
80 | #define CPUFREQ_MIN_SAMPLE_RATE_CHANGE (27000) | |
81 | #endif // MTK_SDIOAUTOK_SUPPORT | |
82 | ||
83 | /*************************** | |
84 | * debug message | |
85 | ****************************/ | |
86 | #define dprintk(fmt, args...) \ | |
87 | do { \ | |
88 | if (mt_cpufreq_debug) { \ | |
89 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", fmt, ##args); \ | |
90 | } \ | |
91 | } while(0) | |
92 | ||
93 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) | |
94 | ||
95 | #ifdef CONFIG_HAS_EARLYSUSPEND | |
96 | static struct early_suspend mt_cpufreq_early_suspend_handler = | |
97 | { | |
98 | .level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 200, | |
99 | .suspend = NULL, | |
100 | .resume = NULL, | |
101 | }; | |
102 | #endif | |
103 | ||
104 | #define DVFS_F0_1 (1690000) // KHz | |
105 | #define DVFS_F0_2 (1599000) // KHz | |
106 | #define DVFS_F0_3 (1508000) // KHz | |
107 | #define DVFS_F0_4 (1391000) // KHz | |
108 | #define DVFS_F0 (1300000) // KHz | |
109 | #define DVFS_F1_0 (1222000) // KHz | |
110 | #define DVFS_F1 (1196000) // KHz | |
111 | #define DVFS_F1_1 (1118000) // KHz | |
112 | #define DVFS_F2 (1040000) // KHz | |
113 | #define DVFS_F2_1 (1001000) // KHz | |
114 | #define DVFS_F3 ( 747500) // KHz | |
115 | #define DVFS_F4 ( 598000) // KHz | |
116 | ||
117 | #if defined(HQA_LV_1_09V) | |
4b9e9796 | 118 | #define DVFS_V0 (1250) // mV |
6fa3eb70 S |
119 | #define DVFS_V1 (1150) // mV |
120 | #define DVFS_V2 (1090) // mV | |
121 | #define DVFS_V3 (1090) // mV | |
122 | #elif defined(HQA_NV_1_15V) | |
123 | #define DVFS_V0 (1260) // mV | |
4b9e9796 | 124 | #define DVFS_V1 (1250) // mV |
6fa3eb70 S |
125 | #define DVFS_V2 (1150) // mV |
126 | #define DVFS_V3 (1050) // mV /*Not used */ | |
127 | #elif defined(HQA_HV_1_21V) | |
128 | #define DVFS_V0 (1320) // mV | |
4b9e9796 | 129 | #define DVFS_V1 (1250) // mV |
6fa3eb70 S |
130 | #define DVFS_V2 (1150) // mV /*Not used */ |
131 | #define DVFS_V3 (1050) // mV /*Not used */ | |
132 | #else /* Normal case */ | |
133 | #define DVFS_V0 (1300) // mV | |
4b9e9796 | 134 | #define DVFS_V1 (1250) // mV |
6fa3eb70 S |
135 | #ifdef CPUFREQ_SDIO_TRANSFER |
136 | #define DVFS_V2_0 (1185) // mV | |
137 | #endif | |
138 | #define DVFS_V2 (1150) // mV | |
139 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
140 | #define DVFS_V3 (1050) // mV | |
141 | #endif | |
142 | #endif | |
143 | ||
144 | /***************************************** | |
145 | * PMIC settle time, should not be changed | |
146 | ******************************************/ | |
147 | #define PMIC_SETTLE_TIME (40) // us | |
148 | ||
149 | /***************************************** | |
150 | * PLL settle time, should not be changed | |
151 | ******************************************/ | |
152 | #define PLL_SETTLE_TIME (30) // us | |
153 | ||
154 | /*********************************************** | |
155 | * RMAP DOWN TIMES to postpone frequency degrade | |
156 | ************************************************/ | |
157 | #define RAMP_DOWN_TIMES (2) | |
158 | ||
159 | /********************************** | |
160 | * Available Clock Source for CPU | |
161 | ***********************************/ | |
162 | #define TOP_CKMUXSEL_CLKSQ 0x0 | |
163 | #define TOP_CKMUXSEL_ARMPLL 0x1 | |
164 | #define TOP_CKMUXSEL_MAINPLL 0x2 | |
165 | #define TOP_CKMUXSEL_UNIVPLL 0x3 | |
166 | ||
167 | /************************************************** | |
168 | * enable DVFS function | |
169 | ***************************************************/ | |
170 | static int g_dvfs_disable_count = 0; | |
171 | ||
172 | static unsigned int g_cur_freq; | |
173 | static unsigned int g_cur_cpufreq_volt; | |
174 | static unsigned int g_limited_max_ncpu; | |
175 | static unsigned int g_limited_max_freq; | |
176 | static unsigned int g_limited_min_freq; | |
177 | //static unsigned int g_gpufreq_level = 0; /* GPU 0: 500MHz 1: 416MHz */ | |
178 | static unsigned int g_cpufreq_get_ptp_level = 0; | |
179 | static unsigned int g_max_freq_by_ptp = DVFS_F0; /* default 1.3GHz */ | |
180 | #if defined(CONFIG_THERMAL_LIMIT_TEST) | |
181 | static unsigned int g_limited_load_for_thermal_test = 0; | |
182 | static unsigned int g_limited_max_thermal_power; | |
183 | #endif | |
184 | static unsigned int g_thermal_protect_limited_power = 0; | |
185 | static unsigned int g_cpu_power_table_num = 0; | |
186 | ||
187 | static int g_ramp_down_count = 0; | |
188 | ||
189 | static bool mt_cpufreq_debug = false; | |
190 | static bool mt_cpufreq_ready = false; | |
191 | static bool mt_cpufreq_pause = false; | |
192 | static bool mt_cpufreq_ptpod_disable = false; | |
193 | //static bool mt_cpufreq_ptpod_voltage_down = false; | |
194 | //static bool mt_cpufreq_max_freq_overdrive = false; | |
195 | static bool mt_cpufreq_limit_max_freq_early_suspend = false; | |
196 | static bool mt_cpufreq_earlysuspend_allow_deepidle_control_vproc = false; | |
197 | static bool mt_cpufreq_freq_table_allocated = false; | |
198 | #ifdef CPUFREQ_SDIO_TRANSFER | |
199 | static bool mt_cpufreq_disabled_by_sdio_autoK = false; | |
200 | static bool mt_cpufreq_disabled_by_sdio_ot = false; | |
201 | static bool g_cpufreq_get_vcore_corner = false; | |
202 | #endif | |
203 | ||
204 | /* pmic volt by PTP-OD */ | |
205 | static unsigned int mt_cpufreq_pmic_volt[8] = {0}; | |
206 | ||
207 | #ifdef MT_DVFS_PTPOD_TEST | |
208 | static unsigned int mt_cpufreq_ptpod_test[8] = {0}; | |
209 | #endif | |
210 | ||
211 | static DEFINE_SPINLOCK(mt_cpufreq_lock); | |
212 | ||
213 | #ifdef CPUFREQ_SDIO_TRANSFER | |
214 | static DEFINE_MUTEX(mt_cpufreq_mutex); | |
215 | #endif | |
216 | ||
217 | /*************************** | |
218 | * Operate Point Definition | |
219 | ****************************/ | |
220 | #define OP(khz, volt) \ | |
221 | { \ | |
222 | .cpufreq_khz = khz, \ | |
223 | .cpufreq_volt = volt, \ | |
224 | } | |
225 | ||
226 | struct mt_cpu_freq_info | |
227 | { | |
228 | unsigned int cpufreq_khz; | |
229 | unsigned int cpufreq_volt; | |
230 | }; | |
231 | ||
232 | struct mt_cpu_power_info | |
233 | { | |
234 | unsigned int cpufreq_khz; | |
235 | unsigned int cpufreq_ncpu; | |
236 | unsigned int cpufreq_power; | |
237 | }; | |
238 | ||
239 | /*************************** | |
240 | * MT8127 E1 DVFS Table | |
241 | ****************************/ | |
242 | #if defined(HQA_LV_1_09V) | |
243 | static struct mt_cpu_freq_info mt8127_freqs_e1[] = { | |
244 | OP(DVFS_F0, DVFS_V0), | |
245 | OP(DVFS_F1, DVFS_V0), | |
246 | OP(DVFS_F2, DVFS_V1), | |
247 | OP(DVFS_F3, DVFS_V1), | |
248 | OP(DVFS_F4, DVFS_V2), | |
249 | }; | |
250 | #elif defined(HQA_NV_1_15V) | |
251 | static struct mt_cpu_freq_info mt8127_freqs_e1[] = { | |
252 | OP(DVFS_F0, DVFS_V0), | |
253 | OP(DVFS_F1, DVFS_V1), | |
254 | OP(DVFS_F2, DVFS_V2), | |
255 | OP(DVFS_F3, DVFS_V2), | |
256 | OP(DVFS_F4, DVFS_V2), | |
257 | }; | |
258 | #elif defined(HQA_HV_1_21V) | |
259 | static struct mt_cpu_freq_info mt8127_freqs_e1[] = { | |
260 | OP(DVFS_F0, DVFS_V0), | |
261 | OP(DVFS_F1, DVFS_V1), | |
262 | OP(DVFS_F2, DVFS_V1), | |
263 | OP(DVFS_F3, DVFS_V1), | |
264 | OP(DVFS_F4, DVFS_V1), | |
265 | }; | |
266 | #else /* Normal case */ | |
267 | static struct mt_cpu_freq_info mt8127_freqs_e1[] = { | |
268 | OP(DVFS_F0, DVFS_V0), | |
269 | OP(DVFS_F1, DVFS_V1), | |
270 | OP(DVFS_F2, DVFS_V2), | |
271 | OP(DVFS_F3, DVFS_V2), | |
272 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
273 | OP(DVFS_F4, DVFS_V3), | |
274 | #else | |
275 | OP(DVFS_F4, DVFS_V2), | |
276 | #endif | |
277 | }; | |
278 | #endif | |
279 | #ifdef CPUSTRESS_VPROC_1_25V_GPU_500MHZ_1BUCK | |
280 | static struct mt_cpu_freq_info mt8127_freqs_e1_gpu[] = { | |
281 | OP(DVFS_F0, DVFS_V0), | |
282 | OP(DVFS_F1, DVFS_V0), | |
283 | OP(DVFS_F2, DVFS_V0), | |
284 | OP(DVFS_F3, DVFS_V0), | |
285 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
286 | OP(DVFS_F4, DVFS_V0), | |
287 | #else | |
288 | OP(DVFS_F4, DVFS_V0), | |
289 | #endif | |
290 | }; | |
291 | #endif | |
292 | static struct mt_cpu_freq_info mt8127_freqs_e1_1[] = { | |
293 | OP(DVFS_F0_1, DVFS_V0), | |
294 | OP(DVFS_F1, DVFS_V1), | |
295 | OP(DVFS_F2, DVFS_V2), | |
296 | OP(DVFS_F3, DVFS_V2), | |
297 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
298 | OP(DVFS_F4, DVFS_V3), | |
299 | #else | |
300 | OP(DVFS_F4, DVFS_V2), | |
301 | #endif | |
302 | }; | |
303 | ||
304 | static struct mt_cpu_freq_info mt8127_freqs_e1_2[] = { | |
305 | OP(DVFS_F0_2, DVFS_V0), | |
306 | OP(DVFS_F1, DVFS_V1), | |
307 | OP(DVFS_F2, DVFS_V2), | |
308 | OP(DVFS_F3, DVFS_V2), | |
309 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
310 | OP(DVFS_F4, DVFS_V3), | |
311 | #else | |
312 | OP(DVFS_F4, DVFS_V2), | |
313 | #endif | |
314 | }; | |
315 | ||
316 | static struct mt_cpu_freq_info mt8127_freqs_e1_3[] = { | |
317 | OP(DVFS_F0_3, DVFS_V0), | |
318 | OP(DVFS_F1, DVFS_V1), | |
319 | OP(DVFS_F2, DVFS_V2), | |
320 | OP(DVFS_F3, DVFS_V2), | |
321 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
322 | OP(DVFS_F4, DVFS_V3), | |
323 | #else | |
324 | OP(DVFS_F4, DVFS_V2), | |
325 | #endif | |
326 | }; | |
327 | #if 0 //TOFIX: temp for build warning | |
328 | static struct mt_cpu_freq_info mt8127_freqs_e1_3_gpu[] = { | |
329 | OP(DVFS_F0_3, DVFS_V0), | |
330 | OP(DVFS_F1, DVFS_V0), | |
331 | OP(DVFS_F2, DVFS_V0), | |
332 | OP(DVFS_F3, DVFS_V0), | |
333 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
334 | OP(DVFS_F4, DVFS_V0), | |
335 | #else | |
336 | OP(DVFS_F4, DVFS_V0), | |
337 | #endif | |
338 | }; | |
339 | #endif | |
340 | ||
341 | static struct mt_cpu_freq_info mt8127_freqs_e1_4[] = { | |
342 | OP(DVFS_F0_4, DVFS_V0), | |
343 | OP(DVFS_F1, DVFS_V1), | |
344 | OP(DVFS_F2, DVFS_V2), | |
345 | OP(DVFS_F3, DVFS_V2), | |
346 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
347 | OP(DVFS_F4, DVFS_V3), | |
348 | #else | |
349 | OP(DVFS_F4, DVFS_V2), | |
350 | #endif | |
351 | }; | |
352 | ||
353 | static struct mt_cpu_freq_info mt8127_freqs_e1_5[] = { | |
354 | OP(DVFS_F1_0, DVFS_V1), | |
355 | OP(DVFS_F2, DVFS_V2), | |
356 | OP(DVFS_F3, DVFS_V2), | |
357 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
358 | OP(DVFS_F4, DVFS_V3), | |
359 | #else | |
360 | OP(DVFS_F4, DVFS_V2), | |
361 | #endif | |
362 | }; | |
363 | ||
364 | static struct mt_cpu_freq_info mt8127_freqs_e1_6[] = { | |
365 | OP(DVFS_F1_1, DVFS_V1), | |
366 | OP(DVFS_F2, DVFS_V2), | |
367 | OP(DVFS_F3, DVFS_V2), | |
368 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
369 | OP(DVFS_F4, DVFS_V3), | |
370 | #else | |
371 | OP(DVFS_F4, DVFS_V2), | |
372 | #endif | |
373 | }; | |
374 | ||
375 | static unsigned int mt_cpu_freqs_num; | |
376 | static struct mt_cpu_freq_info *mt_cpu_freqs = NULL; | |
377 | static struct cpufreq_frequency_table *mt_cpu_freqs_table; | |
378 | static struct mt_cpu_power_info *mt_cpu_power = NULL; | |
379 | ||
380 | /****************************** | |
381 | * Internal Function Declaration | |
382 | *******************************/ | |
383 | static void mt_cpufreq_volt_set(unsigned int target_volt); | |
384 | ||
385 | /****************************** | |
386 | * Extern Function Declaration | |
387 | *******************************/ | |
388 | extern int spm_dvfs_ctrl_volt(u32 value); | |
389 | extern int mtk_cpufreq_register(struct mt_cpu_power_info *freqs, int num); | |
390 | extern void hp_limited_cpu_num(int num); | |
391 | extern u32 PTP_get_ptp_level(void); | |
392 | ||
393 | extern unsigned int mt_get_cpu_freq(void); | |
394 | extern void dbs_freq_thermal_limited(unsigned int limited, unsigned int freq); | |
395 | #ifdef CPUFREQ_SDIO_TRANSFER | |
396 | extern int sdio_start_ot_transfer(void); | |
397 | extern int sdio_stop_transfer(void); | |
398 | extern void cpufreq_min_sampling_rate_change(unsigned int sample_rate); | |
399 | extern bool is_vcore_ss_corner(); | |
400 | #endif | |
401 | ||
402 | /*********************************************** | |
403 | * MT8127 E1 Raw Data: 1.3Ghz @ 1.15V @ TT 125C | |
404 | ************************************************/ | |
405 | #define P_MCU_L (346) // MCU Leakage Power | |
406 | #define P_MCU_T (1115) // MCU Total Power | |
407 | #define P_CA7_L (61) // CA7 Leakage Power | |
408 | #define P_CA7_T (240) // Single CA7 Core Power | |
409 | ||
410 | #define P_MCL99_105C_L (658) // MCL99 Leakage Power @ 105C | |
411 | #define P_MCL99_25C_L (93) // MCL99 Leakage Power @ 25C | |
412 | #define P_MCL50_105C_L (316) // MCL50 Leakage Power @ 105C | |
413 | #define P_MCL50_25C_L (35) // MCL50 Leakage Power @ 25C | |
414 | ||
415 | #define T_105 (105) // Temperature 105C | |
416 | #define T_60 (60) // Temperature 60C | |
417 | #define T_25 (25) // Temperature 25C | |
418 | ||
419 | #define P_MCU_D ((P_MCU_T - P_MCU_L) - 4 * (P_CA7_T - P_CA7_L)) // MCU dynamic power except of CA7 cores | |
420 | ||
421 | #define P_TOTAL_CORE_L ((P_MCL99_105C_L * 42165) / 100000) // Total leakage at T_65 | |
422 | #define P_EACH_CORE_L ((P_TOTAL_CORE_L * ((P_CA7_L * 1000) / P_MCU_L)) / 1000) // 1 core leakage at T_65 | |
423 | ||
424 | #define P_CA7_D_1_CORE ((P_CA7_T - P_CA7_L) * 1) // CA7 dynamic power for 1 cores turned on | |
425 | #define P_CA7_D_2_CORE ((P_CA7_T - P_CA7_L) * 2) // CA7 dynamic power for 2 cores turned on | |
426 | #define P_CA7_D_3_CORE ((P_CA7_T - P_CA7_L) * 3) // CA7 dynamic power for 3 cores turned on | |
427 | #define P_CA7_D_4_CORE ((P_CA7_T - P_CA7_L) * 4) // CA7 dynamic power for 4 cores turned on | |
428 | ||
429 | #define A_1_CORE (P_MCU_D + P_CA7_D_1_CORE) // MCU dynamic power for 1 cores turned on | |
430 | #define A_2_CORE (P_MCU_D + P_CA7_D_2_CORE) // MCU dynamic power for 2 cores turned on | |
431 | #define A_3_CORE (P_MCU_D + P_CA7_D_3_CORE) // MCU dynamic power for 3 cores turned on | |
432 | #define A_4_CORE (P_MCU_D + P_CA7_D_4_CORE) // MCU dynamic power for 4 cores turned on | |
433 | ||
434 | /************************************************************************************* | |
435 | * Only if dvfs enter earlysuspend and set 1.1GHz/1.15V, deep idle could control VPROC. | |
436 | **************************************************************************************/ | |
437 | bool mt_cpufreq_earlysuspend_status_get(void) | |
438 | { | |
439 | return mt_cpufreq_earlysuspend_allow_deepidle_control_vproc; | |
440 | } | |
441 | EXPORT_SYMBOL(mt_cpufreq_earlysuspend_status_get); | |
442 | ||
443 | /************************************************ | |
444 | * Limited max frequency in 1.05GHz when early suspend | |
445 | *************************************************/ | |
446 | static unsigned int mt_cpufreq_limit_max_freq_by_early_suspend(void) | |
447 | { | |
448 | struct cpufreq_policy *policy; | |
449 | ||
450 | policy = cpufreq_cpu_get(0); | |
451 | ||
452 | if (!policy) | |
453 | goto no_policy; | |
454 | ||
455 | cpufreq_driver_target(policy, DVFS_F2, CPUFREQ_RELATION_L); | |
456 | ||
457 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq limited max freq by early suspend %d\n", DVFS_F2); | |
458 | ||
459 | cpufreq_cpu_put(policy); | |
460 | ||
461 | no_policy: | |
462 | return g_cur_freq; | |
463 | } | |
464 | ||
465 | #if 0 | |
466 | /* Check the mapping for DVFS voltage and pmic wrap voltage */ | |
467 | /* Need sync with mt_cpufreq_volt_set(), mt_cpufreq_pdrv_probe() */ | |
468 | static unsigned int mt_cpufreq_volt_to_pmic_wrap(unsigned int target_volt) | |
469 | { | |
470 | unsigned int idx = 0; | |
471 | ||
472 | #if 1 | |
473 | switch (target_volt) | |
474 | { | |
475 | case DVFS_V1: | |
476 | idx = 0; // spm_dvfs_ctrl_volt(0); | |
477 | break; | |
478 | case DVFS_V2: | |
479 | idx = 1; // spm_dvfs_ctrl_volt(1); | |
480 | break; | |
481 | case DVFS_V3: | |
482 | idx = 2; // spm_dvfs_ctrl_volt(2); | |
483 | break; | |
484 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
485 | case DVFS_V4: | |
486 | idx = 3; // spm_dvfs_ctrl_volt(3); | |
487 | break; | |
488 | #endif | |
489 | default: | |
490 | break; | |
491 | } | |
492 | ||
493 | #else | |
494 | if(g_cpufreq_get_ptp_level == 0) | |
495 | { | |
496 | switch (target_volt) | |
497 | { | |
498 | case DVFS_V1: | |
499 | idx = 0; // spm_dvfs_ctrl_volt(0); | |
500 | break; | |
501 | case DVFS_V2: | |
502 | idx = 1; // spm_dvfs_ctrl_volt(1); | |
503 | break; | |
504 | case DVFS_V3: | |
505 | idx = 2; // spm_dvfs_ctrl_volt(2); | |
506 | break; | |
507 | case DVFS_V4: | |
508 | idx = 3; // spm_dvfs_ctrl_volt(3); | |
509 | break; | |
510 | default: | |
511 | break; | |
512 | } | |
513 | } | |
514 | else if((g_cpufreq_get_ptp_level >= 1) && (g_cpufreq_get_ptp_level <= 5)) | |
515 | { | |
516 | switch (target_volt) | |
517 | { | |
518 | case DVFS_V0: | |
519 | idx = 0; // spm_dvfs_ctrl_volt(0); | |
520 | break; | |
521 | case DVFS_V1: | |
522 | idx = 1; // spm_dvfs_ctrl_volt(1); | |
523 | break; | |
524 | case DVFS_V2: | |
525 | idx = 2; // spm_dvfs_ctrl_volt(2); | |
526 | break; | |
527 | case DVFS_V3: | |
528 | idx = 3; // spm_dvfs_ctrl_volt(3); | |
529 | break; | |
530 | case DVFS_V4: | |
531 | idx = 4; // spm_dvfs_ctrl_volt(4); | |
532 | break; | |
533 | default: | |
534 | break; | |
535 | } | |
536 | } | |
537 | else | |
538 | { | |
539 | switch (target_volt) | |
540 | { | |
541 | case DVFS_V1: | |
542 | idx = 0; // spm_dvfs_ctrl_volt(0); | |
543 | break; | |
544 | case DVFS_V2: | |
545 | idx = 1; // spm_dvfs_ctrl_volt(1); | |
546 | break; | |
547 | case DVFS_V3: | |
548 | idx = 2; // spm_dvfs_ctrl_volt(2); | |
549 | break; | |
550 | case DVFS_V4: | |
551 | idx = 3; // spm_dvfs_ctrl_volt(3); | |
552 | break; | |
553 | default: | |
554 | break; | |
555 | } | |
556 | } | |
557 | #endif | |
558 | ||
559 | dprintk("mt_cpufreq_volt_to_pmic_wrap: current pmic wrap idx = %d\n", idx); | |
560 | return idx; | |
561 | } | |
562 | #endif | |
563 | ||
564 | /* Set voltage because PTP-OD modified voltage table by PMIC wrapper */ | |
565 | unsigned int mt_cpufreq_voltage_set_by_ptpod(unsigned int pmic_volt[], unsigned int array_size) | |
566 | { | |
567 | int i;//, idx; | |
568 | unsigned long flags; | |
569 | unsigned int PMIC_WRAP_DVFS_WDATA_array[8] = {PMIC_WRAP_DVFS_WDATA0, PMIC_WRAP_DVFS_WDATA1, PMIC_WRAP_DVFS_WDATA2, | |
570 | PMIC_WRAP_DVFS_WDATA3, PMIC_WRAP_DVFS_WDATA4, PMIC_WRAP_DVFS_WDATA5, | |
571 | PMIC_WRAP_DVFS_WDATA6, PMIC_WRAP_DVFS_WDATA7}; | |
572 | ||
573 | if(array_size > (sizeof(mt_cpufreq_pmic_volt)/4)) | |
574 | { | |
575 | dprintk("mt_cpufreq_voltage_set_by_ptpod: ERROR!array_size is invalide, array_size = %d\n", array_size); | |
576 | } | |
577 | ||
578 | spin_lock_irqsave(&mt_cpufreq_lock, flags); | |
579 | ||
580 | /* Update voltage setting by PTPOD request. */ | |
581 | for (i = 0; i < array_size; i++) | |
582 | { | |
583 | mt_cpufreq_reg_write(pmic_volt[i], PMIC_WRAP_DVFS_WDATA_array[i]); | |
584 | } | |
585 | ||
586 | /* For SPM voltage setting in deep idle.*/ | |
587 | /* Need to sync PMIC_WRAP_DVFS_WDATA in mt_cpufreq_pdrv_probe() */ | |
588 | if((g_cpufreq_get_ptp_level >= 0) && (g_cpufreq_get_ptp_level <= 4)) | |
589 | { | |
590 | mt_cpufreq_reg_write(pmic_volt[2], PMIC_WRAP_DVFS_WDATA_array[5]); | |
591 | #ifndef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
592 | mt_cpufreq_reg_write(pmic_volt[2], PMIC_WRAP_DVFS_WDATA_array[7]); | |
593 | #endif | |
594 | } | |
595 | else if((g_cpufreq_get_ptp_level >= 5) && (g_cpufreq_get_ptp_level <= 6)) | |
596 | { | |
597 | mt_cpufreq_reg_write(pmic_volt[1], PMIC_WRAP_DVFS_WDATA_array[5]); | |
598 | #ifndef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
599 | mt_cpufreq_reg_write(pmic_volt[1], PMIC_WRAP_DVFS_WDATA_array[7]); | |
600 | #endif | |
601 | } | |
602 | else | |
603 | { | |
604 | mt_cpufreq_reg_write(pmic_volt[2], PMIC_WRAP_DVFS_WDATA_array[5]); | |
605 | #ifndef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
606 | mt_cpufreq_reg_write(pmic_volt[2], PMIC_WRAP_DVFS_WDATA_array[7]); | |
607 | #endif | |
608 | } | |
609 | ||
610 | for (i = 0; i < array_size; i++) | |
611 | { | |
612 | mt_cpufreq_pmic_volt[i] = pmic_volt[i]; | |
613 | dprintk("mt_cpufreq_pmic_volt[%d] = %x\n", i, mt_cpufreq_pmic_volt[i]); | |
614 | } | |
615 | ||
616 | /* For SPM voltage setting in deep idle.*/ | |
617 | if((g_cpufreq_get_ptp_level >= 0) && (g_cpufreq_get_ptp_level <= 4)) | |
618 | { | |
619 | mt_cpufreq_pmic_volt[5] = pmic_volt[2]; | |
620 | #ifndef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
621 | mt_cpufreq_pmic_volt[7] = pmic_volt[2]; | |
622 | #endif | |
623 | } | |
624 | else if((g_cpufreq_get_ptp_level >= 5) && (g_cpufreq_get_ptp_level <= 6)) | |
625 | { | |
626 | mt_cpufreq_pmic_volt[5] = pmic_volt[1]; | |
627 | #ifndef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
628 | mt_cpufreq_pmic_volt[7] = pmic_volt[1]; | |
629 | #endif | |
630 | } | |
631 | else | |
632 | { | |
633 | mt_cpufreq_pmic_volt[5] = pmic_volt[2]; | |
634 | #ifndef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
635 | mt_cpufreq_pmic_volt[7] = pmic_volt[2]; | |
636 | #endif | |
637 | } | |
638 | ||
639 | dprintk("mt_cpufreq_voltage_set_by_ptpod: Set voltage directly by PTP-OD request!\n"); | |
640 | ||
641 | mt_cpufreq_volt_set(g_cur_cpufreq_volt); | |
642 | ||
643 | spin_unlock_irqrestore(&mt_cpufreq_lock, flags); | |
644 | ||
645 | return 0; | |
646 | } | |
647 | EXPORT_SYMBOL(mt_cpufreq_voltage_set_by_ptpod); | |
648 | ||
649 | /* Look for MAX frequency in number of DVS. */ | |
650 | unsigned int mt_cpufreq_max_frequency_by_DVS(unsigned int num) | |
651 | { | |
652 | int voltage_change_num = 0; | |
653 | int i = 0; | |
654 | ||
655 | /* Assume mt8127_freqs_e1 voltage will be put in order, and freq will be put from high to low.*/ | |
656 | if(num == voltage_change_num) | |
657 | { | |
658 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "PTPOD0:num = %d, frequency= %d\n", num, mt_cpu_freqs[0].cpufreq_khz); | |
659 | return mt_cpu_freqs[0].cpufreq_khz; | |
660 | } | |
661 | ||
662 | for (i = 1; i < mt_cpu_freqs_num; i++) | |
663 | { | |
664 | if(mt_cpu_freqs[i].cpufreq_volt != mt_cpu_freqs[i-1].cpufreq_volt) | |
665 | voltage_change_num++; | |
666 | ||
667 | if(num == voltage_change_num) | |
668 | { | |
669 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "PTPOD1:num = %d, frequency= %d\n", num, mt_cpu_freqs[i].cpufreq_khz); | |
670 | return mt_cpu_freqs[i].cpufreq_khz; | |
671 | } | |
672 | } | |
673 | ||
674 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "PTPOD2:num = %d, NOT found! return 0!\n", num); | |
675 | return 0; | |
676 | } | |
677 | EXPORT_SYMBOL(mt_cpufreq_max_frequency_by_DVS); | |
678 | ||
679 | ||
680 | static void mt_cpufreq_power_calculation(int index, int ncpu) | |
681 | { | |
682 | int multi = 0, p_dynamic = 0, p_leakage = 0, freq_ratio = 0, volt_square_ratio = 0; | |
683 | int possiblecpu = 0; | |
684 | ||
685 | possiblecpu = num_possible_cpus(); | |
686 | ||
687 | volt_square_ratio = (((mt_cpu_freqs[index].cpufreq_volt * 100) / 1150) * ((mt_cpu_freqs[index].cpufreq_volt * 100) / 1150)) / 100; | |
688 | freq_ratio = (mt_cpu_freqs[index].cpufreq_khz / 1300); | |
689 | dprintk("freq_ratio = %d, volt_square_ratio %d\n", freq_ratio, volt_square_ratio); | |
690 | ||
691 | multi = ((mt_cpu_freqs[index].cpufreq_volt * 100) / 1150) * ((mt_cpu_freqs[index].cpufreq_volt * 100) / 1150) * ((mt_cpu_freqs[index].cpufreq_volt * 100) / 1150); | |
692 | ||
693 | switch (ncpu) | |
694 | { | |
695 | case 0: | |
696 | // 1 core | |
697 | p_dynamic = (((A_1_CORE * freq_ratio) / 1000) * volt_square_ratio) / 100; | |
698 | p_leakage = ((P_TOTAL_CORE_L * (multi)) / (100 * 100 * 100)) - 3 * P_EACH_CORE_L; | |
699 | dprintk("p_dynamic = %d, p_leakage = %d\n", p_dynamic, p_leakage); | |
700 | break; | |
701 | case 1: | |
702 | // 2 core | |
703 | p_dynamic = (((A_2_CORE * freq_ratio) / 1000) * volt_square_ratio) / 100; | |
704 | p_leakage = ((P_TOTAL_CORE_L * (multi)) / (100 * 100 * 100)) - 2 * P_EACH_CORE_L; | |
705 | dprintk("p_dynamic = %d, p_leakage = %d\n", p_dynamic, p_leakage); | |
706 | break; | |
707 | case 2: | |
708 | // 3 core | |
709 | p_dynamic = (((A_3_CORE * freq_ratio) / 1000) * volt_square_ratio) / 100; | |
710 | p_leakage = ((P_TOTAL_CORE_L * (multi)) / (100 * 100 * 100)) - 1 * P_EACH_CORE_L; | |
711 | dprintk("p_dynamic = %d, p_leakage = %d\n", p_dynamic, p_leakage); | |
712 | break; | |
713 | case 3: | |
714 | // 4 core | |
715 | p_dynamic = (((A_4_CORE * freq_ratio) / 1000) * volt_square_ratio) / 100; | |
716 | p_leakage = (P_TOTAL_CORE_L * (multi)) / (100 * 100 * 100); | |
717 | dprintk("p_dynamic = %d, p_leakage = %d\n", p_dynamic, p_leakage); | |
718 | break; | |
719 | default: | |
720 | break; | |
721 | } | |
722 | ||
723 | mt_cpu_power[index * possiblecpu + ncpu].cpufreq_ncpu = ncpu + 1; | |
724 | mt_cpu_power[index * possiblecpu + ncpu].cpufreq_khz = mt_cpu_freqs[index].cpufreq_khz; | |
725 | mt_cpu_power[index * possiblecpu + ncpu].cpufreq_power = p_dynamic + p_leakage; | |
726 | ||
727 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpu_power[%d]: cpufreq_ncpu = %d, cpufreq_khz = %d, cpufreq_power = %d\n", (index * possiblecpu + ncpu), | |
728 | mt_cpu_power[index * possiblecpu + ncpu].cpufreq_ncpu, | |
729 | mt_cpu_power[index * possiblecpu + ncpu].cpufreq_khz, | |
730 | mt_cpu_power[index * possiblecpu + ncpu].cpufreq_power); | |
731 | ||
732 | } | |
733 | ||
734 | static void mt_setup_power_table(int num) | |
735 | { | |
736 | int i = 0, j = 0, ncpu = 0, count = 0; | |
737 | struct mt_cpu_power_info temp_power_info; | |
738 | int possiblecpu = 0; | |
739 | unsigned int mt_cpufreq_power_efficiency[20][10]; | |
740 | ||
741 | dprintk("P_MCU_D = %d\n", P_MCU_D); | |
742 | ||
743 | dprintk("P_CA7_D_1_CORE = %d, P_CA7_D_2_CORE = %d, P_CA7_D_3_CORE = %d, P_CA7_D_4_CORE = %d\n", | |
744 | P_CA7_D_1_CORE, P_CA7_D_2_CORE, P_CA7_D_3_CORE, P_CA7_D_4_CORE); | |
745 | ||
746 | dprintk("P_TOTAL_CORE_L = %d, P_EACH_CORE_L = %d\n", | |
747 | P_TOTAL_CORE_L, P_EACH_CORE_L); | |
748 | ||
749 | dprintk("A_1_CORE = %d, A_2_CORE = %d, A_3_CORE = %d, A_4_CORE = %d\n", | |
750 | A_1_CORE, A_2_CORE, A_3_CORE, A_4_CORE); | |
751 | ||
752 | possiblecpu = num_possible_cpus(); | |
753 | ||
754 | memset( (void *)mt_cpufreq_power_efficiency, 0, sizeof(unsigned int)*20*10 ); | |
755 | ||
756 | mt_cpu_power = kzalloc((num * possiblecpu) * sizeof(struct mt_cpu_power_info), GFP_KERNEL); | |
757 | ||
758 | /* Init power table to 0 */ | |
759 | for (i = 0; i < num; i++) | |
760 | { | |
761 | for (j = 0; j < possiblecpu; j++) | |
762 | { | |
763 | mt_cpu_power[i * possiblecpu + j].cpufreq_ncpu = 0; | |
764 | mt_cpu_power[i * possiblecpu + j].cpufreq_khz = 0; | |
765 | mt_cpu_power[i * possiblecpu + j].cpufreq_power = 0; | |
766 | } | |
767 | } | |
768 | ||
769 | /* Setup power efficiency array */ | |
770 | for (i = 0; i < num; i++) | |
771 | { | |
772 | for (j = 0; j < possiblecpu; j++) | |
773 | { | |
774 | ncpu = j + 1; | |
775 | ||
776 | if (ncpu == possiblecpu) | |
777 | continue; /* Keep power table of max cores. */ | |
778 | ||
779 | if(((mt_cpu_freqs_table[i].frequency == DVFS_F0) && (ncpu == 3)) | |
780 | || ((mt_cpu_freqs_table[i].frequency == DVFS_F0) && (ncpu == 2))) | |
781 | { | |
782 | mt_cpufreq_power_efficiency[i][j] = 1; | |
783 | count++; | |
784 | } | |
785 | } | |
786 | } | |
787 | ||
788 | g_cpu_power_table_num = num * possiblecpu - count; /* Need to check, if condition core num change.*/ | |
789 | ||
790 | /* Calculate power and fill in power table */ | |
791 | for (i = 0; i < num; i++) | |
792 | { | |
793 | for (j = 0; j < possiblecpu; j++) | |
794 | { | |
795 | if(mt_cpufreq_power_efficiency[i][j] == 0) | |
796 | mt_cpufreq_power_calculation(i, j); | |
797 | } | |
798 | } | |
799 | ||
800 | /* Sort power table */ | |
801 | for (i = (num * possiblecpu - 1); i > 0; i--) | |
802 | { | |
803 | for (j = 1; j <= i; j++) | |
804 | { | |
805 | if (mt_cpu_power[j - 1].cpufreq_power < mt_cpu_power[j].cpufreq_power) | |
806 | { | |
807 | temp_power_info.cpufreq_khz = mt_cpu_power[j - 1].cpufreq_khz; | |
808 | temp_power_info.cpufreq_ncpu = mt_cpu_power[j - 1].cpufreq_ncpu; | |
809 | temp_power_info.cpufreq_power = mt_cpu_power[j - 1].cpufreq_power; | |
810 | ||
811 | mt_cpu_power[j - 1].cpufreq_khz = mt_cpu_power[j].cpufreq_khz; | |
812 | mt_cpu_power[j - 1].cpufreq_ncpu = mt_cpu_power[j].cpufreq_ncpu; | |
813 | mt_cpu_power[j - 1].cpufreq_power = mt_cpu_power[j].cpufreq_power; | |
814 | ||
815 | mt_cpu_power[j].cpufreq_khz = temp_power_info.cpufreq_khz; | |
816 | mt_cpu_power[j].cpufreq_ncpu = temp_power_info.cpufreq_ncpu; | |
817 | mt_cpu_power[j].cpufreq_power = temp_power_info.cpufreq_power; | |
818 | } | |
819 | } | |
820 | } | |
821 | ||
822 | for (i = 0; i < (num * possiblecpu); i++) | |
823 | { | |
824 | dprintk("mt_cpu_power[%d].cpufreq_khz = %d, ", i, mt_cpu_power[i].cpufreq_khz); | |
825 | dprintk("mt_cpu_power[%d].cpufreq_ncpu = %d, ", i, mt_cpu_power[i].cpufreq_ncpu); | |
826 | dprintk("mt_cpu_power[%d].cpufreq_power = %d\n", i, mt_cpu_power[i].cpufreq_power); | |
827 | } | |
828 | ||
829 | #ifdef CONFIG_THERMAL | |
830 | mtk_cpufreq_register(mt_cpu_power, g_cpu_power_table_num); | |
831 | #endif | |
832 | } | |
833 | ||
834 | /*********************************************** | |
835 | * register frequency table to cpufreq subsystem | |
836 | ************************************************/ | |
837 | static int mt_setup_freqs_table(struct cpufreq_policy *policy, struct mt_cpu_freq_info *freqs, int num) | |
838 | { | |
839 | struct cpufreq_frequency_table *table; | |
840 | int i, ret; | |
841 | ||
842 | if(mt_cpufreq_freq_table_allocated == false) | |
843 | { | |
844 | table = kzalloc((num + 1) * sizeof(*table), GFP_KERNEL); | |
845 | if (table == NULL) | |
846 | return -ENOMEM; | |
847 | ||
848 | for (i = 0; i < num; i++) { | |
849 | table[i].index = i; | |
850 | table[i].frequency = freqs[i].cpufreq_khz; | |
851 | } | |
852 | table[num].index = i; | |
853 | table[num].frequency = CPUFREQ_TABLE_END; | |
854 | ||
855 | mt_cpu_freqs = freqs; | |
856 | mt_cpu_freqs_num = num; | |
857 | mt_cpu_freqs_table = table; | |
858 | ||
859 | mt_cpufreq_freq_table_allocated = true; | |
860 | } | |
861 | ||
862 | ret = cpufreq_frequency_table_cpuinfo(policy, mt_cpu_freqs_table); | |
863 | if (!ret) | |
864 | cpufreq_frequency_table_get_attr(mt_cpu_freqs_table, policy->cpu); | |
865 | ||
866 | if (mt_cpu_power == NULL) | |
867 | mt_setup_power_table(num); | |
868 | ||
869 | return 0; | |
870 | } | |
871 | ||
872 | /***************************** | |
873 | * set CPU DVFS status | |
874 | ******************************/ | |
875 | int mt_cpufreq_state_set(int enabled) | |
876 | { | |
877 | if (enabled) | |
878 | { | |
879 | if (!mt_cpufreq_pause) | |
880 | { | |
881 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "cpufreq already enabled\n"); | |
882 | return 0; | |
883 | } | |
884 | ||
885 | /************* | |
886 | * enable DVFS | |
887 | **************/ | |
888 | g_dvfs_disable_count--; | |
889 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "enable DVFS: g_dvfs_disable_count = %d\n", g_dvfs_disable_count); | |
890 | ||
891 | /*********************************************** | |
892 | * enable DVFS if no any module still disable it | |
893 | ************************************************/ | |
894 | if (g_dvfs_disable_count <= 0) | |
895 | { | |
896 | mt_cpufreq_pause = false; | |
897 | } | |
898 | else | |
899 | { | |
900 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "someone still disable cpufreq, cannot enable it\n"); | |
901 | } | |
902 | } | |
903 | else | |
904 | { | |
905 | /************** | |
906 | * disable DVFS | |
907 | ***************/ | |
908 | g_dvfs_disable_count++; | |
909 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "disable DVFS: g_dvfs_disable_count = %d\n", g_dvfs_disable_count); | |
910 | ||
911 | if (mt_cpufreq_pause) | |
912 | { | |
913 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "cpufreq already disabled\n"); | |
914 | return 0; | |
915 | } | |
916 | ||
917 | mt_cpufreq_pause = true; | |
918 | } | |
919 | ||
920 | return 0; | |
921 | } | |
922 | EXPORT_SYMBOL(mt_cpufreq_state_set); | |
923 | ||
924 | /* cpufreq disabled by sdio autoK */ | |
925 | /* type 0 = autoK, it will change voltage, need to scaling down frequency. */ | |
926 | /* type 1 = online tuning, just need to stop dvfs. */ | |
927 | void mt_cpufreq_disable(unsigned int type, bool disabled) | |
928 | { | |
929 | #ifdef CPUFREQ_SDIO_TRANSFER | |
930 | ||
931 | if(type == 0) | |
932 | { | |
933 | mt_cpufreq_disabled_by_sdio_autoK = disabled; | |
934 | ||
935 | if(mt_cpufreq_disabled_by_sdio_autoK == true) | |
936 | { | |
937 | struct cpufreq_policy *policy; | |
938 | ||
939 | policy = cpufreq_cpu_get(0); | |
940 | ||
941 | if (!policy) | |
942 | goto no_policy; | |
943 | ||
944 | cpufreq_driver_target(policy, DVFS_F2, CPUFREQ_RELATION_L); | |
945 | ||
946 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq_disable, limited freq. at %d\n", DVFS_F2); | |
947 | ||
948 | cpufreq_cpu_put(policy); | |
949 | } | |
950 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq_disable, mt_cpufreq_disabled_by_sdio_autoK = %d\n", mt_cpufreq_disabled_by_sdio_autoK); | |
951 | } | |
952 | else if(type == 1) | |
953 | { | |
954 | mt_cpufreq_disabled_by_sdio_ot = disabled; | |
955 | dprintk("mt_cpufreq_disable: mt_cpufreq_disabled_by_sdio_ot = %d\n", mt_cpufreq_disabled_by_sdio_ot); | |
956 | } | |
957 | ||
958 | no_policy: | |
959 | return; | |
960 | ||
961 | #endif | |
962 | } | |
963 | EXPORT_SYMBOL(mt_cpufreq_disable); | |
964 | ||
965 | /* 1.15V = 1150000, 1.2125V = 1212500, 1.28125V = 1281250 */ | |
966 | void mt_cpufreq_volt_set_by_sdio(unsigned int volt) | |
967 | { | |
968 | #ifdef CPUFREQ_SDIO_TRANSFER | |
969 | unsigned int reg = 0; | |
970 | ||
971 | reg = (volt - 700000) / 6250; | |
972 | ||
973 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq_volt_set_by_sdio, reg = %d\n", reg); | |
974 | ||
975 | /* sdio autoK need to disable dvfs first, then set volt. */ | |
976 | if(mt_cpufreq_disabled_by_sdio_autoK == true) | |
977 | { | |
978 | #if CONFIG_MTK_PMIC_MT6397 | |
979 | pmic_config_interface(0x226,reg,0xFFFF,0); | |
980 | pmic_config_interface(0x228,reg,0xFFFF,0); | |
981 | #else | |
982 | pmic_config_interface(0x21E,reg,0xFFFF,0); | |
983 | pmic_config_interface(0x220,reg,0xFFFF,0); | |
984 | #endif | |
985 | } | |
986 | else | |
987 | { | |
988 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq_volt_set_by_sdio, could not set volt now, mt_cpufreq_disabled_by_sdio_autoK = %d\n", mt_cpufreq_disabled_by_sdio_autoK); | |
989 | } | |
990 | #endif | |
991 | } | |
992 | EXPORT_SYMBOL(mt_cpufreq_volt_set_by_sdio); | |
993 | ||
994 | ||
995 | static int mt_cpufreq_verify(struct cpufreq_policy *policy) | |
996 | { | |
997 | dprintk("call mt_cpufreq_verify!\n"); | |
998 | return cpufreq_frequency_table_verify(policy, mt_cpu_freqs_table); | |
999 | } | |
1000 | ||
1001 | static unsigned int mt_cpufreq_get(unsigned int cpu) | |
1002 | { | |
1003 | dprintk("call mt_cpufreq_get: %d!\n", g_cur_freq); | |
1004 | return g_cur_freq; | |
1005 | } | |
1006 | ||
1007 | static void mt_cpu_clock_switch(unsigned int sel) | |
1008 | { | |
1009 | unsigned int ckmuxsel = 0; | |
1010 | ||
1011 | ckmuxsel = DRV_Reg32(TOP_CKMUXSEL) & ~0xC; | |
1012 | ||
1013 | switch (sel) | |
1014 | { | |
1015 | case TOP_CKMUXSEL_CLKSQ: | |
1016 | mt_cpufreq_reg_write((ckmuxsel | 0x00), TOP_CKMUXSEL); | |
1017 | break; | |
1018 | case TOP_CKMUXSEL_ARMPLL: | |
1019 | mt_cpufreq_reg_write((ckmuxsel | 0x04), TOP_CKMUXSEL); | |
1020 | break; | |
1021 | case TOP_CKMUXSEL_MAINPLL: | |
1022 | mt_cpufreq_reg_write((ckmuxsel | 0x08), TOP_CKMUXSEL); | |
1023 | break; | |
1024 | case TOP_CKMUXSEL_UNIVPLL: | |
1025 | mt_cpufreq_reg_write((ckmuxsel | 0x0C), TOP_CKMUXSEL); | |
1026 | break; | |
1027 | default: | |
1028 | break; | |
1029 | } | |
1030 | } | |
1031 | ||
1032 | /* Need sync with mt_cpufreq_volt_to_pmic_wrap(), mt_cpufreq_pdrv_probe() */ | |
1033 | static void mt_cpufreq_volt_set(unsigned int target_volt) | |
1034 | { | |
1035 | #if 0 | |
1036 | switch (target_volt) | |
1037 | { | |
1038 | case DVFS_V1: | |
1039 | dprintk("switch to DVS0: %d mV\n", DVFS_V1); | |
1040 | spm_dvfs_ctrl_volt(0); | |
1041 | break; | |
1042 | case DVFS_V2: | |
1043 | dprintk("switch to DVS1: %d mV\n", DVFS_V2); | |
1044 | spm_dvfs_ctrl_volt(1); | |
1045 | break; | |
1046 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1047 | case DVFS_V3: | |
1048 | dprintk("switch to DVS2: %d mV\n", DVFS_V3); | |
1049 | spm_dvfs_ctrl_volt(2); | |
1050 | break; | |
1051 | #endif | |
1052 | default: | |
1053 | break; | |
1054 | } | |
1055 | #else | |
1056 | if((g_cpufreq_get_ptp_level >= 0) && (g_cpufreq_get_ptp_level <= 4)) | |
1057 | { | |
1058 | switch (target_volt) | |
1059 | { | |
1060 | case DVFS_V0: | |
1061 | dprintk("switch to DVS0: %d mV\n", DVFS_V0); | |
1062 | spm_dvfs_ctrl_volt(0); | |
1063 | break; | |
1064 | case DVFS_V1: | |
1065 | dprintk("switch to DVS1: %d mV\n", DVFS_V1); | |
1066 | spm_dvfs_ctrl_volt(1); | |
1067 | break; | |
1068 | case DVFS_V2: | |
1069 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1070 | if(g_cpufreq_get_vcore_corner == false) | |
1071 | dprintk("switch to DVS2: %d mV\n", DVFS_V2); | |
1072 | else | |
1073 | dprintk("switch to DVS2_0: %d mV\n", DVFS_V2_0); | |
1074 | #else | |
1075 | dprintk("switch to DVS2: %d mV\n", DVFS_V2); | |
1076 | #endif | |
1077 | ||
1078 | spm_dvfs_ctrl_volt(2); | |
1079 | break; | |
1080 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1081 | case DVFS_V3: | |
1082 | dprintk("switch to DVS3: %d mV\n", DVFS_V3); | |
1083 | spm_dvfs_ctrl_volt(3); | |
1084 | break; | |
1085 | #endif | |
1086 | default: | |
1087 | break; | |
1088 | } | |
1089 | } | |
1090 | else if((g_cpufreq_get_ptp_level >= 5) && (g_cpufreq_get_ptp_level <= 6)) | |
1091 | { | |
1092 | switch (target_volt) | |
1093 | { | |
1094 | case DVFS_V1: | |
1095 | dprintk("switch to DVS0: %d mV\n", DVFS_V1); | |
1096 | spm_dvfs_ctrl_volt(0); | |
1097 | break; | |
1098 | case DVFS_V2: | |
1099 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1100 | if(g_cpufreq_get_vcore_corner == false) | |
1101 | dprintk("switch to DVS2: %d mV\n", DVFS_V2); | |
1102 | else | |
1103 | dprintk("switch to DVS2_0: %d mV\n", DVFS_V2_0); | |
1104 | #else | |
1105 | dprintk("switch to DVS2: %d mV\n", DVFS_V2); | |
1106 | #endif | |
1107 | ||
1108 | spm_dvfs_ctrl_volt(1); | |
1109 | break; | |
1110 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1111 | case DVFS_V3: | |
1112 | dprintk("switch to DVS2: %d mV\n", DVFS_V3); | |
1113 | spm_dvfs_ctrl_volt(2); | |
1114 | break; | |
1115 | #endif | |
1116 | default: | |
1117 | break; | |
1118 | ||
1119 | } | |
1120 | } | |
1121 | else | |
1122 | { | |
1123 | switch (target_volt) | |
1124 | { | |
1125 | case DVFS_V0: | |
1126 | dprintk("switch to DVS0: %d mV\n", DVFS_V0); | |
1127 | spm_dvfs_ctrl_volt(0); | |
1128 | break; | |
1129 | case DVFS_V1: | |
1130 | dprintk("switch to DVS1: %d mV\n", DVFS_V1); | |
1131 | spm_dvfs_ctrl_volt(1); | |
1132 | break; | |
1133 | case DVFS_V2: | |
1134 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1135 | if(g_cpufreq_get_vcore_corner == false) | |
1136 | dprintk("switch to DVS2: %d mV\n", DVFS_V2); | |
1137 | else | |
1138 | dprintk("switch to DVS2_0: %d mV\n", DVFS_V2_0); | |
1139 | #else | |
1140 | dprintk("switch to DVS2: %d mV\n", DVFS_V2); | |
1141 | #endif | |
1142 | ||
1143 | spm_dvfs_ctrl_volt(2); | |
1144 | break; | |
1145 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1146 | case DVFS_V3: | |
1147 | dprintk("switch to DVS3: %d mV\n", DVFS_V3); | |
1148 | spm_dvfs_ctrl_volt(3); | |
1149 | break; | |
1150 | #endif | |
1151 | default: | |
1152 | break; | |
1153 | } | |
1154 | } | |
1155 | #endif | |
1156 | } | |
1157 | ||
1158 | /***************************************** | |
1159 | * frequency ramp up and ramp down handler | |
1160 | ******************************************/ | |
1161 | /*********************************************************** | |
1162 | * [note] | |
1163 | * 1. frequency ramp up need to wait voltage settle | |
1164 | * 2. frequency ramp down do not need to wait voltage settle | |
1165 | ************************************************************/ | |
1166 | static void mt_cpufreq_set(unsigned int freq_old, unsigned int freq_new, unsigned int target_volt) | |
1167 | { | |
1168 | unsigned int armpll = 0; | |
1169 | ||
1170 | dprintk("Before scaling: ARMPLL_CON0 = 0x%x, ARMPLL_CON1 = 0x%x, g_cur_freq = %d\n", DRV_Reg32(ARMPLL_CON0), DRV_Reg32(ARMPLL_CON1), g_cur_freq); | |
1171 | ||
1172 | if (freq_new >= 1001000) | |
1173 | { | |
1174 | armpll = 0x8009A000; | |
1175 | armpll = armpll + ((freq_new - 1001000) / 13000) * 0x2000; | |
1176 | } | |
1177 | else if (freq_new >= 500500) | |
1178 | { | |
1179 | armpll = 0x8109A000; | |
1180 | armpll = armpll + ((freq_new - 500500) / 6500) * 0x2000; | |
1181 | } | |
1182 | else if (freq_new >= 250250) | |
1183 | { | |
1184 | armpll = 0x8209A000; | |
1185 | armpll = armpll + ((freq_new - 250250) / 3250) * 0x2000; | |
1186 | } | |
1187 | else if (freq_new >= 125125) | |
1188 | { | |
1189 | armpll = 0x8309A000; | |
1190 | armpll = armpll + ((freq_new - 125125) / 1625) * 0x2000; | |
1191 | } | |
1192 | else | |
1193 | { | |
1194 | armpll = 0x8409A000; | |
1195 | armpll = armpll + ((freq_new - 62562) / 812) * 0x2000; | |
1196 | } | |
1197 | ||
1198 | /* YP comment no need to call enable/disable pll. mainpll will always on until suspend. */ | |
1199 | //enable_pll(MAINPLL, "CPU_DVFS"); | |
1200 | if (freq_new > freq_old) | |
1201 | { | |
1202 | #ifdef MT_BUCK_ADJUST | |
1203 | mt_cpufreq_volt_set(target_volt); | |
1204 | udelay(PMIC_SETTLE_TIME); | |
1205 | #endif | |
1206 | ||
1207 | #ifdef MT_CPUFREQ_FHCTL | |
1208 | if(((freq_new > FHCTL_CHANGE_FREQ) && (freq_old > FHCTL_CHANGE_FREQ)) || ((freq_new < FHCTL_CHANGE_FREQ) && (freq_old < FHCTL_CHANGE_FREQ))) | |
1209 | { | |
4b9e9796 | 1210 | dprintk("Before === FHCTL: freq_new = %d < freq_old = %d ===\n", freq_new, freq_old); |
6fa3eb70 S |
1211 | mt_dfs_armpll(freq_old, freq_new); |
1212 | dprintk("=== FHCTL: freq_new = %d > freq_old = %d ===\n", freq_new, freq_old); | |
1213 | ||
1214 | dprintk("=== FHCTL: freq meter = %d ===\n", mt_get_cpu_freq()); | |
1215 | } | |
1216 | else | |
1217 | { | |
1218 | #endif | |
1219 | ||
1220 | mt_cpufreq_reg_write(0x0A, TOP_CKDIV1_CPU); | |
1221 | mt_cpu_clock_switch(TOP_CKMUXSEL_MAINPLL); | |
1222 | ||
1223 | mt_cpufreq_reg_write(armpll, ARMPLL_CON1); | |
1224 | ||
1225 | mb(); | |
1226 | udelay(PLL_SETTLE_TIME); | |
1227 | ||
1228 | mt_cpu_clock_switch(TOP_CKMUXSEL_ARMPLL); | |
1229 | mt_cpufreq_reg_write(0x00, TOP_CKDIV1_CPU); | |
1230 | ||
1231 | #ifdef MT_CPUFREQ_FHCTL | |
1232 | } | |
1233 | #endif | |
1234 | } | |
1235 | else | |
1236 | { | |
1237 | #ifdef MT_CPUFREQ_FHCTL | |
1238 | if(((freq_new > FHCTL_CHANGE_FREQ) && (freq_old > FHCTL_CHANGE_FREQ)) || ((freq_new < FHCTL_CHANGE_FREQ) && (freq_old < FHCTL_CHANGE_FREQ))) | |
1239 | { | |
4b9e9796 | 1240 | dprintk("Before === FHCTL: freq_new = %d < freq_old = %d ===\n", freq_new, freq_old); |
6fa3eb70 S |
1241 | mt_dfs_armpll(freq_old, freq_new); |
1242 | dprintk("=== FHCTL: freq_new = %d < freq_old = %d ===\n", freq_new, freq_old); | |
1243 | ||
1244 | dprintk("=== FHCTL: freq meter = %d ===\n", mt_get_cpu_freq()); | |
1245 | } | |
1246 | else | |
1247 | { | |
1248 | #endif | |
1249 | ||
1250 | mt_cpufreq_reg_write(0x0A, TOP_CKDIV1_CPU); | |
1251 | mt_cpu_clock_switch(TOP_CKMUXSEL_MAINPLL); | |
1252 | ||
1253 | mt_cpufreq_reg_write(armpll, ARMPLL_CON1); | |
1254 | ||
1255 | mb(); | |
1256 | udelay(PLL_SETTLE_TIME); | |
1257 | ||
1258 | mt_cpu_clock_switch(TOP_CKMUXSEL_ARMPLL); | |
1259 | mt_cpufreq_reg_write(0x00, TOP_CKDIV1_CPU); | |
1260 | ||
1261 | #ifdef MT_CPUFREQ_FHCTL | |
1262 | } | |
1263 | #endif | |
1264 | ||
1265 | #ifdef MT_BUCK_ADJUST | |
1266 | mt_cpufreq_volt_set(target_volt); | |
1267 | #endif | |
1268 | } | |
1269 | //disable_pll(MAINPLL, "CPU_DVFS"); | |
1270 | ||
1271 | g_cur_freq = freq_new; | |
1272 | g_cur_cpufreq_volt = target_volt; | |
1273 | ||
1274 | dprintk("After scaling: ARMPLL_CON0 = 0x%x, ARMPLL_CON1 = 0x%x, g_cur_freq = %d\n", DRV_Reg32(ARMPLL_CON0), DRV_Reg32(ARMPLL_CON1), g_cur_freq); | |
1275 | } | |
1276 | ||
1277 | /************************************** | |
1278 | * check if maximum frequency is needed | |
1279 | ***************************************/ | |
1280 | static int mt_cpufreq_keep_org_freq(unsigned int freq_old, unsigned int freq_new) | |
1281 | { | |
1282 | if (mt_cpufreq_pause) | |
1283 | return 1; | |
1284 | ||
1285 | /* check if system is going to ramp down */ | |
1286 | if (freq_new < freq_old) | |
1287 | { | |
1288 | g_ramp_down_count++; | |
1289 | if (g_ramp_down_count < RAMP_DOWN_TIMES) | |
1290 | return 1; | |
1291 | else | |
1292 | return 0; | |
1293 | } | |
1294 | else | |
1295 | { | |
1296 | g_ramp_down_count = 0; | |
1297 | return 0; | |
1298 | } | |
1299 | } | |
1300 | ||
1301 | #ifdef MT_DVFS_RANDOM_TEST | |
1302 | static int mt_cpufreq_idx_get(int num) | |
1303 | { | |
1304 | int random = 0, mult = 0, idx; | |
1305 | random = jiffies & 0xF; | |
1306 | ||
1307 | while (1) | |
1308 | { | |
1309 | if ((mult * num) >= random) | |
1310 | { | |
1311 | idx = (mult * num) - random; | |
1312 | break; | |
1313 | } | |
1314 | mult++; | |
1315 | } | |
1316 | return idx; | |
1317 | } | |
1318 | #endif | |
1319 | ||
1320 | static unsigned int mt_thermal_limited_verify(unsigned int target_freq) | |
1321 | { | |
1322 | int i = 0, index = 0; | |
1323 | ||
1324 | if(g_thermal_protect_limited_power == 0) | |
1325 | return target_freq; | |
1326 | ||
1327 | for (i = 0; i < g_cpu_power_table_num; i++) | |
1328 | { | |
1329 | if (mt_cpu_power[i].cpufreq_ncpu == g_limited_max_ncpu && mt_cpu_power[i].cpufreq_khz == g_limited_max_freq) | |
1330 | { | |
1331 | index = i; | |
1332 | break; | |
1333 | } | |
1334 | } | |
1335 | ||
1336 | for (index = i; index < g_cpu_power_table_num; index++) | |
1337 | { | |
1338 | if (mt_cpu_power[index].cpufreq_ncpu == num_online_cpus()) | |
1339 | { | |
1340 | if (target_freq >= mt_cpu_power[index].cpufreq_khz) | |
1341 | { | |
1342 | dprintk("target_freq = %d, ncpu = %d\n", mt_cpu_power[index].cpufreq_khz, num_online_cpus()); | |
1343 | target_freq = mt_cpu_power[index].cpufreq_khz; | |
1344 | break; | |
1345 | } | |
1346 | } | |
1347 | } | |
1348 | ||
1349 | return target_freq; | |
1350 | } | |
1351 | ||
1352 | /********************************** | |
1353 | * cpufreq target callback function | |
1354 | ***********************************/ | |
1355 | /************************************************* | |
1356 | * [note] | |
1357 | * 1. handle frequency change request | |
1358 | * 2. call mt_cpufreq_set to set target frequency | |
1359 | **************************************************/ | |
1360 | static int mt_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) | |
1361 | { | |
1362 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) | |
1363 | unsigned int cpu; | |
1364 | #endif | |
1365 | int i, idx; | |
1366 | unsigned long flags; | |
1367 | int ret = 0; | |
1368 | ||
1369 | struct mt_cpu_freq_info next; | |
1370 | struct cpufreq_freqs freqs; | |
1371 | ||
1372 | if (!mt_cpufreq_ready) | |
1373 | return -ENOSYS; | |
1374 | ||
1375 | if (policy->cpu >= num_possible_cpus()) | |
1376 | return -EINVAL; | |
1377 | ||
1378 | ret = 0; | |
1379 | ||
1380 | /****************************** | |
1381 | * look up the target frequency | |
1382 | *******************************/ | |
1383 | if (cpufreq_frequency_table_target(policy, mt_cpu_freqs_table, target_freq, relation, &idx)) | |
1384 | { | |
1385 | return -EINVAL; | |
1386 | } | |
1387 | ||
1388 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1389 | /************************************************ | |
1390 | * DVFS disabled when sdio omline tuning | |
1391 | *************************************************/ | |
1392 | if (mt_cpufreq_disabled_by_sdio_ot == TRUE) | |
1393 | { | |
1394 | dprintk("SDIO online tuning, disable dvfs, return!\n"); | |
1395 | return 0; | |
1396 | } | |
1397 | #endif | |
1398 | ||
1399 | #ifdef MT_DVFS_RANDOM_TEST | |
1400 | idx = mt_cpufreq_idx_get(5); | |
1401 | #endif | |
1402 | ||
1403 | #if 0 | |
1404 | next.cpufreq_khz = mt8127_freqs_e1[idx].cpufreq_khz; | |
1405 | #else | |
1406 | if(g_cpufreq_get_ptp_level == 0) | |
1407 | #ifdef CPUSTRESS_VPROC_1_25V_GPU_500MHZ_1BUCK | |
1408 | next.cpufreq_khz = mt8127_freqs_e1_gpu[idx].cpufreq_khz; | |
1409 | #else | |
1410 | next.cpufreq_khz = mt8127_freqs_e1[idx].cpufreq_khz; | |
1411 | #endif | |
1412 | else if(g_cpufreq_get_ptp_level == 1) | |
1413 | next.cpufreq_khz = mt8127_freqs_e1_1[idx].cpufreq_khz; | |
1414 | else if(g_cpufreq_get_ptp_level == 2) | |
1415 | next.cpufreq_khz = mt8127_freqs_e1_2[idx].cpufreq_khz; | |
1416 | else if(g_cpufreq_get_ptp_level == 3) | |
1417 | #ifdef CPUSTRESS_VPROC_1_25V_GPU_500MHZ_1BUCK | |
1418 | next.cpufreq_khz = mt8127_freqs_e1_3_gpu[idx].cpufreq_khz; | |
1419 | #else | |
1420 | next.cpufreq_khz = mt8127_freqs_e1_3[idx].cpufreq_khz; | |
1421 | #endif | |
1422 | else if(g_cpufreq_get_ptp_level == 4) | |
1423 | next.cpufreq_khz = mt8127_freqs_e1_4[idx].cpufreq_khz; | |
1424 | else if(g_cpufreq_get_ptp_level == 5) | |
1425 | next.cpufreq_khz = mt8127_freqs_e1_5[idx].cpufreq_khz; | |
1426 | else if(g_cpufreq_get_ptp_level == 6) | |
1427 | next.cpufreq_khz = mt8127_freqs_e1_6[idx].cpufreq_khz; | |
1428 | else | |
1429 | next.cpufreq_khz = mt8127_freqs_e1[idx].cpufreq_khz; | |
1430 | #endif | |
1431 | ||
1432 | #ifdef MT_DVFS_RANDOM_TEST | |
1433 | dprintk("idx = %d, freqs.old = %d, freqs.new = %d\n", idx, policy->cur, next.cpufreq_khz); | |
1434 | #endif | |
1435 | ||
1436 | freqs.old = policy->cur; | |
1437 | freqs.new = next.cpufreq_khz; | |
1438 | freqs.cpu = policy->cpu; | |
1439 | ||
1440 | #ifndef MT_DVFS_RANDOM_TEST | |
1441 | if (mt_cpufreq_keep_org_freq(freqs.old, freqs.new)) | |
1442 | { | |
1443 | freqs.new = freqs.old; | |
1444 | } | |
1445 | ||
1446 | /************************************************ | |
1447 | * DVFS keep at 1.05GHz/1.15V in earlysuspend when max freq overdrive. | |
1448 | *************************************************/ | |
1449 | if(mt_cpufreq_limit_max_freq_early_suspend == true) | |
1450 | { | |
1451 | freqs.new = DVFS_F2; | |
1452 | dprintk("mt_cpufreq_limit_max_freq_early_suspend, freqs.new = %d\n", freqs.new); | |
1453 | } | |
1454 | ||
1455 | ||
1456 | freqs.new = mt_thermal_limited_verify(freqs.new); | |
1457 | ||
1458 | if (freqs.new < g_limited_min_freq) | |
1459 | { | |
1460 | dprintk("cannot switch CPU frequency to %d Mhz due to voltage limitation\n", g_limited_min_freq / 1000); | |
1461 | freqs.new = g_limited_min_freq; | |
1462 | } | |
1463 | #endif | |
1464 | ||
1465 | /************************************************ | |
1466 | * DVFS keep at 1.05Ghz/1.15V when PTPOD initial | |
1467 | *************************************************/ | |
1468 | if (mt_cpufreq_ptpod_disable) | |
1469 | { | |
1470 | freqs.new = DVFS_F2; | |
1471 | dprintk("PTPOD, freqs.new = %d\n", freqs.new); | |
1472 | } | |
1473 | ||
1474 | /************************************************ | |
1475 | * If MT6333 not support and ISP_VDEC on, | |
1476 | * DVFS can only higher than 1.05Ghz/1.15V when 4 online cpu, for power consumption. | |
1477 | *************************************************/ | |
1478 | #ifndef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1479 | if ( (num_possible_cpus() == 4) && (num_online_cpus() < num_possible_cpus()) && (freqs.new > DVFS_F2)) | |
1480 | { | |
1481 | if (subsys_is_on(SYS_ISP) || subsys_is_on(SYS_VDE)) //(isp_vdec_on_off() == true) | |
1482 | { | |
1483 | dprintk("Limited frequency, because num_online_cpus() = %d, freqs.new = %d\n", num_online_cpus(), freqs.new); | |
1484 | freqs.new = DVFS_F2; | |
1485 | } | |
1486 | } | |
1487 | #endif | |
1488 | ||
1489 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1490 | /************************************************ | |
1491 | * DVFS keep at 1.05Ghz/1.15V when sdio autoK | |
1492 | *************************************************/ | |
1493 | if (mt_cpufreq_disabled_by_sdio_autoK == TRUE) | |
1494 | { | |
1495 | freqs.new = DVFS_F2; | |
1496 | dprintk("SDIO auto K, fix freq, freqs.new = %d\n", freqs.new); | |
1497 | } | |
1498 | #endif | |
1499 | ||
1500 | /************************************************ | |
1501 | * target frequency == existing frequency, skip it | |
1502 | *************************************************/ | |
1503 | if (freqs.old == freqs.new) | |
1504 | { | |
1505 | dprintk("CPU frequency from %d MHz to %d MHz (skipped) due to same frequency\n", freqs.old / 1000, freqs.new / 1000); | |
1506 | return 0; | |
1507 | } | |
1508 | ||
1509 | /************************************** | |
1510 | * search for the corresponding voltage | |
1511 | ***************************************/ | |
1512 | next.cpufreq_volt = 0; | |
1513 | ||
1514 | for (i = 0; i < mt_cpu_freqs_num; i++) | |
1515 | { | |
1516 | dprintk("freqs.new = %d, mt_cpu_freqs[%d].cpufreq_khz = %d\n", freqs.new, i, mt_cpu_freqs[i].cpufreq_khz); | |
1517 | if (freqs.new == mt_cpu_freqs[i].cpufreq_khz) | |
1518 | { | |
1519 | next.cpufreq_volt = mt_cpu_freqs[i].cpufreq_volt; | |
1520 | dprintk("next.cpufreq_volt = %d, mt_cpu_freqs[%d].cpufreq_volt = %d\n", next.cpufreq_volt, i, mt_cpu_freqs[i].cpufreq_volt); | |
1521 | break; | |
1522 | } | |
1523 | } | |
1524 | ||
1525 | if (next.cpufreq_volt == 0) | |
1526 | { | |
1527 | dprintk("Error!! Cannot find corresponding voltage at %d Mhz\n", freqs.new / 1000); | |
1528 | return 0; | |
1529 | } | |
1530 | ||
1531 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1532 | mutex_lock(&mt_cpufreq_mutex); | |
1533 | ||
1534 | ret = sdio_stop_transfer(); | |
1535 | #endif | |
1536 | ||
1537 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) | |
1538 | for_each_online_cpu(cpu) | |
1539 | { | |
1540 | freqs.cpu = cpu; | |
1541 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | |
1542 | } | |
1543 | #else | |
1544 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | |
1545 | #endif | |
1546 | ||
1547 | spin_lock_irqsave(&mt_cpufreq_lock, flags); | |
1548 | ||
1549 | /****************************** | |
1550 | * set to the target freeuency | |
1551 | *******************************/ | |
4b9e9796 S |
1552 | /* Get current frequency */ |
1553 | freqs.old = g_cur_freq; | |
1554 | ||
1555 | if (freqs.old != freqs.new) | |
1556 | mt_cpufreq_set(freqs.old, freqs.new, next.cpufreq_volt); | |
1557 | else | |
1558 | dprintk("CPU frequency from %d MHz to %d MHz (skipped) due to same frequency in critical seciton check\n", freqs.old / 1000, freqs.new / 1000); | |
6fa3eb70 S |
1559 | |
1560 | spin_unlock_irqrestore(&mt_cpufreq_lock, flags); | |
1561 | ||
1562 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) | |
1563 | for_each_online_cpu(cpu) | |
1564 | { | |
1565 | freqs.cpu = cpu; | |
1566 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | |
1567 | } | |
1568 | #else | |
1569 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | |
1570 | #endif | |
1571 | ||
1572 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1573 | if(ret == 0) | |
1574 | sdio_start_ot_transfer(); | |
1575 | ||
1576 | mutex_unlock(&mt_cpufreq_mutex); | |
1577 | #endif | |
1578 | ||
1579 | return 0; | |
1580 | } | |
1581 | ||
1582 | /********************************************************* | |
1583 | * set up frequency table and register to cpufreq subsystem | |
1584 | **********************************************************/ | |
1585 | static int mt_cpufreq_init(struct cpufreq_policy *policy) | |
1586 | { | |
1587 | int ret = -EINVAL; | |
1588 | ||
1589 | if (policy->cpu >= num_possible_cpus()) | |
1590 | return -EINVAL; | |
1591 | ||
1592 | policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; | |
1593 | cpumask_setall(policy->cpus); | |
1594 | ||
1595 | /******************************************************* | |
1596 | * 1 us, assumed, will be overwrited by min_sampling_rate | |
1597 | ********************************************************/ | |
1598 | policy->cpuinfo.transition_latency = 1000; | |
1599 | ||
1600 | /********************************************* | |
1601 | * set default policy and cpuinfo, unit : Khz | |
1602 | **********************************************/ | |
1603 | policy->cpuinfo.max_freq = g_max_freq_by_ptp; | |
1604 | policy->cpuinfo.min_freq = DVFS_F4; | |
1605 | ||
1606 | policy->cur = DVFS_F2; /* Default 1.05GHz in preloader */ | |
1607 | policy->max = g_max_freq_by_ptp; | |
1608 | policy->min = DVFS_F4; | |
1609 | ||
1610 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1611 | // to check | |
1612 | // mutex_init(&mt_cpufreq_mutex); | |
1613 | #endif | |
1614 | ||
1615 | #if 0 | |
1616 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1)); | |
1617 | #else | |
1618 | if(g_cpufreq_get_ptp_level == 0) | |
1619 | #ifdef CPUSTRESS_VPROC_1_25V_GPU_500MHZ_1BUCK | |
1620 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1_gpu)); | |
1621 | #else | |
1622 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1)); | |
1623 | #endif | |
1624 | else if(g_cpufreq_get_ptp_level == 1) | |
1625 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1_1)); | |
1626 | else if(g_cpufreq_get_ptp_level == 2) | |
1627 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1_2)); | |
1628 | else if(g_cpufreq_get_ptp_level == 3) | |
1629 | #ifdef CPUSTRESS_VPROC_1_25V_GPU_500MHZ_1BUCK | |
1630 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1_3_gpu)); | |
1631 | #else | |
1632 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1_3)); | |
1633 | #endif | |
1634 | else if(g_cpufreq_get_ptp_level == 4) | |
1635 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1_4)); | |
1636 | else if(g_cpufreq_get_ptp_level == 5) | |
1637 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1_5)); | |
1638 | else if(g_cpufreq_get_ptp_level == 6) | |
1639 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1_6)); | |
1640 | else | |
1641 | ret = mt_setup_freqs_table(policy, ARRAY_AND_SIZE(mt8127_freqs_e1)); | |
1642 | #endif | |
1643 | ||
1644 | if (ret) { | |
1645 | xlog_printk(ANDROID_LOG_ERROR, "Power/DVFS", "failed to setup frequency table\n"); | |
1646 | return ret; | |
1647 | } | |
1648 | ||
1649 | return 0; | |
1650 | } | |
1651 | ||
1652 | static struct freq_attr *mt_cpufreq_attr[] = { | |
1653 | &cpufreq_freq_attr_scaling_available_freqs, | |
1654 | NULL, | |
1655 | }; | |
1656 | ||
1657 | static struct cpufreq_driver mt_cpufreq_driver = { | |
1658 | .verify = mt_cpufreq_verify, | |
1659 | .target = mt_cpufreq_target, | |
1660 | .init = mt_cpufreq_init, | |
1661 | .get = mt_cpufreq_get, | |
1662 | .name = "mt-cpufreq", | |
1663 | .attr = mt_cpufreq_attr, | |
1664 | }; | |
1665 | ||
1666 | /********************************* | |
1667 | * early suspend callback function | |
1668 | **********************************/ | |
1669 | void mt_cpufreq_early_suspend(struct early_suspend *h) | |
1670 | { | |
1671 | #ifndef MT_DVFS_RANDOM_TEST | |
1672 | ||
1673 | mt_cpufreq_state_set(0); | |
1674 | ||
1675 | mt_cpufreq_limit_max_freq_early_suspend = true; | |
1676 | mt_cpufreq_limit_max_freq_by_early_suspend(); | |
1677 | ||
1678 | /* Deep idle could control vproc now. */ | |
1679 | mt_cpufreq_earlysuspend_allow_deepidle_control_vproc = true; | |
1680 | #endif | |
1681 | ||
1682 | return; | |
1683 | } | |
1684 | ||
1685 | /******************************* | |
1686 | * late resume callback function | |
1687 | ********************************/ | |
1688 | void mt_cpufreq_late_resume(struct early_suspend *h) | |
1689 | { | |
1690 | #ifndef MT_DVFS_RANDOM_TEST | |
1691 | /* Deep idle could NOT control vproc now. */ | |
1692 | mt_cpufreq_earlysuspend_allow_deepidle_control_vproc = false; | |
1693 | ||
1694 | mt_cpufreq_limit_max_freq_early_suspend = false; | |
1695 | ||
1696 | mt_cpufreq_state_set(1); | |
1697 | ||
1698 | #endif | |
1699 | ||
1700 | return; | |
1701 | } | |
1702 | ||
1703 | /************************************************ | |
1704 | * API to switch back default voltage setting for PTPOD disabled | |
1705 | *************************************************/ | |
1706 | void mt_cpufreq_return_default_DVS_by_ptpod(void) | |
1707 | { | |
1708 | #if 0 | |
1709 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
1710 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
1711 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1712 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA2); // 1.05V VPROC | |
1713 | #else | |
1714 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1715 | #endif | |
1716 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
1717 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA4); // 1.15V VPROC | |
1718 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
1719 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VPROC, for spm control in deep idle | |
1720 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VPROC, for spm control in deep idle | |
1721 | ||
1722 | /* For PTP-OD */ | |
1723 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
1724 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
1725 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1726 | mt_cpufreq_pmic_volt[2] = 0x38; // 1.05V VPROC | |
1727 | #else | |
1728 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1729 | #endif | |
1730 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
1731 | mt_cpufreq_pmic_volt[4] = 0x48; // 1.15V VPROC | |
1732 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
1733 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
1734 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
1735 | ||
1736 | #else | |
1737 | if((g_cpufreq_get_ptp_level >= 0) && (g_cpufreq_get_ptp_level <= 4)) | |
1738 | { | |
1739 | #if defined(HQA_LV_1_09V) | |
1740 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
1741 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
1742 | mt_cpufreq_reg_write(0x3D, PMIC_WRAP_DVFS_WDATA2); // 1.09V VPROC | |
1743 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1744 | ||
1745 | /* For PTP-OD */ | |
1746 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
1747 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
1748 | mt_cpufreq_pmic_volt[2] = 0x3D; // 1.09V VPROC | |
1749 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1750 | #elif defined(HQA_NV_1_15V) | |
1751 | mt_cpufreq_reg_write(0x5A, PMIC_WRAP_DVFS_WDATA0); // 1.26V VPROC | |
1752 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
1753 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1754 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1755 | ||
1756 | /* For PTP-OD */ | |
1757 | mt_cpufreq_pmic_volt[0] = 0x5A; // 1.26V VPROC | |
1758 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
1759 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1760 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1761 | #elif defined(HQA_HV_1_21V) | |
1762 | mt_cpufreq_reg_write(0x64, PMIC_WRAP_DVFS_WDATA0); // 1.32V VPROC | |
1763 | mt_cpufreq_reg_write(0x52, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
1764 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1765 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1766 | ||
1767 | /* For PTP-OD */ | |
1768 | mt_cpufreq_pmic_volt[0] = 0x64; // 1.32V VPROC | |
1769 | mt_cpufreq_pmic_volt[1] = 0x52; // 1.20V VPROC | |
1770 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1771 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1772 | #else /* Normal case */ | |
1773 | ||
1774 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1775 | ||
1776 | if(g_cpufreq_get_vcore_corner == false) | |
1777 | { | |
1778 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
1779 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
1780 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1781 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1782 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1783 | #else | |
1784 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
1785 | #endif | |
1786 | ||
1787 | /* For PTP-OD */ | |
1788 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
1789 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
1790 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1791 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1792 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1793 | #else | |
1794 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
1795 | #endif | |
1796 | } | |
1797 | else | |
1798 | { | |
1799 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
1800 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
1801 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA2); // 1.185V VPROC (1.1875v) | |
1802 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1803 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1804 | #else | |
1805 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA3); // 1.185V VPROC | |
1806 | #endif | |
1807 | ||
1808 | /* For PTP-OD */ | |
1809 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
1810 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
1811 | mt_cpufreq_pmic_volt[2] = 0x4E; // 1.185V VPROC (1.1875v) | |
1812 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1813 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1814 | #else | |
1815 | mt_cpufreq_pmic_volt[3] = 0x4E; // 1.185V VPROC | |
1816 | #endif | |
1817 | } | |
1818 | ||
1819 | #else | |
1820 | ||
1821 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
1822 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
1823 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1824 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1825 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1826 | #else | |
1827 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
1828 | #endif | |
1829 | ||
1830 | /* For PTP-OD */ | |
1831 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
1832 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
1833 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1834 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1835 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1836 | #else | |
1837 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
1838 | #endif | |
1839 | ||
1840 | #endif | |
1841 | ||
1842 | #endif | |
1843 | } | |
1844 | else if((g_cpufreq_get_ptp_level >= 5) && (g_cpufreq_get_ptp_level <= 6)) | |
1845 | { | |
1846 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1847 | ||
1848 | if(g_cpufreq_get_vcore_corner == false) | |
1849 | { | |
1850 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
1851 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
1852 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1853 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA2); // 1.05V VPROC | |
1854 | #else | |
1855 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1856 | #endif | |
1857 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
1858 | ||
1859 | /* For PTP-OD */ | |
1860 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
1861 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
1862 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1863 | mt_cpufreq_pmic_volt[2] = 0x38; // 1.05V VPROC | |
1864 | #else | |
1865 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1866 | #endif | |
1867 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
1868 | } | |
1869 | else | |
1870 | { | |
1871 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
1872 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA1); // 1.185V VPROC (1.1875v) | |
1873 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1874 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA2); // 1.05V VPROC | |
1875 | #else | |
1876 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA2); // 1.185V VPROC | |
1877 | #endif | |
1878 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA3); // 1.185V VPROC | |
1879 | ||
1880 | ||
1881 | /* For PTP-OD */ | |
1882 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
1883 | mt_cpufreq_pmic_volt[1] = 0x4E; // 1.185V VPROC (1.1875v) | |
1884 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1885 | mt_cpufreq_pmic_volt[2] = 0x38; // 1.05V VPROC | |
1886 | #else | |
1887 | mt_cpufreq_pmic_volt[2] = 0x4E; // 1.185V VPROC | |
1888 | #endif | |
1889 | mt_cpufreq_pmic_volt[3] = 0x4E; // 1.185V VPROC | |
1890 | } | |
1891 | ||
1892 | #else | |
1893 | ||
1894 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
1895 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
1896 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1897 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA2); // 1.05V VPROC | |
1898 | #else | |
1899 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1900 | #endif | |
1901 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
1902 | ||
1903 | /* For PTP-OD */ | |
1904 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
1905 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
1906 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1907 | mt_cpufreq_pmic_volt[2] = 0x38; // 1.05V VPROC | |
1908 | #else | |
1909 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1910 | #endif | |
1911 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
1912 | ||
1913 | #endif | |
1914 | } | |
1915 | else | |
1916 | { | |
1917 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1918 | ||
1919 | if(g_cpufreq_get_vcore_corner == false) | |
1920 | { | |
1921 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
1922 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
1923 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1924 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1925 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1926 | #else | |
1927 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
1928 | #endif | |
1929 | ||
1930 | /* For PTP-OD */ | |
1931 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
1932 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
1933 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1934 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1935 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1936 | #else | |
1937 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
1938 | #endif | |
1939 | else | |
1940 | { | |
1941 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
1942 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
1943 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA2); // 1.185V VPROC (1.1875v) | |
1944 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1945 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1946 | #else | |
1947 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA3); // 1.185V VPROC | |
1948 | #endif | |
1949 | ||
1950 | /* For PTP-OD */ | |
1951 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
1952 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
1953 | mt_cpufreq_pmic_volt[2] = 0x4E; // 1.185V VPROC (1.1875v) | |
1954 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1955 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1956 | #else | |
1957 | mt_cpufreq_pmic_volt[3] = 0x4E; // 1.185V VPROC | |
1958 | #endif | |
1959 | } | |
1960 | ||
1961 | #else | |
1962 | ||
1963 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
1964 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
1965 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
1966 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1967 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
1968 | #else | |
1969 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
1970 | #endif | |
1971 | ||
1972 | /* For PTP-OD */ | |
1973 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
1974 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
1975 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
1976 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1977 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
1978 | #else | |
1979 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
1980 | #endif | |
1981 | ||
1982 | #endif | |
1983 | } | |
1984 | #endif | |
1985 | ||
1986 | /* DVFS table(4)-(7) for SPM control in deep idle */ | |
1987 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
1988 | ||
1989 | #ifdef CPUFREQ_SDIO_TRANSFER | |
1990 | ||
1991 | if(g_cpufreq_get_vcore_corner == false) | |
1992 | { | |
1993 | mt_cpufreq_reg_write(0x18, PMIC_WRAP_DVFS_WDATA4); // 0.85V VPROC, for spm control in deep idle | |
1994 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
1995 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VCORE, for spm control in deep idle | |
1996 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VCORE, for spm control in deep idle | |
1997 | ||
1998 | /* For PTP-OD */ | |
1999 | mt_cpufreq_pmic_volt[4] = 0x18; // 0.85V VPROC, for spm control in deep idle | |
2000 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2001 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VCORE, for spm control in deep idle | |
2002 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VCORE, for spm control in deep idle | |
2003 | } | |
2004 | else | |
2005 | { | |
2006 | mt_cpufreq_reg_write(0x18, PMIC_WRAP_DVFS_WDATA4); // 0.85V VPROC, for spm control in deep idle | |
2007 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA5); // 1.185V VPROC, for spm control in deep idle | |
2008 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VCORE, for spm control in deep idle | |
2009 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA7); // 1.185V VCORE, for spm control in deep idle | |
2010 | ||
2011 | /* For PTP-OD */ | |
2012 | mt_cpufreq_pmic_volt[4] = 0x18; // 0.85V VPROC, for spm control in deep idle | |
2013 | mt_cpufreq_pmic_volt[5] = 0x4E; // 1.185V VPROC, for spm control in deep idle | |
2014 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VCORE, for spm control in deep idle | |
2015 | mt_cpufreq_pmic_volt[7] = 0x4E; // 1.185V VCORE, for spm control in deep idle | |
2016 | } | |
2017 | #else | |
2018 | mt_cpufreq_reg_write(0x18, PMIC_WRAP_DVFS_WDATA4); // 0.85V VPROC, for spm control in deep idle | |
2019 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
2020 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VCORE, for spm control in deep idle | |
2021 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VCORE, for spm control in deep idle | |
2022 | ||
2023 | /* For PTP-OD */ | |
2024 | mt_cpufreq_pmic_volt[4] = 0x18; // 0.85V VPROC, for spm control in deep idle | |
2025 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2026 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VCORE, for spm control in deep idle | |
2027 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VCORE, for spm control in deep idle | |
2028 | #endif //#ifdef CPUFREQ_SDIO_TRANSFER | |
2029 | ||
2030 | #else | |
2031 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2032 | if(g_cpufreq_get_vcore_corner == false) | |
2033 | { | |
2034 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA4); // 1.05V VPROC, for spm control in deep idle | |
2035 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
2036 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VPROC, for spm control in deep idle | |
2037 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VPROC, for spm control in deep idle | |
2038 | ||
2039 | /* For PTP-OD */ | |
2040 | mt_cpufreq_pmic_volt[4] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2041 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2042 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2043 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2044 | } | |
2045 | else | |
2046 | { | |
2047 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA4); // 1.05V VPROC, for spm control in deep idle | |
2048 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA5); // 1.185V VPROC, for spm control in deep idle | |
2049 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VPROC, for spm control in deep idle | |
2050 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA7); // 1.185V VPROC, for spm control in deep idle | |
2051 | ||
2052 | /* For PTP-OD */ | |
2053 | mt_cpufreq_pmic_volt[4] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2054 | mt_cpufreq_pmic_volt[5] = 0x4E; // 1.185V VPROC, for spm control in deep idle | |
2055 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2056 | mt_cpufreq_pmic_volt[7] = 0x4E; // 1.185V VPROC, for spm control in deep idle | |
2057 | } | |
2058 | #else | |
2059 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA4); // 1.05V VPROC, for spm control in deep idle | |
2060 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
2061 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VPROC, for spm control in deep idle | |
2062 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VPROC, for spm control in deep idle | |
2063 | ||
2064 | /* For PTP-OD */ | |
2065 | mt_cpufreq_pmic_volt[4] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2066 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2067 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2068 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2069 | #endif //#ifdef CPUFREQ_SDIO_TRANSFER | |
2070 | #endif | |
2071 | ||
2072 | ||
2073 | ||
2074 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq return default DVS by ptpod\n"); | |
2075 | } | |
2076 | EXPORT_SYMBOL(mt_cpufreq_return_default_DVS_by_ptpod); | |
2077 | ||
2078 | /************************************************ | |
2079 | * DVFS enable API for PTPOD | |
2080 | *************************************************/ | |
2081 | void mt_cpufreq_enable_by_ptpod(void) | |
2082 | { | |
2083 | mt_cpufreq_ptpod_disable = false; | |
2084 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq enabled by ptpod\n"); | |
2085 | } | |
2086 | EXPORT_SYMBOL(mt_cpufreq_enable_by_ptpod); | |
2087 | ||
2088 | /************************************************ | |
2089 | * DVFS disable API for PTPOD | |
2090 | *************************************************/ | |
2091 | unsigned int mt_cpufreq_disable_by_ptpod(void) | |
2092 | { | |
2093 | struct cpufreq_policy *policy; | |
2094 | ||
2095 | mt_cpufreq_ptpod_disable = true; | |
2096 | ||
2097 | policy = cpufreq_cpu_get(0); | |
2098 | ||
2099 | if (!policy) | |
2100 | goto no_policy; | |
2101 | ||
2102 | cpufreq_driver_target(policy, DVFS_F2, CPUFREQ_RELATION_L); | |
2103 | ||
2104 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq disabled by ptpod, limited freq. at %d\n", DVFS_F2); | |
2105 | ||
2106 | cpufreq_cpu_put(policy); | |
2107 | ||
2108 | no_policy: | |
2109 | return g_cur_freq; | |
2110 | } | |
2111 | EXPORT_SYMBOL(mt_cpufreq_disable_by_ptpod); | |
2112 | ||
2113 | /************************************************ | |
2114 | * frequency adjust interface for thermal protect | |
2115 | *************************************************/ | |
2116 | /****************************************************** | |
2117 | * parameter: target power | |
2118 | *******************************************************/ | |
2119 | void mt_cpufreq_thermal_protect(unsigned int limited_power) | |
2120 | { | |
2121 | int i = 0, ncpu = 0, found = 0; | |
2122 | ||
2123 | struct cpufreq_policy *policy; | |
2124 | ||
2125 | dprintk("mt_cpufreq_thermal_protect, limited_power:%d\n", limited_power); | |
2126 | ||
2127 | g_thermal_protect_limited_power = limited_power; | |
2128 | ||
2129 | policy = cpufreq_cpu_get(0); | |
2130 | ||
2131 | if (!policy) | |
2132 | goto no_policy; | |
2133 | ||
2134 | ncpu = num_possible_cpus(); | |
2135 | ||
2136 | if (limited_power == 0) | |
2137 | { | |
2138 | g_limited_max_ncpu = num_possible_cpus(); | |
2139 | g_limited_max_freq = g_max_freq_by_ptp; | |
2140 | ||
2141 | cpufreq_driver_target(policy, g_limited_max_freq, CPUFREQ_RELATION_L); | |
2142 | hp_limited_cpu_num(g_limited_max_ncpu); | |
2143 | ||
2144 | dbs_freq_thermal_limited(0, g_limited_max_freq); | |
2145 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "thermal limit g_limited_max_freq = %d, g_limited_max_ncpu = %d\n", g_limited_max_freq, g_limited_max_ncpu); | |
2146 | } | |
2147 | else | |
2148 | { | |
2149 | while (ncpu) | |
2150 | { | |
2151 | for (i = 0; i < g_cpu_power_table_num; i++) | |
2152 | { | |
2153 | if (mt_cpu_power[i].cpufreq_ncpu == ncpu) | |
2154 | { | |
2155 | if (mt_cpu_power[i].cpufreq_power <= limited_power) | |
2156 | { | |
2157 | g_limited_max_ncpu = mt_cpu_power[i].cpufreq_ncpu; | |
2158 | g_limited_max_freq = mt_cpu_power[i].cpufreq_khz; | |
2159 | #if defined(CONFIG_THERMAL_LIMIT_TEST) | |
2160 | g_limited_max_thermal_power = mt_cpu_power[i].cpufreq_power; | |
2161 | #endif | |
2162 | ||
2163 | found = 1; | |
2164 | break; | |
2165 | } | |
2166 | } | |
2167 | } | |
2168 | ||
2169 | if (found) | |
2170 | break; | |
2171 | ||
2172 | ncpu--; | |
2173 | } | |
2174 | ||
2175 | if (!found) | |
2176 | { | |
2177 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "Not found suitable DVFS OPP, limit to lowest OPP!\n"); | |
2178 | g_limited_max_ncpu = mt_cpu_power[g_cpu_power_table_num - 1].cpufreq_ncpu; | |
2179 | g_limited_max_freq = mt_cpu_power[g_cpu_power_table_num - 1].cpufreq_khz; | |
2180 | #if defined(CONFIG_THERMAL_LIMIT_TEST) | |
2181 | g_limited_max_thermal_power = mt_cpu_power[g_cpu_power_table_num - 1].cpufreq_power; | |
2182 | #endif | |
2183 | } | |
2184 | ||
2185 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "thermal limit g_limited_max_freq = %d, g_limited_max_ncpu = %d\n", g_limited_max_freq, g_limited_max_ncpu); | |
2186 | ||
2187 | hp_limited_cpu_num(g_limited_max_ncpu); | |
2188 | ||
2189 | if (num_online_cpus() > g_limited_max_ncpu) | |
2190 | { | |
2191 | for (i = num_online_cpus(); i > g_limited_max_ncpu; i--) | |
2192 | { | |
2193 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "turn off CPU%d due to thermal protection\n", (i - 1)); | |
2194 | cpu_down((i - 1)); | |
2195 | } | |
2196 | } | |
2197 | ||
2198 | cpufreq_driver_target(policy, g_limited_max_freq, CPUFREQ_RELATION_L); | |
2199 | ||
2200 | dbs_freq_thermal_limited(1, g_limited_max_freq); | |
2201 | } | |
2202 | ||
2203 | cpufreq_cpu_put(policy); | |
2204 | ||
2205 | no_policy: | |
2206 | return; | |
2207 | } | |
2208 | EXPORT_SYMBOL(mt_cpufreq_thermal_protect); | |
2209 | ||
2210 | #if defined(CONFIG_THERMAL_LIMIT_TEST) | |
2211 | unsigned int mt_cpufreq_thermal_test_limited_load(void) | |
2212 | { | |
2213 | return g_limited_load_for_thermal_test; | |
2214 | } | |
2215 | EXPORT_SYMBOL(mt_cpufreq_thermal_test_limited_load); | |
2216 | #endif | |
2217 | ||
2218 | /*************************** | |
2219 | * show current DVFS stauts | |
2220 | ****************************/ | |
2221 | static int mt_cpufreq_state_show(struct seq_file* s, void* v) | |
2222 | { | |
2223 | if (!mt_cpufreq_pause) | |
2224 | seq_printf(s, "DVFS enabled\n"); | |
2225 | else | |
2226 | seq_printf(s, "DVFS disabled\n"); | |
2227 | ||
2228 | return 0; | |
2229 | } | |
2230 | ||
2231 | static int mt_cpufreq_state_open(struct inode *inode, struct file *file) | |
2232 | { | |
2233 | return single_open(file, mt_cpufreq_state_show, NULL); | |
2234 | } | |
2235 | ||
2236 | ||
2237 | /************************************ | |
2238 | * set DVFS stauts by sysfs interface | |
2239 | *************************************/ | |
2240 | static ssize_t mt_cpufreq_state_write(struct file *file, const char *buffer, size_t count, loff_t *data) | |
2241 | { | |
2242 | int enabled = 0; | |
2243 | ||
2244 | if (sscanf(buffer, "%d", &enabled) == 1) | |
2245 | { | |
2246 | if (enabled == 1) | |
2247 | { | |
2248 | mt_cpufreq_state_set(1); | |
2249 | } | |
2250 | else if (enabled == 0) | |
2251 | { | |
2252 | mt_cpufreq_state_set(0); | |
2253 | } | |
2254 | else | |
2255 | { | |
2256 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "bad argument!! argument should be \"1\" or \"0\"\n"); | |
2257 | } | |
2258 | } | |
2259 | else | |
2260 | { | |
2261 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "bad argument!! argument should be \"1\" or \"0\"\n"); | |
2262 | } | |
2263 | ||
2264 | return count; | |
2265 | } | |
2266 | ||
2267 | /**************************** | |
2268 | * show current limited freq | |
2269 | *****************************/ | |
2270 | static int mt_cpufreq_limited_power_show(struct seq_file* s, void* v) | |
2271 | { | |
2272 | seq_printf(s, "g_limited_max_freq = %d, g_limited_max_ncpu = %d\n", g_limited_max_freq, g_limited_max_ncpu); | |
2273 | ||
2274 | return 0; | |
2275 | } | |
2276 | ||
2277 | static int mt_cpufreq_limited_power_open(struct inode *inode, struct file *file) | |
2278 | { | |
2279 | return single_open(file, mt_cpufreq_limited_power_show, NULL); | |
2280 | } | |
2281 | ||
2282 | ||
2283 | /********************************** | |
2284 | * limited power for thermal protect | |
2285 | ***********************************/ | |
2286 | static ssize_t mt_cpufreq_limited_power_write(struct file *file, const char *buffer, size_t count, loff_t *data) | |
2287 | { | |
2288 | unsigned int power = 0; | |
2289 | ||
2290 | if (sscanf(buffer, "%u", &power) == 1) | |
2291 | { | |
2292 | mt_cpufreq_thermal_protect(power); | |
2293 | return count; | |
2294 | } | |
2295 | else | |
2296 | { | |
2297 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "bad argument!! please provide the maximum limited power\n"); | |
2298 | } | |
2299 | ||
2300 | return -EINVAL; | |
2301 | } | |
2302 | ||
2303 | #if defined(CONFIG_THERMAL_LIMIT_TEST) | |
2304 | /**************************** | |
2305 | * show limited loading for thermal protect test | |
2306 | *****************************/ | |
2307 | static int mt_cpufreq_limited_load_show(struct seq_file* s, void* v) | |
2308 | { | |
2309 | seq_printf(s, "g_limited_load_for_thermal_test = %d\n", g_limited_load_for_thermal_test); | |
2310 | seq_printf(s, "g_limited_max_thermal_power = %d\n", g_limited_max_thermal_power); | |
2311 | seq_printf(s, "g_cur_freq = %d, ncpu = %d\n", g_cur_freq, num_online_cpus()); | |
2312 | ||
2313 | return 0; | |
2314 | } | |
2315 | ||
2316 | static int mt_cpufreq_limited_load_open(struct inode *inode, struct file *file) | |
2317 | { | |
2318 | return single_open(file, mt_cpufreq_limited_load_show, NULL); | |
2319 | } | |
2320 | ||
2321 | ||
2322 | /********************************** | |
2323 | * limited loading for thermal protect test | |
2324 | ***********************************/ | |
2325 | static ssize_t mt_cpufreq_limited_load_write(struct file *file, const char *buffer, size_t count, loff_t *data) | |
2326 | { | |
2327 | unsigned int load = 0; | |
2328 | ||
2329 | if (sscanf(buffer, "%u", &load) == 1) | |
2330 | { | |
2331 | g_limited_load_for_thermal_test = load; | |
2332 | return count; | |
2333 | } | |
2334 | else | |
2335 | { | |
2336 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "bad argument!! please provide the limited load\n"); | |
2337 | } | |
2338 | ||
2339 | return -EINVAL; | |
2340 | } | |
2341 | #endif | |
2342 | ||
2343 | /*************************** | |
2344 | * show current debug status | |
2345 | ****************************/ | |
2346 | static int mt_cpufreq_debug_show(struct seq_file* s, void* v) | |
2347 | { | |
2348 | if (mt_cpufreq_debug) | |
2349 | seq_printf(s, "cpufreq debug enabled\n"); | |
2350 | else | |
2351 | seq_printf(s, "cpufreq debug disabled\n"); | |
2352 | ||
2353 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2354 | seq_printf(s, "g_cpufreq_get_vcore_corner = %d\n", g_cpufreq_get_vcore_corner); | |
2355 | #endif | |
2356 | ||
2357 | return 0; | |
2358 | } | |
2359 | ||
2360 | static int mt_cpufreq_debug_open(struct inode *inode, struct file *file) | |
2361 | { | |
2362 | return single_open(file, mt_cpufreq_debug_show, NULL); | |
2363 | } | |
2364 | ||
2365 | ||
2366 | /*********************** | |
2367 | * enable debug message | |
2368 | ************************/ | |
2369 | static ssize_t mt_cpufreq_debug_write(struct file *file, const char *buffer, size_t count, loff_t *data) | |
2370 | { | |
2371 | int debug = 0; | |
2372 | ||
2373 | if (sscanf(buffer, "%d", &debug) == 1) | |
2374 | { | |
2375 | if (debug == 0) | |
2376 | { | |
2377 | mt_cpufreq_debug = 0; | |
2378 | return count; | |
2379 | } | |
2380 | else if (debug == 1) | |
2381 | { | |
2382 | mt_cpufreq_debug = 1; | |
2383 | return count; | |
2384 | } | |
2385 | else | |
2386 | { | |
2387 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "bad argument!! should be 0 or 1 [0: disable, 1: enable]\n"); | |
2388 | } | |
2389 | } | |
2390 | else | |
2391 | { | |
2392 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "bad argument!! should be 0 or 1 [0: disable, 1: enable]\n"); | |
2393 | } | |
2394 | ||
2395 | return -EINVAL; | |
2396 | } | |
2397 | ||
2398 | /*************************** | |
2399 | * show cpufreq power info | |
2400 | ****************************/ | |
2401 | static int mt_cpufreq_power_dump_show(struct seq_file* s, void* v) | |
2402 | { | |
2403 | int i; | |
2404 | for (i = 0; i < g_cpu_power_table_num; i++) | |
2405 | { | |
2406 | seq_printf(s, "mt_cpu_power[%d].cpufreq_khz = %d\n", i, mt_cpu_power[i].cpufreq_khz); | |
2407 | seq_printf(s, "mt_cpu_power[%d].cpufreq_ncpu = %d\n", i, mt_cpu_power[i].cpufreq_ncpu); | |
2408 | seq_printf(s, "mt_cpu_power[%d].cpufreq_power = %d\n", i, mt_cpu_power[i].cpufreq_power); | |
2409 | } | |
2410 | ||
2411 | seq_printf(s, "done\n"); | |
2412 | ||
2413 | return 0; | |
2414 | } | |
2415 | ||
2416 | static int mt_cpufreq_power_dump_open(struct inode *inode, struct file *file) | |
2417 | { | |
2418 | return single_open(file, mt_cpufreq_power_dump_show, NULL); | |
2419 | } | |
2420 | ||
2421 | ||
2422 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2423 | /*************************** | |
2424 | * show cpufreq sdio info | |
2425 | ****************************/ | |
2426 | static int mt_cpufreq_sdio_info_show(struct seq_file* s, void* v) | |
2427 | { | |
2428 | seq_printf(s, "mt_cpufreq_disabled_by_sdio_autoK = %d\n", mt_cpufreq_disabled_by_sdio_autoK); | |
2429 | seq_printf(s, "mt_cpufreq_disabled_by_sdio_ot = %d\n", mt_cpufreq_disabled_by_sdio_ot); | |
2430 | ||
2431 | return 0; | |
2432 | } | |
2433 | ||
2434 | static int mt_cpufreq_sdio_info_open(struct inode *inode, struct file *file) | |
2435 | { | |
2436 | return single_open(file, mt_cpufreq_sdio_info_show, NULL); | |
2437 | } | |
2438 | #endif | |
2439 | ||
2440 | #ifdef MT_DVFS_PTPOD_TEST | |
2441 | /*********************** | |
2442 | * PTPOD test | |
2443 | ************************/ | |
2444 | static ssize_t mt_cpufreq_ptpod_test_write(struct file *file, const char *buffer, size_t count, loff_t *data) | |
2445 | { | |
2446 | int enable = 0; | |
2447 | ||
2448 | if (sscanf(buffer, "%d", &enable) == 1) | |
2449 | { | |
2450 | if (enable == 0) | |
2451 | { | |
2452 | mt_cpufreq_ptpod_test[0] = 0x58; // 1.25V VPROC | |
2453 | mt_cpufreq_ptpod_test[1] = 0x50; // 1.20V VPROC | |
2454 | mt_cpufreq_ptpod_test[2] = 0x48; // 1.15V VPROC | |
2455 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2456 | mt_cpufreq_ptpod_test[3] = 0x38; // 1.05V VPROC | |
2457 | mt_cpufreq_ptpod_test[4] = 0x18; // 0.85V VPROC, for spm control in deep idle | |
2458 | mt_cpufreq_ptpod_test[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2459 | mt_cpufreq_ptpod_test[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2460 | mt_cpufreq_ptpod_test[7] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2461 | #else | |
2462 | mt_cpufreq_ptpod_test[3] = 0x48; // 1.15V VPROC | |
2463 | mt_cpufreq_ptpod_test[4] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2464 | mt_cpufreq_ptpod_test[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2465 | mt_cpufreq_ptpod_test[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2466 | mt_cpufreq_ptpod_test[7] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2467 | #endif | |
2468 | ||
2469 | mt_cpufreq_voltage_set_by_ptpod(mt_cpufreq_ptpod_test, 8); | |
2470 | ||
2471 | return count; | |
2472 | } | |
2473 | else if (enable == 1) | |
2474 | { | |
2475 | mt_cpufreq_ptpod_test[0] = 0x57; // 1.25V VPROC | |
2476 | mt_cpufreq_ptpod_test[1] = 0x4F; // 1.20V VPROC | |
2477 | mt_cpufreq_ptpod_test[2] = 0x47; // 1.15V VPROC | |
2478 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2479 | mt_cpufreq_ptpod_test[3] = 0x37; // 1.05V VPROC | |
2480 | mt_cpufreq_ptpod_test[4] = 0x17; // 0.85V VPROC, for spm control in deep idle | |
2481 | mt_cpufreq_ptpod_test[5] = 0x47; // 1.15V VPROC, for spm control in deep idle | |
2482 | mt_cpufreq_ptpod_test[6] = 0x37; // 1.05V VPROC, for spm control in deep idle | |
2483 | mt_cpufreq_ptpod_test[7] = 0x47; // 1.15V VPROC, for spm control in deep idle | |
2484 | #else | |
2485 | mt_cpufreq_ptpod_test[3] = 0x47; // 1.15V VPROC | |
2486 | mt_cpufreq_ptpod_test[4] = 0x37; // 1.05V VPROC, for spm control in deep idle | |
2487 | mt_cpufreq_ptpod_test[5] = 0x47; // 1.15V VPROC, for spm control in deep idle | |
2488 | mt_cpufreq_ptpod_test[6] = 0x37; // 1.05V VPROC, for spm control in deep idle | |
2489 | mt_cpufreq_ptpod_test[7] = 0x47; // 1.15V VPROC, for spm control in deep idle | |
2490 | #endif | |
2491 | ||
2492 | mt_cpufreq_voltage_set_by_ptpod(mt_cpufreq_ptpod_test, 8); | |
2493 | ||
2494 | return count; | |
2495 | } | |
2496 | else | |
2497 | { | |
2498 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "bad argument!! should be 0 or 1 [0: disable, 1: enable]\n"); | |
2499 | } | |
2500 | } | |
2501 | else | |
2502 | { | |
2503 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "bad argument!! should be 0 or 1 [0: disable, 1: enable]\n"); | |
2504 | } | |
2505 | ||
2506 | return -EINVAL; | |
2507 | } | |
2508 | #endif | |
2509 | ||
2510 | /*************************** | |
2511 | * show cpufreq freq/volt info | |
2512 | ****************************/ | |
2513 | static int mt_cpufreq_ptpod_freq_volt_show(struct seq_file* s, void* v) | |
2514 | { | |
2515 | int i = 0; | |
2516 | for (i = 0; i < mt_cpu_freqs_num; i++) | |
2517 | { | |
2518 | seq_printf(s, "default freq = %d, volt = %d\n", mt_cpu_freqs[i].cpufreq_khz, mt_cpu_freqs[i].cpufreq_volt); | |
2519 | } | |
2520 | return 0; | |
2521 | } | |
2522 | ||
2523 | static int mt_cpufreq_ptpod_freq_volt_open(struct inode *inode, struct file *file) | |
2524 | { | |
2525 | return single_open(file, mt_cpufreq_ptpod_freq_volt_show, NULL); | |
2526 | } | |
2527 | ||
2528 | ||
2529 | /******************************************* | |
2530 | * cpufrqe platform driver callback function | |
2531 | ********************************************/ | |
2532 | static int mt_cpufreq_pdrv_probe(struct platform_device *pdev) | |
2533 | { | |
2534 | #ifdef CONFIG_HAS_EARLYSUSPEND | |
2535 | mt_cpufreq_early_suspend_handler.suspend = mt_cpufreq_early_suspend; | |
2536 | mt_cpufreq_early_suspend_handler.resume = mt_cpufreq_late_resume; | |
2537 | register_early_suspend(&mt_cpufreq_early_suspend_handler); | |
2538 | #endif | |
2539 | ||
2540 | /************************************************ | |
2541 | * Check PTP level to define default max freq | |
2542 | *************************************************/ | |
2543 | g_cpufreq_get_ptp_level = PTP_get_ptp_level(); | |
2544 | ||
2545 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2546 | g_cpufreq_get_vcore_corner = is_vcore_ss_corner(); | |
2547 | #endif | |
2548 | ||
2549 | #ifdef CPUSTRESS_TURBO | |
2550 | g_cpufreq_get_ptp_level = 3; | |
2551 | #endif | |
2552 | ||
2553 | #if 0 | |
2554 | g_max_freq_by_ptp = DVFS_F1; | |
2555 | ||
2556 | #else | |
2557 | if(g_cpufreq_get_ptp_level == 0) | |
2558 | g_max_freq_by_ptp = DVFS_F0; | |
2559 | else if(g_cpufreq_get_ptp_level == 1) | |
2560 | g_max_freq_by_ptp = DVFS_F0_1; | |
2561 | else if(g_cpufreq_get_ptp_level == 2) | |
2562 | g_max_freq_by_ptp = DVFS_F0_2; | |
2563 | else if(g_cpufreq_get_ptp_level == 3) | |
2564 | g_max_freq_by_ptp = DVFS_F0_3; | |
2565 | else if(g_cpufreq_get_ptp_level == 4) | |
2566 | g_max_freq_by_ptp = DVFS_F0_4; | |
2567 | else if(g_cpufreq_get_ptp_level == 5) | |
2568 | g_max_freq_by_ptp = DVFS_F1_0; | |
2569 | else if(g_cpufreq_get_ptp_level == 6) | |
2570 | g_max_freq_by_ptp = DVFS_F1_1; | |
2571 | else | |
2572 | g_max_freq_by_ptp = DVFS_F0; | |
2573 | #endif | |
2574 | ||
2575 | /************************************************ | |
2576 | * voltage scaling need to wait PMIC driver ready | |
2577 | *************************************************/ | |
2578 | mt_cpufreq_ready = true; | |
2579 | ||
2580 | g_cur_freq = DVFS_F2; /* Default 1.05GHz in preloader */ | |
2581 | g_cur_cpufreq_volt = DVFS_V2; /* Default 1.15V */ | |
2582 | g_limited_max_freq = g_max_freq_by_ptp; | |
2583 | g_limited_min_freq = DVFS_F4; | |
2584 | ||
2585 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mediatek cpufreq initialized\n"); | |
2586 | ||
2587 | #ifdef CONFIG_MTK_PMIC_MT6397 | |
2588 | mt_cpufreq_reg_write(0x0228, PMIC_WRAP_DVFS_ADR0); | |
2589 | mt_cpufreq_reg_write(0x0228, PMIC_WRAP_DVFS_ADR1); | |
2590 | mt_cpufreq_reg_write(0x0228, PMIC_WRAP_DVFS_ADR2); | |
2591 | mt_cpufreq_reg_write(0x0228, PMIC_WRAP_DVFS_ADR3); | |
2592 | mt_cpufreq_reg_write(0x0228, PMIC_WRAP_DVFS_ADR4); // VPROC | |
2593 | mt_cpufreq_reg_write(0x0228, PMIC_WRAP_DVFS_ADR5); // VPROC | |
2594 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2595 | mt_cpufreq_reg_write(0x027A, PMIC_WRAP_DVFS_ADR6); // VCORE | |
2596 | mt_cpufreq_reg_write(0x027A, PMIC_WRAP_DVFS_ADR7); // VCORE | |
2597 | #else | |
2598 | mt_cpufreq_reg_write(0x0228, PMIC_WRAP_DVFS_ADR6); // VPROC | |
2599 | mt_cpufreq_reg_write(0x0228, PMIC_WRAP_DVFS_ADR7); // VPROC | |
2600 | #endif | |
2601 | #else | |
2602 | mt_cpufreq_reg_write(0x0220, PMIC_WRAP_DVFS_ADR0); | |
2603 | mt_cpufreq_reg_write(0x0220, PMIC_WRAP_DVFS_ADR1); | |
2604 | mt_cpufreq_reg_write(0x0220, PMIC_WRAP_DVFS_ADR2); | |
2605 | mt_cpufreq_reg_write(0x0220, PMIC_WRAP_DVFS_ADR3); | |
2606 | mt_cpufreq_reg_write(0x0220, PMIC_WRAP_DVFS_ADR4); | |
2607 | mt_cpufreq_reg_write(0x0220, PMIC_WRAP_DVFS_ADR5); | |
2608 | mt_cpufreq_reg_write(0x0220, PMIC_WRAP_DVFS_ADR6); | |
2609 | mt_cpufreq_reg_write(0x0220, PMIC_WRAP_DVFS_ADR7); | |
2610 | #endif | |
2611 | ||
2612 | #if 0 | |
2613 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
2614 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
2615 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2616 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA2); // 1.05V VPROC | |
2617 | #else | |
2618 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2619 | #endif | |
2620 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
2621 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA4); // 1.15V VPROC | |
2622 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
2623 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VPROC, for spm control in deep idle | |
2624 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VPROC, for spm control in deep idle | |
2625 | ||
2626 | /* For PTP-OD */ | |
2627 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
2628 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
2629 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2630 | mt_cpufreq_pmic_volt[2] = 0x38; // 1.05V VPROC | |
2631 | #else | |
2632 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2633 | #endif | |
2634 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
2635 | mt_cpufreq_pmic_volt[4] = 0x48; // 1.15V VPROC | |
2636 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2637 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2638 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2639 | ||
2640 | #else | |
2641 | if((g_cpufreq_get_ptp_level >= 0) && (g_cpufreq_get_ptp_level <= 4)) | |
2642 | { | |
2643 | #if defined(HQA_LV_1_09V) | |
2644 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
2645 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
2646 | mt_cpufreq_reg_write(0x3D, PMIC_WRAP_DVFS_WDATA2); // 1.09V VPROC | |
2647 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2648 | ||
2649 | /* For PTP-OD */ | |
2650 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
2651 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
2652 | mt_cpufreq_pmic_volt[2] = 0x3D; // 1.09V VPROC | |
2653 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2654 | #elif defined(HQA_NV_1_15V) | |
2655 | mt_cpufreq_reg_write(0x5A, PMIC_WRAP_DVFS_WDATA0); // 1.26V VPROC | |
2656 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
2657 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2658 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2659 | ||
2660 | /* For PTP-OD */ | |
2661 | mt_cpufreq_pmic_volt[0] = 0x5A; // 1.26V VPROC | |
2662 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
2663 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2664 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2665 | #elif defined(HQA_HV_1_21V) | |
2666 | mt_cpufreq_reg_write(0x64, PMIC_WRAP_DVFS_WDATA0); // 1.32V VPROC | |
2667 | mt_cpufreq_reg_write(0x52, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
2668 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2669 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2670 | ||
2671 | /* For PTP-OD */ | |
2672 | mt_cpufreq_pmic_volt[0] = 0x64; // 1.32V VPROC | |
2673 | mt_cpufreq_pmic_volt[1] = 0x52; // 1.20V VPROC | |
2674 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2675 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2676 | #else /* Normal case */ | |
2677 | ||
2678 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2679 | ||
2680 | if(g_cpufreq_get_vcore_corner == false) | |
2681 | { | |
2682 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
2683 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
2684 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2685 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2686 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2687 | #else | |
2688 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
2689 | #endif | |
2690 | ||
2691 | /* For PTP-OD */ | |
2692 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
2693 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
2694 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2695 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2696 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2697 | #else | |
2698 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
2699 | #endif | |
2700 | } | |
2701 | else | |
2702 | { | |
2703 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
2704 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
2705 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA2); // 1.185V VPROC (1.1875v) | |
2706 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2707 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2708 | #else | |
2709 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA3); // 1.185V VPROC | |
2710 | #endif | |
2711 | ||
2712 | /* For PTP-OD */ | |
2713 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
2714 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
2715 | mt_cpufreq_pmic_volt[2] = 0x4E; // 1.185V VPROC (1.1875v) | |
2716 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2717 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2718 | #else | |
2719 | mt_cpufreq_pmic_volt[3] = 0x4E; // 1.185V VPROC | |
2720 | #endif | |
2721 | } | |
2722 | ||
2723 | #else | |
2724 | ||
2725 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
2726 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
2727 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2728 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2729 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2730 | #else | |
2731 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
2732 | #endif | |
2733 | ||
2734 | /* For PTP-OD */ | |
2735 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
2736 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
2737 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2738 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2739 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2740 | #else | |
2741 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
2742 | #endif | |
2743 | ||
2744 | #endif | |
2745 | ||
2746 | #endif | |
2747 | } | |
2748 | else if((g_cpufreq_get_ptp_level >= 5) && (g_cpufreq_get_ptp_level <= 6)) | |
2749 | { | |
2750 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2751 | ||
2752 | if(g_cpufreq_get_vcore_corner == false) | |
2753 | { | |
2754 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
2755 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
2756 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2757 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA2); // 1.05V VPROC | |
2758 | #else | |
2759 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2760 | #endif | |
2761 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
2762 | ||
2763 | /* For PTP-OD */ | |
2764 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
2765 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
2766 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2767 | mt_cpufreq_pmic_volt[2] = 0x38; // 1.05V VPROC | |
2768 | #else | |
2769 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2770 | #endif | |
2771 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
2772 | } | |
2773 | else | |
2774 | { | |
2775 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
2776 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA1); // 1.185V VPROC (1.1875v) | |
2777 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2778 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA2); // 1.05V VPROC | |
2779 | #else | |
2780 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA2); // 1.185V VPROC | |
2781 | #endif | |
2782 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA3); // 1.185V VPROC | |
2783 | ||
2784 | /* For PTP-OD */ | |
2785 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
2786 | mt_cpufreq_pmic_volt[1] = 0x4E; // 1.185V VPROC | |
2787 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2788 | mt_cpufreq_pmic_volt[2] = 0x38; // 1.05V VPROC | |
2789 | #else | |
2790 | mt_cpufreq_pmic_volt[2] = 0x4E; // 1.185V VPROC | |
2791 | #endif | |
2792 | mt_cpufreq_pmic_volt[3] = 0x4E; // 1.185V VPROC | |
2793 | } | |
2794 | ||
2795 | #else | |
2796 | ||
2797 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA0); // 1.20V VPROC | |
2798 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
2799 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2800 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA2); // 1.05V VPROC | |
2801 | #else | |
2802 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2803 | #endif | |
2804 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
2805 | ||
2806 | /* For PTP-OD */ | |
2807 | mt_cpufreq_pmic_volt[0] = 0x50; // 1.20V VPROC | |
2808 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
2809 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2810 | mt_cpufreq_pmic_volt[2] = 0x38; // 1.05V VPROC | |
2811 | #else | |
2812 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2813 | #endif | |
2814 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
2815 | ||
2816 | #endif | |
2817 | } | |
2818 | else | |
2819 | { | |
2820 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2821 | ||
2822 | if(g_cpufreq_get_vcore_corner == false) | |
2823 | { | |
2824 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
2825 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
2826 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2827 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2828 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2829 | #else | |
2830 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
2831 | #endif | |
2832 | ||
2833 | /* For PTP-OD */ | |
2834 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
2835 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
2836 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2837 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2838 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2839 | #else | |
2840 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
2841 | #endif | |
2842 | } | |
2843 | else | |
2844 | { | |
2845 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
2846 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
2847 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA2); // 1.185V VPROC (1.1875v) | |
2848 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2849 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2850 | #else | |
2851 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA3); // 1.185V VPROC | |
2852 | #endif | |
2853 | ||
2854 | /* For PTP-OD */ | |
2855 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
2856 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
2857 | mt_cpufreq_pmic_volt[2] = 0x4E; // 1.185V VPROC | |
2858 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2859 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2860 | #else | |
2861 | mt_cpufreq_pmic_volt[3] = 0x4E; // 1.185V VPROC | |
2862 | #endif | |
2863 | } | |
2864 | ||
2865 | #else | |
2866 | ||
2867 | mt_cpufreq_reg_write(0x60, PMIC_WRAP_DVFS_WDATA0); // 1.30V VPROC | |
2868 | mt_cpufreq_reg_write(0x50, PMIC_WRAP_DVFS_WDATA1); // 1.20V VPROC | |
2869 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2870 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2871 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2872 | #else | |
2873 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
2874 | #endif | |
2875 | ||
2876 | /* For PTP-OD */ | |
2877 | mt_cpufreq_pmic_volt[0] = 0x60; // 1.30V VPROC | |
2878 | mt_cpufreq_pmic_volt[1] = 0x50; // 1.20V VPROC | |
2879 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2880 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2881 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2882 | #else | |
2883 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
2884 | #endif | |
2885 | ||
2886 | #endif | |
2887 | } | |
2888 | #endif | |
2889 | ||
2890 | #ifdef CPUSTRESS_VPROC_1_15V | |
2891 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA0); // 1.15V VPROC | |
2892 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA1); // 1.15V VPROC | |
2893 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA2); // 1.15V VPROC | |
2894 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2895 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2896 | #else | |
2897 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA3); // 1.15V VPROC | |
2898 | #endif | |
2899 | ||
2900 | mt_cpufreq_pmic_volt[0] = 0x48; // 1.15V VPROC | |
2901 | mt_cpufreq_pmic_volt[1] = 0x48; // 1.15V VPROC | |
2902 | mt_cpufreq_pmic_volt[2] = 0x48; // 1.15V VPROC | |
2903 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2904 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2905 | #else | |
2906 | mt_cpufreq_pmic_volt[3] = 0x48; // 1.15V VPROC | |
2907 | #endif | |
2908 | #endif | |
2909 | ||
2910 | #ifdef CPUSTRESS_VPROC_1_25V_GPU_500MHZ_1BUCK | |
2911 | mt_cpufreq_reg_write(0x58, PMIC_WRAP_DVFS_WDATA0); // 1.25V VPROC | |
2912 | mt_cpufreq_reg_write(0x58, PMIC_WRAP_DVFS_WDATA1); // 1.25V VPROC | |
2913 | mt_cpufreq_reg_write(0x58, PMIC_WRAP_DVFS_WDATA2); // 1.25V VPROC | |
2914 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2915 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA3); // 1.05V VPROC | |
2916 | #else | |
2917 | mt_cpufreq_reg_write(0x58, PMIC_WRAP_DVFS_WDATA3); // 1.25V VPROC | |
2918 | #endif | |
2919 | ||
2920 | mt_cpufreq_pmic_volt[0] = 0x58; // 1.25V VPROC | |
2921 | mt_cpufreq_pmic_volt[1] = 0x58; // 1.25V VPROC | |
2922 | mt_cpufreq_pmic_volt[2] = 0x58; // 1.25V VPROC | |
2923 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2924 | mt_cpufreq_pmic_volt[3] = 0x38; // 1.05V VPROC | |
2925 | #else | |
2926 | mt_cpufreq_pmic_volt[3] = 0x58; // 1.25V VPROC | |
2927 | #endif | |
2928 | #endif | |
2929 | ||
2930 | /* DVFS table(4)-(7) for SPM control in deep idle */ | |
2931 | #ifdef MT_DVFS_LOW_VOLTAGE_SUPPORT | |
2932 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2933 | ||
2934 | if(g_cpufreq_get_vcore_corner == false) | |
2935 | { | |
2936 | mt_cpufreq_reg_write(0x18, PMIC_WRAP_DVFS_WDATA4); // 0.85V VPROC, for spm control in deep idle | |
2937 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
2938 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VCORE, for spm control in deep idle | |
2939 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VCORE, for spm control in deep idle | |
2940 | ||
2941 | /* For PTP-OD */ | |
2942 | mt_cpufreq_pmic_volt[4] = 0x18; // 0.85V VPROC, for spm control in deep idle | |
2943 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2944 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VCORE, for spm control in deep idle | |
2945 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VCORE, for spm control in deep idle | |
2946 | } | |
2947 | else | |
2948 | { | |
2949 | mt_cpufreq_reg_write(0x18, PMIC_WRAP_DVFS_WDATA4); // 0.85V VPROC, for spm control in deep idle | |
2950 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA5); // 1.185V VPROC, for spm control in deep idle | |
2951 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VCORE, for spm control in deep idle | |
2952 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA7); // 1.185V VCORE, for spm control in deep idle | |
2953 | ||
2954 | /* For PTP-OD */ | |
2955 | mt_cpufreq_pmic_volt[4] = 0x18; // 0.85V VPROC, for spm control in deep idle | |
2956 | mt_cpufreq_pmic_volt[5] = 0x4E; // 1.185V VPROC, for spm control in deep idle | |
2957 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VCORE, for spm control in deep idle | |
2958 | mt_cpufreq_pmic_volt[7] = 0x4E; // 1.185V VCORE, for spm control in deep idle | |
2959 | } | |
2960 | #else | |
2961 | mt_cpufreq_reg_write(0x18, PMIC_WRAP_DVFS_WDATA4); // 0.85V VPROC, for spm control in deep idle | |
2962 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
2963 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VCORE, for spm control in deep idle | |
2964 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VCORE, for spm control in deep idle | |
2965 | ||
2966 | /* For PTP-OD */ | |
2967 | mt_cpufreq_pmic_volt[4] = 0x18; // 0.85V VPROC, for spm control in deep idle | |
2968 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2969 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VCORE, for spm control in deep idle | |
2970 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VCORE, for spm control in deep idle | |
2971 | #endif | |
2972 | #else | |
2973 | #ifdef CPUFREQ_SDIO_TRANSFER | |
2974 | ||
2975 | if(g_cpufreq_get_vcore_corner == false) | |
2976 | { | |
2977 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA4); // 1.05V VPROC, for spm control in deep idle | |
2978 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
2979 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VPROC, for spm control in deep idle | |
2980 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VPROC, for spm control in deep idle | |
2981 | ||
2982 | /* For PTP-OD */ | |
2983 | mt_cpufreq_pmic_volt[4] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2984 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2985 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2986 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
2987 | } | |
2988 | else | |
2989 | { | |
2990 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA4); // 1.05V VPROC, for spm control in deep idle | |
2991 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA5); // 1.185V VPROC, for spm control in deep idle | |
2992 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VPROC, for spm control in deep idle | |
2993 | mt_cpufreq_reg_write(0x4E, PMIC_WRAP_DVFS_WDATA7); // 1.185V VPROC, for spm control in deep idle | |
2994 | ||
2995 | /* For PTP-OD */ | |
2996 | mt_cpufreq_pmic_volt[4] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2997 | mt_cpufreq_pmic_volt[5] = 0x4E; // 1.185V VPROC, for spm control in deep idle | |
2998 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
2999 | mt_cpufreq_pmic_volt[7] = 0x4E; // 1.185V VPROC, for spm control in deep idle | |
3000 | } | |
3001 | #else | |
3002 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA4); // 1.05V VPROC, for spm control in deep idle | |
3003 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA5); // 1.15V VPROC, for spm control in deep idle | |
3004 | mt_cpufreq_reg_write(0x38, PMIC_WRAP_DVFS_WDATA6); // 1.05V VPROC, for spm control in deep idle | |
3005 | mt_cpufreq_reg_write(0x48, PMIC_WRAP_DVFS_WDATA7); // 1.15V VPROC, for spm control in deep idle | |
3006 | ||
3007 | /* For PTP-OD */ | |
3008 | mt_cpufreq_pmic_volt[4] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
3009 | mt_cpufreq_pmic_volt[5] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
3010 | mt_cpufreq_pmic_volt[6] = 0x38; // 1.05V VPROC, for spm control in deep idle | |
3011 | mt_cpufreq_pmic_volt[7] = 0x48; // 1.15V VPROC, for spm control in deep idle | |
3012 | ||
3013 | #endif | |
3014 | #endif | |
3015 | ||
3016 | ||
3017 | #if 0 | |
3018 | spm_dvfs_ctrl_volt(1); // default set to 1.15V | |
3019 | ||
3020 | #else | |
3021 | if((g_cpufreq_get_ptp_level >= 0) && (g_cpufreq_get_ptp_level <= 4)) | |
3022 | spm_dvfs_ctrl_volt(2); // default set to 1.15V | |
3023 | else if((g_cpufreq_get_ptp_level >= 5) && (g_cpufreq_get_ptp_level <= 6)) | |
3024 | spm_dvfs_ctrl_volt(1); // default set to 1.15V | |
3025 | else | |
3026 | spm_dvfs_ctrl_volt(2); // default set to 1.15V | |
3027 | #endif | |
3028 | ||
3029 | #ifdef CPUFREQ_SDIO_TRANSFER | |
3030 | cpufreq_min_sampling_rate_change(CPUFREQ_MIN_SAMPLE_RATE_CHANGE); | |
3031 | #endif | |
3032 | ||
3033 | return cpufreq_register_driver(&mt_cpufreq_driver); | |
3034 | } | |
3035 | ||
3036 | /*************************************** | |
3037 | * this function should never be called | |
3038 | ****************************************/ | |
3039 | static int mt_cpufreq_pdrv_remove(struct platform_device *pdev) | |
3040 | { | |
3041 | return 0; | |
3042 | } | |
3043 | ||
3044 | static int mt_cpufreq_suspend(struct device *device) | |
3045 | { | |
3046 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq_suspend\n"); | |
3047 | ||
3048 | #ifndef MT_DVFS_RANDOM_TEST | |
3049 | ||
3050 | /* To keep early suspend CPU freq/voltage in suspend function for IPO-H feature */ | |
3051 | ||
3052 | mt_cpufreq_limit_max_freq_early_suspend = true; | |
3053 | mt_cpufreq_limit_max_freq_by_early_suspend(); | |
3054 | ||
3055 | /* Deep idle could control vproc now. */ | |
3056 | mt_cpufreq_earlysuspend_allow_deepidle_control_vproc = true; | |
3057 | ||
3058 | #endif | |
3059 | ||
3060 | return 0; | |
3061 | } | |
3062 | ||
3063 | static int mt_cpufreq_resume(struct device *device) | |
3064 | { | |
3065 | xlog_printk(ANDROID_LOG_INFO, "Power/DVFS", "mt_cpufreq_resume\n"); | |
3066 | ||
3067 | return 0; | |
3068 | } | |
3069 | ||
3070 | static struct dev_pm_ops mt_cpufreq_pdrv_pm_ops = { | |
3071 | .suspend = mt_cpufreq_suspend, | |
3072 | .resume = mt_cpufreq_resume, | |
3073 | .freeze = mt_cpufreq_suspend, | |
3074 | .thaw = mt_cpufreq_resume, | |
3075 | .poweroff = NULL, | |
3076 | .restore = mt_cpufreq_resume, | |
3077 | .restore_noirq = NULL, | |
3078 | }; | |
3079 | ||
3080 | ||
3081 | static struct platform_driver mt_cpufreq_pdrv = { | |
3082 | .probe = mt_cpufreq_pdrv_probe, | |
3083 | .remove = mt_cpufreq_pdrv_remove, | |
3084 | .suspend = NULL, | |
3085 | .resume = NULL, | |
3086 | .driver = { | |
3087 | #ifdef CONFIG_PM | |
3088 | .pm = &mt_cpufreq_pdrv_pm_ops, | |
3089 | #endif | |
3090 | .name = "mt-cpufreq", | |
3091 | .owner = THIS_MODULE, | |
3092 | }, | |
3093 | }; | |
3094 | ||
3095 | ||
3096 | static const struct file_operations mt_cpufreq_debug_fops = { | |
3097 | .owner = THIS_MODULE, | |
3098 | .write = mt_cpufreq_debug_write, | |
3099 | .open = mt_cpufreq_debug_open, | |
3100 | .read = seq_read, | |
3101 | .llseek = seq_lseek, | |
3102 | .release = single_release, | |
3103 | }; | |
3104 | ||
3105 | static const struct file_operations mt_cpufreq_limited_power_fops = { | |
3106 | .owner = THIS_MODULE, | |
3107 | .write = mt_cpufreq_limited_power_write, | |
3108 | .open = mt_cpufreq_limited_power_open, | |
3109 | .read = seq_read, | |
3110 | .llseek = seq_lseek, | |
3111 | .release = single_release, | |
3112 | }; | |
3113 | ||
3114 | static const struct file_operations mt_cpufreq_state_fops = { | |
3115 | .owner = THIS_MODULE, | |
3116 | .write = mt_cpufreq_state_write, | |
3117 | .open = mt_cpufreq_state_open, | |
3118 | .read = seq_read, | |
3119 | .llseek = seq_lseek, | |
3120 | .release = single_release, | |
3121 | }; | |
3122 | ||
3123 | static const struct file_operations mt_cpufreq_power_dump_fops = { | |
3124 | .owner = THIS_MODULE, | |
3125 | .open = mt_cpufreq_power_dump_open, | |
3126 | .read = seq_read, | |
3127 | .llseek = seq_lseek, | |
3128 | .release = single_release, | |
3129 | }; | |
3130 | ||
3131 | #if defined(CONFIG_THERMAL_LIMIT_TEST) | |
3132 | static const struct file_operations mt_cpufreq_limited_load_fops = { | |
3133 | .owner = THIS_MODULE, | |
3134 | .write = mt_cpufreq_limited_load_write, | |
3135 | .open = mt_cpufreq_limited_load_open, | |
3136 | .read = seq_read, | |
3137 | .llseek = seq_lseek, | |
3138 | .release = single_release, | |
3139 | }; | |
3140 | #endif | |
3141 | ||
3142 | #ifdef CPUFREQ_SDIO_TRANSFER | |
3143 | static const struct file_operations mt_cpufreq_sdio_info_fops = { | |
3144 | .owner = THIS_MODULE, | |
3145 | .open = mt_cpufreq_sdio_info_open, | |
3146 | .read = seq_read, | |
3147 | .llseek = seq_lseek, | |
3148 | .release = single_release, | |
3149 | }; | |
3150 | #endif | |
3151 | ||
3152 | #ifdef MT_DVFS_PTPOD_TEST | |
3153 | static const struct file_operations mt_cpufreq_ptpod_test_fops = { | |
3154 | .owner = THIS_MODULE, | |
3155 | .write = mt_cpufreq_ptpod_test_write, | |
3156 | }; | |
3157 | #endif | |
3158 | ||
3159 | static const struct file_operations mt_cpufreq_ptpod_freq_volt_fops = { | |
3160 | .owner = THIS_MODULE, | |
3161 | .open = mt_cpufreq_ptpod_freq_volt_open, | |
3162 | .read = seq_read, | |
3163 | .llseek = seq_lseek, | |
3164 | .release = single_release, | |
3165 | }; | |
3166 | ||
3167 | /*********************************************************** | |
3168 | * cpufreq initialization to register cpufreq platform driver | |
3169 | ************************************************************/ | |
3170 | static int __init mt_cpufreq_pdrv_init(void) | |
3171 | { | |
3172 | int ret = 0; | |
3173 | ||
3174 | struct proc_dir_entry *mt_entry = NULL; | |
3175 | struct proc_dir_entry *mt_cpufreq_dir = NULL; | |
3176 | ||
3177 | mt_cpufreq_dir = proc_mkdir("cpufreq", NULL); | |
3178 | if (!mt_cpufreq_dir) | |
3179 | { | |
3180 | pr_err("[%s]: mkdir /proc/cpufreq failed\n", __FUNCTION__); | |
3181 | } | |
3182 | else | |
3183 | { | |
3184 | mt_entry = proc_create("cpufreq_debug", S_IRUGO | S_IWUSR | S_IWGRP, mt_cpufreq_dir, &mt_cpufreq_debug_fops); | |
3185 | if (!mt_entry) | |
3186 | { | |
3187 | pr_err("[%s]: mkdir /proc/cpufreq/cpufreq_debug failed\n", __FUNCTION__); | |
3188 | } | |
3189 | ||
3190 | mt_entry = proc_create("cpufreq_limited_power", S_IRUGO | S_IWUSR | S_IWGRP, mt_cpufreq_dir, &mt_cpufreq_limited_power_fops); | |
3191 | if (!mt_entry) | |
3192 | { | |
3193 | pr_err("[%s]: mkdir /proc/cpufreq/cpufreq_limited_power failed\n", __FUNCTION__); | |
3194 | } | |
3195 | ||
3196 | mt_entry = proc_create("cpufreq_state", S_IRUGO | S_IWUSR | S_IWGRP, mt_cpufreq_dir, &mt_cpufreq_state_fops); | |
3197 | if (!mt_entry) | |
3198 | { | |
3199 | pr_err("[%s]: mkdir /proc/cpufreq/cpufreq_state failed\n", __FUNCTION__); | |
3200 | } | |
3201 | ||
3202 | mt_entry = proc_create("cpufreq_power_dump", S_IRUGO | S_IWUSR | S_IWGRP, mt_cpufreq_dir, &mt_cpufreq_power_dump_fops); | |
3203 | if (!mt_entry) | |
3204 | { | |
3205 | pr_err("[%s]: mkdir /proc/cpufreq/cpufreq_power_dump failed\n", __FUNCTION__); | |
3206 | } | |
3207 | ||
3208 | #if defined(CONFIG_THERMAL_LIMIT_TEST) | |
3209 | mt_entry = proc_create("cpufreq_limited_load", S_IRUGO | S_IWUSR | S_IWGRP, mt_cpufreq_dir, &mt_cpufreq_limited_load_fops); | |
3210 | if (!mt_entry) | |
3211 | { | |
3212 | pr_err("[%s]: mkdir /proc/cpufreq/cpufreq_limited_load failed\n", __FUNCTION__); | |
3213 | } | |
3214 | #endif | |
3215 | ||
3216 | #ifdef MT_DVFS_PTPOD_TEST | |
3217 | mt_entry = proc_create("cpufreq_ptpod_test", S_IRUGO | S_IWUSR | S_IWGRP, mt_cpufreq_dir, &mt_cpufreq_ptpod_test_fops); | |
3218 | if (!mt_entry) | |
3219 | { | |
3220 | pr_err("[%s]: mkdir /proc/cpufreq/cpufreq_ptpod_test failed\n", __FUNCTION__); | |
3221 | } | |
3222 | #endif | |
3223 | ||
3224 | mt_entry = proc_create("cpufreq_ptpod_freq_volt", S_IRUGO | S_IWUSR | S_IWGRP, mt_cpufreq_dir, &mt_cpufreq_ptpod_freq_volt_fops); | |
3225 | if (!mt_entry) | |
3226 | { | |
3227 | pr_err("[%s]: mkdir /proc/cpufreq/cpufreq_ptpod_freq_volt failed\n", __FUNCTION__); | |
3228 | } | |
3229 | ||
3230 | #ifdef CPUFREQ_SDIO_TRANSFER | |
3231 | mt_entry = proc_create("cpufreq_sdio_info", S_IRUGO | S_IWUSR | S_IWGRP, mt_cpufreq_dir, &mt_cpufreq_sdio_info_fops); | |
3232 | if (!mt_entry) | |
3233 | { | |
3234 | pr_err("[%s]: mkdir /proc/cpufreq/cpufreq_sdio_info failed\n", __FUNCTION__); | |
3235 | } | |
3236 | #endif | |
3237 | } | |
3238 | ||
3239 | ret = platform_driver_register(&mt_cpufreq_pdrv); | |
3240 | if (ret) | |
3241 | { | |
3242 | xlog_printk(ANDROID_LOG_ERROR, "Power/DVFS", "failed to register cpufreq driver\n"); | |
3243 | return ret; | |
3244 | } | |
3245 | else | |
3246 | { | |
3247 | xlog_printk(ANDROID_LOG_ERROR, "Power/DVFS", "cpufreq driver registration done\n"); | |
3248 | xlog_printk(ANDROID_LOG_ERROR, "Power/DVFS", "g_cpufreq_get_ptp_level = %d\n", g_cpufreq_get_ptp_level); | |
3249 | return 0; | |
3250 | } | |
3251 | } | |
3252 | ||
3253 | static void __exit mt_cpufreq_pdrv_exit(void) | |
3254 | { | |
3255 | cpufreq_unregister_driver(&mt_cpufreq_driver); | |
3256 | } | |
3257 | ||
3258 | module_init(mt_cpufreq_pdrv_init); | |
3259 | module_exit(mt_cpufreq_pdrv_exit); | |
3260 | ||
3261 | MODULE_DESCRIPTION("MediaTek CPU Frequency Scaling driver"); | |
3262 | MODULE_LICENSE("GPL"); |