mtk_cooler_dtm.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include <linux/version.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/thermal.h>
  5. #include <linux/platform_device.h>
  6. #include <mt-plat/aee.h>
  7. #include <linux/types.h>
  8. #include <linux/proc_fs.h>
  9. #include "mt-plat/mtk_thermal_monitor.h"
  10. #include "mtk_thermal_typedefs.h"
  11. #include "mach/mt_thermal.h"
  12. #include <mach/mt_clkmgr.h>
  13. #include <mt_ptp.h>
  14. #include <mach/wd_api.h>
  15. #include <linux/slab.h>
  16. #include <linux/seq_file.h>
  17. #include <tscpu_settings.h>
  18. #if defined(CONFIG_ARCH_MT6755)
  19. #include "mach/mt_ppm_api.h"
  20. #else
  21. #include "mt_cpufreq.h"
  22. #endif
  23. /*=============================================================
  24. *Local variable definition
  25. *=============================================================*/
  26. int tscpu_cpu_dmips[CPU_COOLER_NUM] = { 0 };
  27. int mtktscpu_limited_dmips = 0; /* Use in mtk_thermal_platform.c */
  28. static int previous_step = -1;
  29. static unsigned int *cl_dev_state;
  30. static int Num_of_OPP;
  31. static struct thermal_cooling_device **cl_dev;
  32. static char *cooler_name;
  33. static unsigned int prv_stc_cpu_pwr_lim;
  34. unsigned int static_cpu_power_limit = 0x7FFFFFFF;
  35. unsigned int static_gpu_power_limit = 0x7FFFFFFF;
  36. /*=============================================================
  37. *Local function prototype
  38. *=============================================================*/
  39. static void set_static_cpu_power_limit(unsigned int limit);
  40. static void set_static_gpu_power_limit(unsigned int limit);
  41. /*=============================================================
  42. *Weak functions
  43. *=============================================================*/
  44. #if defined(CONFIG_ARCH_MT6755)
  45. void __attribute__ ((weak))
  46. mt_ppm_cpu_thermal_protect(unsigned int limited_power)
  47. {
  48. pr_err("E_WF: %s doesn't exist\n", __func__);
  49. }
  50. #else
  51. void __attribute__ ((weak))
  52. mt_cpufreq_thermal_protect(unsigned int limited_power)
  53. {
  54. pr_err("E_WF: %s doesn't exist\n", __func__);
  55. }
  56. #endif
  57. /*=============================================================*/
  58. static void set_static_cpu_power_limit(unsigned int limit)
  59. {
  60. unsigned int final_limit;
  61. prv_stc_cpu_pwr_lim = static_cpu_power_limit;
  62. static_cpu_power_limit = (limit != 0) ? limit : 0x7FFFFFFF;
  63. final_limit = MIN(adaptive_cpu_power_limit, static_cpu_power_limit);
  64. if (prv_stc_cpu_pwr_lim != static_cpu_power_limit) {
  65. tscpu_printk("set_static_cpu_power_limit% d, T=%d\n",
  66. (final_limit != 0x7FFFFFFF) ? final_limit : 0, tscpu_get_curr_temp());
  67. /*tscpu_print_all_temperature(0);*/
  68. #if defined(CONFIG_ARCH_MT6755)
  69. mt_ppm_cpu_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
  70. #else
  71. mt_cpufreq_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
  72. #endif
  73. }
  74. }
  75. static void set_static_gpu_power_limit(unsigned int limit)
  76. {
  77. unsigned int final_limit;
  78. static_gpu_power_limit = (limit != 0) ? limit : 0x7FFFFFFF;
  79. final_limit = MIN(adaptive_gpu_power_limit, static_gpu_power_limit);
  80. tscpu_printk("set_static_gpu_power_limit %d\n",
  81. (final_limit != 0x7FFFFFFF) ? final_limit : 0);
  82. mt_gpufreq_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
  83. }
  84. static int tscpu_set_power_consumption_state(void)
  85. {
  86. int i = 0;
  87. int power = 0;
  88. tscpu_dprintk("tscpu_set_power_consumption_state Num_of_OPP=%d\n", Num_of_OPP);
  89. /* in 92, Num_of_OPP=34 */
  90. for (i = 0; i < Num_of_OPP; i++) {
  91. if (1 == cl_dev_state[i]) {
  92. if (i != previous_step) {
  93. tscpu_printk("previous_opp=%d, now_opp=%d\n", previous_step, i);
  94. previous_step = i;
  95. mtktscpu_limited_dmips = tscpu_cpu_dmips[previous_step];
  96. if (Num_of_GPU_OPP == 3) {
  97. power =
  98. (i * 100 + 700) - mtk_gpu_power[Num_of_GPU_OPP -
  99. 1].gpufreq_power;
  100. set_static_cpu_power_limit(power);
  101. set_static_gpu_power_limit(mtk_gpu_power
  102. [Num_of_GPU_OPP -
  103. 1].gpufreq_power);
  104. tscpu_dprintk
  105. ("Num_of_GPU_OPP=%d, gpufreq_power=%d, power=%d\n",
  106. Num_of_GPU_OPP,
  107. mtk_gpu_power[Num_of_GPU_OPP - 1].gpufreq_power,
  108. power);
  109. } else if (Num_of_GPU_OPP == 2) {
  110. power = (i * 100 + 700) - mtk_gpu_power[1].gpufreq_power;
  111. set_static_cpu_power_limit(power);
  112. set_static_gpu_power_limit(mtk_gpu_power[1].gpufreq_power);
  113. tscpu_dprintk
  114. ("Num_of_GPU_OPP=%d, gpufreq_power=%d, power=%d\n",
  115. Num_of_GPU_OPP, mtk_gpu_power[1].gpufreq_power, power);
  116. } else if (Num_of_GPU_OPP == 1) {
  117. #if 0
  118. /* 653mW,GPU 500Mhz,1V(preloader default) */
  119. /* 1016mW,GPU 700Mhz,1.1V */
  120. power = (i * 100 + 700) - 653;
  121. #else
  122. power = (i * 100 + 700) - mtk_gpu_power[0].gpufreq_power;
  123. #endif
  124. set_static_cpu_power_limit(power);
  125. tscpu_dprintk
  126. ("Num_of_GPU_OPP=%d, gpufreq_power=%d, power=%d\n",
  127. Num_of_GPU_OPP, mtk_gpu_power[0].gpufreq_power, power);
  128. } else { /* TODO: fix this, temp solution, this project has over 5 GPU OPP... */
  129. power = (i * 100 + 700);
  130. set_static_cpu_power_limit(power);
  131. tscpu_dprintk
  132. ("Num_of_GPU_OPP=%d, gpufreq_power=%d, power=%d\n",
  133. Num_of_GPU_OPP, mtk_gpu_power[0].gpufreq_power, power);
  134. }
  135. }
  136. break;
  137. }
  138. }
  139. /* If temp drop to our expect value, we need to restore initial cpu freq setting */
  140. if (i == Num_of_OPP) {
  141. if (previous_step != -1) {
  142. tscpu_printk("Free all static thermal limit, previous_opp=%d\n",
  143. previous_step);
  144. previous_step = -1;
  145. mtktscpu_limited_dmips = tscpu_cpu_dmips[CPU_COOLER_NUM - 1]; /* highest dmips */
  146. set_static_cpu_power_limit(0);
  147. set_static_gpu_power_limit(0);
  148. }
  149. }
  150. return 0;
  151. }
  152. static int dtm_cpu_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
  153. {
  154. /* tscpu_dprintk("dtm_cpu_get_max_state\n"); */
  155. *state = 1;
  156. return 0;
  157. }
  158. static int dtm_cpu_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
  159. {
  160. int i = 0;
  161. /* tscpu_dprintk("dtm_cpu_get_cur_state %s\n", cdev->type); */
  162. for (i = 0; i < Num_of_OPP; i++) {
  163. if (!strcmp(cdev->type, &cooler_name[i * 20]))
  164. *state = cl_dev_state[i];
  165. }
  166. return 0;
  167. }
  168. static int dtm_cpu_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
  169. {
  170. int i = 0;
  171. /* tscpu_dprintk("dtm_cpu_set_cur_state %s\n", cdev->type); */
  172. for (i = 0; i < Num_of_OPP; i++) {
  173. if (!strcmp(cdev->type, &cooler_name[i * 20])) {
  174. cl_dev_state[i] = state;
  175. tscpu_set_power_consumption_state();
  176. break;
  177. }
  178. }
  179. return 0;
  180. }
  181. static struct thermal_cooling_device_ops mtktscpu_cooling_F0x2_ops = {
  182. .get_max_state = dtm_cpu_get_max_state,
  183. .get_cur_state = dtm_cpu_get_cur_state,
  184. .set_cur_state = dtm_cpu_set_cur_state,
  185. };
  186. /* Init local structure for AP coolers */
  187. static int init_cooler(void)
  188. {
  189. int i;
  190. int num = CPU_COOLER_NUM; /* 700~4000, 92 */
  191. cl_dev_state = kzalloc((num) * sizeof(unsigned int), GFP_KERNEL);
  192. if (cl_dev_state == NULL)
  193. return -ENOMEM;
  194. cl_dev = kzalloc((num) * sizeof(struct thermal_cooling_device *), GFP_KERNEL);
  195. if (cl_dev == NULL)
  196. return -ENOMEM;
  197. cooler_name = kzalloc((num) * sizeof(char) * 20, GFP_KERNEL);
  198. if (cooler_name == NULL)
  199. return -ENOMEM;
  200. for (i = 0; i < num; i++)
  201. sprintf(cooler_name + (i * 20), "cpu%02d", i); /* using index=>0=700,1=800 ~ 33=4000 */
  202. Num_of_OPP = num; /* CPU COOLER COUNT, not CPU OPP count */
  203. return 0;
  204. }
  205. static int __init mtk_cooler_dtm_init(void)
  206. {
  207. int err = 0, i;
  208. tscpu_dprintk("mtk_cooler_dtm_init: Start\n");
  209. err = init_cooler();
  210. if (err) {
  211. tscpu_printk("init_cooler fail\n");
  212. return err;
  213. }
  214. for (i = 0; i < Num_of_OPP; i++) {
  215. cl_dev[i] = mtk_thermal_cooling_device_register(&cooler_name[i * 20], NULL,
  216. &mtktscpu_cooling_F0x2_ops);
  217. }
  218. if (err) {
  219. tscpu_printk("tscpu_register_DVFS_hotplug_cooler fail\n");
  220. return err;
  221. }
  222. tscpu_dprintk("mtk_cooler_dtm_init: End\n");
  223. return 0;
  224. }
  225. static void __exit mtk_cooler_dtm_exit(void)
  226. {
  227. int i;
  228. tscpu_dprintk("mtk_cooler_dtm_exit\n");
  229. for (i = 0; i < Num_of_OPP; i++) {
  230. if (cl_dev[i]) {
  231. mtk_thermal_cooling_device_unregister(cl_dev[i]);
  232. cl_dev[i] = NULL;
  233. }
  234. }
  235. }
  236. module_init(mtk_cooler_dtm_init);
  237. module_exit(mtk_cooler_dtm_exit);